/** Split a hyperblock. */ private void splitHyperblock(Hyperblock hb) { PredicateBlock block = (hb.numSpills() > 0) ? findSplitPointSpills(hb) : findSplitPoint(hb); if (block.isPredicated()) { reverseIfConvert(hb, block); return; } int bsize = block.getBlockSize() + block.getFanout() + block.getSpillSize(); if (bsize > Trips2Machine.maxBlockSize) { splitBlock(hb, block); return; } if (block.maxLSID() >= Trips2Machine.maxLSQEntries) { splitBlock(hb, block); return; } if (block.numInEdges() == 0) { splitBlock(hb, block); return; } reverseIfConvert(hb, block); }
/** Find the predicate block in a hyperblock to split. */ private PredicateBlock findSplitPoint(Hyperblock hb) { Vector<PredicateBlock> wl = new Vector<PredicateBlock>(); int totalSize = hb.getFanout() + hb.getBlockSize(); int splits = (totalSize / Trips2Machine.maxBlockSize) + 1; int splitSize = totalSize / splits; int hbSize = 0; PredicateBlock start = hb.getFirstBlock(); PredicateBlock lastUnpredicated = null; int lastUnpredicatedHBSize = 0; assert (hb.numSpills() == 0) : "This method should not be called for blocks with spills."; start.nextVisit(); start.setVisited(); wl.add(start); while (!wl.isEmpty()) { int l = wl.size(); int levelSize = 0; int levelLSID = 0; // Compute the statistics for this level of the PFG. for (int i = 0; i < l; i++) { PredicateBlock block = wl.get(i); int blockSize = block.getBlockSize() + block.getFanout(); int id = block.maxLSID(); levelSize += blockSize; if (id > levelLSID) { levelLSID = id; } // Remember the block and the hyperblock size if this block is unpredicated // and not the special exit block. // TODO - Can we remove the restriction on being the last block now? if (!block.isPredicated()) { if (block.numOutEdges() > 0) { if (lastUnpredicatedHBSize < (blockSize + hbSize)) { lastUnpredicatedHBSize = blockSize + hbSize; lastUnpredicated = block; } } } } // Determine if all the blocks can be added to the hyperblock. int size = hbSize + levelSize; if ((size > Trips2Machine.maxBlockSize) || (levelLSID >= Trips2Machine.maxLSQEntries)) { break; } hbSize = size; wl = hb.getNextPFGLevel(wl); } assert (!wl.isEmpty()) : "This block does not need to be split?"; // If there is only one unpredicated block in the level and it is // not the special exit block use it. Or if this is the only // block in the PFG. int l = wl.size(); if (l == 1) { PredicateBlock block = wl.get(0); if (!block.isPredicated()) { if ((start == block) || (block.numOutEdges() > 0)) { // System.out.println("block"); return block; } } } // Is there a last known unpredicated block of adequate size use it. if (lastUnpredicated != null) { if (lastUnpredicatedHBSize >= splitSize) { // System.out.println("*** last unpred is greater than split sz " + splitSize); return lastUnpredicated; } } // Try to find a parent that's unpredicated unless the parent is // the first block. for (int i = 0; i < l; i++) { PredicateBlock block = wl.get(i); int pl = block.numInEdges(); for (int j = 0; j < pl; j++) { PredicateBlock pred = (PredicateBlock) block.getInEdge(j); if (!pred.isPredicated() && pred.numInEdges() > 1) { // System.out.println("unpred parent not start"); return pred; } } } // Reverse if-convert the largest block in this level which is not // an exit. Although this seems like a good idea, there is not // always enough room in the hyperblock to fanout the live-outs to // the write instructions. Don't do this for now. -- Aaron PredicateBlock candidate = null; int largest = 0; // for (int i = 0; i < l; i++) { // PredicateBlock block = (PredicateBlock) wl.get(i); // int bsize = block.getBlockSize() + block.getFanout() + block.getSpillSize(); // if ((bsize > largest) && (block.numBranches() == 0)) { // largest = bsize; // candidate = block; // } // } // if (candidate != null) { // //System.out.println("level no exit"); // return candidate; // } // Reverse if-convert a parent which is not start. // Prefer parents that are split points. for (int i = 0; i < l; i++) { PredicateBlock block = wl.get(i); int pl = block.numInEdges(); for (int j = 0; j < pl; j++) { PredicateBlock pred = (PredicateBlock) block.getInEdge(j); if (pred != start) { if (pred.isSplitPoint()) { // System.out.println("pred out isSplit not start"); return pred; } candidate = pred; } } } if (candidate != null) { // System.out.println("pred out not start"); return candidate; } // Reverse if-convert the largest successor of start without an exit. largest = 0; for (int i = 0; i < start.numOutEdges(); i++) { PredicateBlock block = (PredicateBlock) start.getOutEdge(i); int bsize = block.getBlockSize() + block.getFanout() + block.getSpillSize(); if ((bsize > largest) && !block.hasBranch()) { largest = bsize; candidate = block; } } if (candidate != null) { // System.out.println("start successor no exit"); return candidate; } // System.out.println("1st start successor ?"); return (PredicateBlock) start.getOutEdge(0); }