use of org.jikesrvm.compilers.opt.util.TreeNode 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;
}
}
use of org.jikesrvm.compilers.opt.util.TreeNode in project JikesRVM by JikesRVM.
the class DominanceFrontier method perform.
/**
* Calculate the dominance frontier for each basic block in the
* CFG. Stores the result in the DominatorTree for the governing
* IR.
*
* <p> NOTE: The dominator tree MUST be calculated BEFORE calling this
* routine.
*
* @param ir the governing IR
*/
@Override
public void perform(IR ir) {
final boolean DEBUG = false;
// make sure the dominator computation completed successfully
if (!ir.HIRInfo.dominatorsAreComputed) {
return;
}
// make sure dominator tree is computed
if (ir.HIRInfo.dominatorTree == null) {
return;
}
// for each X in a bottom-up traversal of the dominator tree do
DominatorTree tree = ir.HIRInfo.dominatorTree;
for (Enumeration<TreeNode> x = tree.getBottomUpEnumerator(); x.hasMoreElements(); ) {
DominatorTreeNode v = (DominatorTreeNode) x.nextElement();
BasicBlock X = v.getBlock();
if (DEBUG) {
System.out.println("Computing frontier for node " + X);
}
BitVector DF = new BitVector(ir.getMaxBasicBlockNumber() + 1);
v.setDominanceFrontier(DF);
// for each Y in Succ(X) do
for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
BasicBlock Y = y.nextElement();
// skip EXIT node
if (Y.isExit()) {
continue;
}
// if (idom(Y)!=X) then DF(X) <- DF(X) U Y
if (LTDominatorInfo.getIdom(Y, ir) != X) {
DF.set(Y.getNumber());
}
}
if (DEBUG) {
System.out.println("After local " + DF);
}
// for each Z in {idom(z) = X} do
for (Enumeration<TreeNode> z = tree.getChildren(X); z.hasMoreElements(); ) {
DominatorTreeNode zVertex = (DominatorTreeNode) z.nextElement();
BasicBlock Z = zVertex.getBlock();
if (DEBUG) {
System.out.println("Processing Z = " + Z);
}
// for each Y in DF(Z) do
for (Enumeration<BasicBlock> y = zVertex.domFrontierEnumerator(ir); y.hasMoreElements(); ) {
BasicBlock Y = y.nextElement();
// if (idom(Y)!=X) then DF(X) <- DF(X) U Y
if (LTDominatorInfo.getIdom(Y, ir) != X) {
DF.set(Y.getNumber());
}
}
}
if (DEBUG) {
System.out.println("After up " + DF);
}
}
if (DEBUG) {
for (Enumeration<BasicBlock> bbEnum = ir.cfg.basicBlocks(); bbEnum.hasMoreElements(); ) {
BasicBlock block = bbEnum.nextElement();
if (block.isExit()) {
continue;
}
System.out.println(block + " DF: " + tree.getDominanceFrontier(block));
}
}
}
Aggregations