Changeset 319


Ignore:
Timestamp:
Oct 15, 2009, 2:07:12 PM (10 years ago)
Author:
eamiri
Message:

optimize pragma introduced

Location:
proto/parabix2/Compiler
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • proto/parabix2/Compiler/bitexpr.py

    r298 r319  
    77# add and subtract.
    88#
     9
     10class Pragma:
     11    pass
     12
     13class Reduce(Pragma):
     14    def __init__(self, target, replace):
     15        self.target = target
     16        self.replace = replace
    917
    1018class BitExpr:
     
    1725    def __init__(self, varname):
    1826        self.varname = varname
     27        self.vars = [self]
    1928    def show(self): return 'Var("' + self.varname + '")'
     29    def show_C(self):
     30        return self.varname
    2031
    2132class TrueLiteral(BitExpr):
    2233    def __init__(self):
    2334        self.value = True
     35        self.vars = []
     36        self.varname = 'allone'
    2437    def show(self): return 'T'
     38    def show_C(self): return 'AllOne'
    2539
    2640class FalseLiteral(BitExpr):
    2741    def __init__(self):
    2842        self.value = False
     43        self.varname = 'allzero'
     44        self.vars = []
    2945    def show(self): return 'F'
     46    def show_C(self):return 'AllZero'
    3047
    3148class Not(BitExpr):
    3249    def __init__(self, expr):
    3350        self.operand = expr
     51        self.vars = [self.operand]
    3452    def show(self): return 'Not(%s)' % (self.operand.show())
     53    def show_C(self): return "NOT IMPLEMENTED"
    3554
    3655class And(BitExpr):
     
    3857        self.operand1 = expr1
    3958        self.operand2 = expr2
    40     def show(self): return 'And(%s, %s)' % (self.operand1.show(), self.operand2.show())
     59        self.vars = [self.operand1, self.operand2]
     60    def show(self):
     61        return 'And(%s, %s)' % (self.operand1.show(), self.operand2.show())
     62    def show_C(self): return 'simd_and(%s, %s)'%(self.operand1.show_C(), self.operand2.show_C())
     63
     64class Andc(BitExpr):
     65    def __init__(self, expr1, expr2):
     66        self.operand1 = expr1
     67        self.operand2 = expr2
     68        self.vars = [self.operand1, self.operand2]
     69    def show(self): return 'Andc(%s, %s)' % (self.operand1.show(), self.operand2.show())
     70    def show_C(self): return 'simd_andc(%s, %s)' % (self.operand1.show_C(), self.operand2.show_C())
    4171
    4272class Or(BitExpr):
     
    4474        self.operand1 = expr1
    4575        self.operand2 = expr2
     76        self.vars = [self.operand1, self.operand2]
    4677    def show(self): return 'Or(%s, %s)' % (self.operand1.show(), self.operand2.show())
    47 
     78    def show_C(self): return 'simd_or(%s, %s)' % (self.operand1.show_C(), self.operand2.show_C())
    4879class Xor(BitExpr):
    4980    def __init__(self, expr1, expr2):
    5081        self.operand1 = expr1
    5182        self.operand2 = expr2
     83        self.vars = [self.operand1, self.operand2]
    5284    def show(self): return 'Xor(%s, %s)' % (self.operand1.show(), self.operand2.show())
     85    def show_C(self): return 'simd_xor(%s, %s)' % (self.operand1.show_C(), self.operand2.show_C())
    5386
    5487class Sel(BitExpr):
     
    5790        self.true_branch = expr2
    5891        self.false_branch = expr3
     92        self.vars = [self.operand1, self.operand2]
    5993    def show(self): return 'Sel(%s, %s, %s)' % (self.sel.show(), self.true_branch.show(), self.false_branch.show())
    60 
     94    def show_C(self): return 'Sel(%s, %s, %s)' % (self.sel.show_C(), self.true_branch.show_C(), self.false_branch.show_C())
    6195class Add(BitExpr):
    62     def __init__(self, expr1, expr2):
    63         self.operand1 = expr1
    64         self.operand2 = expr2
     96    def __init__(self, expr1, expr2, carry = None):
     97        self.operand1 = expr1
     98        self.operand2 = expr2
     99        self.carry = carry
     100        self.vars = [self.operand1, self.operand2, self.carry]
    65101    def show(self): return 'Add(%s, %s)' % (self.operand1.show(), self.operand2.show())
     102    def show_C(self): return 'adc128(%s, %s, %s)' % (self.operand1.show_C(), self.operand2.show_C(), self.carry)
    66103
    67104class Sub(BitExpr):
    68     def __init__(self, expr1, expr2):
    69         self.operand1 = expr1
    70         self.operand2 = expr2
     105    def __init__(self, expr1, expr2, brw = None):
     106        self.operand1 = expr1
     107        self.operand2 = expr2
     108        self.vars = [self.operand1, self.operand2]
     109        self.brw = None
    71110    def show(self): return 'Sub(%s, %s)' % (self.operand1.show(), self.operand2.show())
     111    def show_C(self): return 'sbb128(%s, %s)' % (self.operand1.show_C(), self.operand2.show_C())
    72112
    73113
     
    83123        self.LHS = var
    84124        self.RHS = expr
    85     def show(self): return '%s = %s' % (self.LHS, self.RHS.show())
     125    def show(self):
     126            if self.LHS is None:
     127                return "%s"%self.RHS.show_C()
     128            else:
     129                return '%s = %s' % (self.LHS.show_C(), self.RHS.show_C())
    86130
    87131#
  • proto/parabix2/Compiler/bitstream_compiler.py

    r311 r319  
    1 #
     1
    22# bitstream_compiler.py - compile unbounded bitstreams code into
    33#   equivalent block-by-block code in C.
     
    88#
    99
    10 import ast, bitexpr, py2bitexpr
    11 
    12 #
     10import ast, bitexpr, py2bitexpr, copy
     11
     12
    1313#
    1414#  Code Generation
    1515#
    16 
    17 def pairs(lst):
    18         if lst == []:
    19                 return []
    20         return zip(lst,lst[1:]+[lst[0]])
    2116
    2217Nop = 'nop'
     
    2924Add = 'adc128'
    3025Sub = 'sbb128'
    31 
    32 AllOne = 'allone'
    33 AllZero = 'allzero'
    34 
    35 class simple_op:
    36         def __init__(self, *arg):
    37                 self.op = arg[0]
    38                 self.vars = list(arg[1:])
    39                
    40         def show(self):
    41                 if self.op == Nop:
    42                         return "%s;\n"%self.vars[0]
    43                 else:
    44                         line_of_code = self.op + "("
    45                        
    46                         for index, var in enumerate(self.vars):
    47                                 line_of_code += str(var)
    48                                 if index+1 < len(self.vars):
    49                                         line_of_code += ', '
    50                        
    51                         line_of_code += ');\n'
    52                        
    53                         return line_of_code
    54        
    55         def update_var(self, old, new):
    56                 while old in self.vars:
    57                         i = self.vars.index(old)
    58                         self.vars[i] = new
    59 
    60 
    61 def parse_var(var):
    62     index=var.find('.')
    63     if index >= 0:
    64         return ('struct', var[0:index], var[index+1:])
    65                
    66     index = var.find('[')
    67     if index >= 0:
    68         right_index = var.find(']')
    69         return ('array', var[0:index], var[index+1:right_index])       
    70        
    71     return ('bitblock', var, None)
    72 
    73 
    74 class CodeGenObject:
    75     def __init__(self, predeclared):
    76         self.gensym_template = 'temp%i'
    77         self.gensym_counter = 0
    78         self.generated_code = []
    79         self.common_expression_map = {}
    80         self.new_vars = []
    81         self.carry_counter = 0
    82         self.brw_counter = 0
    83         self.vars = {}
    84         for sym in predeclared: self.common_expression_map[sym] = sym
    85 
    86     def add_stmt(self, varname, expr):
    87         self.common_expression_map[expr.show()] = varname
    88         self.generated_code.append(bitexpr.BitAssign(varname, expr))
    89         if expr.op == Add:
    90                 self.carry_counter += 1
    91         if expr.op == Sub:
    92                 self.brw_counter += 1
    93 
    94     def expr_string_to_variable(self, expr_string):
    95         if self.common_expression_map.has_key(expr_string.show()):
    96             return self.common_expression_map[expr_string.show()]
    97         else:
    98             self.gensym_counter += 1
    99             sym = self.gensym_template % self.gensym_counter
    100             self.add_stmt(sym, expr_string)
    101             return sym
    102 
    103     def gen_declarations(self):
    104         s = ''
    105         for i in self.vars['int']:
    106                 s+="int %s=0;\n"%i
    107        
    108         for i in self.vars['bitblock']:
    109                 if i == AllOne:
    110                         s += "BitBlock %s = simd_const_1(1);\n"%i
    111                 elif i==AllZero:
    112                         s+="BitBlock %s = simd_const_1(0);\n"%i
    113                 else:
    114                         s+="BitBlock %s;\n"%i
    115                
    116         for i in self.vars['array']:
    117                 s+="BitBlock %s[%i];\n"%(i, int(self.vars['array'][i])+1)
    118        
    119         for i in self.vars['struct']:
    120                 s+="struct __%s__{\n"%i
    121                 for j in self.vars['struct'][i]:
    122                         s+= "\tBitBlock %s;\n"%j
    123                 s+="};\n"
    124                 s+="struct __%s__ %s;\n"%(i,i)
    125 
    126         return s
    127 
    128 
    129     def extract_vars(self):
    130         ints = set([])
    131         bitblocks = set([])
    132         arrays = {}
    133         structs = {}
    134 
    135         for stmt in self.generated_code:
    136                 all_vars = [stmt.LHS]+stmt.RHS.vars
    137                
    138                 if stmt.RHS.op == Add or stmt.RHS.op == Sub:
    139                         ints.add(all_vars.pop())
    140                
    141                 for var in all_vars:
    142                         (var_type, name, extra) = parse_var(var)
    143                         #print
    144                         #print var, var_type, name
    145                
    146                         if (var_type == "bitblock"):
    147                                 bitblocks.add(name)
    148                
    149                         if var_type == "array":
    150                                 if not name in arrays:
    151                                         arrays[name]= extra
    152                                 else:
    153                                         arrays[name] = max(arrays[name], extra)
    154                        
    155                         if var_type == "struct":
    156                                 if not name in structs:
    157                                         structs[name] = set([extra])
    158                                 else:
    159                                         structs[name].add(extra)
    160                                 #print structs[name]
    161 
    162         self.vars={'int':ints, 'bitblock': bitblocks, 'array': arrays, 'struct': structs}
    163 
    164 
    165     def showcode(self, line_no = False):
    166         self.extract_vars()
    167         s = self.gen_declarations()
    168         for index, stmt in enumerate(self.generated_code):
    169                 if line_no:
    170                         s+= "%i %s"%(index, stmt.show())
    171                 else:
    172                         s += stmt.show()
    173         return s
    174 
    175     def get_code(self):
    176         return self.generated_code
     26If = 'simd_has_bit'
     27
     28AllOne = 'AllOne'
     29AllZero = 'AllZero'
     30
    17731
    17832def expr2simd(genobj, expr):
    17933    """Translate a Boolean expression into three-address simd code
    18034       using code generator object genobj.
     35       
    18136    """
    182     if isinstance(expr, bitexpr.TrueLiteral): return simple_op(Nop, AllOne)
    183     elif isinstance(expr, bitexpr.FalseLiteral): return simple_op(Nop, AllZero)
    184     elif isinstance(expr, bitexpr.Var):
    185         v = simple_op(Nop, expr.varname)
    186         genobj.common_expression_map[v.show()] = expr.varname
    187         return v
     37    if isinstance(expr, bitexpr.TrueLiteral): return expr
     38    elif isinstance(expr, bitexpr.FalseLiteral): return expr
     39    elif isinstance(expr, bitexpr.Var):
     40        genobj.common_expression_map[expr.show()] = expr
     41        return expr
    18842    elif isinstance(expr, bitexpr.Not):
    18943       e = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand))
    190        return simple_op(Andc, AllOne, e)
     44       return bitexpr.Andc(bitexpr.Var('AllOne'), e)
    19145    elif isinstance(expr, bitexpr.Or):
     46       if isinstance(expr.operand1, bitexpr.FalseLiteral):
     47           return expr.operand2
     48       elif isinstance(expr.operand1, bitexpr.TrueLiteral):
     49           return bitexpr.TrueLiteral()
     50       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     51           return expr.operand1
     52       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     53           return bitexpr.TrueLiteral()
    19254       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    193        e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    194        return simple_op(Or, e1, e2)
     55       i = expr2simd(genobj, expr.operand2)
     56       e2 = genobj.expr_string_to_variable(i)
     57       return bitexpr.Or(e1, e2)
    19558    elif isinstance(expr, bitexpr.Xor):
    19659       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    19760       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    198        return simple_op(Xor, e1, e2)
     61       return bitexpr.Xor(e1,e2)
    19962    elif isinstance(expr, bitexpr.And):
    20063       if isinstance(expr.operand1, bitexpr.Not):
    20164           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1.operand))
    20265           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    203            return simple_op(Andc, e2, e1)
     66           return bitexpr.Andc(e2, e1)
    20467       elif isinstance(expr.operand2, bitexpr.Not):
    20568           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    20669           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2.operand))
    207            return simple_op(Andc, e1, e2)
     70           return bitexpr.Andc(e1,e2)
     71       elif isinstance(expr.operand1, bitexpr.FalseLiteral):
     72           return bitexpr.FalseLiteral()
     73       elif isinstance(expr.operand1, bitexpr.TrueLiteral):
     74           return expr.operand2
     75       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     76           return bitexpr.FalseLiteral()
     77       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     78           return expr.operand1
    20879       else:
    20980           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    210            e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    211            return simple_op(And, e1, e2)
     81           j = expr2simd(genobj, expr.operand2)
     82           e2 = genobj.expr_string_to_variable(j)
     83           return bitexpr.And(e1, e2)
    21284    elif isinstance(expr, bitexpr.Sel):
    21385       sel = genobj.expr_string_to_variable(expr2simd(genobj, expr.sel))
    21486       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.true_branch))
    21587       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.false_branch))
    216        return simple_op(Sel, sel, e1, e2)
     88       return bitexpr.Sel(sel,e1,e2)
    21789    elif isinstance(expr, bitexpr.Add):
    21890       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    21991       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    220        carry = "carry%i"%genobj.carry_counter
    221        return simple_op(Add, e1, e2, carry)
     92       carry = "carry%i"%BasicBlock.carry_counter
     93       return bitexpr.Add(e1, e2, carry)
    22294    elif isinstance(expr, bitexpr.Sub):
    22395       e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
    22496       e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2))
    225        brw = "brw%i"%genobj.brw_counter
    226        return simple_op(Sub, e1, e2, brw)
    227 
    228 def pybit_codegen(cgo, stmts):
    229         for s in stmts:
    230                 e = expr2simd(cgo, s.RHS)
    231                 cgo.add_stmt(s.LHS, e)
     97       brw = "brw%i"%BasicBlock.brw_counter
     98       return bitexpr.Sub(e1, e2, brw)
     99    elif isinstance(expr, bitexpr.Andc):
     100       if isinstance(expr.operand2, bitexpr.Not):
     101           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
     102           e2 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand2.operand))
     103           return bitexpr.And(e1,e2)
     104       elif isinstance(expr.operand1, bitexpr.FalseLiteral):
     105           return bitexpr.FalseLiteral()
     106       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     107           return expr.operand1
     108       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     109           return bitexpr.FalseLiteral()
     110       else:
     111           e1 = genobj.expr_string_to_variable(expr2simd(genobj, expr.operand1))
     112           j = expr2simd(genobj, expr.operand2)
     113           e2 = genobj.expr_string_to_variable(j)
     114           return bitexpr.Andc(e1, e2)
     115
     116
     117def simplify_expr(expr):
     118    """
     119       simplifies a logical expression due to replacement of variables by constants
     120    """
     121    if isinstance(expr, bitexpr.TrueLiteral): return expr
     122    elif isinstance(expr, bitexpr.FalseLiteral): return expr
     123    elif isinstance(expr, bitexpr.Var): return expr
     124    elif isinstance(expr, bitexpr.Not): return expr
     125    elif isinstance(expr, bitexpr.Or):
     126       if isinstance(expr.operand1, bitexpr.FalseLiteral):
     127           return expr.operand2
     128       elif isinstance(expr.operand1, bitexpr.TrueLiteral):
     129           return bitexpr.TrueLiteral()
     130       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     131           return expr.operand1
     132       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     133           return bitexpr.TrueLiteral()
     134       else:
     135           return expr
     136    elif isinstance(expr, bitexpr.Xor):
     137       if isinstance(expr.operand1, bitexpr.FalseLiteral):
     138           return expr.operand2
     139       elif isinstance(expr.operand1, bitexpr.TrueLiteral):
     140           return bitexpr.Andc(bitexpr.TrueLiteral() ,expr.operand2)
     141       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     142           return expr.operand1
     143       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     144           return bitexpr.Andc(bitexpr.TrueLiteral() ,expr.operand1)
     145       else:
     146           return expr
     147    elif isinstance(expr, bitexpr.And):
     148       if isinstance(expr.operand1, bitexpr.FalseLiteral):
     149           return bitexpr.FalseLiteral()
     150       elif isinstance(expr.operand1, bitexpr.TrueLiteral):
     151           return expr.operand2
     152       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     153           return bitexpr.FalseLiteral()
     154       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     155           return expr.operand1
     156       else:
     157            return expr
     158    elif isinstance(expr, bitexpr.Sel):
     159       if isinstance(expr.sel, bitexpr.FalseLiteral):
     160           return expr.false_branch
     161       elif isinstance(expr.sel, bitexpr.TrueLiteral):
     162           return expr.true_branch
     163       elif isinstance(expr.true_branch, bitexpr.FalseLiteral):
     164           return bitexpr.Andc(expr.false_branch, expr.sel)
     165       elif isinstance(expr.true_branch, bitexpr.TrueLiteral):
     166           return bitexpr.Or(expr.false_branch, expr.sel)
     167       elif isinstance(expr.false_branch, bitexpr.FalseLiteral):
     168           return bitexpr.And(expr.true_branch, expr.sel)
     169       elif isinstance(expr.false_branch, bitexpr.TrueLiteral):
     170           return expr #SIMPLIFICATION IS POSSIBLE BUT ACCESS TO BASIC BLOCK IS NEEDED
     171       else:
     172            return expr
     173    elif isinstance(expr, bitexpr.Add):
     174        return expr
     175    elif isinstance(expr, bitexpr.Sub):
     176        return expr
     177    elif isinstance(expr, bitexpr.Andc):
     178       if isinstance(expr.operand1, bitexpr.FalseLiteral):
     179           return bitexpr.FalseLiteral()
     180       elif isinstance(expr.operand2, bitexpr.FalseLiteral):
     181           return expr.operand1
     182       elif isinstance(expr.operand2, bitexpr.TrueLiteral):
     183           return bitexpr.FalseLiteral()
     184       else:
     185           return expr
    232186
    233187def gen_sym_table(code):
     
    247201                        else:
    248202                                table[var] = [[], [index]]
    249                                
    250203        return table
    251204
    252 def simplify_name(var):
    253     (vartype, name, extra) = parse_var(var)
    254     if vartype == 'bitblock':
    255         return name
    256     if vartype == 'array':
    257         return "a_%s_%s"%(name, extra)
    258     if vartype == 'struct':
    259         return "s_%s_%s"%(name, extra)
    260     assert(1==0)
    261 
    262 def make_SSA(code, st):
    263         new_vars = []
    264         total_lines = len(code)
    265         for var in st:
    266                 st[var][0].append(total_lines)
    267                 st[var][1].append(total_lines)
    268        
    269         for var in st:
    270                 use_index = 0
    271                 def_index = 1
    272                 for current, next in pairs(st[var][0])[0:-2]:
    273                         code[current].LHS = "%s_%i"%(simplify_name(var), current)
    274                         new_vars.append("%s_%i"%(simplify_name(var), current))
    275                         uline = st[var][1][use_index]
    276                         while uline <= next and uline < total_lines:
    277                                 if uline > current:
    278                                         code[uline].RHS.update_var(var, "%s_%i"%(simplify_name(var), current))
    279                                 use_index += 1
    280                                 uline = st[var][1][use_index]
    281        
    282         return new_vars
    283 
     205
     206
     207
     208def gen_declarations(var_dic):
     209        s = ''
     210        for i in  var_dic['int']:
     211                s+="int %s=0;\n"%i
     212
     213        for i in var_dic['bitblock']:
     214                if i == AllOne:
     215                        s += "BitBlock %s = simd_const_1(1);\n"%i
     216                elif i==AllZero:
     217                        s+="BitBlock %s = simd_const_1(0);\n"%i
     218                else:
     219                        s+="BitBlock %s;\n"%i
     220
     221        for i in var_dic['array']:
     222                s+="BitBlock %s[%i];\n"%(i, int(var_dic['array'][i])+1)
     223
     224        for i in var_dic['struct']:
     225                s+="struct __%s__{\n"%i
     226                for j in var_dic['struct'][i]:
     227                        s+= "\tBitBlock %s;\n"%j
     228                s+="};\n"
     229                s+="struct __%s__ %s;\n"%(i,i)
     230
     231        return s
     232
     233def extract_vars(code):
     234        ints = set([])
     235        bitblocks = set(['AllOne', 'AllZero'])
     236        arrays = {}
     237        structs = {}
     238
     239        for stmt in code:
     240
     241                all_vars = [stmt.LHS]+stmt.RHS.vars
     242
     243                if isinstance(stmt.RHS, bitexpr.Add) or isinstance(stmt.RHS, bitexpr.Sub):
     244                        ints.add(all_vars.pop())
     245
     246                for var in all_vars:
     247                        #print var
     248                        (var_type, name, extra) = py2bitexpr.parse_var(var.varname)
     249
     250                        if (var_type == "bitblock"):
     251                                bitblocks.add(name)
     252
     253                        if var_type == "array":
     254                                if not name in arrays:
     255                                        arrays[name]= extra
     256                                else:
     257                                        arrays[name] = max(arrays[name], extra)
     258
     259                        if var_type == "struct":
     260                                if not name in structs:
     261                                        structs[name] = set([extra])
     262                                else:
     263                                        structs[name].add(extra)
     264                                #print structs[name]
     265
     266        return {'int':ints, 'bitblock': bitblocks, 'array': arrays, 'struct': structs}
     267
     268def merge_var_dic(first, second):
     269    res = {}
     270    res['int'] = first['int'].union(second['int'])
     271    res['bitblock'] = first['bitblock'].union(second['bitblock'])
     272
     273    res['array'] = first['array']
     274    temp = dict({'array':copy.copy(second['array'])})
     275    for i in res['array']:
     276        if i in temp['array']:
     277            res['array'][i] = max(res['array'][i], temp['array'][i])
     278            del temp['array'][i]
     279    res['array'].update(temp['array'])
     280
     281   
     282    res['struct'] = first['struct']
     283    temp = dict({'struct':copy.copy(second['struct'])})
     284    for i in res['struct']:
     285        if i in temp['struct']:
     286            res['struct'][i] = res['struct'][i].union(temp['struct'][i])
     287            del temp['struct'][i]
     288    res['struct'].update(temp['struct'])
     289    return res
     290################################################################
     291## This class abstracts one basic block of code
     292################################################################
     293
     294class BasicBlock:
     295    gensym_counter = 0
     296    carry_counter = 0
     297    brw_counter = 0
     298    def __init__(self, predeclared={}):
     299        self.gensym_template = 'Temp%i'
     300        self.code = []
     301        self.common_expression_map = {}
     302        self.new_vars = []
     303        self.vars = {}
     304        #for sym in predeclared: self.common_expression_map[sym] =sym
     305        self.common_expression_map.update(predeclared)
     306    def __len__(self):
     307        return len(self.code)
     308    def join(self, block):
     309        self.code += block.code
     310        self.common_expression_map.update(block.common_expression_map)
     311    def get_defs(self, varname):
     312        defs = []
     313        for line, loc in enumerate(self.code):
     314            if loc.LHS.varname == varname:
     315                defs.append(line)
     316        if len(defs)==0:
     317            defs.append(None)
     318        return defs
     319    def get_uses(self, varname):
     320        uses = []
     321        for line, loc in enumerate(self.code):
     322            if isinstance(loc.RHS, bitexpr.Not):
     323                if loc.RHS.operand.varname == varname:
     324                    uses.append(line)
     325                continue
     326            if isinstance(loc.RHS, bitexpr.Var):
     327                if loc.RHS.varname == varname:
     328                    uses.append(line)
     329                continue
     330               
     331            if loc.RHS.operand1.varname == varname:
     332                uses.append(line)
     333            if loc.RHS.operand2.varname == varname:
     334                uses.append(line)
     335        if len(uses)==0:
     336            uses.append(None)
     337        return uses
     338
     339    def split(self, line):
     340        code1 = self.code[:line]
     341        code2 = self.code[line:]
     342        bb2 = BasicBlock()
     343        bb2.code = code2
     344        bb2.common_expression_map = copy.copy(self.common_expression_map)
     345       
     346        bb2vars = []
     347        for loc in code2:
     348            bb2vars.append(loc.LHS.varname)
     349        bb1vars = []
     350        for loc in code1:
     351            bb1vars.append(loc.LHS.varname)
     352       
     353        for i in self.common_expression_map:
     354            if self.common_expression_map[i] in bb2vars and not self.common_expression_map[i] in bb1vars:
     355                del self.common_expression_map[i]
     356       
     357        bb1 = BasicBlock()
     358        bb1.code = code1
     359        bb1.common_expression_map = self.common_expression_map
     360        return bb1, bb2
     361    def add_stmt(self, varname, expr):
     362        assert(not isinstance(varname, str))
     363        self.common_expression_map[expr.show()] = varname
     364        self.code.append(bitexpr.BitAssign(varname, expr))
     365        if isinstance(expr, bitexpr.Add):
     366                BasicBlock.carry_counter += 1
     367        if isinstance(expr, bitexpr.Sub):
     368                BasicBlock.brw_counter += 1
     369
     370    def expr_string_to_variable(self, expr_string):
     371        #if isinstance(expr_string, bitexpr.And):
     372        #    print expr_string.operand1, expr_string.operand2
     373        #print expr_string.show()
     374        if self.common_expression_map.has_key(expr_string.show()):
     375            return self.common_expression_map[expr_string.show()]
     376        else:
     377            BasicBlock.gensym_counter += 1
     378            sym = bitexpr.Var(self.gensym_template % BasicBlock.gensym_counter)
     379            self.add_stmt(sym, expr_string)
     380            return sym
     381
     382    def showcode(self, indent, line_no = False):
     383        s=""
     384        for index, stmt in enumerate(self.code):
     385                #if index == 36:
     386                #    print "::::", stmt, stmt.LHS, stmt.RHS, stmt.RHS.varname
     387                if line_no:
     388                        s+= "%i %s%s;\n"%(index, " "*indent,stmt.show())
     389                else:
     390                        if not isinstance(stmt, bitexpr.BitAssign):
     391                            print "~~~~", index, stmt
     392                        s += " "*indent + stmt.show() + ";\n"
     393        return s
     394
     395    def get_code(self):
     396        return self.code
     397
     398    def propagate_constant(self, previous):
     399        changed = False
     400        fixed = previous
     401        for s in self.code:
     402            #print s.RHS.__class__
     403            if isinstance(s.RHS, bitexpr.FalseLiteral):
     404                fixed[s.LHS.varname] = bitexpr.FalseLiteral()
     405                continue
     406            if isinstance(s.RHS, bitexpr.TrueLiteral):
     407                fixed[s.LHS.varname] = bitexpr.TrueLiteral()
     408                continue
     409            if isinstance(s.RHS, bitexpr.Var):
     410                if s.RHS.varname in fixed:
     411                    s.RHS = fixed[s.RHS.varname]
     412                fixed[s.LHS.varname] = s.RHS
     413                continue
     414            #   fixed[s.LHS] = s.RHS
     415            if isinstance(s.RHS, bitexpr.Not):
     416                if s.RHS.operand.varname in fixed:
     417                    s.RHS.operand = fixed[s.RHS.operand.varname]
     418                continue
     419            if s.RHS.operand1.varname in fixed:
     420                changed = True
     421                s.RHS.operand1 = fixed[s.RHS.operand1.varname]
     422            if s.RHS.operand2.varname in fixed:
     423                s.RHS.operand2 = fixed[s.RHS.operand2.varname]
     424                changed = True
     425
     426        #for i in fixed:
     427        #   print i, fixed[i]
     428        return fixed, changed
     429
     430    def normalize(self, stmts):
     431        for s in stmts:
     432            self.add_stmt(s.LHS, expr2simd(self, s.RHS))
     433    def transform(self):
     434        for loc in self.code:
     435            loc.RHS = simplify_expr(loc.RHS)
     436    def simplify(self, previous):
     437        changed = True
     438        while changed:
     439            self.transform()
     440            fixed, changed = self.propagate_constant(previous)
     441        return fixed
     442################################################################
     443# This class abstracts the whole program
     444################################################################
     445
     446class Program:
     447    def __init__(self):
     448        self. reducer = Reducer()
     449        self.declar = ""
     450
     451    def generate_if_stmt(self, expr, indent):
     452        target = expr.target
     453        replace = expr.replace
     454        if replace == "allzero":
     455            return "\n%sif (bitblock_has_bit(%s) == 0)  {\n"%(" "*indent, target)
     456        elif replace == "allone":
     457           return "\n%sif (bitblock_bit_count(%s) == 128) {\n"%(" "*indent, target)
     458        else:
     459            assert (1==0)
     460
     461    def break_to_segs(self, s, breaks):
     462        segs = []
     463        breaks = [-1]+breaks+[len(s)]
     464        for start, stop in py2bitexpr.pairs(breaks)[:-1]:
     465            next = s[start+1:stop]
     466            if len(next)>0:
     467                segs.append(next)
     468        return segs
     469
     470    def unwind(self, tree, head = [], indent = 0):
     471        #TODO: There might be a bug here, previous declarations are not passed to CodeGenObject
     472        indent_unit = 4
     473        s = ""
     474        total = []
     475        if tree[0] is None:
     476                return tree[1].showcode(indent)
     477        else:
     478                bnum = len(tree) - 1 #number of branches
     479                s += tree[1].showcode(indent)
     480                if bnum == 1:
     481                    return s
     482                s += self.generate_if_stmt(tree[0], indent)
     483                indent += indent_unit
     484                s+=self.unwind(tree[2], tree[1], indent)
     485                indent -= indent_unit
     486                s+=" "*indent+"}\n"
     487                if bnum == 2:
     488                    return s
     489                s+=" "*indent+"else {\n"
     490                indent += indent_unit
     491                s+=self.unwind(tree[3], tree[1], indent)
     492                indent -= indent_unit
     493                s+=" "*indent+"}\n"
     494                if bnum == 3:
     495                    return s
     496                s+=self.unwind(tree[4], tree[1], indent)
     497                return s
     498    def partition2bb(self, s):
     499        """
     500        At this point we assume all expression in the input Python code
     501        are optimize statements
     502        """
     503        basicblocks = []
     504        exprs = []
     505        lineno = []
     506        s = py2bitexpr.translate_stmts(s)
     507
     508        st = py2bitexpr.gen_sym_table(s)
     509        #print st
     510        s=py2bitexpr.make_SSA(s, st)
     511
     512        for line, loc in enumerate(s):
     513            if isinstance(loc, bitexpr.Reduce):
     514                lineno.append(line)
     515                exprs.append(loc)
     516        code_segs = self.break_to_segs(s, lineno)
     517        previous = {}
     518
     519        for seg in code_segs:
     520            bb = BasicBlock(previous)
     521            bb.normalize(seg)
     522            previous.update(bb.common_expression_map)
     523            basicblocks.append(bb)
     524
     525        #gen_compound_sym_table(basicblocks)
     526        #make_SSA(basicblocks)
     527
     528        #make_SSA(basicblocks)
     529        vd = extract_vars(basicblocks[0].code)
     530        for bb in basicblocks[1:]:
     531            more = extract_vars(bb.code)
     532            vd = merge_var_dic(vd, more)
     533        self.declar = gen_declarations(vd)
     534        return basicblocks, exprs
     535
     536    def construct_tree(self, all_code, exprs):
     537        #print ">>>>>", len(all_code), len(exprs)
     538        #print len(all_code)
     539        #for i in all_code:
     540        #    print "  ", len(i)
     541        if all_code == []:
     542            dummy = BasicBlock()
     543            dummy.code = []
     544            return [None, dummy]
     545
     546        if len(all_code) == 1+len(exprs):
     547            head = all_code.pop(0)
     548        elif len(all_code) == len(exprs):
     549            dummy = BasicBlock()
     550            dummy.code = []
     551            head = dummy
     552        else:
     553            assert (1==0)
     554
     555        if exprs == []:
     556            return [None, head]
     557        first_cond = exprs.pop(0)
     558
     559        first_def = (None, None) #Basic Block number and line number of first def
     560        last_use = (None, None) #Basic Block number and line number of last_use
     561
     562        target = first_cond.target
     563
     564        for bbn, bb in enumerate(all_code):
     565            fdef = bb.get_defs(target)[0]
     566            luse = bb.get_uses(target)[-1]
     567            if not fdef is None and first_def[0] is None:
     568                first_def = (bbn, fdef)
     569            if not luse is None:
     570                last_use = (bbn, luse)
     571
     572        if first_def[0] is None and last_use[0] is None:
     573            cut = (None, None)
     574            dummy = BasicBlock()
     575            dummy.code = []
     576            #print ";;;;;;;;;;;;", len(all_code), len(exprs)
     577            return [first_cond, head, self.construct_tree(copy.deepcopy(all_code), copy.copy(exprs)), self.construct_tree(all_code, copy.copy(exprs)), [None, dummy]]
     578        else:
     579            if first_def[0] is None:
     580                cut = last_use
     581            else:
     582                cut = first_def
     583
     584            #bb1, bb2 = all_code[cut[0]].split(cut[1]+1)
     585            #all_code[cut[0]] = bb1
     586            #all_code.insert(cut[0]+1, bb2)
     587            #new_exprs =
     588            #print "~~~~~", len(all_code), len(exprs)
     589            #print "cut[0] = ", cut[0]
     590            return [first_cond, head, self.construct_tree(copy.deepcopy(all_code[:cut[0]+1]), copy.copy(exprs[:cut[0]])), self.construct_tree(all_code[:cut[0]+1], copy.copy(exprs[:cut[0]])), self.construct_tree(all_code[cut[0]+1:], exprs[cut[0]:])]
     591
     592    def prune(self, fixed, tree):
     593        """removes unreachable branches of the tree"""
     594        target = tree[0].target
     595        replace = tree[0].replace
     596        if target in fixed:
     597            if replace == 'allone':
     598                if isinstance(fixed[target], bitexpr.TrueLiteral):
     599                    tree[0] = None
     600                    tree[1].join(tree[2][1])
     601                    del tree[3]
     602                    del tree[2]
     603                    fixed.update(tree[1].simplify(fixed))
     604                if isinstance(fixed[target], bitexpr.FalseLiteral):
     605                    tree[0] = None
     606                    tree[1].join(tree[3][1])
     607                    del tree[3]
     608                    del tree[2]
     609                    fixed.update(tree[1].simplify(fixed))
     610            if replace == 'allzero':
     611                if isinstance(fixed[target], bitexpr.FalseLiteral):
     612                    tree[0] = None
     613                    tree[1].join(tree[2][1])
     614                    del tree[3]
     615                    del tree[2]
     616                    fixed.update(tree[1].simplify(fixed))
     617                if isinstance(fixed[target], bitexpr.TrueLiteral):
     618                    tree[0] = None
     619                    tree[1].join(tree[3][1])
     620                    del tree[3]
     621                    del tree[2]
     622                    fixed.update(tree[1].simplify(fixed))
     623
     624        empty_list = []
     625        for index, branch in enumerate(tree[2:]):
     626            if branch[0] is None:
     627                if branch[1].code == []:
     628                    empty_list.append(2+index)
     629
     630        empty_list.reverse()
     631        for i in empty_list:
     632            del tree[i]
     633
     634    def simplify_tree(self, tree, fixed = {}):
     635        fixed.update(tree[1].simplify(fixed))
     636        if tree[0] is None:
     637            return
     638        else:
     639            #self.prune(fixed, tree)
     640            for branch in tree[2:]:
     641                self.simplify_tree(branch, copy.copy(fixed))
     642
     643    def generate_code(self, s):
     644        bb, exprs = self.partition2bb(s)
     645        tree = self.construct_tree(bb, exprs)
     646        #tree = self.reducer.apply_all_opt(bb, exprs)
     647        #print tree
     648        tree = self.reducer.apply_all_opt(tree)
     649
     650        #print tree
     651        #print
     652        #print
     653
     654        self.simplify_tree(tree)
     655
     656        #print tree
     657
     658        s = self.unwind(tree)
     659        return self.declar+s
     660
     661################################################################
     662## This class is an optimization pass
     663################################################################
     664
     665class Reducer:
     666    def __init__(self):
     667        pass
     668
     669    def replace_in_rhs(self, expr, target, replace):
     670        #print target,replace
     671        #print ",,,,",expr.LHS.varname
     672        if replace=='allzero':
     673            replace = bitexpr.FalseLiteral()
     674        if replace == 'allone':
     675            replace = bitexpr.TrueLiteral()
     676
     677        if isinstance(expr.RHS, bitexpr.Var):
     678            if expr.RHS.varname == target:
     679                expr.RHS = replace
     680            return
     681
     682        if expr.RHS.operand1.varname == target:
     683            expr.RHS.operand1 = replace
     684
     685        if expr.RHS.operand2.varname == target:
     686            expr.RHS.operand2 = replace
     687
     688    def apply_single_opt(self, expr, tree):
     689
     690        target = expr.target
     691        replace = expr.replace
     692        assert(replace=='allzero' or replace=='allone')
     693
     694        for loc in tree[1].code:
     695            if loc.LHS.varname == target:
     696                break
     697            self.replace_in_rhs(loc, target, replace)
     698        if tree[0] is None:
     699            return
     700        else:
     701            for branch in tree[2:]:
     702                self.apply_single_opt(expr, branch)
     703
     704        return
     705
     706    def apply_all_opt(self, tree):
     707        """
     708          all_code is  list of basic blocks.
     709          exp is a list of optimize pragmas found in the code
     710        """
     711        if tree[0] is None:
     712            return tree
     713        else:
     714            self.apply_single_opt(tree[0], tree[2])
     715            tree = [tree[0], tree[1], self.apply_all_opt(tree[2]), self.apply_all_opt(tree[3]), self.apply_all_opt(tree[4])]
     716            return tree
     717
     718        return [first_cond, head, self.apply_all_opt(optimized_code, copy.copy(exp)), self.apply_all_opt(all_code, exp)]
     719###############################################################
    284720if __name__ == '__main__':
    285721        s=ast.parse(r"""def u8u16(u8, u8bit):
     
    289725        temp1 = (u8bit[2] &~ u8bit[3]);
    290726        u8.prefix3 = (u8.prefix & temp1);
     727        optimize(u8.prefix3, allzero)
    291728        temp2 = (u8bit[2] & u8bit[3]);
    292729        u8.prefix4 = (u8.prefix & temp2);
     730        optimize(u8.prefix4, allzero)
    293731        u8.suffix = (u8bit[0] &~ u8bit[1]);
    294732        temp3 = (u8bit[2] | u8bit[3]);
     
    322760        u8.scope42 = bitutil.Advance(u8.prefix4)
    323761        u8.scope43 = bitutil.Advance(u8.scope42)
     762        optimize(u8.scope43, allzero)
    324763        u8.scope44 = bitutil.Advance(u8.scope43)
    325764        u8lastscope = u8.scope22 | u8.scope33 | u8.scope44
     
    339778        u8lastscope = u8.scope22 | u8.scope33 | u8.scope44
    340779        u8lastbyte = u8.unibyte | u8lastscope
     780        optimize(u8lastbyte, allzero)
    341781        u16lo[2] = u8lastbyte & u8bit[2]
    342782        u16lo[3] = u8lastbyte & u8bit[3]
     
    358798
    359799        u8surrogate = u8.scope43 | u8.scope44
     800        optimize(u8surrogate, allzero)
    360801        u16hi[0] = u16hi[0] | u8surrogate       
    361802        u16hi[1] = u16hi[1] | u8surrogate       
     
    385826        delmask = u8.prefix | u8.scope32 | u8.scope42
    386827""")
    387         s=s.body[0].body
    388 
    389         c=CodeGenObject([])
    390 
    391         pybit_codegen(c, py2bitexpr.translate_stmts(s))
    392         #print c.showcode(True)
    393         code = c.generated_code
    394         c.new_vars = make_SSA(code, gen_sym_table(code))
    395         print c.showcode(False)
     828        s = s.body[0].body
     829        prog = Program()
     830        s = prog.generate_code(s)
     831        print s
     832
     833#TODO: merge expr2simd() and a simplify_expr()
     834#TODO: there is some unnecesary code in output  duplication that can be removed
     835#TODO: removing unreachable code is developed but is incomplete. Currently the code is not used.
     836#TODO: Support optimizing over subset of values
  • proto/parabix2/Compiler/py2bitexpr.py

    r297 r319  
    99# Requires ast module of python 2.6
    1010
    11 import ast, bitexpr
     11import ast, bitexpr, copy
    1212
    1313class PyBitError(Exception):
     
    3434def translate(ast_expr):
    3535        if isinstance(ast_expr, ast.Name):
     36                if ast_expr.id=="allzero":
     37                        return bitexpr.FalseLiteral()
     38                if ast_expr.id=="allone":
     39                        return bitexpr.TrueLiteral()
    3640                return bitexpr.Var(ast_expr.id)
    3741        elif isinstance(ast_expr, ast.Attribute):
     
    6569                if is_Advance_Call(ast_expr):
    6670                        e = translate(ast_expr.args[0])
    67                         return bitexpr.make_add(e,e)
     71                        temp = bitexpr.make_add(e,e)
     72                        return temp
    6873                elif is_ScanThru_Call(ast_expr):
    6974                        e0 = translate(ast_expr.args[0])
     
    8994        translated = []
    9095        for s in ast_stmts:
    91                 if isinstance(s, ast.Assign):
     96                if isinstance(s, ast.Expr):
     97                    target = translate_var(s.value.args[0])
     98                    replace = translate_var(s.value.args[1])
     99                    translated.append(bitexpr.Reduce(target, replace))
     100                elif isinstance(s, ast.Assign):
    92101                        e = translate(s.value)
    93102                        for astv in s.targets:
    94                                 translated.append(bitexpr.BitAssign(translate_var(astv), e))
     103                                translated.append(bitexpr.BitAssign(bitexpr.Var(translate_var(astv)), e))
    95104                elif isinstance(s, ast.AugAssign):
    96                         v = translate_var(s.target)
     105                        #print "~~~~~", translate_var(s.target)
     106                        v = bitexpr.Var(translate_var(s.target))
    97107                        translated.append(bitexpr.BitAssign(v, translate(ast.BinOp(s.target, s.op, s.value))))
    98108                else: raise PyBitError("Unknown PyBit statement type %s\n" % ast.dump(s))
    99109        return translated
    100 
    101 
     110               
     111               
     112def arglist(value):
     113        if isinstance(value, ast.UnaryOp):
     114                return (translate_var(value.operand))
     115        if isinstance(value, ast.BinOp):
     116                return (translate_var(value.left), translate_var(value.right))
     117        if isinstance(value, ast.Call):
     118                return value.args
     119        if isinstance(value, ast.Attribute):
     120                return (translate_var(value.value))
     121        if isinstance(value, ast.Name):
     122                return (translate_var(value))
     123
     124        print "BUG: %s not supported!"%value.__class__
     125
     126
     127def extract_vars(rhs):
     128    if isinstance(rhs, bitexpr.Var):
     129        return [rhs.varname]
     130    if isinstance(rhs, bitexpr.FalseLiteral) or isinstance(rhs, bitexpr.TrueLiteral):
     131        return []
     132    if isinstance(rhs, bitexpr.Not):
     133        return extract_vars(rhs.operand)
     134    #So it is a binary operation WHAT ABOUT ADD AND SUBTRACT?
     135    return extract_vars(rhs.operand1)+extract_vars(rhs.operand2)
     136
     137def gen_sym_table(code):
     138        """Generate a simple symbol table for a three address code
     139           each entry is of this form: var_name:[[defs][uses]]
     140        """
     141        table = {}
     142        for index, stmt in enumerate(code):
     143                if isinstance(stmt, bitexpr.Reduce):
     144                    if stmt.target in table:
     145                        table[stmt.target][1].append(index)
     146                    else:
     147                        table[stmt.target][1] = [[], [index]]
     148                else:
     149                        assert(isinstance(stmt, bitexpr.BitAssign))
     150                        current = stmt.LHS.varname
     151                        if current in table:
     152                                table[current][0].append(index)
     153                        else:
     154                                table[current] = [[index],[]]
     155
     156                        varlist = extract_vars(stmt.RHS)
     157                        for var in varlist:
     158                                if var in table:
     159                                        table[var][1].append(index)
     160                                else:
     161                                        table[var] = [[], [index]]
     162        return table
     163
     164def parse_var(var):
     165    index=var.find('.')
     166    if index >= 0:
     167        return ('struct', var[0:index], var[index+1:])
     168               
     169    index = var.find('[')
     170    if index >= 0:
     171        right_index = var.find(']')
     172        return ('array', var[0:index], var[index+1:right_index])       
     173       
     174    return ('bitblock', var, None)
     175
     176def simplify_name(var):
     177    (vartype, name, extra) = parse_var(var)
     178    if vartype == 'bitblock':
     179        return name
     180    if vartype == 'array':
     181        return "a_%s_%s"%(name, extra)
     182    if vartype == 'struct':
     183        return "s_%s_%s"%(name, extra)
     184    assert(1==0)
     185
     186def update_rhs(rhs, varname, newname):
     187    if isinstance(rhs, bitexpr.Var):
     188        if rhs.varname == varname:
     189            rhs.varname = newname
     190        return
     191           
     192    if isinstance(rhs, bitexpr.FalseLiteral) or isinstance(rhs, bitexpr.TrueLiteral):
     193        return
     194   
     195    if isinstance(rhs, bitexpr.Not):
     196        update_rhs(rhs.operand, varname, newname)
     197        return
     198    #So it is a binary operation WHAT ABOUT ADD AND SUBTRACT?
     199    update_rhs(rhs.operand1, varname, newname)
     200    update_rhs(rhs.operand2, varname, newname)
     201
     202def pairs(lst):
     203        if lst == []:
     204                return []
     205        return zip(lst,lst[1:]+[lst[0]])
     206
     207def make_SSA(code, st):
     208        new_vars = []
     209        total_lines = len(code)
     210        for var in st:
     211                st[var][0].append(total_lines)
     212                st[var][1].append(total_lines)
     213
     214        unique_number = 0
     215        for var in st:
     216                use_index = 0
     217                for current, next in pairs(st[var][0])[0:-2]:
     218                        code[current].LHS.varname = "%s_%i"%(simplify_name(var), unique_number)
     219                        new_vars.append("%s_%i"%(simplify_name(var), unique_number))
     220                        uline = st[var][1][use_index]
     221                        while uline <= next and uline < total_lines:
     222                                if uline > current:
     223                                        update_rhs(code[uline].RHS, var, "%s_%i"%(simplify_name(var), unique_number))
     224                                        #code[uline].RHS.update_var(var, )
     225                                use_index += 1
     226                                uline = st[var][1][use_index]
     227                        unique_number += 1
     228        return code
Note: See TracChangeset for help on using the changeset viewer.