from .primitives import GROUP as PRIMITIVES, prim_to_bv, prim_from_bv
from cdsl.xform import Rtl
from cdsl.ast import Var
try:
from typing import TYPE_CHECKING, Dict, Union, List, Set, Tuple from cdsl.xform import XForm from cdsl.ast import Def, VarAtomMap from cdsl.ti import VarTyping except ImportError:
TYPE_CHECKING = False
def find_matching_xform(d):
res = [] typing = {v: v.get_typevar() for v in d.vars()}
for x in d.expr.inst.semantics:
subst = d.substitution(x.src.rtl[0], {})
if (subst is None):
continue
inner_typing = {} for (v, tv) in typing.items():
inner_v = subst[v]
assert isinstance(inner_v, Var)
inner_typing[inner_v] = tv
if x.ti.permits(inner_typing):
res.append(x)
assert len(res) == 1, "Couldn't find semantic transform for {}".format(d)
return res[0]
def cleanup_semantics(r, outputs):
new_defs = [] subst_m = {v: v for v in r.vars()} definition = {} prim_to_bv_map = {}
for d in r.rtl:
inst = d.expr.inst
if (inst == prim_to_bv):
arg = d.expr.args[0]
df = d.defs[0]
assert isinstance(arg, Var)
if arg in definition:
def_loc = definition[arg]
if def_loc.expr.inst == prim_from_bv:
assert isinstance(def_loc.expr.args[0], Var)
subst_m[df] = def_loc.expr.args[0]
continue
if arg in prim_to_bv_map:
subst_m[df] = prim_to_bv_map[arg].defs[0]
continue
prim_to_bv_map[arg] = d
new_def = d.copy(subst_m)
for v in new_def.defs:
assert v not in definition definition[v] = new_def
new_defs.append(new_def)
live = set(outputs) for d in new_defs:
live = live.union(d.uses())
new_defs = [d for d in new_defs if not (d.expr.inst == prim_from_bv and
d.defs[0] not in live)]
return Rtl(*new_defs)
def elaborate(r):
fp = False
primitives = set(PRIMITIVES.instructions)
idx = 0
res = Rtl(*r.rtl)
outputs = res.definitions()
while not fp:
assert res.is_concrete()
new_defs = [] fp = True
for d in res.rtl:
inst = d.expr.inst
if (inst not in primitives):
t = find_matching_xform(d)
transformed = t.apply(Rtl(d), str(idx))
idx += 1
new_defs.extend(transformed.rtl)
fp = False
else:
new_defs.append(d)
res.rtl = tuple(new_defs)
return cleanup_semantics(res, outputs)