use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method init.
// ============================================================================================================= //
// =============================================== Initialization ============================================== //
// ============================================================================================================= //
private void init() {
// init pccs
for (CopyPhiStmt copyPhi : defuse.phiDefs.values()) {
Local phiTarget = copyPhi.getVariable().getLocal();
pccs.getNonNull(phiTarget).add(phiTarget);
// System.out.println("Initphi " + phiTarget);
for (Entry<BasicBlock, Expr> phiEntry : copyPhi.getExpression().getArguments().entrySet()) {
if (phiEntry.getValue().getOpcode() != LOCAL_LOAD)
throw new IllegalArgumentException("Phi arg is not local; instead is " + phiEntry.getValue().getClass().getSimpleName());
Local phiSource = ((VarExpr) phiEntry.getValue()).getLocal();
pccs.getNonNull(phiSource).add(phiSource);
// System.out.println("Initphi " + phiSource);
}
}
// System.out.println();
// compute liveness
(liveness = new SSABlockLivenessAnalyser(cfg)).compute();
// writer.add("liveness", new LivenessDecorator<ControlFlowGraph, BasicBlock, FlowEdge<BasicBlock>>().setLiveness(liveness));
buildInterference();
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class SreedharDestructor method resolvePhiSource.
private Local resolvePhiSource(Local xi, BasicBlock lk, Type phiType) {
// Insert spill copy
Local spill = insertEnd(xi, lk, phiType);
// Update liveness
GenericBitSet<Local> liveOut = liveness.out(lk);
liveOut.add(spill);
// xi can be removed from liveOut iff it isn't live into any succ or used in any succ phi.
for (BasicBlock lj : succsCache.getNonNull(lk)) {
if (!liveness.in(lj).contains(xi))
removeFromOut: {
for (int i = 0; i < lj.size() && lj.get(i).getOpcode() == Opcode.PHI_STORE; i++) if (((VarExpr) ((CopyPhiStmt) lj.get(i)).getExpression().getArguments().get(lk)).getLocal() == xi)
break removeFromOut;
// poor man's for-else loop
liveOut.remove(xi);
}
}
// Reflexively update interference
interfere.getNonNull(spill).addAll(liveOut);
for (Local l : liveOut) interfere.get(l).add(spill);
return spill;
}
use of org.mapleir.ir.cfg.BasicBlock 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.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class GenerationPass method process.
protected void process(LabelNode label) {
/* it may not be properly initialised yet, however. */
BasicBlock block = builder.graph.getBlock(label);
/* if it is, we don't need to process it. */
if (block != null && finished.get(block.getNumericId())) {
return;
} else if (block == null) {
block = makeBlock(label);
} else {
// i.e. not finished.
}
preprocess(block);
/* populate instructions. */
int codeIndex = insns.indexOf(label);
finished.set(block.getNumericId());
while (codeIndex < insns.size() - 1) {
AbstractInsnNode ain = insns.get(++codeIndex);
int type = ain.type();
if (ain.opcode() != -1) {
process(block, ain);
}
if (type == LABEL) {
// split into new block
BasicBlock immediate = resolveTarget((LabelNode) ain);
builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
break;
} else if (type == JUMP_INSN) {
JumpInsnNode jin = (JumpInsnNode) ain;
BasicBlock target = resolveTarget(jin.label);
if (jin.opcode() == JSR) {
throw new UnsupportedOperationException("jsr " + builder.method);
} else if (jin.opcode() == GOTO) {
builder.graph.addEdge(block, new UnconditionalJumpEdge<>(block, target));
} else {
builder.graph.addEdge(block, new ConditionalJumpEdge<>(block, target, jin.opcode()));
int nextIndex = codeIndex + 1;
AbstractInsnNode nextInsn = insns.get(nextIndex);
if (!(nextInsn instanceof LabelNode)) {
LabelNode newLabel = new LabelNode();
insns.insert(ain, newLabel);
nextInsn = newLabel;
}
// create immediate successor reference if it's not already done
BasicBlock immediate = resolveTarget((LabelNode) nextInsn);
builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
}
break;
} else if (type == LOOKUPSWITCH_INSN) {
LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) ain;
for (int i = 0; i < lsin.keys.size(); i++) {
BasicBlock target = resolveTarget(lsin.labels.get(i));
builder.graph.addEdge(block, new SwitchEdge<>(block, target, lsin, lsin.keys.get(i)));
}
BasicBlock dflt = resolveTarget(lsin.dflt);
builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, lsin));
break;
} else if (type == TABLESWITCH_INSN) {
TableSwitchInsnNode tsin = (TableSwitchInsnNode) ain;
for (int i = tsin.min; i <= tsin.max; i++) {
BasicBlock target = resolveTarget(tsin.labels.get(i - tsin.min));
builder.graph.addEdge(block, new SwitchEdge<>(block, target, tsin, i));
}
BasicBlock dflt = resolveTarget(tsin.dflt);
builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, tsin));
break;
} else if (isExitOpcode(ain.opcode())) {
break;
}
}
// TODO: check if it should have an immediate.
BasicBlock im = block.getImmediate();
if (im != null) /* && !queue.contains(im)*/
{
// System.out.println("Updating " + block.getId() + " -> " + im.getId());
// System.out.println(" Pre: " + currentStack);
update_target_stack(block, im, currentStack);
// System.out.println(" Pos: " + currentStack);
}
}
use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.
the class GenerationPass method range.
private static List<BasicBlock> range(List<BasicBlock> gblocks, int start, int end) {
if (start > end) {
throw new IllegalArgumentException("start > end: " + start + " > " + end);
}
BasicBlock startBlock = null, endBlock = null;
int startIndex = 0, endIndex = 0;
// String startName = StringHelper.createBlockName(start);
// String endName = StringHelper.createBlockName(end);
int blockIndex = 0;
for (BasicBlock b : gblocks) {
if (b.getNumericId() == start) {
startBlock = b;
startIndex = blockIndex;
}
if (b.getNumericId() == end) {
endBlock = b;
endIndex = blockIndex;
}
if (startBlock != null && endBlock != null) {
break;
}
blockIndex++;
}
if (startBlock == null || endBlock == null) {
throw new UnsupportedOperationException("start or end null, " + start + " " + end);
} else if (startIndex > endIndex) {
throw new IllegalArgumentException("startIndex > endIndex: " + startIndex + " > " + endIndex);
}
List<BasicBlock> blocks = new ArrayList<>();
for (int i = startIndex; i <= endIndex; i++) {
BasicBlock block = gblocks.get(i);
if (block == null) {
throw new IllegalArgumentException("block " + StringHelper.createBlockName(i) + "not in range");
}
blocks.add(block);
}
return blocks;
}
Aggregations