use of org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode in project JikesRVM by JikesRVM.
the class GlobalCSE method globalCSE.
/**
* Recursively descend over all blocks dominated by b. For each
* instruction in the block, if it defines a GVN then record it in
* the available expressions. If the GVN already exists in the
* available expressions then eliminate the instruction and change
* all uses of the result of the instruction to be uses of the first
* instruction to define the result of this expression.
* @param b the current block to process
*/
private void globalCSE(BasicBlock b) {
Instruction next, inst;
// Iterate over instructions in b
inst = b.firstInstruction();
while (!BBend.conforms(inst)) {
next = inst.nextInstructionInCodeOrder();
// check instruction is safe for GCSE, {@see shouldCSE}
if (!shouldCSE(inst)) {
inst = next;
continue;
}
// check the instruction defines a result
RegisterOperand result = getResult(inst);
if (result == null) {
inst = next;
continue;
}
// get the value number for this result. The value number for
// the same sub-expression is shared by all results showing they
// can be eliminated. If the value number is UNKNOWN the result
// is negative.
int vn = valueNumbers.getValueNumber(result);
if (vn < 0) {
inst = next;
continue;
}
// was this the first definition of the value number?
Integer Vn = vn;
Instruction former = avail.get(Vn);
if (former == null) {
// first occurance of value number, record it in the available
// expressions
avail.put(Vn, inst);
} else {
// this value number has been seen before so we can use the
// earlier version
// NB instead of trying to repair Heap SSA, we rebuild it
// after CSE
// relink scalar dependencies - make all uses of the current
// instructions result use the first definition of the result
// by the earlier expression
RegisterOperand formerDef = getResult(former);
Register reg = result.getRegister();
formerDef.getRegister().setSpansBasicBlock();
Enumeration<RegisterOperand> uses = DefUse.uses(reg);
while (uses.hasMoreElements()) {
RegisterOperand use = uses.nextElement();
DefUse.transferUse(use, formerDef);
}
if (verbose) {
VM.sysWriteln("using " + former + "\n" + "instead of " + inst);
}
// remove the redundant instruction
inst.remove();
}
inst = next;
}
// end of instruction iteration
// Recurse over all blocks that this block dominates
Enumeration<TreeNode> e = dominator.getChildren(b);
while (e.hasMoreElements()) {
DominatorTreeNode n = (DominatorTreeNode) e.nextElement();
BasicBlock bl = n.getBlock();
// don't process infrequently executed basic blocks
if (ir.options.FREQ_FOCUS_EFFORT && bl.getInfrequent())
continue;
globalCSE(bl);
}
// Iterate over instructions in this basic block removing
// available expressions that had been created for this block
inst = b.firstInstruction();
while (!BBend.conforms(inst)) {
next = inst.nextInstructionInCodeOrder();
if (!shouldCSE(inst)) {
inst = next;
continue;
}
RegisterOperand result = getResult(inst);
if (result == null) {
inst = next;
continue;
}
int vn = valueNumbers.getValueNumber(result);
if (vn < 0) {
inst = next;
continue;
}
Integer Vn = vn;
Instruction former = avail.get(Vn);
if (former == inst) {
avail.remove(Vn);
}
inst = next;
}
}
Aggregations