source: proto/Compiler/pablo.py @ 3018

Last change on this file since 3018 was 3018, checked in by cameron, 7 years ago

Multicarry while mode: initial check-in

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