Methods Summary |
---|
private static boolean | hasSideEffect(SsaInsn insn)Returns true if this insn has a side-effect. Returns true
if the insn is null for reasons stated in the code block.
if (insn == null) {
/* While false would seem to make more sense here, true
* prevents us from adding this back to a worklist unnecessarally.
*/
return true;
}
return insn.hasSideEffect();
|
private boolean | isCircularNoSideEffect(int regV, java.util.BitSet set)Returns true if the only uses of this register form a circle of
operations with no side effects.
if ((set != null) && set.get(regV)) {
return true;
}
for (SsaInsn use : useList[regV]) {
if (hasSideEffect(use)) {
return false;
}
}
if (set == null) {
set = new BitSet(regCount);
}
// This register is only used in operations that have no side effect.
set.set(regV);
for (SsaInsn use : useList[regV]) {
RegisterSpec result = use.getResult();
if (result == null
|| !isCircularNoSideEffect(result.getReg(), set)) {
return false;
}
}
return true;
|
public static void | process(SsaMethod ssaMethod)Process a method with the dead-code remver
DeadCodeRemover dc = new DeadCodeRemover(ssaMethod);
dc.run();
|
private void | pruneDeadInstructions()Removes all instructions from every unreachable block.
HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
ssaMeth.computeReachability();
for (SsaBasicBlock block : ssaMeth.getBlocks()) {
if (block.isReachable()) continue;
// Prune instructions from unreachable blocks
for (int i = 0; i < block.getInsns().size(); i++) {
SsaInsn insn = block.getInsns().get(i);
RegisterSpecList sources = insn.getSources();
int sourcesSize = sources.size();
// Delete this instruction completely if it has sources
if (sourcesSize != 0) {
deletedInsns.add(insn);
}
// Delete this instruction from all usage lists.
for (int j = 0; j < sourcesSize; j++) {
RegisterSpec source = sources.get(j);
useList[source.getReg()].remove(insn);
}
// Remove this instruction result from the sources of any phis
RegisterSpec result = insn.getResult();
if (result == null) continue;
for (SsaInsn use : useList[result.getReg()]) {
if (use instanceof PhiInsn) {
PhiInsn phiUse = (PhiInsn) use;
phiUse.removePhiRegister(result);
}
}
}
}
ssaMeth.deleteInsns(deletedInsns);
|
private void | run()Runs the dead code remover.
pruneDeadInstructions();
HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
ssaMeth.forEachInsn(new NoSideEffectVisitor(worklist));
int regV;
while ( 0 <= (regV = worklist.nextSetBit(0)) ) {
worklist.clear(regV);
if (useList[regV].size() == 0
|| isCircularNoSideEffect(regV, null)) {
SsaInsn insnS = ssaMeth.getDefinitionForRegister(regV);
// This insn has already been deleted.
if (deletedInsns.contains(insnS)) {
continue;
}
RegisterSpecList sources = insnS.getSources();
int sz = sources.size();
for (int i = 0; i < sz; i++) {
// Delete this insn from all usage lists.
RegisterSpec source = sources.get(i);
useList[source.getReg()].remove(insnS);
if (!hasSideEffect(
ssaMeth.getDefinitionForRegister(
source.getReg()))) {
/*
* Only registers whose definition has no side effect
* should be added back to the worklist.
*/
worklist.set(source.getReg());
}
}
// Schedule this insn for later deletion.
deletedInsns.add(insnS);
}
}
ssaMeth.deleteInsns(deletedInsns);
|