Mercurial > hg > graal-jvmci-8
view graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java @ 7385:6ad818b8892e
fixed warnings
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 15 Jan 2013 21:11:45 +0100 |
parents | 44012c5c6783 |
children | 0f8c6dbf68be |
line wrap: on
line source
/* * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.graal.alloc; import java.util.*; import com.oracle.graal.nodes.cfg.*; /** * Computes an ordering of the block that can be used by the linear scan register allocator * and the machine code generator. */ public final class ComputeBlockOrder { private List<Block> linearScanOrder; private List<Block> codeEmittingOrder; private Comparator<Block> blockComparator = new Comparator<Block>() { @Override public int compare(Block o1, Block o2) { // Loop blocks before any loop exit block. int diff = o2.getLoopDepth() - o1.getLoopDepth(); if (diff != 0) { return diff; } // Blocks with high probability before blocks with low probability. if (o1.getBeginNode().probability() > o2.getBeginNode().probability()) { return -1; } else { return 1; } }}; public ComputeBlockOrder(int maxBlockId, @SuppressWarnings("unused") int loopCount, Block startBlock, @SuppressWarnings("unused") boolean reorderLoops) { List<Block> newLinearScanOrder = new ArrayList<>(); List<Block> order = new ArrayList<>(); PriorityQueue<Block> worklist = new PriorityQueue<>(10, blockComparator); BitSet orderedBlocks = new BitSet(maxBlockId); orderedBlocks.set(startBlock.getId()); worklist.add(startBlock); computeCodeEmittingOrder(order, worklist, orderedBlocks); codeEmittingOrder = order; orderedBlocks.clear(); orderedBlocks.set(startBlock.getId()); worklist.add(startBlock); computeNewLinearScanOrder(newLinearScanOrder, worklist, orderedBlocks); assert order.size() == newLinearScanOrder.size() : codeEmittingOrder.size() + " vs " + newLinearScanOrder.size(); linearScanOrder = newLinearScanOrder; } private void computeCodeEmittingOrder(List<Block> order, PriorityQueue<Block> worklist, BitSet orderedBlocks) { while (!worklist.isEmpty()) { Block nextImportantPath = worklist.poll(); addImportantPath(nextImportantPath, order, worklist, orderedBlocks); } } private void computeNewLinearScanOrder(List<Block> order, PriorityQueue<Block> worklist, BitSet orderedBlocks) { while (!worklist.isEmpty()) { Block nextImportantPath = worklist.poll(); addImportantLinearScanOrderPath(nextImportantPath, order, worklist, orderedBlocks); } } private void addImportantLinearScanOrderPath(Block block, List<Block> order, PriorityQueue<Block> worklist, BitSet orderedBlocks) { order.add(block); Block bestSucc = null; double bestSuccProb = 0; for (Block succ : block.getSuccessors()) { if (!orderedBlocks.get(succ.getId()) && succ.getLoopDepth() >= block.getLoopDepth()) { double curProb = succ.getBeginNode().probability(); if (curProb >= bestSuccProb) { bestSuccProb = curProb; bestSucc = succ; } assert curProb >= 0 : curProb; } } for (Block succ : block.getSuccessors()) { if (!orderedBlocks.get(succ.getId())) { if (succ != bestSucc) { orderedBlocks.set(succ.getId()); worklist.add(succ); } } } if (bestSucc != null) { if (!bestSucc.isLoopHeader() && bestSucc.getPredecessors().size() > 1) { // We are at a merge. Check probabilities of predecessors that are not yet scheduled. double unscheduledSum = 0.0; double scheduledSum = 0.0; for (Block pred : bestSucc.getPredecessors()) { if (!orderedBlocks.get(pred.getId())) { unscheduledSum += pred.getBeginNode().probability(); } else { scheduledSum += pred.getBeginNode().probability(); } } if (unscheduledSum > 0.0 && unscheduledSum > scheduledSum / 10) { return; } } orderedBlocks.set(bestSucc.getId()); addImportantLinearScanOrderPath(bestSucc, order, worklist, orderedBlocks); } } private void addImportantPath(Block block, List<Block> order, PriorityQueue<Block> worklist, BitSet orderedBlocks) { if (!skipLoopHeader(block)) { if (block.isLoopHeader()) { block.align = true; } order.add(block); } if (block.isLoopEnd() && skipLoopHeader(block.getLoop().header)) { order.add(block.getLoop().header); for (Block succ : block.getLoop().header.getSuccessors()) { if (succ.getLoopDepth() == block.getLoopDepth()) { succ.align = true; } } } Block bestSucc = null; double bestSuccProb = 0; for (Block succ : block.getSuccessors()) { if (!orderedBlocks.get(succ.getId()) && succ.getLoopDepth() >= block.getLoopDepth()) { double curProb = succ.getBeginNode().probability(); if (curProb >= bestSuccProb) { bestSuccProb = curProb; bestSucc = succ; } assert curProb >= 0 : curProb; } } for (Block succ : block.getSuccessors()) { if (!orderedBlocks.get(succ.getId())) { if (succ != bestSucc) { orderedBlocks.set(succ.getId()); worklist.add(succ); } } } if (bestSucc != null) { orderedBlocks.set(bestSucc.getId()); addImportantPath(bestSucc, order, worklist, orderedBlocks); } } private static boolean skipLoopHeader(Block bestSucc) { return (bestSucc.isLoopHeader() && !bestSucc.isLoopEnd() && bestSucc.getLoop().loopBegin().loopEnds().count() == 1); } /** * Returns the block order used for the linear scan register allocator. * @return list of sorted blocks */ public List<Block> linearScanOrder() { return linearScanOrder; } /** * Returns the block order used for machine code generation. * @return list of sorted blocks2222 */ public List<Block> codeEmittingOrder() { return codeEmittingOrder; } }