source: proto/Compiler/pablo.py @ 3520

Last change on this file since 3520 was 3520, checked in by cameron, 6 years ago

Updates for carry_t = uint64_t support

File size: 42.6 KB
Line 
1#
2# Pablo.py - parallel bitstream to bitblock
3#  2nd generation compiler
4#
5# Copyright 2010, 2011, Robert D. Cameron, Kenneth S. Herdy
6# All rights reserved.
7#
8import ast, copy, sys
9import mkast
10import Cgen
11from carryInfo import *
12import CCGO
13import CCGO_HMCPS
14import lookAhead
15
16do_block_inline_decorator = 'IDISA_INLINE '
17do_final_block_inline_decorator = ''
18error_routine = 'raise_assert'
19experimentalMode=False
20pablo_char_type = 'char'
21
22
23def dump_Call(fncall):
24        if isinstance(fncall.func, ast.Name): print "fn_name = %s\n" % fncall.func.id
25        elif isinstance(fncall.func, ast.Attribute) and isinstance(fncall.func.value, ast.Name):
26                print "fn_name = %s.%s\n" % (fncall.func.value.id, fncall.func.attr)
27        print "len(fncall.args) = %s\n" % len(fncall.args)
28
29def is_simd_not(e):
30  return isinstance(e, ast.Call) and isinstance(e.func, ast.Name) and e.func.id == 'simd_not'
31
32
33#
34# Reducing AugAssign, e.g.  x |= y becomes x = x | y
35#
36class AugAssignRemoval(ast.NodeTransformer):
37  def xfrm(self, t):
38    return self.generic_visit(t)
39  def visit_AugAssign(self, e):
40    self.generic_visit(e)
41    return ast.Assign([e.target], ast.BinOp(e.target, e.op, e.value))
42#
43# pablo.Advance(pablo.Advance(x, n)) => pablo.Advance(x, n+1)
44#
45class AdvanceCombiner(ast.NodeTransformer):
46  def xfrm(self, t):
47    return self.generic_visit(t)
48  def visit_if(self, ifNode):
49    return IfNode
50  def visit_While(self, whileNode):
51    return whileNode
52  def visit_Call(self, callnode):
53    self.generic_visit(callnode)
54    if len(callnode.args) == 0: return callnode
55    if not isinstance(callnode.args[0], ast.Call): return callnode
56    if is_BuiltIn_Call(callnode,'Advance', 1):
57        if is_BuiltIn_Call(callnode.args[0],'Advance', 1):
58          callnode.args = [callnode.args[0].args[0], ast.Num(2)]
59        elif is_BuiltIn_Call(callnode.args[0], 'Advance', 2):
60          if isinstance(callnode.args[0].args[1], ast.Num):
61            callnode.args = [callnode.args[0].args[0], ast.Num(callnode.args[0].args[1].n + 1)]
62          else:
63            callnode.args = [callnode.args[0].args[0], ast.BinOp(callnode.args[0].args[1], ast.Add(), ast.Num(1))]
64    return callnode
65
66
67#
68#  Translating pablo.match(marker, str)
69#  Incremental character match with lookahead
70#
71CharNameMap = {'[' : 'LBrak', ']' : 'RBrak', '{' : 'LBrace', '}' : 'LBrace', '(' : 'LParen', ')' : 'RParen', \
72              '!' : 'Exclam', '"' : 'DQuote', '#' : 'Hash', '$' : 'Dollar', '%' : 'PerCent', '&': 'RefStart', \
73              "'" : 'SQuote', '*': 'Star', '+' : 'Plus', ',' : 'Comma', '-' : 'Hyphen', '.' : 'Dot', '/' : 'Slash', \
74              ':' : 'Colon', ';' : 'Semicolon', '=' : 'Equals', '?' : 'QMark', '@' : 'AtSign', '\\' : 'BackSlash', \
75              '^' : 'Caret', '_' : 'Underscore', '|' : 'VBar', '~' : 'Tilde', ' ' : 'SP', '\t' : 'HT', '\m' : 'CR', '\n' : 'LF'}
76
77def GetCharName(char):
78        if char >= 'a' and char <= 'z' or char >= 'A' and char <= 'Z': return 'letter_' + char
79        elif char >= '0' and char <= '9': return 'digit_' + char
80        else: return CharNameMap[char]
81
82def MkCharStream(char):
83        return mkast.Qname('lex', GetCharName(char))
84
85def MkLookAheadExpr(v, i):
86        return mkast.call(mkast.Qname('pablo', 'LookAhead'), [v, ast.Num(i)])
87
88def CompileMatch(match_var, string_to_match):
89        expr = mkast.call('simd_and', [match_var, MkCharStream(string_to_match[0])])
90        for i in range(1, len(string_to_match)):
91                expr = mkast.call('simd_and', [expr, MkLookAheadExpr(MkCharStream(string_to_match[i]), i)])
92        return expr
93
94class StringMatchCompiler(ast.NodeTransformer):
95  def xfrm(self, t):
96    return self.generic_visit(t)
97  def visit_Call(self, callnode):
98    if is_BuiltIn_Call(callnode,'match', 2):
99        ast.dump(callnode)
100        assert isinstance(callnode.args[0], ast.Str)
101        string_to_match = callnode.args[0].s
102        match_var = callnode.args[1]
103        expr = mkast.call('simd_and', [match_var, MkCharStream(string_to_match[0])])
104        for i in range(1, len(string_to_match)):
105                expr = mkast.call('simd_and', [expr, MkLookAheadExpr(MkCharStream(string_to_match[i]), i)])
106        return expr
107    else: return callnode
108
109
110
111#
112#  Converting expressions involving built-ins to compiled form. 
113#  Apply before carry variable insertion.
114#
115class TempifyBuiltins(ast.NodeTransformer):
116    def __init__(self, tempVarpfx = "tempvar"):
117      self.tempVarCount = 0
118      self.newTempList = []
119      self.tempVarPrefix = tempVarpfx
120    def genVar(self):
121      newTemp = self.tempVarPrefix + repr(self.tempVarCount)
122      self.newTempList.append(newTemp)
123      self.tempVarCount += 1
124      return newTemp
125    def tempVars(self):
126      return self.newTempList
127    def xfrm(self, t):
128      self.setUpStmts = []
129      self.assigNode = None
130      return self.generic_visit(t)
131    def is_Assign_value(self, node):
132      return self.assigNode != None and self.assigNode.value == node
133    def visit_If(self, ifNode):
134      self.setUpStmts = []
135      self.generic_visit(ifNode.test)
136      ifSetUpStmts = self.setUpStmts
137      self.generic_visit(ifNode)
138      if ifSetUpStmts == []: return ifNode
139      else: return ifSetUpStmts + [ifNode]
140    def visit_While(self, whileNode):
141      self.setUpStmts = []
142      self.generic_visit(whileNode.test)
143      whileSetUpStmts = self.setUpStmts
144      self.generic_visit(whileNode)
145      whileNode.body = whileNode.body + whileSetUpStmts
146      return whileSetUpStmts + [whileNode]
147    def visit_Assign(self, node):
148      self.assigNode = node
149      self.setUpStmts = []
150      self.generic_visit(node)
151      return self.setUpStmts + [node]
152    def visit_AugAssign(self, node):
153      self.setUpStmts = []
154      self.generic_visit(node)
155      return self.setUpStmts + [node]
156    def visit_Call(self, callnode):     
157        self.generic_visit(callnode)
158        if CheckForBuiltin(callnode) and not self.is_Assign_value(callnode):
159        #if not self.is_Assign_value(callnode):
160            tempVar = ast.Name(self.genVar(), ast.Load())
161            self.setUpStmts.append(ast.Assign([tempVar], callnode))
162            return tempVar
163        else: return callnode
164
165
166
167
168
169#
170# Introducing BitBlock logical operations
171#
172class Bitwise_to_SIMD(ast.NodeTransformer):
173  """
174  Make the following substitutions:
175     x & y => simd_and(x, y)
176     x & ~y => simd_andc(x, y)
177     x | y => simd_or(x, y)
178     x ^ y => simd_xor(x, y)
179     ~x    => simd_not(x)
180     0     => simd_const_1(0)
181     -1    => simd_const_1(1)
182     if x: => if bitblock::any(x):
183  while x: => while bitblock::any(x):
184  >>> ast_show(Bitwise_to_SIMD().xfrm(ast.parse("pfx = bit0 & bit1; sfx = bit0 &~ bit1")))
185 
186  pfx = simd_and(bit0, bit1)
187  sfx = simd_and(bit0, simd_not(bit1))
188  >>>
189  """
190  def xfrm(self, t):
191    return self.generic_visit(t)
192  def visit_UnaryOp(self, t):
193    self.generic_visit(t)
194    if isinstance(t.op, ast.Invert):
195      return mkast.call('simd_not', [t.operand])
196    else: return t
197  def visit_BinOp(self, t):
198    self.generic_visit(t)
199    if isinstance(t.op, ast.BitOr):
200      return mkast.call('simd_or', [t.left, t.right])
201    elif isinstance(t.op, ast.BitAnd):
202      if is_simd_not(t.right): return mkast.call('simd_andc', [t.left, t.right.args[0]])
203      elif is_simd_not(t.left): return mkast.call('simd_andc', [t.right, t.left.args[0]])
204      else: return mkast.call('simd_and', [t.left, t.right])
205    elif isinstance(t.op, ast.BitXor):
206      return mkast.call('simd_xor', [t.left, t.right])
207    else: return t
208  def visit_Num(self, numnode):
209    n = numnode.n
210    if n == 0: return mkast.call('simd<1>::constant<0>', [])
211    elif n == -1: return mkast.call('simd<1>::constant<1>', [])
212    else: return numnode
213  def visit_If(self, ifNode):
214    self.generic_visit(ifNode)
215    ifNode.test = mkast.call('bitblock::any', [ifNode.test])
216    return ifNode
217  def visit_While(self, whileNode):
218    self.generic_visit(whileNode)
219    whileNode.test = mkast.call('bitblock::any', [whileNode.test])
220    return whileNode
221  def visit_Subscript(self, numnode):
222    return numnode  # no recursive modifications of index expressions
223
224#
225#  Generating BitBlock declarations for Local Variables
226#
227class FunctionVars(ast.NodeVisitor):
228  def __init__(self,node):
229        self.params = []
230        self.stores = []
231        self.generic_visit(node)
232  def visit_Name(self, nm):
233    if isinstance(nm.ctx, ast.Param):
234      self.params.append(nm.id)
235    if isinstance(nm.ctx, ast.Store):
236      if nm.id not in self.stores: self.stores.append(nm.id)
237  def getLocals(self): 
238    return [v for v in self.stores if not v in self.params]
239
240MAX_LINE_LENGTH = 80
241
242def BitBlock_decls_from_vars(varlist):
243  global MAX_LINE_LENGTH
244  decls =  ""
245  if not len(varlist) == 0:
246          decls = "             BitBlock"
247          pending = ""
248          linelgth = 10
249          for v in varlist:
250            if linelgth + len(v) + 2 <= MAX_LINE_LENGTH:
251              decls += pending + " " + v
252              linelgth += len(pending + v) + 1
253            else:
254              decls += ";\n             BitBlock " + v
255              linelgth = 11 + len(v)
256            pending = ","
257          decls += ";"
258  return decls
259
260def BitBlock_decls_of_fn(fndef):
261  return BitBlock_decls_from_vars(FunctionVars(fndef).getLocals())
262
263def BitBlock_header_of_fn(fndef):
264  Ccode = "static inline void " + fndef.name + "("
265  pending = ""
266  for arg in fndef.args.args:
267    if isinstance(arg, ast.Name):
268      Ccode += pending + arg.id.upper()[0] + arg.id[1:] + " & " + arg.id
269      pending = ", "
270  if CarryCounter().count(fndef) > 0:
271    Ccode += pending + " CarryQtype & carryQ"
272  Ccode += ")"
273  return Ccode
274
275
276
277#
278#  Stream Initialization Statement Extraction
279#
280#  streamvar = 1 ==> streamvar = sisd_from_int(1) initially.
281class StreamInitializations(ast.NodeTransformer):
282  def xfrm(self, node):
283    self.stream_stmts = []
284    self.loop_post_inits = []
285    self.generic_visit(node)
286    return Cgen.py2C().gen(self.stream_stmts)
287  def visit_Assign(self, node):
288    if isinstance(node.value, ast.Num):
289      if node.value.n == 0: return node
290      elif node.value.n == -1: return node
291      else: 
292        stream_init = copy.deepcopy(node)
293        stream_init.value = mkast.call('sisd_from_int', [node.value])
294        loop_init = copy.deepcopy(node)
295        loop_init.value.n = 0
296        self.stream_stmts.append(stream_init)
297        self.loop_post_inits.append(loop_init)
298        return None
299    else: return node
300  def visit_FunctionDef(self, node):
301    self.generic_visit(node)
302    node.body = node.body + self.loop_post_inits
303    return node
304
305
306
307#
308# Carry Introduction Transformation
309#
310import CCGO_While
311
312def Strategic_CCGO_Factory(carryInfoSet):
313  BLOCK_SIZE = 128
314  if multicarryWhileMode: ccgo = CCGO_While.CCGO_While1(BLOCK_SIZE, carryInfoSet)
315  elif experimentalMode:
316    ops = carryInfoSet.operation_count
317    if ops == 0: ccgo = CCGO.CCGO()
318    elif ops <= 2: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 64, carryInfoSet, 'carryG', '__c')
319    elif ops <= 4: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 32, carryInfoSet, 'carryG', '__c')
320    #elif ops <= 8: ccgo = CCGO_HMCPS.HMCPS_CCGO(BLOCK_SIZE, 16, carryInfoSet, 'carryG', '__c')
321    #else: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 16, carryInfoSet, 'carryG', '__c')
322    else: ccgo = CCGO_HMCPS.HMCPS_CCGO_BitPack2(BLOCK_SIZE, 8, carryInfoSet, 'carryG', '__c')
323  else:
324    ccgo = CCGO.testCCGO(BLOCK_SIZE, carryInfoSet, 'carryQ')
325  ccgo.allocate_all()
326  return ccgo
327
328
329class CarryIntro(ast.NodeTransformer):
330  def __init__(self, ccgo, carryvar="carryQ", carryin = "_ci", carryout = "_co"):
331    self.carryvar = ast.Name(carryvar, ast.Load())
332    self.carryin = carryin
333    self.carryout = carryout
334    self.ccgo = ccgo
335  def xfrm_fndef(self, fndef):
336    self.block_no = 0
337    self.operation_count = 0
338    self.current_carry = 0
339    self.current_adv_n = 0
340    self.generic_visit(fndef)
341  def xfrm_fndef_final(self, fndef):
342    self.block_no = 0
343    self.operation_count = 0
344    self.carryout = ""
345    self.current_carry = 0
346    self.current_adv_n = 0
347    self.generic_visit(fndef)
348    return fndef
349  def generic_xfrm(self, node):
350    self.block_no = 0
351    self.operation_count = 0
352    self.current_carry = 0
353    self.current_adv_n = 0
354    self.last_stmt = None
355    self.last_stmt_carries = 0
356    self.generic_visit(node)
357    return node
358   
359  def local_while_xfrm(self, local_carryvar, whileNode):
360    saved_state = (self.block_no, self.operation_count, self.carryvar, self.carryin, self.carryout, self.current_carry, self.current_adv_n)
361    (self.carryvar, self.carryin, self.current_carry, self.current_adv_n) = (local_carryvar, '', 0, 0)
362    #(self.carryvar, self.carryin) = (local_carryvar, '')
363    self.ccgo.EnterLocalWhileBlock(self.operation_count);
364    inner_while = self.generic_visit(whileNode)
365    self.ccgo.ExitLocalWhileBlock();
366    (self.block_no, self.operation_count, self.carryvar, self.carryin, self.carryout, self.current_carry, self.current_adv_n) = saved_state
367    return inner_while
368   
369  def visit_Call(self, callnode):
370    self.generic_visit(callnode)
371#    if self.carryout == "" and is_BuiltIn_Call(callnode, 'simd_not', 1):
372#      return [mkast.call('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[0]])]
373    if is_BuiltIn_Call(callnode, 'atEOF', 1):
374      if self.carryout != "": 
375        # Non final block: atEOF(x) = 0.
376        return mkast.call('simd<1>::constant<0>', [])
377      else: 
378        mask1 = mkast.call('bitblock::slli<1>', [mkast.call('simd_not', [ast.Name('EOF_mask', ast.Load())])])
379        return mkast.call('simd_andc', [mkast.call('simd_andc', [callnode.args[0], ast.Name('EOF_mask', ast.Load())]), mask1])
380    elif is_BuiltIn_Call(callnode, 'inFile', 1):
381      if self.carryout != "": 
382        # Non final block: inFile(x) = x.
383        return callnode.args[0]
384      else: return mkast.call('simd_and', [callnode.args[0], ast.Name('EOF_mask', ast.Load())])
385    elif is_BuiltIn_Call(callnode, 'StreamScan', 2):
386      rtn = "StreamScan"           
387      c = mkast.call(rtn, [ast.Name('(ScanBlock *) &' + callnode.args[0].id, ast.Load()), 
388                                           ast.Name('sizeof(BitBlock)/sizeof(ScanBlock)', ast.Load()),
389                                           ast.Name(callnode.args[1].id, ast.Load())])
390      return c
391    elif is_BuiltIn_Call(callnode,'match', 3):
392        assert isinstance(callnode.args[1], ast.Str)
393        string_to_match = callnode.args[1].s
394        match_len = len(string_to_match)
395        match_var = callnode.args[2]
396        expr = mkast.call('pablo_blk_match<%s>' % pablo_char_type, [callnode.args[0], callnode.args[1], match_var, ast.Num(match_len)]) 
397        return expr
398    else:
399      #dump_Call(callnode)
400      return callnode
401  def visit_BinOp(self, exprnode):
402    self.generic_visit(exprnode)
403    carry_args = [ast.Num(self.current_carry)]
404    if self.carryin == "_ci":
405        carry_args = [mkast.call(self.carryvar.id + "." + 'get_carry_in', [ast.Num(self.current_carry)]), ast.Num(self.current_carry)]
406    else: 
407        carry_args = [mkast.call('simd<1>::constant<0>', []), ast.Num(self.current_carry)]
408    if isinstance(exprnode.op, ast.Sub):
409      assert False, "Subtraction no longer supported - use pablo.SpanUpTo ..."
410    elif isinstance(exprnode.op, ast.Add):
411      assert False, "Addition no longer supported - use pablo.Scan ..."
412    else: return exprnode
413  def visit_Assign(self, assigNode):
414    self.last_stmt_carries = CarryCounter().count(assigNode)
415    f = CheckForBuiltin(assigNode.value)
416    if f == None: 
417            self.generic_visit(assigNode)
418            self.last_stmt = assigNode
419            return assigNode
420    elif isCarryGenerating(f) or (isAdvance(f) and ((len(assigNode.value.args) == 1) or (assigNode.value.args[1].n==1))):
421    # We have an assignment v = pablo.SomeCarryGeneratingFunction()
422            if self.carryin == "_ci":
423                carry_in_expr = self.ccgo.GenerateCarryInAccess(self.operation_count)
424            else: 
425                carry_in_expr = mkast.var('Carry0')
426            callnode = assigNode.value
427            if isAdvance(f):
428               pablo_routine_call = mkast.call('pablo_blk_' + f, [assigNode.value.args[0], carry_in_expr, assigNode.targets[0]])
429            elif f in ['ScanTo', 'AdvanceThenScanTo']:
430               if self.carryout == "":  scanclass = mkast.call('simd_andc', [ast.Name('EOF_mask', ast.Load()), callnode.args[1]])
431               else: scanclass = mkast.call('simd_not', [callnode.args[1]])
432               pablo_routine_call = mkast.call('pablo_blk_' +f[:-2] + 'Thru', [callnode.args[0], scanclass, carry_in_expr, assigNode.targets[0]])
433            else:
434               pablo_routine_call = mkast.call('pablo_blk_' + f, assigNode.value.args + [carry_in_expr, assigNode.targets[0]])
435            self.last_stmt = pablo_routine_call
436            compiled = self.ccgo.GenerateCarryOutStore(self.operation_count, pablo_routine_call)
437            self.operation_count += 1
438            self.current_carry += 1
439            return compiled
440    elif isAdvance(f):
441            if self.carryin == "_ci":
442                carry_in_expr = self.ccgo.GenerateAdvanceInAccess(self.operation_count)
443            else: 
444                carry_in_expr = mkast.var('Carry0')
445            callnode = assigNode.value
446            pablo_routine_call = mkast.call('pablo_blk_Advance_n_<%i>' %  assigNode.value.args[1].n, [assigNode.value.args[0], carry_in_expr, assigNode.targets[0]])
447            self.last_stmt = pablo_routine_call
448            compiled = self.ccgo.GenerateAdvanceOutStore(self.operation_count, pablo_routine_call)
449            self.operation_count += 1
450            self.current_adv_n += 1
451            return compiled
452
453    else:
454            self.generic_visit(assigNode)
455            self.last_stmt = assigNode
456            self.operation_count += 1
457            return assigNode
458           
459           
460  def visit_If(self, ifNode):
461    self.block_no += 1
462    this_block = self.block_no
463    carry_base = self.current_carry
464    carries = CarryCounter().count(ifNode)
465    #assert adv_nCounter().count(ifNode) == 0, "Advance(x,n) within if: illegal\n"
466    self.generic_visit(ifNode)
467    if carries == 0: # or self.carryin == "":
468      self.last_stmt = ifNode
469      return ifNode
470    #CARRYSET
471    carry_arglist = [ast.Num(carry_base), ast.Num(carries)]
472    #new_test = ast.BoolOp(ast.Or(), [ifNode.test, mkast.call(ast.Attribute(self.carryvar, 'CarryTest', ast.Load()), carry_arglist)])
473    #new_else_part = ifNode.orelse + [mkast.callStmt(ast.Attribute(self.carryvar, 'CarryDequeueEnqueue', ast.Load()), carry_arglist)]
474    if self.carryin == "": new_test = ifNode.test
475    else: new_test = self.ccgo.GenerateCarryIfTest(this_block, ifNode.test)
476    new_then_part = ifNode.body + self.ccgo.GenerateCarryThenFinalization(this_block)
477    new_else_part = ifNode.orelse + self.ccgo.GenerateCarryElseFinalization(this_block)
478    newIf = ast.If(new_test, new_then_part, new_else_part)
479    self.last_stmt = newIf
480    self.last_stmt_carries = carries
481    return newIf
482
483
484  def is_while_special_case(self, whileNode):
485    #
486    # Special case optimization for pattern:
487    #   m=pablo.scan...()
488    #   while m:
489    #      S
490    #      m=pablo.scan...()
491    #
492    # Determine the original test expression, now encloded in bitblock::any()
493    original_test_expr = whileNode.test.args[0]
494    if not isinstance(original_test_expr, ast.Name): return False
495    test_var = original_test_expr.id
496    if not isinstance(self.last_stmt, ast.Assign): return False
497    if not isinstance(whileNode.body[-1], ast.Assign): return False
498    if len(self.last_stmt.targets) != 1: return False
499    if len(whileNode.body[-1].targets) != 1: return False
500    if not isinstance(self.last_stmt.targets[0], ast.Name): return False
501    if not isinstance(whileNode.body[-1].targets[0], ast.Name): return False
502    if self.last_stmt.targets[0].id != test_var: return False
503    if whileNode.body[-1].targets[0].id != test_var: return False
504    if self.last_stmt_carries != 1: return False
505    if CarryCounter().count(whileNode.body[-1]) != 1: return False
506    return True
507
508  def multicarry_While(self, whileNode):
509    self.block_no += 1
510    this_block = self.block_no
511    original_test_expr = whileNode.test.args[0]
512    if self.carryout == '':
513      whileNode.test.args[0] = mkast.call("simd_and", [original_test_expr, ast.Name('EOF_mask', ast.Load())])
514
515    self.generic_visit(whileNode)
516    local_carry_decl = self.ccgo.GenerateLocalDeclare(this_block)
517    whileNode.body = local_carry_decl + whileNode.body
518    whileNode.test = self.ccgo.GenerateCarryWhileTest(this_block, whileNode.test)
519    final_combine = self.ccgo.GenerateCarryWhileFinalization(this_block)
520    return [whileNode] + final_combine
521
522
523  def visit_While(self, whileNode):
524    if multicarryWhileMode: return self.multicarry_While(whileNode)
525
526    # Determine the original test expression, now encloded in bitblock::any()
527    self.block_no += 1
528    this_block = self.block_no
529    original_test_expr = whileNode.test.args[0]
530    if self.carryout == '':
531      whileNode.test.args[0] = mkast.call("simd_and", [original_test_expr, ast.Name('EOF_mask', ast.Load())])
532    carry_base = self.current_carry
533    assert adv_nCounter().count(whileNode) == 0, "Advance(x,n) within while: illegal\n"
534    carries = CarryCounter().count(whileNode)
535#   Special Case Recognition
536    is_special = self.is_while_special_case(whileNode)
537    #CARRYSET
538    if carries == 0: return whileNode
539
540    local_carryvar = ast.Name('sub' + self.carryvar.id, ast.Load())
541    inner_while = self.local_while_xfrm(local_carryvar, copy.deepcopy(whileNode))
542    self.generic_visit(whileNode)
543    local_carry_decl = self.ccgo.GenerateLocalDeclare(this_block)
544    #local_carry_decl = []
545    #local_carry_decl = mkast.callStmt('LocalCarryDeclare', [local_carryvar, ast.Num(carries)])
546    inner_while.body = local_carry_decl + inner_while.body
547    #final_combine = mkast.callStmt(ast.Attribute(self.carryvar, 'CarryCombine', ast.Load()), [ast.Attribute(local_carryvar, 'cq', ast.Load()),ast.Num(carry_base), ast.Num(carries)])
548    final_combine = self.ccgo.GenerateCarryWhileFinalization(this_block)
549    inner_while.body += final_combine
550    #CARRYSET
551
552#   Special Case Optimization
553    if is_special:
554      # We combine the final carry into the one preceeding the loop.
555      combine1 = mkast.callStmt(ast.Attribute(self.carryvar, 'CarryCombine1', ast.Load()), [ast.Num(carry_base-1), ast.Num(carry_base+carries-1)])
556      while_body_extend = [inner_while, combine1]
557      # The carry test can skip the final case.
558      carry_test_arglist = [ast.Num(carry_base), ast.Num(carries-1)]
559    else: 
560      carry_test_arglist = [ast.Num(carry_base), ast.Num(carries)]
561      while_body_extend = [inner_while]
562
563    if self.carryin == '': new_test = whileNode.test
564    else: new_test = self.ccgo.GenerateCarryWhileTest(this_block, whileNode.test)
565    else_part = [self.ccgo.GenerateCarryElseFinalization(this_block)]   
566    newIf = ast.If(new_test, whileNode.body + while_body_extend, else_part)
567    self.last_stmt = newIf
568    self.last_stmt_carries = carries
569    return newIf
570
571class StreamStructGen(ast.NodeVisitor):
572  """
573  Given a BitStreamSet subclass, generate the equivalent C struct.
574  >>> obj = ast.parse(r'''
575  ... class S1(BitStreamSet):
576  ...   a1 = 0
577  ...   a2 = 0
578  ...   a3 = 0
579  ...
580  ... class S2(BitStreamSet):
581  ...   x1 = 0
582  ...   x2 = 0
583  ... ''')
584  >>> print StreamStructGen().gen(obj)
585  struct S1 {
586    BitBlock a1;
587    BitBlock a2;
588    BitBlock a3;
589  }    self.current_adv_n = 0
590
591 
592  struct S2 {
593    BitBlock x1;
594    BitBlock x2;
595  }
596  """
597  def __init__(self, asType=False):
598    self.asType = asType
599  def gen(self, tree):
600    self.Ccode=""
601    self.generic_visit(tree)
602    return self.Ccode
603  def gen_struct_types(self, tree):
604    self.asType = True
605    self.Ccode=""
606    self.generic_visit(tree)
607    return self.Ccode
608  def gen_struct_vars(self, tree):
609    self.asType = False
610    self.Ccode=""
611    self.generic_visit(tree)
612    return self.Ccode
613  def visit_ClassDef(self, node):
614    class_name = node.name[0].upper() + node.name[1:]
615    instance_name = node.name[0].lower() + node.name[1:]
616    self.Ccode += "  struct " + class_name
617    if self.asType:
618            self.Ccode += " {\n"
619            for stmt in node.body:
620              if isinstance(stmt, ast.Assign):
621                for v in stmt.targets:
622                  if isinstance(v, ast.Name):
623                    self.Ccode += "  BitBlock " + v.id + ";\n"
624            self.Ccode += "}" 
625    else: self.Ccode += " " + instance_name
626    self.Ccode += ";\n\n"
627 
628class StreamFunctionDecl(ast.NodeVisitor):
629  def __init__(self):
630    pass
631  def gen(self, tree):
632    self.Ccode=""
633    self.generic_visit(tree)
634    return self.Ccode
635  def visit_FunctionDef(self, node):
636    self.Ccode += "static inline void " + node.name + "("
637    pending = ""
638    for arg in node.args.args:
639      if isinstance(arg, ast.Name):
640        self.Ccode += pending + arg.id.upper()[0] + arg.id[1:] + " & " + arg.id
641        pending = ", "
642    self.Ccode += ");\n"
643
644class AssertCompiler(ast.NodeTransformer):
645  def __init__(self):
646    self.assert_routine = ast.parse(error_routine).body[0].value
647  def xfrm(self, t):
648    return self.generic_visit(t)
649  def visit_Expr(self, node):
650    if isinstance(node.value, ast.Call):
651        if is_BuiltIn_Call(node.value, "assert_0", 2):
652                err_stream = node.value.args[0]
653                err_code = node.value.args[1]
654                return ast.If(mkast.call('bitblock::any', [err_stream]),
655                              [ast.Expr(mkast.call(self.assert_routine, [err_code, err_stream]))],
656                              [])
657        else: return node
658    else: return node
659       
660#
661# Adding Debugging Statements
662#
663class Add_SIMD_Register_Dump(ast.NodeTransformer):
664  def xfrm(self, t):
665    return self.generic_visit(t)
666  def visit_Assign(self, t):
667    self.generic_visit(t)
668    v = t.targets[0]
669    dump_stmt = mkast.callStmt('print_register<BitBlock>', [ast.Str(Cgen.py2C().gen(v)), v])
670    return [t, dump_stmt]
671
672#
673# Adding ASSERT_BITBLOCK_ALIGN macros
674#
675class Add_Assert_BitBlock_Align(ast.NodeTransformer):
676    def xfrm(self, t):
677      return self.generic_visit(t)
678    def visit_Assign(self, t):
679      self.generic_visit(t)
680      v = t.targets[0]
681      dump_stmt = mkast.callStmt(' ASSERT_BITBLOCK_ALIGN', [v])
682      return [t, dump_stmt]
683
684class StreamFunctionCarryCounter(ast.NodeVisitor):
685  def __init__(self):
686        self.carry_count = {}
687       
688  def count(self, node):
689        self.generic_visit(node)
690        return self.carry_count
691                                   
692  def visit_FunctionDef(self, node):   
693        type_name = node.name[0].upper() + node.name[1:]                       
694        self.carry_count[type_name] = CarryCounter().count(node)
695     
696class StreamFunctionCallXlator(ast.NodeTransformer):
697  def __init__(self, xlate_type="normal"):
698        self.stream_function_type_names = []
699        self.xlate_type = xlate_type
700
701  def xfrm(self, node, stream_function_type_names, C_syntax):
702        self.stream_function_type_names = stream_function_type_names
703        self.C_syntax = C_syntax
704        self.generic_visit(node)
705       
706  def visit_Call(self, node):   
707        self.generic_visit(node)
708
709        if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):# and node.func.id in self.stream_function_type_names:
710             name = lower1(node.func.id)
711             node.func.id = name + ("_" if self.C_syntax else ".") + ("do_final_block" if self.xlate_type == "final" else "do_block")
712             if self.C_syntax:
713                     node.args = [ast.Name(lower1(name), ast.Load())] + node.args
714             if self.xlate_type == "final":
715                   node.args = node.args + [ast.Name("EOF_mask", ast.Load())]
716                     
717        return node     
718               
719class StreamFunctionVisitor(ast.NodeVisitor):
720        def __init__(self,node):
721                self.stream_function_node = {}
722                self.generic_visit(node)
723                                                             
724        def visit_FunctionDef(self, node):                     
725                key = node.name[0].upper() + node.name[1:]
726                self.stream_function_node[key] = node
727
728
729               
730class StreamFunction():
731        def __init__(self):
732                self.carry_count = 0 
733                self.init_to_one_list = [] 
734                self.adv_n_count = 0 
735                self.type_name = ""
736                self.instance_name = "" 
737                self.parameters = ""
738                self.declarations = "" 
739                self.initializations = "" 
740       
741        def dump(self):
742                print "%s" % (self.type_name)
743                print "%s=%s" % ("Carry Count", str(self.carry_count))
744                print "%s=[%s]" % ("Init to One List" , ','.join(map(str,self.init_to_one_list)))
745                print "%s=%s" % ("Adv n Count", str(self.adv_n_count)) 
746        #print "Instance Name:"     #+ self.instance_name = ""
747        #print "Parameters:"        #+ self.parameters = ""
748        #print "Declarations:"           #+ self.declarations = ""
749        #print "Initializations:"   # + self.initializations = ""
750   
751#
752# TODO Consolidate *all* C code generation into the Emitter class.   Medium priority.
753# TODO Implement 'pretty print' indentation.   Low priority.
754# TODO Migrate Emiter() class to Emitter module.  Medium priority.
755
756def lower1(name):
757    return name[0].lower() + name[1:]
758def upper1(name):
759    return name[0].upper() + name[1:]
760
761def escape_newlines(str):
762  return str.replace('\n', '\\\n')
763
764class Emitter():
765        def __init__(self, use_C_syntax, strm_fn):
766                self.use_C_syntax = use_C_syntax
767                self.strm_fn = strm_fn
768
769        def definition(self, stream_function, icount=0):
770               
771                constructor = ""
772                carry_declaration = ""
773                self.type_name = stream_function.type_name
774               
775                if stream_function.carry_count > 0 or stream_function.adv_n_count > 0:
776                        constructor = self.constructor(stream_function.type_name, stream_function.carry_count, stream_function.init_to_one_list, stream_function.adv_n_count)
777                        carry_declaration = self.carry_declare('carryQ', stream_function.carry_count, stream_function.adv_n_count)
778
779                do_block_function = self.do_block(self.do_block_parameters(stream_function.parameters), 
780                                                stream_function.declarations, 
781                                                stream_function.initializations, 
782                                                stream_function.statements)             
783                clear_function = self.mk_clear(stream_function.carry_count)             
784
785                do_final_block_function = self.do_final_block(self.do_final_block_parameters(stream_function.parameters), 
786                                                stream_function.declarations, 
787                                                stream_function.initializations, 
788                                                stream_function.final_block_statements)                 
789
790                do_segment_function = self.do_segment(self.do_segment_parameters(stream_function.parameters), 
791                                                self.do_segment_args(stream_function.parameters))       
792
793                if self.use_C_syntax:
794                        return self.indent(icount) + "struct " + stream_function.type_name + " {" \
795                               + "\n" + self.indent(icount) + carry_declaration \
796                               + "\n" + self.indent(icount) + "};\n" \
797                               + "\n" + self.indent(icount) + do_block_function \
798                               + "\n" + self.indent(icount) + do_final_block_function + "\n\n"
799                               
800                return self.indent(icount) + "struct " + stream_function.type_name + " {" \
801                + "\n" + self.indent(icount) + constructor \
802                + "\n" + self.indent(icount) + do_block_function \
803                + "\n" + self.indent(icount) + clear_function \
804                + "\n" + self.indent(icount) + do_final_block_function \
805                + "\n" + self.indent(icount) + carry_declaration \
806                + "\n" + self.indent(icount) + "};\n\n"
807
808        def constructor(self, type_name, carry_count, init_to_one_list, adv_n_count, icount=0):
809                one_inits = self.strm_fn.ccgo.GenerateInitializations()
810                #one_inits = ""
811                #for v in init_to_one_list:
812                #       one_inits += "  carryQ.cq[%s] = carryQ.carry_flip(carryQ.cq[%s]);\n" % (v, v)
813                adv_n_decl = ""
814                #for i in range(adv_n_count): adv_n_decl += self.indent(icount+2) + "pending64[%s] = simd<1>::constant<0>();\n" % i     
815                return self.indent(icount) + "%s() { ""\n" % (type_name) + adv_n_decl + self.carry_init(carry_count) + one_inits + " }" 
816                       
817        def mk_clear(self, carry_count, icount=0):
818                one_inits = self.strm_fn.ccgo.GenerateInitializations()
819                return self.indent(icount) + "IDISA_INLINE void clear() { ""\n" + self.carry_init(carry_count) + one_inits + " }" 
820
821        def do_block(self, parameters, declarations, initializations, statements, icount=0):
822                pfx = (lower1(self.type_name) + "_" if self.use_C_syntax else "")
823                if self.use_C_syntax:
824                        return "#define " + pfx + "do_block(" + parameters + ")\\\n do {" \
825                        + "\\\n" + self.indent(icount) + escape_newlines(declarations) \
826                        + "\\\n" + self.indent(icount) + escape_newlines(initializations) \
827                        + "\\\n" + self.indent(icount) + escape_newlines(statements) \
828                        + "\\\n" + self.indent(icount + 2) + "} while (0)" 
829                return self.indent(icount) + do_block_inline_decorator + "void " + pfx + "do_block(" + parameters + ") {" \
830                + "\n" + self.indent(icount) + declarations \
831                + "\n" + self.indent(icount) + initializations \
832                + "\n" + self.indent(icount) + statements \
833                + "\n" + self.indent(icount + 2) + "}" 
834
835
836
837
838        def do_final_block(self, parameters, declarations, initializations, statements, icount=0):
839                pfx = (lower1(self.type_name) + "_" if self.use_C_syntax else "")
840                if self.use_C_syntax:
841                        return "#define " + pfx + "do_final_block(" + parameters + ")\\\n do {" \
842                        + "\\\n" + self.indent(icount) + escape_newlines(declarations) \
843                        + "\\\n" + self.indent(icount) + escape_newlines(initializations) \
844                        + "\\\n" + self.indent(icount) + escape_newlines(statements) \
845                        + "\\\n" + self.indent(icount + 2) + "} while (0)" 
846                return self.indent(icount) + do_final_block_inline_decorator + "void " + pfx + "do_final_block(" + parameters + ") {" \
847                + "\n" + self.indent(icount) + declarations \
848                + "\n" + self.indent(icount) + initializations \
849                + "\n" + self.indent(icount) + statements \
850                + "\n" + self.indent(icount + 2) + "}" 
851
852        def do_segment(self, parameters, do_block_call_args, icount=0):
853                pfx = (lower1(self.type_name) + "_" if self.use_C_syntax else "")
854                if self.use_C_syntax:
855                        return "#define " + pfx + "do_segment(" + parameters + ")\\\n do {" \
856                        + "\\\n" + self.indent(icount) + "  int i;" \
857                        + "\\\n" + self.indent(icount) + "  for (i = 0; i < segment_blocks; i++)" \
858                        + "\\\n" + self.indent(icount) + "    " + pfx + "do_block(" + do_block_call_args + ");" \
859                        + "\\\n" + self.indent(icount + 2) + "} while (0)" 
860                return self.indent(icount) + "void " + pfx + "do_segment(" + parameters + ") {" \
861                + "\n" + self.indent(icount) + "  int i;" \
862                + "\n" + self.indent(icount) + "  for (i = 0; i < segment_blocks; i++)" \
863                + "\n" + self.indent(icount) + "    " + pfx + "do_block(" + do_block_call_args + ");" \
864                + "\n" + self.indent(icount + 2) + "}" 
865
866        def declaration(self, type_name, instance_name, icount=0):
867                if self.use_C_syntax: return self.indent(icount) + "struct " + type_name + " " + instance_name + ";\n"
868                return self.indent(icount) + type_name + " " + instance_name + ";\n"
869               
870        def carry_init(self, carry_count, icount=0):   
871                #CARRY SET
872                return ""
873               
874        def carry_declare(self, carry_variable, carry_count, adv_n_count=0, icount=0):
875                adv_n_decl = ""
876                #if adv_n_count > 0:
877                #       adv_n_decl = "\n" + self.indent(icount) + "BitBlock pending64[%s];" % adv_n_count
878                #CARRY SET
879                return self.indent(icount) + self.strm_fn.ccgo.GenerateCarryDecls()
880
881        def carry_test(self, carry_variable, carry_count, icount=0):
882                #CARRY SET
883                return self.indent(icount) + "carryQ.CarryTest(0, %i)" % (carry_count)         
884               
885        def indent(self, icount):
886                s = ""
887                for i in range(0,icount): s += " "
888                return s       
889               
890        def do_block_parameters(self, parameters):
891                if self.use_C_syntax:
892                        #return ", ".join([self.type_name + " * " + self.instance_name] + [upper1(p) + " * " + lower1(p) for p in parameters])
893                        return ", ".join([lower1(self.type_name)] + [lower1(p) for p in parameters])
894                else: 
895                  normal_parms = [upper1(p) + " & " + lower1(p) for p in parameters]
896                  lookahead_parms = [upper1(p) + " & " + lower1(p) + "_ahead" for p in parameters if self.strm_fn.lookahead_info.LookAheadSet.has_key(p)]
897                  return ", ".join(normal_parms + lookahead_parms)
898               
899        def do_final_block_parameters(self, parameters):
900                if self.use_C_syntax:
901                        #return ", ".join([self.type_name + " * " + self.instance_name] + [upper1(p) + " * " + lower1(p) for p in parameters]+ ["BitBlock EOF_mask"])
902                        return ", ".join([lower1(self.type_name)] + [lower1(p) for p in parameters]+ ["EOF_mask"])
903                else: return ", ".join([upper1(p) + " & " + lower1(p) for p in parameters]+ ["BitBlock EOF_mask"])
904               
905        def do_segment_parameters(self, parameters):
906                if self.use_C_syntax:
907                        #return ", ".join([self.type_name + " * " + + self.instance_name] + [upper1(p) + " " + lower1(p) + "[]" for p in parameters])
908                        return ", ".join([lower1(self.type_name)] + [lower1(p) for p in parameters] + ["segment_blocks"])
909                else: return ", ".join([upper1(p) + " " + lower1(p) + "[]" for p in parameters] + ["int segment_blocks"])
910
911        def do_segment_args(self, parameters):
912                if self.use_C_syntax:
913                        return ", ".join([lower1(self.type_name)] + [lower1(p) + "[i]" for p in parameters])
914                else: return ", ".join([lower1(p) + "[i]" for p in parameters])
915
916def main(infilename, outfile = sys.stdout):
917  t = ast.parse(file(infilename).read())
918  outfile.write(StreamStructGen(True).gen(t))
919  outfile.write(FunctionXlator().xlat(t))
920
921#
922#  Routines for compatibility with the old compiler/template.
923#  Quick and dirty hacks for now - Dec. 2010.
924#
925
926class MainLoopTransformer:
927  def __init__(self, main_module, C_syntax=False, add_dump_stmts=False, add_assert_bitblock_align=False, dump_func_data=False, main_node_id='Main'):
928       
929    self.main_module = main_module
930    self.main_node_id = main_node_id
931    self.use_C_syntax = C_syntax
932    mkast.use_C_syntax = self.use_C_syntax
933    self.add_dump_stmts = add_dump_stmts
934    self.add_assert_bitblock_align = add_assert_bitblock_align
935    self.dump_func_data = dump_func_data
936   
937        # Gather and partition function definition nodes.
938    stream_function_visitor = StreamFunctionVisitor(self.main_module)
939    self.stream_function_node = stream_function_visitor.stream_function_node
940    for key, node in self.stream_function_node.iteritems():
941                AdvanceCombiner().xfrm(node)
942    self.main_node = self.stream_function_node[main_node_id]
943    self.main_carry_count = CarryCounter().count(self.main_node)
944    self.main_adv_n_count = adv_nCounter().count(self.main_node)
945    self.main_carry_info_set = CarryInfoSetVisitor(self.main_node)
946    self.main_ccgo = Strategic_CCGO_Factory(self.main_carry_info_set)
947    assert self.main_adv_n_count == 0, "Advance32() in main not supported.\n"
948    del self.stream_function_node[self.main_node_id]
949   
950    self.stream_functions = {}
951    for key, node in self.stream_function_node.iteritems():
952                stream_function = StreamFunction()
953                stream_function.carry_count = CarryCounter().count(node)
954                stream_function.init_to_one_list = CarryInitToOneList().count(node)
955                stream_function.adv_n_count = adv_nCounter().count(node)
956                carry_info_set = CarryInfoSetVisitor(node)
957                # Lookahead info is unused, but the visitor is called to verify some conditions
958                stream_function.lookahead_info = lookAhead.LookAheadInfoSetVisitor(node)
959                stream_function.ccgo = Strategic_CCGO_Factory(carry_info_set)
960                stream_function.type_name = node.name[0].upper() + node.name[1:]
961                stream_function.instance_name = node.name[0].lower() + node.name[1:]
962                stream_function.parameters = FunctionVars(node).params
963                stream_function.declarations = BitBlock_decls_of_fn(node)
964                stream_function.declarations += "\n" + stream_function.ccgo.GenerateStreamFunctionDecls()
965                stream_function.initializations = StreamInitializations().xfrm(node) 
966               
967                AugAssignRemoval().xfrm(node)
968                if self.add_dump_stmts: 
969                        Add_SIMD_Register_Dump().xfrm(node)
970                t = TempifyBuiltins()
971                t.xfrm(node)
972                stream_function.declarations += "\n" + BitBlock_decls_from_vars(t.tempVars())
973
974                #StringMatchCompiler().xfrm(node)
975
976                Bitwise_to_SIMD().xfrm(node)
977                final_block_node = copy.deepcopy(node)
978
979                if self.use_C_syntax:
980                        carryQname = stream_function.instance_name + ".carryQ"
981                else: carryQname = "carryQ"
982                CarryIntroVisitor = CarryIntro(stream_function.ccgo, carryQname)
983
984                lookAhead.LookAheadTransformer(stream_function, "nonfinal").xfrm(node)
985                lookAhead.LookAheadTransformer(stream_function, "final").xfrm(final_block_node)
986
987                CarryIntroVisitor.xfrm_fndef(node)
988                CarryIntroVisitor.xfrm_fndef_final(final_block_node)
989                #
990                # Compile asserts after carry intro so that generated if-statements
991                # are ignored.
992                AssertCompiler().xfrm(node)
993                AssertCompiler().xfrm(final_block_node)
994
995                if self.add_assert_bitblock_align:
996                        Add_Assert_BitBlock_Align().xfrm(node)
997                        Add_Assert_BitBlock_Align().xfrm(final_block_node)
998
999                #if stream_function.carry_count > 0:
1000                #       node.body += [mkast.callStmt('carryQ.CarryQ_Adjust', [ast.Num(stream_function.carry_count)])]
1001                node.body += stream_function.ccgo.GenerateStreamFunctionFinalization()
1002
1003               
1004                stream_function.statements = Cgen.py2C(4).gen(node.body)
1005                stream_function.final_block_statements = Cgen.py2C(4).gen(final_block_node.body)
1006                self.stream_functions[stream_function.type_name] = stream_function
1007               
1008    if self.dump_func_data:     
1009        for key, value in self.stream_functions.iteritems():
1010                        value.dump()
1011        sys.exit()
1012               
1013    self.emitter = Emitter(self.use_C_syntax, stream_function)
1014   
1015  def any_carry_expr(self):
1016
1017        tests = [self.stream_functions[key].ccgo.GenerateTestAll(self.stream_functions[key].instance_name) for key in self.stream_functions.keys()]
1018        return " || ".join([Cgen.py2C().gen(t) for t in tests])
1019
1020  def gen_globals(self):
1021    self.Cglobals = StreamStructGen().gen_struct_types(self.main_module)
1022    for key in self.stream_functions.keys():
1023                sf = self.stream_functions[key]
1024                self.Cglobals += Emitter(self.use_C_syntax, sf).definition(sf, 2)         
1025                       
1026  def gen_declarations(self): 
1027    self.Cdecls = StreamStructGen().gen_struct_vars(self.main_module)
1028    self.Cdecls += BitBlock_decls_of_fn(self.main_node) + "\n" + self.main_ccgo.GenerateStreamFunctionDecls()
1029    if self.main_carry_count > 0: 
1030        self.Cdecls += self.emitter.carry_declare('carryQ', self.main_carry_count)
1031               
1032  def gen_initializations(self):
1033    self.Cinits = ""
1034    if self.main_carry_count > 0: 
1035        self.Cinits += self.emitter.carry_init(self.main_carry_count)
1036    self.Cinits += StreamInitializations().xfrm(self.main_module)
1037    if self.use_C_syntax:
1038                for key in self.stream_functions.keys():
1039                        if self.stream_functions[key].carry_count == 0: continue
1040                        self.Cinits += self.emitter.declaration(self.stream_functions[key].type_name, self.stream_functions[key].instance_name, 2)
1041                        self.Cinits += "CarryInit(" + self.stream_functions[key].instance_name + ".carryQ, %i);\n" % (self.stream_functions[key].carry_count)
1042    else:
1043                for key in self.stream_functions.keys():
1044                        self.Cinits += self.emitter.declaration(self.stream_functions[key].type_name, self.stream_functions[key].instance_name, 2)
1045
1046                       
1047  def xfrm_block_stmts(self):
1048    #StringMatchCompiler().xfrm(self.main_node)
1049    AugAssignRemoval().xfrm(self.main_node)
1050    Bitwise_to_SIMD().xfrm(self.main_node)
1051    Bitwise_to_SIMD().xfrm(self.main_node)
1052    final_block_main = copy.deepcopy(self.main_node)
1053    carry_info_set = CarryInfoSetVisitor(self.main_node)
1054    #ccgo = Strategic_CCGO_Factory(carry_info_set)
1055    #CarryIntroVisitor = CarryIntro(ccgo)
1056    #CarryIntroVisitor.xfrm_fndef(self.main_node)
1057    #CarryIntroVisitor.xfrm_fndef_final(final_block_main)
1058    AssertCompiler().xfrm(self.main_node)
1059    if self.add_dump_stmts: 
1060        Add_SIMD_Register_Dump().xfrm(self.main_node)
1061        Add_SIMD_Register_Dump().xfrm(final_block_main)
1062               
1063    if self.add_assert_bitblock_align:
1064        print "add_assert_bitblock_align"
1065        Add_Assert_BitBlock_Align().xfrm(self.main_node)
1066        Add_Assert_BitBlock_Align().xfrm(final_block_main)
1067
1068    StreamFunctionCallXlator().xfrm(self.main_node, self.stream_function_node.keys(), self.use_C_syntax)
1069    StreamFunctionCallXlator('final').xfrm(final_block_main, self.stream_function_node.keys(), self.use_C_syntax)
1070   
1071    #if self.main_carry_count > 0:
1072                #self.main_node.body += [mkast.callStmt('CarryQ_Adjust', [ast.Name('carryQ', ast.Load()), ast.Num(self.main_carry_count)])]
1073    #self.main_node.body += ccgo.GenerateStreamFunctionFinalization()
1074   
1075   
1076       
1077    self.Cstmts = Cgen.py2C().gen(self.main_node.body)
1078    self.Cfinal_stmts = Cgen.py2C().gen(final_block_main.body)
1079   
1080if __name__ == "__main__":
1081                import doctest
1082                doctest.testmod()
Note: See TracBrowser for help on using the repository browser.