use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class DominanceLivenessAnalyser method isLiveIn.
public boolean isLiveIn(BasicBlock b, Local l) {
BasicBlock defBlock = defuse.defs.get(l);
if (defuse.phiDefs.containsKey(l) && defBlock == b) {
return true;
}
GenericBitSet<BasicBlock> tqa = tq.get(b).intersect(sdoms.getNonNull(defBlock));
for (BasicBlock t : tqa) {
GenericBitSet<BasicBlock> rt = rv.get(t).intersect(defuse.uses.get(l));
if (!rt.isEmpty())
return true;
}
return false;
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class DominanceLivenessAnalyser method reduce.
private ControlFlowGraph reduce(ControlFlowGraph cfg, Set<FastGraphEdge<BasicBlock>> back) {
ControlFlowGraph reducedCfg = cfg.copy();
for (FastGraphEdge<BasicBlock> e : back) {
reducedCfg.removeEdge(e.src(), (FlowEdge<BasicBlock>) e);
backTargets.add(e.dst());
backEdges.getNonNull(e.src()).add(e.dst());
}
return reducedCfg;
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSABlockLivenessAnalyser method precomputeBlock.
// compute def, use, and phi for given block
private void precomputeBlock(BasicBlock b) {
def.getNonNull(b);
use.getNonNull(b);
phiUse.getNonNull(b);
phiDef.getNonNull(b);
// we have to iterate in reverse order because a definition will kill a use in the current block
// this is so that uses do not escape a block if its def is in the same block. this is basically
// simulating a statement graph analysis
ListIterator<Stmt> it = b.listIterator(b.size());
while (it.hasPrevious()) {
Stmt stmt = it.previous();
int opcode = stmt.getOpcode();
if (opcode == Opcode.PHI_STORE) {
CopyPhiStmt copy = (CopyPhiStmt) stmt;
phiDef.get(b).add(copy.getVariable().getLocal());
PhiExpr phi = copy.getExpression();
for (Map.Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
BasicBlock exprSource = e.getKey();
Expr phiExpr = e.getValue();
GenericBitSet<Local> useSet = phiUse.get(b).getNonNull(exprSource);
if (phiExpr.getOpcode() == Opcode.LOCAL_LOAD) {
useSet.add(((VarExpr) phiExpr).getLocal());
} else
for (Expr child : phiExpr.enumerateOnlyChildren()) {
if (child.getOpcode() == Opcode.LOCAL_LOAD) {
useSet.add(((VarExpr) child).getLocal());
}
}
}
} else {
if (opcode == Opcode.LOCAL_STORE) {
CopyVarStmt copy = (CopyVarStmt) stmt;
Local l = copy.getVariable().getLocal();
def.get(b).add(l);
use.get(b).remove(l);
Expr e = copy.getExpression();
// adding it as live-in.
if (e.getOpcode() == Opcode.CATCH) {
if (hasNaturalPredecessors(cfg, b)) {
use.get(b).add(l);
}
}
}
for (Expr c : stmt.enumerateOnlyChildren()) {
if (c.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) c;
use.get(b).add(v.getLocal());
}
}
}
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSABlockLivenessAnalyser method init.
private void init() {
// initialize in and out
for (BasicBlock b : cfg.vertices()) {
in.getNonNull(b);
out.getNonNull(b);
}
// compute def, use, and phi for each block
for (BasicBlock b : cfg.vertices()) precomputeBlock(b);
// enqueue every block
for (BasicBlock b : cfg.vertices()) enqueue(b);
// System.out.println();
// System.out.println();
// for (BasicBlock b : cfg.vertices())
// System.out.println(b.getId() + " |||| DEF: " + def.get(b) + " ||||| USE: " + use.get(b));
// System.out.println();
// for (BasicBlock b : cfg.vertices())
// System.out.println(b.getId() + " |||| \u0278DEF: " + phiDef.get(b) + " ||||| \u0278USE: " + phiUse.get(b));
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SSABlockLivenessAnalyser method compute.
public void compute() {
// negative handling always goes after positive and any adds
while (!queue.isEmpty()) {
BasicBlock b = queue.remove();
// System.out.println("\n\nProcessing " + b.getId());
GenericBitSet<Local> oldIn = new GenericBitSet<>(in.get(b));
GenericBitSet<Local> curIn = new GenericBitSet<>(use.get(b));
GenericBitSet<Local> curOut = locals.createBitSet();
// out[n] = U(s in succ[n])(in[s])
for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.addAll(in.get(succEdge.dst()));
// negative phi handling for defs
for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.removeAll(phiDef.get(succEdge.dst()));
// positive phi handling for uses, see ยง5.4.2 "Meaning of copy statements in Sreedhar's method"
for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.addAll(phiUse.get(succEdge.dst()).getNonNull(b));
// negative phi handling for uses
for (FlowEdge<BasicBlock> predEdge : cfg.getReverseEdges(b)) curIn.removeAll(phiUse.get(b).getNonNull(predEdge.src()).relativeComplement(use.get(b)));
// positive phi handling for defs
curIn.addAll(phiDef.get(b));
oldIn.addAll(phiDef.get(b));
// in[n] = use[n] U(out[n] - def[n])
curIn.addAll(curOut.relativeComplement(def.get(b)));
in.put(b, curIn);
out.put(b, curOut);
// queue preds if dataflow state changed
if (!oldIn.equals(curIn)) {
cfg.getReverseEdges(b).stream().map(e -> e.src()).forEach(this::enqueue);
// for (BasicBlock b2 : cfg.vertices())
// System.out.println(b2.getId() + " |||| IN: " + in.get(b2) + " ||||| OUT: " + out.get(b2));
}
}
}
Aggregations