def apply_rel_wrapper (lhs, rhs): assert lhs.typ == syntax.builtinTs['RelWrapper'] assert rhs.typ == syntax.builtinTs['RelWrapper'] assert lhs.kind == 'Op' assert rhs.kind == 'Op' ops = set ([lhs.name, rhs.name]) if ops == set (['StackWrapper']): [sp1, st1] = lhs.vals[:2] [sp2, st2] = rhs.vals[:2] excepts = list (set (lhs.vals[2:] + rhs.vals[2:])) for p in excepts: st1 = syntax.mk_memupd (st1, p, syntax.mk_word32 (0)) st2 = syntax.mk_memupd (st2, p, syntax.mk_word32 (0)) return syntax.Expr ('Op', boolT, name = 'StackEquals', vals = [sp1, st1, sp2, st2]) elif ops == set (['MemAccWrapper', 'MemWrapper']): [acc] = [v for v in [lhs, rhs] if v.is_op ('MemAccWrapper')] [addr, val] = acc.vals assert addr.typ == syntax.word32T [m] = [v for v in [lhs, rhs] if v.is_op ('MemWrapper')] [m] = m.vals assert m.typ == builtinTs['Mem'] expr = mk_eq (mk_memacc (m, addr, val.typ), val) return expr elif ops == set (['EqSelectiveWrapper']): [lhs_v, _, _] = lhs.vals [rhs_v, _, _] = rhs.vals if lhs_v.typ == syntax.builtinTs['RelWrapper']: return apply_rel_wrapper (lhs_v, rhs_v) else: return mk_eq (lhs, rhs) else: assert not 'rel wrapper opname understood'
def loop_var_analysis(p, split): """computes the same loop dataflow analysis as in the 'logic' module but with stack slots treated as virtual variables.""" if not is_asm_node(p, split): return None head = p.loop_id(split) tag = p.node_tags[split][0] assert head key = ('loop_stack_virtual_var_cycle_analysis', split) if key in p.cached_analysis: return p.cached_analysis[key] (vds, adj_nodes, loc_offs, upd_offsets, _) = get_loop_virtual_stack_analysis(p, tag) loop = p.loop_body(head) va = logic.compute_loop_var_analysis(p, vds, split, override_nodes=adj_nodes) (stack, _) = get_stack_sp(p, tag) va2 = [] uoffs = upd_offsets.get(head, []) for (v, data) in va: if v.kind == 'Var' and v.name[0] == 'Fake': (_, k, offs) = v.name if (k, offs) not in uoffs: continue v2 = loc_offs(split, 'MemAcc', offs, k) va2.append((v2, data)) elif v.kind == 'Var' and v.name.startswith('stack'): assert v.typ == stack.typ continue else: va2.append((v, data)) stack_const = stack for (k, off) in uoffs: stack_const = syntax.mk_memupd(stack_const, loc_offs(split, 'Ptr', off, k), syntax.mk_word32(0)) sp = asm_stack_rep_hook(p, (stack.name, stack.typ), 'Loop', split) assert sp and sp[0] == 'SplitMem', (split, sp) (_, st_split) = sp stack_const = logic.mk_stack_wrapper(st_split, stack_const, []) stack_const = logic.mk_eq_selective_wrapper(stack_const, ([], [0])) va2.append((stack_const, 'LoopConst')) p.cached_analysis[key] = va2 return va2
def loop_var_analysis (p, split): """computes the same loop dataflow analysis as in the 'logic' module but with stack slots treated as virtual variables.""" if not is_asm_node (p, split): return None head = p.loop_id (split) tag = p.node_tags[split][0] assert head key = ('loop_stack_virtual_var_cycle_analysis', split) if key in p.cached_analysis: return p.cached_analysis[key] (vds, adj_nodes, loc_offs, upd_offsets, _) = get_loop_virtual_stack_analysis (p, tag) loop = p.loop_body (head) va = logic.compute_loop_var_analysis (adj_nodes, vds, split, loop, p.preds) (stack, _) = get_stack_sp (p, tag) va2 = [] uoffs = upd_offsets.get (head, []) for (v, data) in va: if v.kind == 'Var' and v.name[0] == 'Fake': (_, k, offs) = v.name if (k, offs) not in uoffs: continue v2 = loc_offs (split, 'MemAcc', offs, k) va2.append ((v2, data)) elif v.kind == 'Var' and v.name.startswith ('stack'): assert v.typ == stack.typ continue else: va2.append ((v, data)) stack_const = stack for (k, off) in uoffs: stack_const = syntax.mk_memupd (stack_const, loc_offs (split, 'Ptr', off, k), syntax.mk_word32 (0)) sp = asm_stack_rep_hook (p, (stack.name, stack.typ), 'Loop', split) assert sp and sp[0] == 'SplitMem', (split, sp) (_, st_split) = sp stack_const = logic.mk_stack_wrapper (st_split, stack_const, []) stack_const = logic.mk_eq_selective_wrapper (stack_const, ([], [0])) va2.append ((stack_const, 'LoopConst')) p.cached_analysis[key] = va2 return va2