Changeset 365 for proto/Compiler


Ignore:
Timestamp:
Feb 22, 2010, 3:16:32 PM (10 years ago)
Author:
eamiri
Message:

Bit stream initialization support added.
Improvements in inlining.

Location:
proto/Compiler
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/basic_block.py

    r363 r365  
    11import bitexpr
    2 
     2import copy
    33
    44def expr2simd(genobj, expr):
     
    88    if isinstance(expr, bitexpr.TrueLiteral): return expr
    99    elif isinstance(expr, bitexpr.FalseLiteral): return expr
     10    elif isinstance(expr, bitexpr.Const): return expr
    1011    elif isinstance(expr, bitexpr.Var):
     12        #print expr.show()
    1113        genobj.common_expression_map[expr.show()] = expr
    1214        return expr
     
    104106    def add_stmt(self, varname, expr):
    105107        assert(not isinstance(varname, str))
    106         if self.common_expression_map.has_key(expr.show()) and self.ceelim:
     108        if isinstance(expr, bitexpr.FalseLiteral):
     109            self.code.append(bitexpr.BitAssign(varname, expr))
     110        elif self.common_expression_map.has_key(expr.show()) and self.ceelim:
    107111            self.code.append(bitexpr.BitAssign(varname, self.common_expression_map[expr.show()]))
    108112        else:
     
    150154    if isinstance(expr, bitexpr.TrueLiteral): return expr
    151155    elif isinstance(expr, bitexpr.FalseLiteral): return expr
     156    elif isinstance(expr, bitexpr.Const): return expr
    152157    elif isinstance(expr, bitexpr.Var): return expr
    153158    elif isinstance(expr, bitexpr.Not): return make_not(simplify(expr.operand1))
     
    224229        if isinstance(s.RHS, bitexpr.TrueLiteral):
    225230            fixed[s.LHS.varname] = bitexpr.TrueLiteral()
     231            continue
     232        if isinstance(s.RHS, bitexpr.Const):
     233            #fixed[s.LHS.varname] = copy.copy(s.RHS)
    226234            continue
    227235        if isinstance(s.RHS, bitexpr.Var):
  • proto/Compiler/bitexpr.py

    r363 r365  
    8080    def show(self): return 'Xor(%s, %s)' % (self.operand1.show(), self.operand2.show())
    8181    def show_C(self): return 'simd_xor(%s, %s)' % (self.operand1.show_C(), self.operand2.show_C())
     82
     83class Const(BitExpr):
     84    def __init__(self, n):
     85        self.n = n
     86        BitExpr.__init__(self, self, self, data_type = "int")
     87    def show(self): return "%i", self.n
    8288
    8389class Sel(BitExpr):
  • proto/Compiler/bitstream_compiler.py

    r363 r365  
    22#   equivalent block-by-block code in C.
    33#
    4 # (c) 2009 Robert D. Cameron and Ehsan Amiri
     4# (c) 2009 Ehsan Amiri and Robert D. Cameron
    55# All rights reserved.
    66# Licensed to International Characters, Inc. under Academic Free License 3.0
     
    3939        livelist.append('error_mask')
    4040        s = py2bitexpr.do_inlining(s)
    41         #return s
    4241        s = py2bitexpr.translate_stmts(s)
    4342        st = py2bitexpr.gen_sym_table(s)
  • proto/Compiler/py2bitexpr.py

    r364 r365  
    1 #
    2 # py2bitexpr.py
    3 #
    4 # (c) 2009 Robert D. Cameron with modifications by Ehsan Amiri
    5 # All rights reserved.
    6 # Licensed to International Characters, Inc. under Academic Free License 3.0
    7 #
    8 # Translate unbounded bitstream code in "PyBit" form into our internal
    9 # representation.
    10 # Pybit form: series of sequential assignment statements using
    11 # bitwise logice operations, Advance, ScanThru.
    12 #
    13 # Requires ast module of python 2.6
    14 
    151import ast, bitexpr, copy, basic_block
    162
     
    228AllZero = 'AllZero'
    239
    24 STRUCT_TEMPLATE="struct_%s_%s_"
    25 ARRAY_TEMPLATE="array_%s_%s_"
     10STRUCT_TEMPLATE="strct_%s__%s_"
     11ARRAY_TEMPLATE="array_%s__%s_"
    2612
    2713
     
    6753def register_var(final_name, original_name, type_name, extra):
    6854    pass
    69     #type_dict[original_name] = type_name
    70     #type_dict[final_name] = type_name
    7155
    7256def collect_functions(module):
     
    8973            mod_file.close()
    9074            mod_parsed = ast.parse(mod_code)
     75            modified = []
    9176            for item in mod_parsed.body:
    92                 #assert (isinstance(item, ast.FunctionDef))
    9377                if isinstance(item, ast.FunctionDef):
    9478                    item.name = translate_var(ast.Attribute(value=ast.Name(id=mod.name), attr=item.name))
    9579            module.body += mod_parsed.body
     80    return module
     81
     82
     83def remove_unsupported_code(callee, fn_names, predefined, main=False):
     84    to_remove = []
     85   
     86    for index, loc in enumerate(callee.body):
     87        if not (isinstance(loc, ast.Assign) or isinstance(loc, ast.AugAssign) or isinstance(loc, ast.Return)):
     88            if isinstance(loc, ast.While):
     89                if not main:
     90                    to_remove.append(index)
     91
     92            else:
     93                to_remove.append(index)
     94       
     95        #we do not support AugAssign with function calls
     96        if isinstance(loc, ast.AugAssign):
     97            if isinstance(loc.value, ast.Call):
     98                assert (1==0)
     99                to_remove.append(index)
     100
     101        #we do not support function calls in functions other than main
     102        #these are OK if they are object construction, otherwise error.
     103        if isinstance(loc, ast.Assign):
     104            if isinstance(loc.value, ast.Call):
     105                if main and not (translate_var(loc.value.func) in fn_names+predefined):
     106                    to_remove.append(index)
     107                if not main and not translate_var(loc.value.func) in predefined:
     108                    to_remove.append(index)
     109    to_remove.sort(reverse=True)
     110    for line_no in to_remove:
     111        del callee.body[line_no]
     112    return callee
     113
     114
     115def clean_functions(module, fn_names, predefined):
     116    new = []
     117    for item in module.body:
     118        if isinstance(item, ast.FunctionDef):
     119            new.append(remove_unsupported_code(item, fn_names, predefined, item.name == "main"))
     120        else:
     121             new.append(item)
     122    module.body = new
    96123    return module
    97124
     
    137164        for index, elt in enumerate(exp.elts):
    138165            exp.elts[index] = replace_in_exp(elt, args, cargs, unique_prefix)
    139     #elif isinstance(exp,)
     166    elif isinstance(exp, ast.Num):
     167        pass
    140168    else:
    141         #print exp
     169        print exp
    142170        assert(1==0)
    143171    return exp
     
    146174    call_list = []
    147175    for index, loc in enumerate(main.body):
     176        #print loc.value
    148177        if isinstance(loc, ast.Assign) and isinstance(loc.value, ast.Call):
    149178                func_name = translate_var(loc.value.func)
     
    158187def update_var_names(callee, args):
    159188    unique_prefix = '_'+callee.name.replace('.', '_')+'_'
    160    
    161189
    162190    assert (len(args)==len(callee.args.args))
     
    178206    return callee, unique_prefix
    179207
    180 def remove_unsupported_code(callee):
    181     to_remove = []
    182 
    183     for index, loc in enumerate(callee.body):
    184         if not (isinstance(loc, ast.Assign) or isinstance(loc, ast.AugAssign) or isinstance(loc, ast.Return)):
    185             to_remove.append(index)
    186     to_remove.sort(reverse=True)
    187     for line_no in to_remove:
    188         del callee.body[line_no]
    189     return callee
    190 
    191 
    192 def remove_return_stmt(callee, unique_num):
    193     rets = {}
    194     for index, loc in enumerate(callee.body):
    195         if isinstance(loc, ast.Return):
    196             if isinstance(loc.value, ast.Tuple):
    197                 all_assignments = []
    198                 for ind, item in enumerate(loc.value.elts):
    199                     #print item.id
    200                     next = ast.Assign([ast.Name(id=TEMP_VAR_TEMPLATE%unique_num+"_"+str(ind))], item )
    201                     all_assignments.append(next)
    202                 rets[index] = all_assignments
    203             else:
    204                 rets[index] = [ast.Assign([ast.Name(id=(TEMP_VAR_TEMPLATE+"_0")%unique_num)], loc.value)]
    205 
    206     ret_keys = [x for x in rets]
    207     ret_keys.sort(reverse=True)
    208     for key in ret_keys:
    209         callee.body = callee.body[:key]+rets[key]+callee.body[key+1:]
    210     return callee
    211208
    212209def get_name(loc, index):
     
    309306    return field_info
    310307
    311 def fix_return_list(callee, args):
    312     if isinstance(callee.body[-1].value, ast.Tuple):
    313         all_ret = [translate_var(x, True) for x in callee.body[-1].value.elts]
    314         tuple_return = True
    315     else:
    316         all_ret = [translate_var(callee.body[-1].value, True)]
    317         tuple_return = False
     308
     309def generate_expanded_code(loc):
     310    new_code = []
     311    array_name = translate_var(loc.targets[0])
     312    for ind, i in enumerate(range(len(loc.value.elts))):
     313        new_loc = ast.Assign([ast.Subscript(value=ast.Name(id=array_name), slice=ast.Index(ast.Num(n=ind)) )], loc.value.elts[i])
     314        new_code.append(new_loc)
     315
     316    return new_code
     317
     318def expand_list_init(module):
     319    for item in module.body:
     320        replace_code = {}
     321        if isinstance(item, ast.FunctionDef):
     322            for index, loc in enumerate(item.body):
     323                if isinstance(loc, ast.Assign):
     324                    if isinstance(loc.value, ast.List):
     325                        equivalent_code = generate_expanded_code(loc)
     326                        replace_code[index] = equivalent_code
     327            keys = [key for key in replace_code]
     328            keys.sort(reverse = True)
     329            for line_no in keys:
     330                item.body = item.body[:line_no]+replace_code[line_no]+item.body[line_no+1:]
    318331   
    319     myargs = [translate_var(x, True) for x in callee.args.args]
    320     caller_args = [translate_var(x, True) for x in args]
    321    
    322     to_remove = []
    323     for index, item in enumerate(all_ret):
    324         if item in myargs:
    325             arg_index = myargs.index(item)
    326             if caller_args[arg_index] == item:
    327                 to_remove.append(index)
    328    
    329     if len(to_remove) == 0:
    330         return callee
    331    
    332     if tuple_return:
    333         to_remove.sort(reverse = True)
    334         for rem in to_remove:
    335             del callee.body[-1].value.elts[rem]   
    336     else:
    337         del callee.body[-1]
    338         return callee
     332    return module
     333
     334def get_predefined_funcs():
     335    advance = ast.Attribute(value=ast.Name(id="bitutil"), attr="Advance")
     336    scan_thru = ast.Attribute(value=ast.Name(id="bitutil"), attr="ScanThru")
     337    return [translate_var(advance), translate_var(scan_thru)]
    339338
    340339def do_inlining(module):
    341340    module = collect_functions(module)
    342341    func_dict = collect_names(module.body)
    343 
     342    module = expand_list_init(module)
     343   
     344   
     345    valid_fn = [name for name in func_dict]
     346    predef_fn = get_predefined_funcs()
     347    module = clean_functions(module, valid_fn, predef_fn)
    344348    main = module.body[func_dict["main"]]
    345349    call_list = get_all_calls(main, [func for func in func_dict])
    346     inline_code = []
    347350    call_list.sort(reverse=True)
    348351    for line_no in call_list:
    349352        callee = copy.deepcopy(module.body[func_dict[translate_var(main.body[line_no].value.func)]])
    350353        args = main.body[line_no].value.args
    351         callee = remove_unsupported_code(callee)
    352         #callee = fix_return_list(callee, args)
    353354        return_list = process_return(callee)
    354355        callee, prefix = update_var_names(callee, args)
    355         #callee = remove_return_stmt(callee, line_no)
    356356
    357357        main = modify_assignments_in_caller(main, line_no, return_list, prefix, callee)
     
    391391                return bitexpr.Var(translate_var(ast_expr))
    392392        elif isinstance(ast_expr, ast.Num):
    393                 assert(ast_expr.n == 0)
    394                 return bitexpr.FalseLiteral()
     393                if ast_expr.n == 0:
     394                    return bitexpr.FalseLiteral()
     395                else:
     396                    return bitexpr.Const(ast_expr.n)
    395397        elif isinstance(ast_expr, ast.Attribute):
    396398                if isinstance(ast_expr.value, ast.Name):
     
    438440                        return bitexpr.isNoneZero(e0)
    439441                else:   raise PyBitError("Bad condition in while loop: %s\n" % ast.dump(ast_expr))
    440         else: raise PyBitError("Unknown expression %s\n" % ast.dump(ast_expr))
     442               
     443        else:
     444            raise PyBitError("Unknown expression %s\n" % ast.dump(ast_expr))
    441445
    442446def translate_var(v, aggregate_type = False):
     
    453457               var_name = ARRAY_TEMPLATE%(v.value.id, translate_index(v.slice.value))
    454458               agg_name = "%s[%s]" % (v.value.id, translate_index(v.slice.value))
     459               
    455460        else: raise PyBitError("Unknown operator %s\n" % ast.dump(v))
    456461
     
    489494    if isinstance(rhs, bitexpr.Var):
    490495        return [rhs.varname]
    491     if isinstance(rhs, bitexpr.FalseLiteral) or isinstance(rhs, bitexpr.TrueLiteral):
     496    if isinstance(rhs, bitexpr.FalseLiteral) or isinstance(rhs, bitexpr.TrueLiteral) or isinstance(rhs, bitexpr.Const):
    492497        return []
    493498    if isinstance(rhs, bitexpr.Not):
     
    894899    basicblocks = []
    895900    lineno = []
    896     #####
    897901    def_line = []
    898902    lastuse_line = []
     
    905909    for item in opt_list:
    906910        if len(st2[item[0]][0]) > 0:
    907             #The last definition of the variable is extracted
    908911            def_line.append(st2[item[0]][0][-1])
    909912        else:
    910             #This variable is an input variable and not defined by the programmer
    911913            def_line.append(-1)
    912914
    913         #if len(st[item[0]][1]) > 0:
    914             #last use of the variables is extracted
    915         #    lastuse_line.append(st[item[0]][1][-1])
    916         #else:
    917             #The variable is not used in the code anywhere, we assume it is needed at the end
    918915        lastuse_line.append(total_lines)
    919916
     
    948945        orig = copy.deepcopy(predec)
    949946        s[0].stmts = normalize(s[0].stmts, predec, False)
    950         #return [s[0]]+normalize(s[1:], orig)
    951947        return [s[0]]+normalize(s[1:], {})
    952948    if isinstance(s[0], bitexpr.BitAssign):
     
    968964
    969965        all_vars = [stmt.LHS, stmt.RHS.operand1, stmt.RHS.operand2]
     966       
     967
    970968
    971969        if isinstance(stmt.RHS, bitexpr.Add):
     
    975973
    976974        for var in all_vars:
     975                if isinstance(var, bitexpr.Const):
     976                    continue
     977               
    977978                (var_type, name, extra) = parse_var(var.varname)
    978979
     
    12101211           
    12111212def simplify_tree(code, fixed = {}, prev = []):
    1212     #print len(code)
    1213     #print "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
    12141213    if len(code) == 0:
    12151214        return []
     
    12201219        this, next = recurse_forward(code)
    12211220        fixed.update(basic_block.simplify(this, fixed))
    1222         #assumptions = basic_block.calc_implications(this, copy.deepcopy(fixed))
    1223         #fixed.update(assumptions)
    12241221        return this+simplify_tree(next, fixed, this)
    12251222
     
    12321229            assumptions[code[0].control_expr.var.varname] = bitexpr.FalseLiteral()
    12331230        assumptions = basic_block.calc_implications(copy.deepcopy(prev), assumptions)
    1234         #print assumptions, len(prev), prev[0].LHS.varname
    12351231        fixed1.update(assumptions)
    12361232        code[0].true_branch = simplify_tree(code[0].true_branch, fixed1)
     
    12491245#################################################################################################################
    12501246def get_effective_name(varname):
    1251     dot = varname.find('.')
    1252     bracket = varname.find('[')
    1253     if dot > 0: return varname[:dot]
    1254     if bracket > 0: return varname[:bracket]
     1247    if varname.startswith("array") or varname.startswith("strct"):
     1248        try:
     1249            ind = varname.index("__")
     1250           
     1251            return varname[6:ind]
     1252           
     1253        except:
     1254            return varname
     1255   
    12551256    return varname
    12561257   
    12571258   
    12581259def check_loc(loc, must_liv):
     1260   
    12591261    effective_name = get_effective_name(loc.LHS.varname)
    1260     if effective_name in must_liv:
     1262    #if effective_name == "lex":
     1263           
     1264    if effective_name in must_liv or loc.LHS.varname in must_liv:
    12611265        if isinstance(loc.RHS, bitexpr.Not):
    12621266            return set([loc.RHS.operand1.varname]), False
     
    12661270            return set([]), False
    12671271        elif isinstance(loc.RHS, bitexpr.TrueLiteral):
     1272            return set([]), False
     1273        elif isinstance(loc.RHS, bitexpr.Const):
    12681274            return set([]), False
    12691275        else:
     
    15801586                code += s[0].RHS.operand2.varname
    15811587                code += ";\n"
    1582             if isinstance(s[0].RHS, bitexpr.FalseLiteral):
     1588            elif isinstance(s[0].RHS, bitexpr.Const):
     1589                code += "sisd_from_int(%i);"%s[0].RHS.n
     1590                code += "\n"
     1591            elif isinstance(s[0].RHS, bitexpr.FalseLiteral):
    15831592                code += "0;\n"
    15841593
  • proto/Compiler/template.c

    r351 r365  
    135135    BitBlock mask_8 = simd_himask_8;
    136136    s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
    137     u8bit[0], u8bit[1], u8bit[2], u8bit[3], u8bit[4], u8bit[5], u8bit[6], u8bit[7]);
     137    array_u8bit__0_,array_u8bit__1_,array_u8bit__2_,array_u8bit__3_,array_u8bit__4_,array_u8bit__5_,array_u8bit__6_,array_u8bit__7_);
    138138
    139139    @stmts
Note: See TracChangeset for help on using the changeset viewer.