use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class GenerationPass method _dup2_x2.
protected void _dup2_x2() {
Type topType = peek().getType();
int baseHeight = currentStack.height();
save_stack(false);
if (topType.getSize() == 2) {
Type bottomType = currentStack.peek(1).getType();
if (bottomType.getSize() == 2) {
// 64x64
// prestack: var2, var0 (height = 4)
// poststack: var4, var2, var0
// assignments: var0 = var2(initial)
// assignments: var2 = var0(initial)
// assignments: var4 = var2(initial)
currentStack.assertHeights(DUP2_X2_64x64_HEIGHTS);
Expr var2 = pop();
Expr var0 = pop();
// var6 = var0(initial)
Type var6Type = assign_stack(baseHeight + 2, var0);
// var0 = var2(initial)
Type var0Type = assign_stack(baseHeight - 4, var2);
// var4 = var2(initial)
Type var4Type = assign_stack(baseHeight - 0, var2);
// var2 = var6 = var0(initial)
Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
// push var0;
push(load_stack(baseHeight - 4, var0Type));
// push var2;
push(load_stack(baseHeight - 2, var2Type));
// push var4;
push(load_stack(baseHeight - 0, var4Type));
} else {
// 64x32
// prestack: var2, var1, var0 (height = 4)
// poststack: var4, var3, var2, var0
// assignments: var0 = var2(initial)
// assignments: var2 = var0(initial)
// assignments: var3 = var1(initial)
// assignments: var4 = var2(initial)
currentStack.assertHeights(DUP2_X2_64x32_HEIGHTS);
Expr var2 = pop();
Expr var1 = pop();
Expr var0 = pop();
// var6 = var0(initial)
Type var6Type = assign_stack(baseHeight + 2, var0);
// var0 = var2
Type var0Type = assign_stack(baseHeight - 4, var2);
// var3 = var1
Type var3Type = assign_stack(baseHeight - 1, var1);
// var4 = var2
Type var4Type = assign_stack(baseHeight + 0, var2);
// var2 = var0
Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
// push var0
push(load_stack(baseHeight - 4, var0Type));
// push var2
push(load_stack(baseHeight - 2, var2Type));
// push var3
push(load_stack(baseHeight - 1, var3Type));
// push var4
push(load_stack(baseHeight + 0, var4Type));
}
} else {
Type bottomType = currentStack.peek(2).getType();
if (bottomType.getSize() == 2) {
// 32x64
// prestack: var3, var2, var0 (height = 4)
// poststack: var5, var4, var2, var1, var0
// assignments: var0 = var2(initial)
// assignments: var1 = var3(initial)
// assignments: var2 = var0(initial)
// assignments: var4 = var2(initial)
// assignments: var5 = var3(initial)
currentStack.assertHeights(DUP2_X2_32x64_HEIGHTS);
Expr var3 = pop();
Expr var2 = pop();
Expr var0 = pop();
// var6 = var0(initial)
Type var6Type = assign_stack(baseHeight + 2, var0);
// var0 = var2(initial)
Type var0Type = assign_stack(baseHeight - 4, var2);
// var1 = var3(initial)
Type var1Type = assign_stack(baseHeight - 3, var3);
// var4 = var2(initial)
Type var4Type = assign_stack(baseHeight + 0, var2);
// var5 = var3(initial)
Type var5Type = assign_stack(baseHeight + 1, var3);
// var2 = var6 = var0(initial)
Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
// push var0
push(load_stack(baseHeight - 4, var0Type));
// push var1
push(load_stack(baseHeight - 3, var1Type));
// push var2
push(load_stack(baseHeight - 2, var2Type));
// push var4
push(load_stack(baseHeight + 0, var4Type));
// push var5
push(load_stack(baseHeight + 1, var5Type));
} else {
// 32x32
// prestack: var3, var2, var1, var0 (height = 4)
// poststack: var5, var4, var3, var2, var1, var0
// var0 = var2
// var1 = var3
// var2 = var0
// var3 = var1
// var4 = var2
// var5 = var3
currentStack.assertHeights(DUP2_X2_32x32_HEIGHTS);
Expr var3 = pop();
Expr var2 = pop();
Expr var1 = pop();
Expr var0 = pop();
// var6 = var0(initial)
Type var6Type = assign_stack(baseHeight + 2, var0);
// var7 = var1(initial)
Type var7Type = assign_stack(baseHeight + 3, var1);
// var0 = var2(initial)
Type var0Type = assign_stack(baseHeight - 4, var2);
// var1 = var3(initial)
Type var1Type = assign_stack(baseHeight - 3, var3);
// var4 = var2(initial)
Type var4Type = assign_stack(baseHeight + 0, var2);
// var5 = var3(initial)
Type var5Type = assign_stack(baseHeight + 1, var3);
// var2 = var6 = var0(initial)
Type var2Type = assign_stack(baseHeight - 2, load_stack(baseHeight + 2, var6Type));
// var3 = var7 = var1(initial)
Type var3Type = assign_stack(baseHeight - 1, load_stack(baseHeight + 3, var7Type));
// push var0
push(load_stack(baseHeight - 4, var0Type));
// push var1
push(load_stack(baseHeight - 3, var1Type));
// push var2
push(load_stack(baseHeight - 2, var2Type));
// push var3
push(load_stack(baseHeight - 1, var3Type));
// push var4
push(load_stack(baseHeight + 0, var4Type));
// push var5
push(load_stack(baseHeight + 1, var5Type));
}
}
}
use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class SSAGenPass method isSameValue.
private boolean isSameValue(Expr e1, Expr e2) {
Expr val1 = getValue(e1);
Expr val2 = getValue(e2);
if (!shouldCoalesce(val1.getOpcode()) || !shouldCoalesce(val2.getOpcode())) {
return false;
}
return val1.equivalent(val2);
}
use of org.mapleir.ir.code.Expr 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.Expr 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.Expr in project maple-ir by LLVM-but-worse.
the class PoolLocalValueResolver method getValues.
@Override
public TaintableSet<Expr> getValues(ControlFlowGraph cfg, Local l) {
if (cfg.getLocals() != pool) {
throw new UnsupportedOperationException();
}
AbstractCopyStmt copy = pool.defs.get(l);
TaintableSet<Expr> set = new TaintableSet<>();
if (copy.getOpcode() == Opcode.PHI_STORE) {
// checkRecursive(l);
// PhiExpr phi = ((CopyPhiStmt) copy).getExpression();
/*for(Expr e : phi.getArguments().values()) {
if(e.getOpcode() == Opcode.LOCAL_LOAD) {
Local l2 = ((VarExpr) e).getLocal();
if(l2 == l) {
throw new RuntimeException(copy.toString());
}
}
}*/
// set.addAll(phi.getArguments().values());
} else {
// set.add(copy.getExpression());
}
set.add(copy.getExpression());
return set;
}
Aggregations