use of org.jikesrvm.compilers.opt.ir.WeightedBranchTargets in project JikesRVM by JikesRVM.
the class ReorderingPhase method doPettisHansenAlgo2.
// ///////////////////////
// Code for P&H Algo2
// ///////////////////////
/**
* Reorder code using Algo2 (Bottom-Up Positioning) from
* Pettis and Hansen PLDI'90.
* @param ir the IR to reorder.
*/
private void doPettisHansenAlgo2(IR ir) {
// (1) Setup:
// (a) Count the blocks
// (b) Create a sorted set of CFG edges
// (c) Create a set of blocks
// (d) Make fallthroughs explict by adding GOTOs
int numBlocks = 0;
TreeSet<Edge> edges = new TreeSet<Edge>();
LinkedHashSet<BasicBlock> chainHeads = new LinkedHashSet<BasicBlock>();
HashMap<BasicBlock, BasicBlock> associatedChain = new HashMap<BasicBlock, BasicBlock>();
BasicBlock entry = ir.cfg.entry();
if (VM.VerifyAssertions)
VM._assert(ir.cfg.entry() == ir.cfg.firstInCodeOrder());
for (BasicBlock bb = entry; bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
numBlocks++;
chainHeads.add(bb);
associatedChain.put(bb, bb);
BasicBlock ft = bb.getFallThroughBlock();
if (ft != null) {
bb.appendInstruction(Goto.create(GOTO, ft.makeJumpTarget()));
}
float bw = bb.getExecutionFrequency();
for (WeightedBranchTargets wbt = new WeightedBranchTargets(bb); wbt.hasMoreElements(); wbt.advance()) {
edges.add(new Edge(bb, wbt.curBlock(), wbt.curWeight() * bw));
}
}
if (DEBUG)
VM.sysWriteln("Edges = " + edges);
// (2) Build chains
ir.cfg.clearCodeOrder();
for (Edge e : edges) {
// then merge the chains.
if (DEBUG)
VM.sysWriteln("Processing edge " + e);
if (e.target == entry) {
if (DEBUG)
VM.sysWriteln("\tCan't put entry block in interior of chain");
continue;
}
if (e.source.nextBasicBlockInCodeOrder() != null) {
if (DEBUG)
VM.sysWriteln("\tSource is not at end of a chain");
continue;
}
if (e.target.prevBasicBlockInCodeOrder() != null) {
if (DEBUG)
VM.sysWriteln("\tTarget is not at start of a chain");
continue;
}
BasicBlock sourceChain = associatedChain.get(e.source);
BasicBlock targetChain = associatedChain.get(e.target);
if (sourceChain == targetChain) {
if (DEBUG)
VM.sysWriteln("\tSource and target are in same chain");
continue;
}
if (DEBUG)
VM.sysWriteln("\tMerging chains");
chainHeads.remove(e.target);
ir.cfg.linkInCodeOrder(e.source, e.target);
// Yuck....we should really use near-linear time union find here
// Doing this crappy thing makes us O(N^2) in the worst case.
BasicBlock newChain = sourceChain;
for (BasicBlock ptr = e.target; ptr != null; ptr = ptr.nextBasicBlockInCodeOrder()) {
associatedChain.put(ptr, newChain);
}
}
if (DEBUG)
VM.sysWriteln("Chains constructed ");
LinkedHashMap<BasicBlock, ChainInfo> chainInfo = new LinkedHashMap<BasicBlock, ChainInfo>();
for (BasicBlock head : chainHeads) {
if (DEBUG)
dumpChain(head);
chainInfo.put(head, new ChainInfo(head));
}
// (3) Summarize inter-chain edges.
for (Edge e : edges) {
BasicBlock sourceChain = associatedChain.get(e.source);
BasicBlock targetChain = associatedChain.get(e.target);
if (sourceChain != targetChain) {
ChainInfo sourceInfo = chainInfo.get(sourceChain);
ChainInfo targetInfo = chainInfo.get(targetChain);
if (DEBUG)
VM.sysWriteln("Inter-chain edge " + sourceChain + "->" + targetChain + " (" + e.weight + ")");
Float value = sourceInfo.outWeights.get(targetInfo);
float weight = e.weight;
if (value != null) {
weight += value;
}
sourceInfo.outWeights.put(targetInfo, weight);
targetInfo.inWeight += e.weight;
if (DEBUG)
VM.sysWriteln("\t" + targetInfo + "," + sourceInfo.outWeights.get(targetInfo));
}
}
if (DEBUG)
VM.sysWriteln("Chain Info " + chainInfo);
// (4) Construct a total order of the chains, guided by the interchain edge weights.
// Constructing an optimal order is NP-Hard, so we apply the following heuristic.
// The chain that starts with the entry node is placed first.
// At each step, pick the chain with the maximal placedWeight (incoming edges from chains
// that are already placed) and minimal inWeight (incoming edges from chains that are not
// already placed). Prefer a node with non-zero placedWeight and inWeight to one that has
// zeros for both. (A node with both zero placedWeight and zero inWeight is something that
// the profile data predicts is not reachable via normal control flow from the entry node).
BasicBlock lastNode = null;
ChainInfo nextChoice = chainInfo.get(entry);
int numPlaced = 0;
ir.cfg.setFirstNode(entry);
while (true) {
if (DEBUG)
VM.sysWriteln("Placing chain " + nextChoice);
// Append nextChoice to the previous chain
if (lastNode != null)
ir.cfg.linkInCodeOrder(lastNode, nextChoice.head);
for (BasicBlock ptr = nextChoice.head; ptr != null; ptr = ptr.nextBasicBlockInCodeOrder()) {
numPlaced++;
lastNode = ptr;
}
// update ChainInfo
chainInfo.remove(nextChoice.head);
// no chains left to place.
if (chainInfo.isEmpty())
break;
for (ChainInfo target : nextChoice.outWeights.keySet()) {
if (DEBUG)
VM.sysWrite("\toutedge " + target);
float weight = nextChoice.outWeights.get(target);
if (DEBUG)
VM.sysWriteln(" = " + weight);
target.placedWeight += weight;
target.inWeight -= weight;
}
if (DEBUG)
VM.sysWriteln("Chain Info " + chainInfo);
// Find the next chain to append.
nextChoice = null;
for (ChainInfo cand : chainInfo.values()) {
if (cand.placedWeight > 0f) {
if (nextChoice == null) {
if (DEBUG)
VM.sysWriteln("First reachable candidate " + cand);
nextChoice = cand;
} else if (cand.inWeight > nextChoice.inWeight || (cand.inWeight == nextChoice.inWeight && cand.placedWeight > nextChoice.placedWeight)) {
if (DEBUG)
VM.sysWriteln(cand + " is a better choice than " + nextChoice);
nextChoice = cand;
}
}
}
if (nextChoice != null)
continue;
// Pick one with minimal inWeight and continue.
for (ChainInfo cand : chainInfo.values()) {
if (nextChoice == null) {
if (DEBUG)
VM.sysWriteln("First candidate " + cand);
nextChoice = cand;
} else if (cand.inWeight < nextChoice.inWeight) {
if (DEBUG)
VM.sysWriteln(cand + " is a better choice than " + nextChoice);
nextChoice = cand;
}
}
}
// Don't lose blocks!!
if (VM.VerifyAssertions)
VM._assert(numPlaced == numBlocks);
ir.cfg.setLastNode(lastNode);
}
use of org.jikesrvm.compilers.opt.ir.WeightedBranchTargets in project JikesRVM by JikesRVM.
the class EstimateBlockFrequencies method computeNodeWeights.
/**
* Propagate execution frequencies through the loop.
* Also records loop exit edges in loopExits.
*
* @param n starting node
*/
private void computeNodeWeights(LSTNode n) {
n.header.setExecutionFrequency(1f);
int idx = 0;
while (topOrder[idx] != n.header) idx++;
for (int numNodes = n.getLoop().populationCount(); numNodes > 0; ) {
if (idx >= topOrder.length) {
numNodes--;
continue;
}
BasicBlock cur = topOrder[idx++];
if (cur == null) {
numNodes--;
continue;
}
// node was not in the loop nest being processed.
if (!n.getLoop().get(cur.getNumber()))
continue;
LSTNode other = lst.getLoop(cur);
if (other != n) {
if (cur == other.header) {
// loop header of nested loop
numNodes -= other.getLoop().populationCount();
}
// skip over nodes in nested loop.
continue;
}
numNodes--;
cur.setScratchFlag();
float weight = cur.getExecutionFrequency();
for (WeightedBranchTargets wbt = new WeightedBranchTargets(cur); wbt.hasMoreElements(); wbt.advance()) {
processEdge(n, cur, wbt.curBlock(), wbt.curWeight(), weight);
}
}
}
use of org.jikesrvm.compilers.opt.ir.WeightedBranchTargets in project JikesRVM by JikesRVM.
the class CFGTransformations method edgeFrequency.
private static float edgeFrequency(BasicBlock a, BasicBlock b) {
float prop = 0f;
WeightedBranchTargets ws = new WeightedBranchTargets(a);
while (ws.hasMoreElements()) {
if (ws.curBlock() == b)
prop += ws.curWeight();
ws.advance();
}
return a.getExecutionFrequency() * prop;
}
use of org.jikesrvm.compilers.opt.ir.WeightedBranchTargets in project JikesRVM by JikesRVM.
the class EstimateBlockFrequencies method computeBlockFrequencies.
private void computeBlockFrequencies() {
ir.cfg.entry().setExecutionFrequency(1f);
for (BasicBlock cur : topOrder) {
// ignore exit node.
if (cur == null || cur.isExit())
continue;
if (lst != null) {
LSTNode loop = lst.getLoop(cur);
if (loop != null && loop.header == cur) {
cur.setExecutionFrequency(cur.getExecutionFrequency() * loop.loopMultiplier);
}
}
float weight = cur.getExecutionFrequency();
cur.setScratchFlag();
for (WeightedBranchTargets wbt = new WeightedBranchTargets(cur); wbt.hasMoreElements(); wbt.advance()) {
BasicBlock target = wbt.curBlock();
if (!target.getScratchFlag()) {
target.augmentExecutionFrequency(wbt.curWeight() * weight);
}
}
}
}
Aggregations