BLOAT made use of a special instruction called a 'Label' this instruction denoted the target of a jump, exception handler, or the start and end of a try catch block (the start of a basic block). BCEL has no such instruction, however Labels can be emulated by setting a Label attribute to InstructionHandles and creating a NOP instruction. For Peephole this would work but I wanted to allow Peephole to be run on code that had not been generated using CodeGenerator. For this reason when calling transform on Peephole there is a flag to indicate whether Labels have been set or not. If Labels have not been set a call to FlowGraph.buildBLOATInstructionList(method) is performed. This only sets the Label attribute in InstructionHandles it does not create the NOP instructions.

This means that Peephole code had to be changed to reflect the fact that a Label is also the first and also possibly the last instruction in a basic block. In the method Peephole.removeUnreachable(...) a block consisting of a single goto instruction caused an error, the code marking visited blocks did not take into account that the current instruction could be both a Label and a branch instruction, this lead to the target instruction not being included in the visited code and therefore being considered unreachable. This was solved by allowing the code to mark as visited an InstructionHandle with the Label attribute set and then go on to test if the same instruction was a branch instruction, and mark as visited any targets of the branch instruction. Previously the code tested if an instruction had the Label attribute set and if it did marked it as visited, if it did not it  went on to test if the instruction was a branch instruction and marked as visited any target instructions.
bcel
jzigman 18 years ago
parent 7cd141f28e
commit 5d9acc45e8
  1. 111
      src/edu/purdue/cs/bloat/trans/Peephole.java

@ -54,9 +54,10 @@ import java.util.*;
*/
public class Peephole implements Optimization {
public static boolean DEBUG = false;
public String traceMessage(String dateString) {
public String traceMessage(String dateString) {
return null;
}
@ -447,74 +448,75 @@ public class Peephole implements Optimization {
blockIter = blockIter.getNext();
Instruction inst = blockIter.getInstruction();
if (!FlowGraph.label(blockIter)) {
if (inst instanceof ReturnInstruction
|| inst instanceof ATHROW) {
// We've reached the end of the block, but we don't know
// which block will be executed next.
break;
// BCEL - BLOAT means jumps can also be Labels.
if (FlowGraph.label(blockIter)) {
label = blockIter;
visited.add(label);
}
} else if (inst instanceof IfInstruction
|| inst instanceof JsrInstruction) {
// We've reached the end of the block, add the Label of
// the next block to be executed to the list. It's a
// conditional jump, so don't break. The rest of the
// code in the block is not necessarily dead.
if (inst instanceof ReturnInstruction || inst instanceof ATHROW) {
// We've reached the end of the block, but we don't know
// which block will be executed next.
break;
label = ((BranchInstruction) inst).getTarget();
} else if (inst instanceof IfInstruction
|| inst instanceof JsrInstruction) {
// We've reached the end of the block, add the Label of
// the next block to be executed to the list. It's a
// conditional jump, so don't break. The rest of the
// code in the block is not necessarily dead.
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
label = ((BranchInstruction) inst).getTarget();
// Fall through.
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
} else if (inst instanceof GotoInstruction) {
// Add next block to work list.
// Fall through.
label = ((GotoInstruction) inst).getTarget();
} else if (inst instanceof GotoInstruction) {
// Add next block to work list.
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
label = ((GotoInstruction) inst).getTarget();
break;
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
} else if (inst instanceof RET) {
// The ret targets were handled by the jsr.
break;
break;
} else if (inst instanceof Select) {
// A switch. Add all possible targets of the switch to
// the worklist.
} else if (inst instanceof RET) {
// The ret targets were handled by the jsr.
break;
Select sw = (Select) inst;
} else if (inst instanceof Select) {
// A switch. Add all possible targets of the switch to
// the worklist.
label = sw.getTarget();
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
Select sw = (Select) inst;
InstructionHandle[] targets = sw.getTargets();
label = sw.getTarget();
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
for (int j = 0; j < targets.length; j++) {
label = targets[j];
InstructionHandle[] targets = sw.getTargets();
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
}
for (int j = 0; j < targets.length; j++) {
label = targets[j];
break;
if (!visited.contains(label)) {
visited.add(label);
stack.push(label);
}
}
} else if (FlowGraph.label(blockIter)) {
label = blockIter;
visited.add(label);
break;
}
}
}
if (DEBUG) {
@ -538,7 +540,12 @@ public class Peephole implements Optimization {
if (Peephole.DEBUG) {
System.out.println("Removing unreachable " + ce);
}
iter.remove();
try {
code.delete(ce);
} catch (TargetLostException lte) {
// do nothing if this is dead code there shouldn't be a
// targeter.
}
}
}
}

Loading…
Cancel
Save