use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class DefUseVerifier method verify0.
public static void verify0(ControlFlowGraph cfg) {
LocalsPool lp = cfg.getLocals();
Map<Local, AbstractCopyStmt> defs = new HashMap<>();
NullPermeableHashMap<VersionedLocal, Set<VarExpr>> uses = new NullPermeableHashMap<>(SetCreator.getInstance());
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
if (stmt.getOpcode() == Opcode.LOCAL_STORE || stmt.getOpcode() == Opcode.PHI_STORE) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
defs.put(copy.getVariable().getLocal(), copy);
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
uses.getNonNull((VersionedLocal) v.getLocal()).add(v);
}
}
}
}
{
Set<Local> dlocals = new HashSet<>();
dlocals.addAll(defs.keySet());
dlocals.addAll(lp.defs.keySet());
for (Local l : dlocals) {
if (!defs.containsKey(l)) {
throw new IllegalStateException("(other): def of " + l);
}
if (!lp.defs.containsKey(l)) {
throw new IllegalStateException("(real): def of " + l);
}
AbstractCopyStmt copy1 = defs.get(l);
AbstractCopyStmt copy2 = lp.defs.get(l);
if (copy1 != copy2) {
throw new IllegalStateException("dtest: " + copy1 + " :: " + copy2);
}
}
}
{
Set<VersionedLocal> ulocals = new HashSet<>();
ulocals.addAll(uses.keySet());
ulocals.addAll(lp.uses.keySet());
for (VersionedLocal l : ulocals) {
/*if(!uses.containsKey(l)) {
throw new IllegalStateException("(other): use of " + l);
}
if(!lp.uses.containsKey(l)) {
throw new IllegalStateException("(real): use of " + l);
}*/
Set<VarExpr> uses1 = uses.get(l);
Set<VarExpr> uses2 = lp.uses.get(l);
if (uses1 == null) {
if (uses2.size() != 0) {
throw new IllegalStateException(String.format("utest1: %s, u1:null :: u2:%d", l, uses2.size()));
}
} else if (uses2 == null) {
if (uses1.size() == 0) {
throw new IllegalStateException(String.format("utest2: %s, u1:%d :: u2:null", l, uses1.size()));
}
} else {
if (uses2.size() != uses1.size()) {
throw new IllegalStateException(String.format("utest3: %s, u1:%d :: u2:%d", l, uses1.size(), uses2.size()));
}
}
}
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class NaturalisationPass1 method mergeImmediates.
int mergeImmediates() {
class MergePair {
final BasicBlock src;
final BasicBlock dst;
MergePair(BasicBlock src, BasicBlock dst) {
this.src = src;
this.dst = dst;
}
}
List<MergePair> merges = new ArrayList<>();
Map<BasicBlock, BasicBlock> remap = new HashMap<>();
Map<BasicBlock, List<ExceptionRange<BasicBlock>>> ranges = new HashMap<>();
for (BasicBlock b : builder.graph.vertices()) {
BasicBlock in = b.getIncomingImmediate();
if (in == null) {
continue;
}
if (in.isFlagSet(BasicBlock.FLAG_NO_MERGE)) {
continue;
}
Set<FlowEdge<BasicBlock>> inSuccs = in.getSuccessors(e -> !(e instanceof TryCatchEdge));
if (inSuccs.size() != 1 || builder.graph.getReverseEdges(b).size() != 1) {
continue;
}
List<ExceptionRange<BasicBlock>> range1 = b.getProtectingRanges();
List<ExceptionRange<BasicBlock>> range2 = in.getProtectingRanges();
if (!range1.equals(range2)) {
continue;
}
ranges.put(b, range1);
ranges.put(in, range2);
merges.add(new MergePair(in, b));
remap.put(in, in);
remap.put(b, b);
}
for (MergePair p : merges) {
BasicBlock src = remap.get(p.src);
BasicBlock dst = p.dst;
dst.transfer(src);
for (FlowEdge<BasicBlock> e : builder.graph.getEdges(dst)) {
// to clone these.
if (e.getType() != FlowEdges.TRYCATCH) {
BasicBlock edst = e.dst();
edst = remap.getOrDefault(edst, edst);
builder.graph.addEdge(src, e.clone(src, edst));
}
}
builder.graph.removeVertex(dst);
remap.put(dst, src);
for (ExceptionRange<BasicBlock> r : ranges.get(src)) {
r.removeVertex(dst);
}
for (ExceptionRange<BasicBlock> r : ranges.get(dst)) {
r.removeVertex(dst);
}
// System.out.printf("Merged %s into %s.%n", dst.getId(), src.getId());
}
// we need to update the assigns map if we change the cfg.
for (Entry<Local, Set<BasicBlock>> e : builder.assigns.entrySet()) {
Set<BasicBlock> set = e.getValue();
Set<BasicBlock> copy = new HashSet<>(set);
for (BasicBlock b : copy) {
BasicBlock r = remap.getOrDefault(b, b);
if (r != b) {
set.remove(b);
set.add(r);
}
}
}
return merges.size();
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SSAGenPass method insertPhis.
private void insertPhis() {
int i = 0;
for (Local l : builder.locals) {
i++;
LinkedList<BasicBlock> queue = new LinkedList<>();
for (BasicBlock b : builder.assigns.get(l)) {
process.put(b, i);
queue.add(b);
}
while (!queue.isEmpty()) {
insertPhis(queue.poll(), l, i, queue);
}
}
}
use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.
the class SSAGenPass method rename.
private void rename() {
for (Local l : builder.locals) {
counters.put(l, 0);
stacks.put(l, new Stack<>());
}
Set<BasicBlock> vis = new HashSet<>();
for (BasicBlock e : builder.graph.getEntries()) {
search(e, vis);
}
updatePhiArgTypes(vis);
}
Aggregations