use of org.mapleir.ir.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.
the class BoissinotDestructor method coalescePhis.
// Initialize ccs based on phis and drop phi statements
private void coalescePhis() {
GenericBitSet<BasicBlock> processed = cfg.createBitSet();
for (Entry<Local, CopyPhiStmt> e : defuse.phiDefs.entrySet()) {
Local l = e.getKey();
BasicBlock b = e.getValue().getBlock();
// since we are now in csaa, phi locals never interfere and are in the same congruence class.
// therefore we can coalesce them all together and drop phis. with this, we leave cssa.
PhiExpr phi = e.getValue().getExpression();
CongruenceClass pcc = new CongruenceClass();
pcc.add(l);
congruenceClasses.put(l, pcc);
for (Expr ex : phi.getArguments().values()) {
VarExpr v = (VarExpr) ex;
Local argL = v.getLocal();
pcc.add(argL);
congruenceClasses.put(argL, pcc);
}
// we can simply drop all the phis without further consideration
if (!processed.contains(b)) {
processed.add(b);
Iterator<Stmt> it = b.iterator();
while (it.hasNext()) {
Stmt stmt = it.next();
if (stmt.getOpcode() == Opcode.PHI_STORE) {
it.remove();
} else {
break;
}
}
}
}
defuse.phiDefs.clear();
}
use of org.mapleir.ir.code.expr.PhiExpr 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.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.
the class SSADefUseMap method build.
protected void build(BasicBlock b, Stmt stmt, Set<Local> usedLocals) {
if (stmt instanceof AbstractCopyStmt) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
Local l = copy.getVariable().getLocal();
defs.put(l, b);
if (copy instanceof CopyPhiStmt) {
phiDefs.put(l, (CopyPhiStmt) copy);
PhiExpr phi = (PhiExpr) copy.getExpression();
for (Entry<BasicBlock, Expr> en : phi.getArguments().entrySet()) {
Local ul = ((VarExpr) en.getValue()).getLocal();
uses.getNonNull(ul).add(en.getKey());
phiUses.get(b).add(ul);
}
return;
}
}
for (Local usedLocal : usedLocals) uses.getNonNull(usedLocal).add(b);
}
use of org.mapleir.ir.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method csaa_iii.
// ============================================================================================================= //
// =================================================== CSSA ==================================================== //
// ============================================================================================================= //
private void csaa_iii() {
// iterate over each phi expression
for (Entry<Local, CopyPhiStmt> entry : defuse.phiDefs.entrySet()) {
// System.out.println("process phi " + entry.getValue());
// x0
Local phiTarget = entry.getKey();
CopyPhiStmt copy = entry.getValue();
// l0
BasicBlock defBlock = defuse.defs.get(phiTarget);
PhiExpr phi = copy.getExpression();
candidateResourceSet.clear();
unresolvedNeighborsMap.clear();
// Initialize phiResources set for convenience
final GenericBitSet<PhiResource> phiResources = phiResSetCreator.create();
phiResources.add(new PhiResource(defBlock, phiTarget, true));
for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiResources.add(new PhiResource(phiEntry.getKey(), ((VarExpr) phiEntry.getValue()).getLocal(), false));
// Determine what copies are needed using the four cases.
handleInterference(phiResources);
// Process unresolved resources
resolveDeferred();
// System.out.println(" Cand: " + candidateResourceSet);
// Resolve the candidate resources
Type phiType = phi.getType();
for (PhiResource toResolve : candidateResourceSet) {
if (toResolve.isTarget)
resolvePhiTarget(toResolve, phiType);
else
for (Entry<BasicBlock, Expr> phiArg : phi.getArguments().entrySet()) {
VarExpr phiVar = (VarExpr) phiArg.getValue();
if (phiVar.getLocal() == toResolve.local)
phiVar.setLocal(resolvePhiSource(toResolve.local, phiArg.getKey(), phiType));
}
}
// System.out.println(" interference: ");
// for (Entry<Local, GenericBitSet<Local>> entry2 : interfere.entrySet())
// System.out.println(" " + entry2.getKey() + " : " + entry2.getValue());
// System.out.println(" post-inserted: " + copy);
// Merge pccs for all locals in phi
final GenericBitSet<Local> phiLocals = locals.createBitSet();
phiLocals.add(copy.getVariable().getLocal());
for (Entry<BasicBlock, Expr> phiEntry : phi.getArguments().entrySet()) phiLocals.add(((VarExpr) phiEntry.getValue()).getLocal());
for (Local phiLocal : phiLocals) pccs.put(phiLocal, phiLocals);
// Nullify singleton pccs
for (GenericBitSet<Local> pcc : pccs.values()) if (pcc.size() <= 1)
pcc.clear();
// System.out.println(" pccs:");
// for (Entry<Local, GenericBitSet<Local>> entry2 : pccs.entrySet())
// System.out.println(" " + entry2.getKey() + " : " + entry2.getValue());
// System.out.println();
}
}
use of org.mapleir.ir.code.expr.PhiExpr in project maple-ir by LLVM-but-worse.
the class ControlFlowGraph method exciseEdge.
/**
* Properly removes the edge, and cleans up phi uses in fe.dst of phi arguments from fe.src.
* @param fe Edge to excise phi uses.
*/
public void exciseEdge(FlowEdge<BasicBlock> fe) {
if (!this.containsEdge(fe.src(), fe))
throw new IllegalArgumentException("Graph does not contain the specified edge");
removeEdge(fe.src(), fe);
for (Stmt stmt : fe.dst()) {
if (stmt.getOpcode() == PHI_STORE) {
CopyPhiStmt phs = (CopyPhiStmt) stmt;
PhiExpr phi = phs.getExpression();
BasicBlock pred = fe.src();
VarExpr arg = (VarExpr) phi.getArgument(pred);
VersionedLocal l = (VersionedLocal) arg.getLocal();
locals.uses.get(l).remove(arg);
phi.removeArgument(pred);
} else {
return;
}
}
}
Aggregations