source: proto/Compiler/pablo.py @ 2409

Last change on this file since 2409 was 2409, checked in by ksherdy, 7 years ago

Updated indentation.

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