use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSAGenPass method updatePhiArgTypes.
private void updatePhiArgTypes(Set<BasicBlock> vis) {
// update types for phi args
for (BasicBlock b : order) {
for (Stmt s : b) {
if (s.getOpcode() != Opcode.PHI_STORE) {
break;
}
CopyPhiStmt cps = (CopyPhiStmt) s;
for (Entry<BasicBlock, Expr> e : cps.getExpression().getArguments().entrySet()) {
BasicBlock src = e.getKey();
if (vis.contains(src))
continue;
VarExpr v = (VarExpr) e.getValue();
Local l = v.getLocal();
// what if the def is never reached?
AbstractCopyStmt def = pool.defs.get(l);
v.setType(def.getType());
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSAGenPass method insertPhis.
private void insertPhis(BasicBlock b, Local l, int i, LinkedList<BasicBlock> queue) {
if (b == null || b == builder.head) {
// exit
return;
}
Local newl = builder.graph.getLocals().get(l.getIndex(), 0, l.isStack());
for (BasicBlock x : doms.iteratedFrontier(b)) {
if (insertion.get(x) < i) {
// pruned SSA
if (liveness.in(x).contains(l)) {
if ((l == svar0) && handlers.contains(x)) /* == faster than contains. */
{
/* Note: this is quite subtle. Since there is a
* copy, (svar0 = catch()) at the start of each
* handler block, technically any natural flowing
* svar0 definition is killed upon entry to the
* block, so it is not considered live. One way to
* check if the variable is live-in, therefore, is
* by checking whether svar0 is live-out of the
* catch() definition. We handle it here, since
* the previous liveness check which is used for
* pruned SSA will fail in this case. */
/* Ok fuck that that, it's considered live-in
* even if there is a catch()::
* #see SSaBlockLivenessAnalyser.precomputeBlock*/
boolean naturalFlow = false;
for (FlowEdge<BasicBlock> e : builder.graph.getReverseEdges(x)) {
if (e.getType() != FlowEdges.TRYCATCH) {
naturalFlow = true;
break;
}
}
if (naturalFlow) {
CopyVarStmt catcher = null;
for (Stmt stmt : x) {
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
CopyVarStmt copy = (CopyVarStmt) stmt;
Expr e = copy.getExpression();
if (e.getOpcode() == Opcode.CATCH) {
catcher = copy;
break;
}
}
}
if (catcher == null) {
/* Handler but no catch copy?
* This can't happen since svar0 is
* the only reserved register for
* catch copies, and this block cannot
* be visited twice to insert a phi or
* psi(ephi) node. */
throw new IllegalStateException(x.getDisplayName());
}
/* Map<BasicBlock, Expression> vls = new HashMap<>();
for(FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
vls.put(fe.src, new VarExpr(newl, null));
}
vls.put(x, catcher.getExpression().copy());
catcher.delete();
PhiExpr phi = new PhiExceptionExpr(vls);
CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
x.add(0, assign); */
throw new UnsupportedOperationException(builder.method.toString());
}
}
if (builder.graph.getReverseEdges(x).size() > 1) {
Map<BasicBlock, Expr> vls = new HashMap<>();
for (FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
vls.put(fe.src(), new VarExpr(newl, null));
}
PhiExpr phi = new PhiExpr(vls);
CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
x.add(0, assign);
}
}
insertion.put(x, i);
if (process.get(x) < i) {
process.put(x, i);
queue.add(x);
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSAGenPass method search.
private void search(BasicBlock b, Set<BasicBlock> vis) {
if (vis.contains(b)) {
return;
}
vis.add(b);
searchImpl(b);
List<FlowEdge<BasicBlock>> succs = new ArrayList<>();
for (FlowEdge<BasicBlock> succE : builder.graph.getEdges(b)) {
succs.add(succE);
}
succs.sort(Comparator.comparing(o -> o.dst()));
for (FlowEdge<BasicBlock> succE : succs) {
BasicBlock succ = succE.dst();
fixPhiArgs(b, succ);
}
for (FlowEdge<BasicBlock> succE : succs) {
BasicBlock succ = succE.dst();
search(succ, vis);
}
unstackDefs(b);
if (OPTIMISE) {
optimisePhis(b);
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class LatestValue method findReachable.
private Set<Stmt> findReachable(Stmt from, Stmt to) {
Set<Stmt> res = new HashSet<>();
BasicBlock f = from.getBlock();
BasicBlock t = to.getBlock();
int end = f == t ? f.indexOf(to) : f.size();
for (int i = f.indexOf(from); i < end; i++) {
res.add(f.get(i));
}
if (f != t) {
for (BasicBlock r : cfg.wanderAllTrails(f, t)) {
res.addAll(r);
}
}
return res;
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class PhiExpr method equivalent.
@Override
public boolean equivalent(CodeUnit s) {
if (s instanceof PhiExpr) {
PhiExpr phi = (PhiExpr) s;
Set<BasicBlock> sources = new HashSet<>();
sources.addAll(arguments.keySet());
sources.addAll(phi.arguments.keySet());
if (sources.size() != arguments.size()) {
return false;
}
for (BasicBlock b : sources) {
Expr e1 = arguments.get(b);
Expr e2 = phi.arguments.get(b);
if (e1 == null || e2 == null) {
return false;
}
if (!e1.equivalent(e2)) {
return false;
}
}
return true;
}
return false;
}
Aggregations