use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class GenerationPass method addEntry.
private void addEntry(int index, Type type, BasicBlock b) {
VarExpr var = _var_expr(index, type, false);
CopyVarStmt stmt = selfDefine(var);
builder.assigns.getNonNull(var.getLocal()).add(b);
b.add(stmt);
}
use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class GenerationPass method assign_stack.
// var[index] = expr
protected Type assign_stack(int index, Expr expr) {
if (expr.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) expr;
if (v.getIndex() == index && v.getLocal().isStack()) {
return expr.getType();
}
}
Type type = expr.getType();
VarExpr var = _var_expr(index, type, true);
CopyVarStmt stmt = copy(var, expr);
addStmt(stmt);
return type;
}
use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class LocalsPool method realloc.
/* public Local newLocal(boolean isStack) {
int index = cache.size();
while(true) {
String key = key(index, isStack);
if(!cache.containsKey(key)) {
return get(index, isStack);
}
}
} */
public int realloc(ControlFlowGraph cfg) {
NullPermeableHashMap<Local, Set<Type>> types = new NullPermeableHashMap<>(SetCreator.getInstance());
int min = 0;
Set<Local> safe = new HashSet<>();
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
CopyVarStmt cp = (CopyVarStmt) stmt;
VarExpr var = cp.getVariable();
Local local = var.getLocal();
if (!cp.isSynthetic()) {
types.getNonNull(local).add(var.getType());
} else {
safe.add(local);
}
types.getNonNull(local).add(var.getType());
}
for (Expr s : stmt.enumerateOnlyChildren()) {
if (s.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr var = (VarExpr) s;
Local local = var.getLocal();
types.getNonNull(local).add(var.getType());
}
}
}
}
Map<Local, Type> stypes = new HashMap<>();
for (Entry<Local, Set<Type>> e : types.entrySet()) {
Set<Type> set = e.getValue();
Set<Type> refined = new HashSet<>();
if (set.size() > 1) {
for (Type t : set) {
refined.add(TypeUtils.asSimpleType(t));
}
if (refined.size() != 1) {
boolean valid = false;
if (refined.size() == 2) {
// TODO: proper check
Iterator<Type> it = refined.iterator();
if (it.next().getSize() == it.next().getSize()) {
Type t = refined.iterator().next();
refined.clear();
refined.add(t);
valid = true;
}
}
if (!valid) {
for (Entry<Local, Set<Type>> e1 : types.entrySet()) {
System.err.println(e1.getKey() + " == " + e1.getValue());
}
// String.format("illegal typesets for %s, set=%s, refined=%s", args)
throw new RuntimeException("illegal typesets for " + e.getKey());
}
}
Local l = e.getKey();
stypes.put(l, refined.iterator().next());
// if(!safe.contains(l)) {
// stypes.put(l, refined.iterator().next());
// }
} else {
Local l = e.getKey();
stypes.put(l, set.iterator().next());
// if(!safe.contains(l)) {
// }
}
}
// for(Entry<Local, Type> e : stypes.entrySet()) {
// System.out.println(e.getKey() + " == " + e.getValue());
// }
// lvars then svars, ordered of course,
List<Local> wl = new ArrayList<>(stypes.keySet());
// System.out.println("safe: " + safe);
wl.sort(new Comparator<Local>() {
@Override
public int compare(Local o1, Local o2) {
boolean s1 = safe.contains(o1);
boolean s2 = safe.contains(o2);
if (s1 && !s2) {
return -1;
} else if (!s1 && s2) {
return 1;
} else {
return o1.compareTo(o2);
}
}
});
// System.out.println("wl: " + wl);
Map<Local, Local> remap = new HashMap<>();
int idx = min;
for (Local l : wl) {
Type type = stypes.get(l);
Local newL = get(idx, false);
if (l != newL) {
remap.put(l, newL);
}
idx += type.getSize();
}
remap(cfg, remap);
return idx;
}
use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class LocalsPool method remap.
public static void remap(ControlFlowGraph cfg, Map<? extends Local, ? extends Local> remap) {
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
VarExpr v = ((CopyVarStmt) stmt).getVariable();
Local l = v.getLocal();
if (remap.containsKey(l)) {
Local l2 = remap.get(l);
v.setLocal(l2);
}
}
for (Expr s : stmt.enumerateOnlyChildren()) {
if (s.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) s;
Local l = v.getLocal();
if (remap.containsKey(l)) {
v.setLocal(remap.get(l));
}
}
}
}
}
}
use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method inlineConstant.
private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
/* we don't actually demote the synthetic copy
* here as we would also need to change the
* method desc and we can't do that until
* later so we defer it. */
LocalsPool pool = cfg.getLocals();
/* create the spill variable but not the
* actual definition yet. */
VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
VersionedLocal spill = pool.makeLatestVersion(argLocal);
AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
/* we have to maintain local references in
* phis as opposed to direct constant refs,
* so we go through every use of the argLocal
* and either replace it with the constant or
* a reference to the spill local if it is in
* a phi. */
Set<VarExpr> spillUses = new HashSet<>();
boolean requireSpill = false;
Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
while (it.hasNext()) {
VarExpr v = it.next();
if (v.getParent() == null) {
/* the use is in a phi, we can't
* remove the def.
*
* we also replace the old var
* with the new spill one so we
* have to add this as a use of
* the new spill local. */
spillUses.add(v);
v.setLocal(spill);
requireSpill = true;
} else {
CodeUnit par = v.getParent();
par.overwrite(rhsVal.copy(), par.indexOf(v));
}
/* this use is no longer associated
* with the old argLocal. */
it.remove();
}
if (pool.uses.get(argLocal).size() != 0) {
throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
}
if (requireSpill) {
/* generate the copy for the spill (v = const) */
CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
synthParamCopy.getBlock().add(spillCopy);
/* initialise data entries for the new spill
* variable. */
pool.defs.put(spill, spillCopy);
pool.uses.put(spill, spillUses);
}
}
Aggregations