Search in sources :

Example 1 with WeightedBranchTargets

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) WeightedBranchTargets(org.jikesrvm.compilers.opt.ir.WeightedBranchTargets) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) LinkedHashMap(java.util.LinkedHashMap) TreeSet(java.util.TreeSet)

Example 2 with WeightedBranchTargets

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);
        }
    }
}
Also used : WeightedBranchTargets(org.jikesrvm.compilers.opt.ir.WeightedBranchTargets) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Example 3 with WeightedBranchTargets

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;
}
Also used : WeightedBranchTargets(org.jikesrvm.compilers.opt.ir.WeightedBranchTargets)

Example 4 with WeightedBranchTargets

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);
            }
        }
    }
}
Also used : WeightedBranchTargets(org.jikesrvm.compilers.opt.ir.WeightedBranchTargets) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Aggregations

WeightedBranchTargets (org.jikesrvm.compilers.opt.ir.WeightedBranchTargets)4 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)3 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 TreeSet (java.util.TreeSet)1