def subst_expr (expr): if expr.kind == 'Symbol': return mk_word32 (symbols[expr.name][0]) elif expr.is_op ('PAlignValid'): [typ, p] = expr.vals assert typ.kind == 'Type' return logic.mk_align_valid_ineq (('Type', typ.val), p) elif expr.kind in ['Op', 'Var', 'Num', 'Type']: return None else: assert not 'expression simple-substitutable', expr
def subst_expr(expr): if expr.kind == 'Symbol': if expr.name in symbols: return mk_word32(symbols[expr.name][0]) else: return None elif expr.is_op('PAlignValid'): [typ, p] = expr.vals assert typ.kind == 'Type' return logic.mk_align_valid_ineq(('Type', typ.val), p) elif expr.kind in ['Op', 'Var', 'Num', 'Type']: return None else: assert not 'expression simple-substitutable', expr
def compile_accs (replaces, expr): r = compile_const_global_acc (expr) if r: return compile_accs (replaces, r) if expr.kind == 'Field': expr = compile_field_acc (expr.field[0], expr.struct, replaces) return compile_accs (replaces, expr) elif expr.is_op ('ArrayIndex'): [arr, n] = expr.vals expr2 = compile_array_acc (n, arr, replaces, False) if expr2: return compile_accs (replaces, expr2) arr = compile_accs (replaces, arr) n = compile_accs (replaces, n) expr2 = compile_array_acc (n, arr, replaces, False) if expr2: return compile_accs (replaces, expr2) else: return mk_arr_index (arr, n) elif (expr.is_op ('MemUpdate') and expr.vals[2].is_op ('MemAcc') and expr.vals[2].vals[0] == expr.vals[0] and expr.vals[2].vals[1] == expr.vals[1]): # null memory copy. probably created by ops below return compile_accs (replaces, expr.vals[0]) elif (expr.is_op ('MemUpdate') and expr.vals[2].kind == 'FieldUpd'): [m, p, f_upd] = expr.vals assert f_upd.typ.kind == 'Struct' (typ, offs, _) = structs[f_upd.typ.name].fields[f_upd.field[0]] assert f_upd.val.typ == typ return compile_accs (replaces, mk_memupd (mk_memupd (m, p, f_upd.struct), mk_plus (p, mk_word32 (offs)), f_upd.val)) elif (expr.is_op ('MemUpdate') and expr.vals[2].typ.kind == 'Struct'): [m, p, s_val] = expr.vals struct = structs[s_val.typ.name] for (nm, (typ, offs, _)) in struct.fields.iteritems (): f = compile_field_acc (nm, s_val, replaces) assert f.typ == typ m = mk_memupd (m, mk_plus (p, mk_word32 (offs)), f) return compile_accs (replaces, m) elif (expr.is_op ('MemUpdate') and expr.vals[2].is_op ('ArrayUpdate')): [m, p, arr_upd] = expr.vals [arr, i, v] = arr_upd.vals return compile_accs (replaces, mk_memupd (mk_memupd (m, p, arr), mk_arroffs (p, arr.typ, i), v)) elif (expr.is_op ('MemUpdate') and expr.vals[2].typ.kind == 'Array'): [m, p, arr] = expr.vals n = arr.typ.num typ = arr.typ.el_typ for i in range (n): offs = i * typ.size () assert offs == i or offs % 4 == 0 e = compile_array_acc (i, arr, replaces) m = mk_memupd (m, mk_plus (p, mk_word32 (offs)), e) return compile_accs (replaces, m) elif expr.is_op ('Equals') \ and expr.vals[0].typ.kind in ['Struct', 'Array']: [x, y] = expr.vals assert x.typ == y.typ xs = compile_val_fields (x, replaces) ys = compile_val_fields (y, replaces) eq = foldr1 (mk_and, map (mk_eq, xs, ys)) return compile_accs (replaces, eq) elif expr.is_op ('PAlignValid'): [typ, p] = expr.vals p = compile_accs (replaces, p) assert typ.kind == 'Type' return logic.mk_align_valid_ineq (('Type', typ.val), p) elif expr.kind == 'Op': vals = [compile_accs (replaces, v) for v in expr.vals] return Expr ('Op', expr.typ, expr.name, vals = vals) elif expr.kind == 'Symbol': return mk_word32 (symbols[expr.name][0]) else: if expr.kind not in {'Var':True, 'ConstGlobal':True, 'Num':True, 'Invent':True, 'Type':True}: print expr assert not 'field acc compiled' return expr
def compile_accs(replaces, expr): r = compile_const_global_acc(expr) if r: return compile_accs(replaces, r) if expr.kind == 'Field': expr = compile_field_acc(expr.field[0], expr.struct, replaces) return compile_accs(replaces, expr) elif expr.is_op('ArrayIndex'): [arr, n] = expr.vals expr2 = compile_array_acc(n, arr, replaces, False) if expr2: return compile_accs(replaces, expr2) arr = compile_accs(replaces, arr) n = compile_accs(replaces, n) expr2 = compile_array_acc(n, arr, replaces, False) if expr2: return compile_accs(replaces, expr2) else: return mk_arr_index(arr, n) elif (expr.is_op('MemUpdate') and expr.vals[2].is_op('MemAcc') and expr.vals[2].vals[0] == expr.vals[0] and expr.vals[2].vals[1] == expr.vals[1]): # null memory copy. probably created by ops below return compile_accs(replaces, expr.vals[0]) elif (expr.is_op('MemUpdate') and expr.vals[2].kind == 'FieldUpd'): [m, p, f_upd] = expr.vals assert f_upd.typ.kind == 'Struct' (typ, offs, _) = structs[f_upd.typ.name].fields[f_upd.field[0]] assert f_upd.val.typ == typ return compile_accs( replaces, mk_memupd(mk_memupd(m, p, f_upd.struct), mk_plus(p, mk_word32(offs)), f_upd.val)) elif (expr.is_op('MemUpdate') and expr.vals[2].typ.kind == 'Struct'): [m, p, s_val] = expr.vals struct = structs[s_val.typ.name] for (nm, (typ, offs, _)) in struct.fields.iteritems(): f = compile_field_acc(nm, s_val, replaces) assert f.typ == typ m = mk_memupd(m, mk_plus(p, mk_word32(offs)), f) return compile_accs(replaces, m) elif (expr.is_op('MemUpdate') and expr.vals[2].is_op('ArrayUpdate')): [m, p, arr_upd] = expr.vals [arr, i, v] = arr_upd.vals return compile_accs( replaces, mk_memupd(mk_memupd(m, p, arr), mk_arroffs(p, arr.typ, i), v)) elif (expr.is_op('MemUpdate') and expr.vals[2].typ.kind == 'Array'): [m, p, arr] = expr.vals n = arr.typ.num typ = arr.typ.el_typ for i in range(n): offs = i * typ.size() assert offs == i or offs % 4 == 0 e = compile_array_acc(i, arr, replaces) m = mk_memupd(m, mk_plus(p, mk_word32(offs)), e) return compile_accs(replaces, m) elif expr.is_op ('Equals') \ and expr.vals[0].typ.kind in ['Struct', 'Array']: [x, y] = expr.vals assert x.typ == y.typ xs = compile_val_fields(x, replaces) ys = compile_val_fields(y, replaces) eq = foldr1(mk_and, map(mk_eq, xs, ys)) return compile_accs(replaces, eq) elif expr.is_op('PAlignValid'): [typ, p] = expr.vals p = compile_accs(replaces, p) assert typ.kind == 'Type' return logic.mk_align_valid_ineq(('Type', typ.val), p) elif expr.kind == 'Op': vals = [compile_accs(replaces, v) for v in expr.vals] return syntax.adjust_op_vals(expr, vals) elif expr.kind == 'Symbol': return mk_word32(symbols[expr.name][0]) else: if expr.kind not in { 'Var': True, 'ConstGlobal': True, 'Num': True, 'Invent': True, 'Type': True }: print expr assert not 'field acc compiled' return expr