use of org.mapleir.ir.code.Stmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method searchImpl.
private void searchImpl(BasicBlock b) {
Iterator<Stmt> it = b.iterator();
while (it.hasNext()) {
Stmt stmt = it.next();
int opcode = stmt.getOpcode();
if (opcode == Opcode.POP) {
PopStmt pop = (PopStmt) stmt;
if (!ConstraintUtil.isUncopyable(pop.getExpression())) {
it.remove();
continue;
}
}
if (opcode == Opcode.PHI_STORE) {
/* We can rename these any time as these
* are visited before all other statements
* in a block (since they are always
* the starting statements of a block, if
* that block contains phi statements).
*/
CopyPhiStmt copy = (CopyPhiStmt) stmt;
generate(copy);
} else {
/* Translates locals into their latest SSA
* versioned locals.
*
* Do this before a LOCAL_STORE (x = ...)
* so that the target local isn't defined
* before the use so that copies in the
* form x = x; do not get mangled into
* x0 = x0 after SSA renaming.
*
* We rename phi args later as the source
* local can originate from exotic blocks.
*/
translate(stmt, true, false);
}
if (opcode == Opcode.LOCAL_STORE) {
/* Generate the target local after
* renaming the source pool.uses.
*/
CopyVarStmt copy = (CopyVarStmt) stmt;
generate(copy);
}
}
}
use of org.mapleir.ir.code.Stmt in project maple-ir by LLVM-but-worse.
the class SSAGenPass method fixPhiArgs.
private void fixPhiArgs(BasicBlock b, BasicBlock succ) {
for (Stmt stmt : succ) {
if (stmt.getOpcode() == Opcode.PHI_STORE) {
CopyPhiStmt copy = (CopyPhiStmt) stmt;
PhiExpr phi = copy.getExpression();
Expr e = phi.getArgument(b);
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
translate(v, true, true);
VersionedLocal ssaL = (VersionedLocal) v.getLocal();
Type t = types.get(ssaL);
copy.getVariable().setType(t);
phi.setType(t);
} else {
throw new IllegalArgumentException(phi + ", " + e);
}
} else {
/* No need to search the rest of the block
* after we have visited the phis as they
* precede all other statements.
*/
break;
}
}
}
use of org.mapleir.ir.code.Stmt in project maple-ir by LLVM-but-worse.
the class LatestValue method canPropagate.
public boolean canPropagate(AbstractCopyStmt def, Stmt use, Expr tail, boolean debug) {
Local local = def.getVariable().getLocal();
Set<Stmt> path = findReachable(def, use);
path.remove(def);
path.add(use);
if (debug) {
System.out.println();
System.out.println("from " + def);
System.out.println("to " + use);
System.out.println(this);
System.out.println("constraints: " + constraints.size());
for (Constraint c : constraints) {
System.out.println(" " + c);
}
System.out.println(" path:");
for (Stmt s : path) {
System.out.println(" " + s);
}
}
for (Stmt stmt : path) {
if (stmt != use) {
for (CodeUnit s : stmt.enumerateWithSelf()) {
for (Constraint c : constraints) {
if (c.fails(s)) {
if (debug) {
System.out.println(" Fail: " + c);
System.out.println(" stmt: " + stmt);
System.out.println(" c: " + s);
}
return false;
}
}
}
} else {
if (constraints.size() > 0) {
for (CodeUnit s : stmt.enumerateExecutionOrder()) {
if (s == tail && (s.getOpcode() == Opcode.LOCAL_LOAD && ((VarExpr) s).getLocal() == local)) {
break;
} else {
for (Constraint c : constraints) {
if (c.fails(s)) {
if (debug) {
System.out.println(" Fail: " + c);
System.out.println(" stmt: " + stmt);
System.out.println(" c: " + s);
}
return false;
}
}
}
}
}
}
}
return true;
}
use of org.mapleir.ir.code.Stmt in project maple-ir by LLVM-but-worse.
the class ControlFlowGraphDecorator method outputBlock.
private void outputBlock(BasicBlock n, StringBuilder sb2) {
Iterator<Stmt> it = n.iterator();
TabbedStringWriter sw = new TabbedStringWriter();
int insn = 0;
while (it.hasNext()) {
Stmt stmt = it.next();
sw.print(insn++ + ". ");
stmt.toString(sw);
sw.print("\n");
}
sb2.append(sw.toString());
}
use of org.mapleir.ir.code.Stmt 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;
}
Aggregations