Mercurial > hg > truffle
changeset 14803:c4219e527b83
Merge.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Fri, 14 Mar 2014 17:19:52 +0100 |
parents | 10dde0063f5a (diff) f659d019d3ab (current diff) |
children | 056357ac3efb 80147dac0d6e |
files | agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java mx/projects src/os/bsd/dtrace/hotspot.d src/os/bsd/dtrace/hotspot_jni.d src/os/bsd/dtrace/hs_private.d src/os/solaris/dtrace/hotspot.d src/os/solaris/dtrace/hotspot_jni.d src/os/solaris/dtrace/hs_private.d src/share/vm/utilities/dtrace_usdt2_disabled.hpp |
diffstat | 47 files changed, 1334 insertions(+), 241 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Fri Mar 14 17:19:52 2014 +0100 @@ -26,7 +26,6 @@ import java.util.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.util.*; /** * Computes an ordering of the block that can be used by the linear scan register allocator and the @@ -67,11 +66,11 @@ * * @return sorted list of blocks */ - public static <T extends AbstractBlock<T>> List<T> computeLinearScanOrder(int blockCount, T startBlock, NodesToDoubles nodeProbabilities) { + public static <T extends AbstractBlock<T>> List<T> computeLinearScanOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { List<T> order = new ArrayList<>(); BitSet visitedBlocks = new BitSet(blockCount); - PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks, nodeProbabilities); - computeLinearScanOrder(order, worklist, visitedBlocks, nodeProbabilities); + PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks, blockProbabilities); + computeLinearScanOrder(order, worklist, visitedBlocks, blockProbabilities); assert checkOrder(order, blockCount); return order; } @@ -81,11 +80,11 @@ * * @return sorted list of blocks */ - public static <T extends AbstractBlock<T>> List<T> computeCodeEmittingOrder(int blockCount, T startBlock, NodesToDoubles nodeProbabilities) { + public static <T extends AbstractBlock<T>> List<T> computeCodeEmittingOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { List<T> order = new ArrayList<>(); BitSet visitedBlocks = new BitSet(blockCount); - PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks, nodeProbabilities); - computeCodeEmittingOrder(order, worklist, visitedBlocks, nodeProbabilities); + PriorityQueue<T> worklist = initializeWorklist(startBlock, visitedBlocks, blockProbabilities); + computeCodeEmittingOrder(order, worklist, visitedBlocks, blockProbabilities); assert checkOrder(order, blockCount); return order; } @@ -93,28 +92,28 @@ /** * Iteratively adds paths to the code emission block order. */ - private static <T extends AbstractBlock<T>> void computeCodeEmittingOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { + private static <T extends AbstractBlock<T>> void computeCodeEmittingOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { while (!worklist.isEmpty()) { T nextImportantPath = worklist.poll(); - addPathToCodeEmittingOrder(nextImportantPath, order, worklist, visitedBlocks, nodeProbabilities); + addPathToCodeEmittingOrder(nextImportantPath, order, worklist, visitedBlocks, blockProbabilities); } } /** * Iteratively adds paths to the linear scan block order. */ - private static <T extends AbstractBlock<T>> void computeLinearScanOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { + private static <T extends AbstractBlock<T>> void computeLinearScanOrder(List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { while (!worklist.isEmpty()) { T nextImportantPath = worklist.poll(); - addPathToLinearScanOrder(nextImportantPath, order, worklist, visitedBlocks, nodeProbabilities); + addPathToLinearScanOrder(nextImportantPath, order, worklist, visitedBlocks, blockProbabilities); } } /** * Initializes the priority queue used for the work list of blocks and adds the start block. */ - private static <T extends AbstractBlock<T>> PriorityQueue<T> initializeWorklist(T startBlock, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { - PriorityQueue<T> result = new PriorityQueue<>(INITIAL_WORKLIST_CAPACITY, new BlockOrderComparator<T>(nodeProbabilities)); + private static <T extends AbstractBlock<T>> PriorityQueue<T> initializeWorklist(T startBlock, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { + PriorityQueue<T> result = new PriorityQueue<>(INITIAL_WORKLIST_CAPACITY, new BlockOrderComparator<T>(blockProbabilities)); result.add(startBlock); visitedBlocks.set(startBlock.getId()); return result; @@ -123,10 +122,10 @@ /** * Add a linear path to the linear scan order greedily following the most likely successor. */ - private static <T extends AbstractBlock<T>> void addPathToLinearScanOrder(T block, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { + private static <T extends AbstractBlock<T>> void addPathToLinearScanOrder(T block, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { block.setLinearScanNumber(order.size()); order.add(block); - T mostLikelySuccessor = findAndMarkMostLikelySuccessor(block, visitedBlocks, nodeProbabilities); + T mostLikelySuccessor = findAndMarkMostLikelySuccessor(block, visitedBlocks, blockProbabilities); enqueueSuccessors(block, worklist, visitedBlocks); if (mostLikelySuccessor != null) { if (!mostLikelySuccessor.isLoopHeader() && mostLikelySuccessor.getPredecessorCount() > 1) { @@ -135,17 +134,17 @@ double unscheduledSum = 0.0; for (T pred : mostLikelySuccessor.getPredecessors()) { if (pred.getLinearScanNumber() == -1) { - unscheduledSum += nodeProbabilities.get(pred.getBeginNode()); + unscheduledSum += blockProbabilities.get(pred); } } - if (unscheduledSum > nodeProbabilities.get(block.getBeginNode()) / PENALTY_VERSUS_UNSCHEDULED) { + if (unscheduledSum > blockProbabilities.get(block) / PENALTY_VERSUS_UNSCHEDULED) { // Add this merge only after at least one additional predecessor gets scheduled. visitedBlocks.clear(mostLikelySuccessor.getId()); return; } } - addPathToLinearScanOrder(mostLikelySuccessor, order, worklist, visitedBlocks, nodeProbabilities); + addPathToLinearScanOrder(mostLikelySuccessor, order, worklist, visitedBlocks, blockProbabilities); } } @@ -153,7 +152,7 @@ * Add a linear path to the code emission order greedily following the most likely successor. */ @SuppressWarnings("unchecked") - private static <T extends AbstractBlock<T>> void addPathToCodeEmittingOrder(T initialBlock, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { + private static <T extends AbstractBlock<T>> void addPathToCodeEmittingOrder(T initialBlock, List<T> order, PriorityQueue<T> worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { T block = initialBlock; while (block != null) { // Skip loop headers if there is only a single loop end block to @@ -184,7 +183,7 @@ } } - T mostLikelySuccessor = findAndMarkMostLikelySuccessor(block, visitedBlocks, nodeProbabilities); + T mostLikelySuccessor = findAndMarkMostLikelySuccessor(block, visitedBlocks, blockProbabilities); enqueueSuccessors(block, worklist, visitedBlocks); block = mostLikelySuccessor; } @@ -201,12 +200,11 @@ /** * Find the highest likely unvisited successor block of a given block. */ - private static <T extends AbstractBlock<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks, NodesToDoubles nodeProbabilities) { + private static <T extends AbstractBlock<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { T result = null; for (T successor : block.getSuccessors()) { - assert nodeProbabilities.get(successor.getBeginNode()) >= 0.0 : "Probabilities must be positive"; - if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && - (result == null || nodeProbabilities.get(successor.getBeginNode()) >= nodeProbabilities.get(result.getBeginNode()))) { + assert blockProbabilities.get(successor) >= 0.0 : "Probabilities must be positive"; + if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && (result == null || blockProbabilities.get(successor) >= blockProbabilities.get(result))) { result = successor; } } @@ -249,9 +247,9 @@ */ private static class BlockOrderComparator<T extends AbstractBlock<T>> implements Comparator<T> { - private final NodesToDoubles probabilities; + private final BlocksToDoubles probabilities; - public BlockOrderComparator(NodesToDoubles probabilities) { + public BlockOrderComparator(BlocksToDoubles probabilities) { this.probabilities = probabilities; } @@ -264,7 +262,7 @@ } // Blocks with high probability before blocks with low probability. - if (probabilities.get(a.getBeginNode()) > probabilities.get(b.getBeginNode())) { + if (probabilities.get(a) > probabilities.get(b)) { return -1; } else { return 1;
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Fri Mar 14 17:19:52 2014 +0100 @@ -23,37 +23,33 @@ package com.oracle.graal.baseline; import static com.oracle.graal.api.code.TypeCheckHints.*; -import static com.oracle.graal.api.meta.DeoptimizationAction.*; -import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.bytecode.Bytecodes.*; import static com.oracle.graal.phases.GraalOptions.*; import static java.lang.reflect.Modifier.*; -import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; import com.oracle.graal.java.BciBlockMapping.Block; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; -import com.oracle.graal.java.GraphBuilderPhase.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.nodes.java.*; /** * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph. @@ -90,7 +86,8 @@ return method; } - public LIR generate(ResolvedJavaMethod method, int entryBCI) { + public CompilationResult generate(ResolvedJavaMethod method, int entryBCI, Backend backend, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, + CompilationResultBuilderFactory factory) { this.method = method; this.entryBCI = entryBCI; profilingInfo = method.getProfilingInfo(); @@ -100,12 +97,42 @@ unwindBlock = null; methodSynchronizedObject = null; TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); + + // build blocks try { build(); } finally { filter.remove(); } - return null; + // emitLIR + LIRBlock b = new LIRBlock(0); + LIRBlock[] blocks = new LIRBlock[1]; + blocks[0] = b; + + AbstractControlFlowGraph<?> cfg = new LIRControlFlowGraph(blocks, null); + BlocksToDoubles blockProbabilities = new BlocksToDoubles(blocks.length); + blockProbabilities.put(b, 1); + + List<? extends AbstractBlock<?>> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, b, blockProbabilities); + List<? extends AbstractBlock<?>> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, b, blockProbabilities); + LIR lir = new LIR(cfg, linearScanOrder, codeEmittingOrder); + CallingConvention cc = CodeUtil.getCallingConvention(backend.getProviders().getCodeCache(), CallingConvention.Type.JavaCallee, method, false); + LIRGenerator lirGen = backend.newLIRGenerator(null, null, backend.newFrameMap(), cc, lir); + + // add instruction + lirGen.emitAdd(Constant.forLong(42), Constant.forLong(73)); + + List<LIRInstruction> lirList = null; + lir.setLir(b, lirList); + + // register allocation + lirGen.getFrameMap().finish(); + + // emitCode + Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); + GraalCompiler.emitCode(backend, assumptions, lirGen, compilationResult, installedCodeOwner, factory); + + return compilationResult; } protected void build() { @@ -131,9 +158,9 @@ throw GraalInternalError.unimplemented("Handle start block as loop header"); } - for (Block block : blockMap.blocks) { - processBlock(block); - } + /* + * for (Block block : blockMap.blocks) { processBlock(block); } + */ indent.outdent(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, 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.baseline; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; + +public class LIRBlock extends AbstractBlockBase<LIRBlock> { + + public LIRBlock(int id) { + this.id = id; + predecessors = Collections.emptyList(); + successors = Collections.emptyList(); + } + + public AbstractBeginNode getBeginNode() { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + public Loop getLoop() { + // TODO Auto-generated method stub + return null; + } + + public int getLoopDepth() { + // TODO Auto-generated method stub + return 0; + } + + public boolean isLoopEnd() { + // TODO Auto-generated method stub + return false; + } + + public boolean isLoopHeader() { + // TODO Auto-generated method stub + return false; + } + + public boolean isExceptionEntry() { + // TODO Auto-generated method stub + return false; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, 2014, 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.baseline; + +import com.oracle.graal.nodes.cfg.*; + +public class LIRControlFlowGraph implements AbstractControlFlowGraph<LIRBlock> { + + private LIRBlock[] blocks; + private Loop[] loops; + + public LIRControlFlowGraph(LIRBlock[] blocks, Loop[] loops) { + this.blocks = blocks; + this.loops = loops; + } + + public LIRBlock[] getBlocks() { + return blocks; + } + + public Loop[] getLoops() { + return loops; + } + + public LIRBlock getStartBlock() { + if (blocks.length > 0) + return blocks[0]; + return null; + } + +}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Mar 14 17:19:52 2014 +0100 @@ -982,7 +982,7 @@ sig[i] = node.arguments().get(i).stamp().javaType(getMetaAccess()); } - Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); + Value[] parameters = visitInvokeArguments(getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); append(new AMD64BreakpointOp(parameters)); }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Mar 14 17:19:52 2014 +0100 @@ -930,7 +930,7 @@ sig[i] = node.arguments().get(i).stamp().javaType(getMetaAccess()); } - Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); + Value[] parameters = visitInvokeArguments(getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); append(new SPARCBreakpointOp(parameters)); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Mar 14 17:19:52 2014 +0100 @@ -500,8 +500,7 @@ private CompilationResult compileBaseline(ResolvedJavaMethod javaMethod) { try (Scope bds = Debug.scope("compileBaseline")) { BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess()); - baselineCompiler.generate(javaMethod, -1); - return null; + return baselineCompiler.generate(javaMethod, -1, getBackend(), new CompilationResult(), javaMethod, CompilationResultBuilderFactory.Default); } catch (Throwable e) { throw Debug.handle(e); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Mar 14 17:19:52 2014 +0100 @@ -73,7 +73,7 @@ public RegisterStats(LIR lir) { this.lir = lir; - for (Block block : lir.codeEmittingOrder()) { + for (AbstractBlock<?> block : lir.codeEmittingOrder()) { for (LIRInstruction instr : lir.lir(block)) { collectStats(instr); } @@ -121,6 +121,6 @@ CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); LIRGenerator lirGen = GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), schedule, graph, null, cc); - return new RegisterStats(lirGen.lir); + return new RegisterStats(lirGen.getLIR()); } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Mar 14 17:19:52 2014 +0100 @@ -211,7 +211,7 @@ } private static void emitBlock(LIRGenerator lirGen, Block b, StructuredGraph graph, BlockMap<List<ScheduledNode>> blockMap) { - if (lirGen.lir.lir(b) == null) { + if (lirGen.getLIR().lir(b) == null) { for (Block pred : b.getPredecessors()) { if (!b.isLoopHeader() || !pred.isLoopEnd()) { emitBlock(lirGen, pred, graph, blockMap); @@ -228,11 +228,14 @@ assert startBlock.getPredecessorCount() == 0; LIR lir = null; + List<Block> codeEmittingOrder = null; + List<Block> linearScanOrder = null; try (Scope ds = Debug.scope("MidEnd")) { try (Scope s = Debug.scope("ComputeLinearScanOrder")) { NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply(); - List<Block> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities); - List<Block> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities); + BlocksToDoubles blockProbabilities = BlocksToDoubles.createFromNodeProbability(nodeProbabilities, schedule.getCFG()); + codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, blockProbabilities); + linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, blockProbabilities); lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder); Debug.dump(lir, "After linear scan order"); @@ -247,7 +250,7 @@ LIRGenerator lirGen = backend.newLIRGenerator(graph, stub, frameMap, cc, lir); try (Scope s = Debug.scope("LIRGen", lirGen)) { - for (Block b : lir.linearScanOrder()) { + for (Block b : linearScanOrder) { emitBlock(lirGen, b, graph, schedule.getBlockToNodesMap()); } lirGen.beforeRegisterAllocation(); @@ -267,7 +270,7 @@ try (Scope s = Debug.scope("ControlFlowOptimizations")) { EdgeMoveOptimizer.optimize(lir); - ControlFlowOptimizer.optimize(lir); + ControlFlowOptimizer.optimize(lir, codeEmittingOrder); if (lirGen.canEliminateRedundantMoves()) { RedundantMoveElimination.optimize(lir, frameMap); } @@ -286,7 +289,7 @@ public static void emitCode(Backend backend, Assumptions assumptions, LIRGenerator lirGen, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGen, compilationResult, factory); - backend.emitCode(crb, lirGen.lir, installedCodeOwner); + backend.emitCode(crb, lirGen.getLIR(), installedCodeOwner); crb.finish(); if (!assumptions.isEmpty()) { compilationResult.setAssumptions(assumptions);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Mar 14 17:19:52 2014 +0100 @@ -135,9 +135,9 @@ LIRInstruction[] opIdToInstructionMap; /** - * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain Block block} - * containing the instruction. Entries should be retrieved with {@link #blockForId(int)} as the - * id is not simply an index into this array. + * Map from an instruction {@linkplain LIRInstruction#id id} to the {@linkplain AbstractBlock + * block} containing the instruction. Entries should be retrieved with {@link #blockForId(int)} + * as the id is not simply an index into this array. */ AbstractBlock<?>[] opIdToBlockMap; @@ -629,7 +629,7 @@ // initialize with correct length opIdToInstructionMap = new LIRInstruction[numInstructions]; - opIdToBlockMap = new Block[numInstructions]; + opIdToBlockMap = new AbstractBlock<?>[numInstructions]; int opId = 0; int index = 0; @@ -869,7 +869,7 @@ } // check that the liveIn set of the first block is empty - Block startBlock = ir.getControlFlowGraph().getStartBlock(); + AbstractBlock<?> startBlock = ir.getControlFlowGraph().getStartBlock(); if (blockData.get(startBlock).liveIn.cardinality() != 0) { if (DetailedAsserts.getValue()) { reportFailure(numBlocks);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Mar 14 17:19:52 2014 +0100 @@ -68,9 +68,9 @@ // @formatter:on } - public final FrameMap frameMap; - public final NodeMap<Value> nodeOperands; - public final LIR lir; + private final FrameMap frameMap; + private final NodeMap<Value> nodeOperands; + private final LIR lir; private final Providers providers; protected final CallingConvention cc; @@ -341,7 +341,8 @@ } public LabelRef getLIRBlock(FixedNode b) { - Block result = lir.getControlFlowGraph().blockFor(b); + assert lir.getControlFlowGraph() instanceof ControlFlowGraph; + Block result = ((ControlFlowGraph) lir.getControlFlowGraph()).blockFor(b); int suxIndex = currentBlock.getSuccessors().indexOf(result); assert suxIndex != -1 : "Block not in successor list of current block"; @@ -856,7 +857,15 @@ protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key); - public FrameMap frameMap() { + public final LIR getLIR() { + return lir; + } + + public final NodeMap<Value> getNodeOperands() { + return nodeOperands; + } + + public final FrameMap getFrameMap() { return frameMap; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Mar 14 17:19:52 2014 +0100 @@ -200,8 +200,8 @@ // - has no deoptimization points // - makes no foreign calls (which require an aligned stack) AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen; - FrameMap frameMap = gen.frameMap; - LIR lir = gen.lir; + FrameMap frameMap = gen.getFrameMap(); + LIR lir = gen.getLIR(); assert gen.deoptimizationRescueSlot == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame"; boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame() && !gen.hasForeignCall();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Mar 14 17:19:52 2014 +0100 @@ -106,7 +106,7 @@ public SaveRbp(NoOp placeholder) { this.placeholder = placeholder; - this.reservedSlot = frameMap.allocateSpillSlot(Kind.Long); + this.reservedSlot = getFrameMap().allocateSpillSlot(Kind.Long); assert reservedSlot.getRawOffset() == -16 : reservedSlot.getRawOffset(); } @@ -120,11 +120,11 @@ if (useStack) { dst = reservedSlot; } else { - frameMap.freeSpillSlot(reservedSlot); + getFrameMap().freeSpillSlot(reservedSlot); dst = newVariable(Kind.Long); } - placeholder.replace(lir, new MoveFromRegOp(dst, rbp.asValue(Kind.Long))); + placeholder.replace(getLIR(), new MoveFromRegOp(dst, rbp.asValue(Kind.Long))); return dst; } } @@ -144,10 +144,9 @@ } } - @SuppressWarnings("hiding") @Override protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) { - HotSpotLockStack lockStack = new HotSpotLockStack(frameMap, Kind.Long); + HotSpotLockStack lockStack = new HotSpotLockStack(getFrameMap(), Kind.Long); return new HotSpotDebugInfoBuilder(nodeOperands, lockStack); } @@ -166,8 +165,8 @@ params[i] = toStackKind(incomingArguments.getArgument(i)); if (isStackSlot(params[i])) { StackSlot slot = ValueUtil.asStackSlot(params[i]); - if (slot.isInCallerFrame() && !lir.hasArgInCallerFrame()) { - lir.setHasArgInCallerFrame(); + if (slot.isInCallerFrame() && !getLIR().hasArgInCallerFrame()) { + getLIR().setHasArgInCallerFrame(); } } } @@ -175,7 +174,7 @@ emitIncomingValues(params); - saveRbp = new SaveRbp(new NoOp(currentBlock, lir.lir(currentBlock).size())); + saveRbp = new SaveRbp(new NoOp(currentBlock, getLIR().lir(currentBlock).size())); append(saveRbp.placeholder); for (ParameterNode param : graph.getNodes(ParameterNode.class)) { @@ -248,12 +247,12 @@ if (destroysRegisters) { if (getStub() != null) { if (getStub().preservesRegisters()) { - Register[] savedRegisters = frameMap.registerConfig.getAllocatableRegisters(); + Register[] savedRegisters = getFrameMap().registerConfig.getAllocatableRegisters(); savedRegisterLocations = new StackSlot[savedRegisters.length]; for (int i = 0; i < savedRegisters.length; i++) { PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory()); assert kind != Kind.Illegal; - StackSlot spillSlot = frameMap.allocateSpillSlot(kind); + StackSlot spillSlot = getFrameMap().allocateSpillSlot(kind); savedRegisterLocations[i] = spillSlot; } save = emitSaveRegisters(savedRegisters, savedRegisterLocations); @@ -296,7 +295,7 @@ } protected boolean zapRegisters() { - Register[] zappedRegisters = frameMap.registerConfig.getAllocatableRegisters(); + Register[] zappedRegisters = getFrameMap().registerConfig.getAllocatableRegisters(); Constant[] zapValues = new Constant[zappedRegisters.length]; for (int i = 0; i < zappedRegisters.length; i++) { PlatformKind kind = target().arch.getLargestStorableKind(zappedRegisters[i].getRegisterCategory()); @@ -350,7 +349,7 @@ @Override public void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments) { Value[] argLocations = new Value[args.length]; - frameMap.callsMethod(nativeCallingConvention); + getFrameMap().callsMethod(nativeCallingConvention); // TODO(mg): in case a native function uses floating point varargs, the ABI requires that // RAX contains the length of the varargs AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue(); @@ -449,10 +448,10 @@ @Override public void beforeRegisterAllocation() { super.beforeRegisterAllocation(); - boolean hasDebugInfo = lir.hasDebugInfo(); + boolean hasDebugInfo = getLIR().hasDebugInfo(); AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo); if (hasDebugInfo) { - deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long); + deoptimizationRescueSlot = getFrameMap().allocateSpillSlot(Kind.Long); } for (AMD64HotSpotEpilogueOp op : epilogueOps) {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Fri Mar 14 17:19:52 2014 +0100 @@ -216,7 +216,7 @@ @Override public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) { - FrameMap frameMap = lirGen.frameMap; + FrameMap frameMap = lirGen.getFrameMap(); Assembler masm = createAssembler(frameMap); HotSpotFrameContext frameContext = new HotSpotFrameContext(); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Fri Mar 14 17:19:52 2014 +0100 @@ -333,7 +333,7 @@ // - has no callee-saved registers // - has no incoming arguments passed on the stack // - has no instructions with debug info - FrameMap frameMap = lirGen.frameMap; + FrameMap frameMap = lirGen.getFrameMap(); Assembler masm = createAssembler(frameMap); PTXFrameContext frameContext = new PTXFrameContext(); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult); @@ -367,7 +367,7 @@ asm.emitString(""); // Get the start block - Block startBlock = lir.getControlFlowGraph().getStartBlock(); + AbstractBlock<?> startBlock = lir.getControlFlowGraph().getStartBlock(); // Keep a list of ParameterOp instructions to delete from the // list of instructions in the block. ArrayList<LIRInstruction> deleteOps = new ArrayList<>(); @@ -398,7 +398,7 @@ RegisterAnalysis registerAnalysis = new RegisterAnalysis(); - for (Block b : lir.codeEmittingOrder()) { + for (AbstractBlock<?> b : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.lir(b)) { if (op instanceof LabelOp) { // Don't consider this as a definition
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Fri Mar 14 17:19:52 2014 +0100 @@ -244,7 +244,7 @@ append(new WriteNode(buf, nullWord, location, BarrierType.NONE, false, false)); } - FrameStateBuilder fsb = new FrameStateBuilder(method, getGraph(), true); + HIRFrameStateBuilder fsb = new HIRFrameStateBuilder(method, getGraph(), true); FrameState fs = fsb.create(0); getGraph().start().setStateAfter(fs);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Mar 14 17:19:52 2014 +0100 @@ -22,6 +22,12 @@ */ package com.oracle.graal.hotspot.sparc; +import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.sparc.SPARC.*; +import static java.lang.reflect.Modifier.*; + import java.util.*; import sun.misc.*; @@ -30,26 +36,27 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; -import com.oracle.graal.compiler.gen.LIRGenerator; +import com.oracle.graal.asm.sparc.SPARCAssembler.Bpne; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.Save; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; +import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.stubs.Stub; +import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.nodes.*; -import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.api.code.CallingConvention.Type.*; -import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.phases.GraalOptions.*; -import static java.lang.reflect.Modifier.*; - /** * HotSpot SPARC specific backend. */ @@ -154,7 +161,7 @@ @Override public CompilationResultBuilder newCompilationResultBuilder(LIRGenerator lirGen, CompilationResult compilationResult, CompilationResultBuilderFactory factory) { SPARCHotSpotLIRGenerator gen = (SPARCHotSpotLIRGenerator) lirGen; - FrameMap frameMap = gen.frameMap; + FrameMap frameMap = gen.getFrameMap(); assert gen.deoptimizationRescueSlot == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame"; Stub stub = gen.getStub();
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Mar 14 17:19:52 2014 +0100 @@ -71,10 +71,9 @@ */ StackSlot deoptimizationRescueSlot; - @SuppressWarnings("hiding") @Override protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) { - HotSpotLockStack lockStack = new HotSpotLockStack(frameMap, Kind.Long); + HotSpotLockStack lockStack = new HotSpotLockStack(getFrameMap(), Kind.Long); return new HotSpotDebugInfoBuilder(nodeOperands, lockStack); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Fri Mar 14 17:19:52 2014 +0100 @@ -113,7 +113,7 @@ return value; } }; - for (Block block : lir.codeEmittingOrder()) { + for (AbstractBlock<?> block : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.lir(block)) { if (op instanceof LabelOp) { // Don't consider this as a definition
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Mar 14 17:19:52 2014 +0100 @@ -520,7 +520,7 @@ // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) int localsOffset = (graph.method().getMaxLocals() - 1) * 8; for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { - int size = FrameStateBuilder.stackSlots(osrLocal.kind()); + int size = HIRFrameStateBuilder.stackSlots(osrLocal.kind()); int offset = localsOffset - (osrLocal.index() + size - 1) * 8; IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1); ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Fri Mar 14 17:19:52 2014 +0100 @@ -122,7 +122,7 @@ public int getParameterSlots(boolean withReceiver) { int argSlots = 0; for (int i = 0; i < getParameterCount(false); i++) { - argSlots += FrameStateBuilder.stackSlots(getParameterKind(i)); + argSlots += HIRFrameStateBuilder.stackSlots(getParameterKind(i)); } return argSlots + (withReceiver ? 1 : 0); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java Fri Mar 14 17:19:52 2014 +0100 @@ -58,7 +58,7 @@ @Override public void generate(LIRGenerator gen) { - StackSlot array = gen.frameMap().allocateStackSlots(slots, objects, null); + StackSlot array = gen.getFrameMap().allocateStackSlots(slots, objects, null); Value result = gen.emitAddress(array); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Fri Mar 14 17:19:52 2014 +0100 @@ -51,7 +51,7 @@ int size = rank * 4; int wordSize = gen.target().wordSize; int slots = roundUp(size, wordSize) / wordSize; - StackSlot array = gen.frameMap().allocateStackSlots(slots, new BitSet(0), null); + StackSlot array = gen.getFrameMap().allocateStackSlots(slots, new BitSet(0), null); Value result = gen.emitAddress(array); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Fri Mar 14 17:19:52 2014 +0100 @@ -43,7 +43,7 @@ @Override public void generate(LIRGenerator gen) { assert graph().getNodes().filter(MonitorCounterNode.class).count() == 1 : "monitor counters not canonicalized to single instance"; - StackSlot counter = gen.frameMap().allocateStackSlots(1, new BitSet(0), null); + StackSlot counter = gen.getFrameMap().allocateStackSlots(1, new BitSet(0), null); Value result = gen.emitAddress(counter); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Fri Mar 14 17:19:52 2014 +0100 @@ -65,9 +65,9 @@ boolean isStatic = Modifier.isStatic(method.getModifiers()); JavaType[] signature = MetaUtil.signatureToTypes(method.getSignature(), isStatic ? null : method.getDeclaringClass()); - CallingConvention cc = gen.frameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, signature, gen.target(), false); + CallingConvention cc = gen.getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, signature, gen.target(), false); List<ValueNode> parameters = new ArrayList<>(); - for (int i = 0, slot = 0; i < cc.getArgumentCount(); i++, slot += FrameStateBuilder.stackSlots(frameState.localAt(slot).kind())) { + for (int i = 0, slot = 0; i < cc.getArgumentCount(); i++, slot += HIRFrameStateBuilder.stackSlots(frameState.localAt(slot).kind())) { parameters.add(frameState.localAt(slot)); } Value[] args = gen.visitInvokeArguments(cc, parameters);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,202 @@ +package com.oracle.graal.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public abstract class AbstractFrameStateBuilder<T> { + + protected final ResolvedJavaMethod method; + protected final StructuredGraph graph; + protected int stackSize; + + public AbstractFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph) { + assert graph != null; + this.method = method; + this.graph = graph; + } + + protected AbstractFrameStateBuilder(AbstractFrameStateBuilder other) { + assert other.graph != null; + this.method = other.method; + this.graph = other.graph; + } + + /** + * Returns the size of the local variables. + * + * @return the size of the local variables + */ + public abstract int localsSize(); + + /** + * Gets the current size (height) of the stack. + */ + public int stackSize() { + return stackSize; + } + + /** + * Gets the value in the local variables at the specified index, without any sanity checking. + * + * @param i the index into the locals + * @return the instruction that produced the value for the specified local + */ + public abstract T localAt(int i); + + /** + * Get the value on the stack at the specified stack index. + * + * @param i the index into the stack, with {@code 0} being the bottom of the stack + * @return the instruction at the specified position in the stack + */ + public abstract T stackAt(int i); + + /** + * Loads the local variable at the specified index, checking that the returned value is non-null + * and that two-stack values are properly handled. + * + * @param i the index of the local variable to load + * @return the instruction that produced the specified local + */ + public abstract T loadLocal(int i); + + /** + * Stores a given local variable at the specified index. If the value occupies + * {@linkplain HIRFrameStateBuilder#isTwoSlot(Kind) two slots}, then the next local variable index + * is also overwritten. + * + * @param i the index at which to store + * @param x the instruction which produces the value for the local + */ + public abstract void storeLocal(int i, T x); + + public abstract void storeStack(int i, T x); + + /** + * Pushes an instruction onto the stack with the expected type. + * + * @param kind the type expected for this instruction + * @param x the instruction to push onto the stack + */ + public abstract void push(Kind kind, T x); + + /** + * Pushes a value onto the stack without checking the type. + * + * @param x the instruction to push onto the stack + */ + public abstract void xpush(T x); + + /** + * Pushes a value onto the stack and checks that it is an int. + * + * @param x the instruction to push onto the stack + */ + public abstract void ipush(T x); + + /** + * Pushes a value onto the stack and checks that it is a float. + * + * @param x the instruction to push onto the stack + */ + public abstract void fpush(T x); + + /** + * Pushes a value onto the stack and checks that it is an object. + * + * @param x the instruction to push onto the stack + */ + public abstract void apush(T x); + + /** + * Pushes a value onto the stack and checks that it is a long. + * + * @param x the instruction to push onto the stack + */ + public abstract void lpush(T x); + + /** + * Pushes a value onto the stack and checks that it is a double. + * + * @param x the instruction to push onto the stack + */ + public abstract void dpush(T x); + + public abstract void pushReturn(Kind kind, T x); + + /** + * Pops an instruction off the stack with the expected type. + * + * @param kind the expected type + * @return the instruction on the top of the stack + */ + public abstract T pop(Kind kind); + + /** + * Pops a value off of the stack without checking the type. + * + * @return x the instruction popped off the stack + */ + public abstract T xpop(); + + /** + * Pops a value off of the stack and checks that it is an int. + * + * @return x the instruction popped off the stack + */ + public abstract T ipop(); + + /** + * Pops a value off of the stack and checks that it is a float. + * + * @return x the instruction popped off the stack + */ + public abstract T fpop(); + + /** + * Pops a value off of the stack and checks that it is an object. + * + * @return x the instruction popped off the stack + */ + public abstract T apop(); + + /** + * Pops a value off of the stack and checks that it is a long. + * + * @return x the instruction popped off the stack + */ + public abstract T lpop(); + + /** + * Pops a value off of the stack and checks that it is a double. + * + * @return x the instruction popped off the stack + */ + public abstract T dpop(); + + /** + * Pop the specified number of slots off of this stack and return them as an array of + * instructions. + * + * @return an array containing the arguments off of the stack + */ + public abstract T[] popArguments(int slotSize, int argSize); + + /** + * Peeks an element from the operand stack. + * + * @param argumentNumber The number of the argument, relative from the top of the stack (0 = + * top). Long and double arguments only count as one argument, i.e., null-slots are + * ignored. + * @return The peeked argument. + */ + public abstract T peek(int argumentNumber); + + /** + * Clears all values on this stack. + */ + public void clearStack() { + stackSize = 0; + } + +}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Mar 14 17:19:52 2014 +0100 @@ -83,7 +83,7 @@ public int blockID; public FixedWithNextNode firstInstruction; - public FrameStateBuilder entryState; + public HIRFrameStateBuilder entryState; public ArrayList<Block> successors = new ArrayList<>(2); public long exits;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Mar 14 17:19:52 2014 +0100 @@ -117,7 +117,7 @@ private BytecodeStream stream; // the bytecode stream - protected FrameStateBuilder frameState; // the current execution state + protected HIRFrameStateBuilder frameState; // the current execution state private Block currentBlock; private ValueNode methodSynchronizedObject; @@ -165,7 +165,7 @@ /** * Gets the current frame state being processed by this builder. */ - protected FrameStateBuilder getCurrentFrameState() { + protected HIRFrameStateBuilder getCurrentFrameState() { return frameState; } @@ -202,7 +202,7 @@ unwindBlock = null; methodSynchronizedObject = null; this.currentGraph = graph; - this.frameState = new FrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving()); + this.frameState = new HIRFrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving()); TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); try { build(); @@ -438,7 +438,7 @@ dispatchBlock = unwindBlock(bci); } - FrameStateBuilder dispatchState = frameState.copy(); + HIRFrameStateBuilder dispatchState = frameState.copy(); dispatchState.clearStack(); DispatchBeginNode dispatchBegin; @@ -1458,15 +1458,15 @@ private static class Target { FixedNode fixed; - FrameStateBuilder state; + HIRFrameStateBuilder state; - public Target(FixedNode fixed, FrameStateBuilder state) { + public Target(FixedNode fixed, HIRFrameStateBuilder state) { this.fixed = fixed; this.state = state; } } - private Target checkLoopExit(FixedNode target, Block targetBlock, FrameStateBuilder state) { + private Target checkLoopExit(FixedNode target, Block targetBlock, HIRFrameStateBuilder state) { if (currentBlock != null) { long exits = currentBlock.loops & ~targetBlock.loops; if (exits != 0) { @@ -1496,7 +1496,7 @@ if (targetBlock instanceof ExceptionDispatchBlock) { bci = ((ExceptionDispatchBlock) targetBlock).deoptBci; } - FrameStateBuilder newState = state.copy(); + HIRFrameStateBuilder newState = state.copy(); for (Block loop : exitLoops) { LoopBeginNode loopBegin = (LoopBeginNode) loop.firstInstruction; LoopExitNode loopExit = currentGraph.add(new LoopExitNode(loopBegin)); @@ -1519,7 +1519,7 @@ return new Target(target, state); } - private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { + private FixedNode createTarget(double probability, Block block, HIRFrameStateBuilder stateAfter) { assert probability >= 0 && probability <= 1.01 : probability; if (isNeverExecutedCode(probability)) { return currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); @@ -1533,7 +1533,7 @@ return probability == 0 && optimisticOpts.removeNeverExecutedCode() && entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI; } - private FixedNode createTarget(Block block, FrameStateBuilder state) { + private FixedNode createTarget(Block block, HIRFrameStateBuilder state) { assert block != null && state != null; assert !block.isExceptionEntry || state.stackSize() == 1; @@ -1613,7 +1613,7 @@ * Returns a block begin node with the specified state. If the specified probability is 0, * the block deoptimizes immediately. */ - private AbstractBeginNode createBlockTarget(double probability, Block block, FrameStateBuilder stateAfter) { + private AbstractBeginNode createBlockTarget(double probability, Block block, HIRFrameStateBuilder stateAfter) { FixedNode target = createTarget(probability, block, stateAfter); AbstractBeginNode begin = AbstractBeginNode.begin(target); @@ -1622,7 +1622,7 @@ return begin; } - private ValueNode synchronizedObject(FrameStateBuilder state, ResolvedJavaMethod target) { + private ValueNode synchronizedObject(HIRFrameStateBuilder state, ResolvedJavaMethod target) { if (isStatic(target.getModifiers())) { return appendConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass)); } else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2012, 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.java; + +import static com.oracle.graal.graph.iterators.NodePredicates.*; +import static com.oracle.graal.nodes.ValueNodeUtil.*; +import static java.lang.reflect.Modifier.*; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.java.BciBlockMapping.Block; +import com.oracle.graal.java.BciBlockMapping.LocalLiveness; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; + +public class HIRFrameStateBuilder extends AbstractFrameStateBuilder<ValueNode> { + + private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; + private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; + + private final ValueNode[] locals; + private final ValueNode[] stack; + private ValueNode[] lockedObjects; + private MonitorIdNode[] monitorIds; + + /** + * @see BytecodeFrame#rethrowException + */ + private boolean rethrowException; + + public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean eagerResolve) { + super(method, graph); + + this.locals = new ValueNode[method.getMaxLocals()]; + // we always need at least one stack slot (for exceptions) + this.stack = new ValueNode[Math.max(1, method.getMaxStackSize())]; + this.lockedObjects = EMPTY_ARRAY; + this.monitorIds = EMPTY_MONITOR_ARRAY; + + int javaIndex = 0; + int index = 0; + if (!isStatic(method.getModifiers())) { + // add the receiver + ParameterNode receiver = graph.unique(new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass()))); + storeLocal(javaIndex, receiver); + javaIndex = 1; + index = 1; + } + Signature sig = method.getSignature(); + int max = sig.getParameterCount(false); + ResolvedJavaType accessingClass = method.getDeclaringClass(); + for (int i = 0; i < max; i++) { + JavaType type = sig.getParameterType(i, accessingClass); + if (eagerResolve) { + type = type.resolve(accessingClass); + } + Kind kind = type.getKind().getStackKind(); + Stamp stamp; + if (kind == Kind.Object && type instanceof ResolvedJavaType) { + stamp = StampFactory.declared((ResolvedJavaType) type); + } else { + stamp = StampFactory.forKind(kind); + } + ParameterNode param = graph.unique(new ParameterNode(index, stamp)); + storeLocal(javaIndex, param); + javaIndex += stackSlots(kind); + index++; + } + } + + private HIRFrameStateBuilder(HIRFrameStateBuilder other) { + super(other); + locals = other.locals.clone(); + stack = other.stack.clone(); + lockedObjects = other.lockedObjects == EMPTY_ARRAY ? EMPTY_ARRAY : other.lockedObjects.clone(); + monitorIds = other.monitorIds == EMPTY_MONITOR_ARRAY ? EMPTY_MONITOR_ARRAY : other.monitorIds.clone(); + stackSize = other.stackSize; + rethrowException = other.rethrowException; + + assert locals.length == method.getMaxLocals(); + assert stack.length == Math.max(1, method.getMaxStackSize()); + assert lockedObjects.length == monitorIds.length; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[locals: ["); + for (int i = 0; i < locals.length; i++) { + sb.append(i == 0 ? "" : ",").append(locals[i] == null ? "_" : locals[i].toString(Verbosity.Id)); + } + sb.append("] stack: ["); + for (int i = 0; i < stackSize; i++) { + sb.append(i == 0 ? "" : ",").append(stack[i] == null ? "_" : stack[i].toString(Verbosity.Id)); + } + sb.append("] locks: ["); + for (int i = 0; i < lockedObjects.length; i++) { + sb.append(i == 0 ? "" : ",").append(lockedObjects[i].toString(Verbosity.Id)).append(" / ").append(monitorIds[i].toString(Verbosity.Id)); + } + sb.append("]"); + if (rethrowException) { + sb.append(" rethrowException"); + } + sb.append("]"); + return sb.toString(); + } + + public FrameState create(int bci) { + return graph.add(new FrameState(method, bci, locals, Arrays.asList(stack).subList(0, stackSize), lockedObjects, monitorIds, rethrowException, false)); + } + + public HIRFrameStateBuilder copy() { + return new HIRFrameStateBuilder(this); + } + + public boolean isCompatibleWith(HIRFrameStateBuilder other) { + assert method.equals(other.method) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method"; + assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds"; + + if (stackSize() != other.stackSize()) { + return false; + } + for (int i = 0; i < stackSize(); i++) { + ValueNode x = stackAt(i); + ValueNode y = other.stackAt(i); + if (x != y && (x == null || x.isDeleted() || y == null || y.isDeleted() || x.kind() != y.kind())) { + return false; + } + } + if (lockedObjects.length != other.lockedObjects.length) { + return false; + } + for (int i = 0; i < lockedObjects.length; i++) { + if (GraphUtil.originalValue(lockedObjects[i]) != GraphUtil.originalValue(other.lockedObjects[i]) || monitorIds[i] != other.monitorIds[i]) { + throw new BailoutException("unbalanced monitors"); + } + } + return true; + } + + public void merge(MergeNode block, HIRFrameStateBuilder other) { + assert isCompatibleWith(other); + + for (int i = 0; i < localsSize(); i++) { + storeLocal(i, merge(localAt(i), other.localAt(i), block)); + } + for (int i = 0; i < stackSize(); i++) { + storeStack(i, merge(stackAt(i), other.stackAt(i), block)); + } + for (int i = 0; i < lockedObjects.length; i++) { + lockedObjects[i] = merge(lockedObjects[i], other.lockedObjects[i], block); + assert monitorIds[i] == other.monitorIds[i]; + } + } + + private ValueNode merge(ValueNode currentValue, ValueNode otherValue, MergeNode block) { + if (currentValue == null || currentValue.isDeleted()) { + return null; + + } else if (block.isPhiAtMerge(currentValue)) { + if (otherValue == null || otherValue.isDeleted() || currentValue.kind() != otherValue.kind()) { + propagateDelete((PhiNode) currentValue); + return null; + } + ((PhiNode) currentValue).addInput(otherValue); + return currentValue; + + } else if (currentValue != otherValue) { + assert !(block instanceof LoopBeginNode) : "Phi functions for loop headers are create eagerly for all locals and stack slots"; + if (otherValue == null || otherValue.isDeleted() || currentValue.kind() != otherValue.kind()) { + return null; + } + + PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.kind(), block)); + for (int i = 0; i < block.phiPredecessorCount(); i++) { + phi.addInput(currentValue); + } + phi.addInput(otherValue); + assert phi.valueCount() == block.phiPredecessorCount() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount(); + return phi; + + } else { + return currentValue; + } + } + + private void propagateDelete(FloatingNode node) { + assert node instanceof PhiNode || node instanceof ProxyNode; + if (node.isDeleted()) { + return; + } + // Collect all phi functions that use this phi so that we can delete them recursively (after + // we delete ourselves to avoid circles). + List<FloatingNode> propagateUsages = node.usages().filter(FloatingNode.class).filter(isA(PhiNode.class).or(ProxyNode.class)).snapshot(); + + // Remove the phi function from all FrameStates where it is used and then delete it. + assert node.usages().filter(isNotA(FrameState.class).nor(PhiNode.class).nor(ProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states"; + node.replaceAtUsages(null); + node.safeDelete(); + + for (FloatingNode phiUsage : propagateUsages) { + propagateDelete(phiUsage); + } + } + + public void insertLoopPhis(LoopBeginNode loopBegin) { + for (int i = 0; i < localsSize(); i++) { + storeLocal(i, createLoopPhi(loopBegin, localAt(i))); + } + for (int i = 0; i < stackSize(); i++) { + storeStack(i, createLoopPhi(loopBegin, stackAt(i))); + } + for (int i = 0; i < lockedObjects.length; i++) { + lockedObjects[i] = createLoopPhi(loopBegin, lockedObjects[i]); + } + } + + public void insertLoopProxies(LoopExitNode loopExit, HIRFrameStateBuilder loopEntryState) { + for (int i = 0; i < localsSize(); i++) { + ValueNode value = localAt(i); + if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { + Debug.log(" inserting proxy for %s", value); + storeLocal(i, ProxyNode.forValue(value, loopExit, graph)); + } + } + for (int i = 0; i < stackSize(); i++) { + ValueNode value = stackAt(i); + if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { + Debug.log(" inserting proxy for %s", value); + storeStack(i, ProxyNode.forValue(value, loopExit, graph)); + } + } + for (int i = 0; i < lockedObjects.length; i++) { + ValueNode value = lockedObjects[i]; + if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { + Debug.log(" inserting proxy for %s", value); + lockedObjects[i] = ProxyNode.forValue(value, loopExit, graph); + } + } + } + + public void insertProxies(AbstractBeginNode begin) { + for (int i = 0; i < localsSize(); i++) { + ValueNode value = localAt(i); + if (value != null) { + Debug.log(" inserting proxy for %s", value); + storeLocal(i, ProxyNode.forValue(value, begin, graph)); + } + } + for (int i = 0; i < stackSize(); i++) { + ValueNode value = stackAt(i); + if (value != null) { + Debug.log(" inserting proxy for %s", value); + storeStack(i, ProxyNode.forValue(value, begin, graph)); + } + } + for (int i = 0; i < lockedObjects.length; i++) { + ValueNode value = lockedObjects[i]; + if (value != null) { + Debug.log(" inserting proxy for %s", value); + lockedObjects[i] = ProxyNode.forValue(value, begin, graph); + } + } + } + + private PhiNode createLoopPhi(MergeNode block, ValueNode value) { + if (value == null) { + return null; + } + assert !block.isPhiAtMerge(value) : "phi function for this block already created"; + + PhiNode phi = graph.addWithoutUnique(new PhiNode(value.kind(), block)); + phi.addInput(value); + return phi; + } + + public void cleanupDeletedPhis() { + for (int i = 0; i < localsSize(); i++) { + if (localAt(i) != null && localAt(i).isDeleted()) { + assert localAt(i) instanceof PhiNode || localAt(i) instanceof ProxyNode : "Only phi and value proxies can be deleted during parsing: " + localAt(i); + storeLocal(i, null); + } + } + } + + public void clearNonLiveLocals(Block block, LocalLiveness liveness, boolean liveIn) { + if (liveness == null) { + return; + } + if (liveIn) { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveIn(block, i)) { + locals[i] = null; + } + } + } else { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveOut(block, i)) { + locals[i] = null; + } + } + } + } + + /** + * @see BytecodeFrame#rethrowException + */ + public boolean rethrowException() { + return rethrowException; + } + + /** + * @see BytecodeFrame#rethrowException + */ + public void setRethrowException(boolean b) { + rethrowException = b; + } + + @Override + public int localsSize() { + return locals.length; + } + + @Override + public ValueNode localAt(int i) { + return locals[i]; + } + + @Override + public ValueNode stackAt(int i) { + return stack[i]; + } + + /** + * Adds a locked monitor to this frame state. + * + * @param object the object whose monitor will be locked. + */ + public void pushLock(ValueNode object, MonitorIdNode monitorId) { + assert object.isAlive() && object.kind() == Kind.Object : "unexpected value: " + object; + lockedObjects = Arrays.copyOf(lockedObjects, lockedObjects.length + 1); + monitorIds = Arrays.copyOf(monitorIds, monitorIds.length + 1); + lockedObjects[lockedObjects.length - 1] = object; + monitorIds[monitorIds.length - 1] = monitorId; + assert lockedObjects.length == monitorIds.length; + } + + /** + * Removes a locked monitor from this frame state. + * + * @return the object whose monitor was removed from the locks list. + */ + public ValueNode popLock() { + try { + return lockedObjects[lockedObjects.length - 1]; + } finally { + lockedObjects = lockedObjects.length == 1 ? EMPTY_ARRAY : Arrays.copyOf(lockedObjects, lockedObjects.length - 1); + monitorIds = monitorIds.length == 1 ? EMPTY_MONITOR_ARRAY : Arrays.copyOf(monitorIds, monitorIds.length - 1); + } + } + + public MonitorIdNode peekMonitorId() { + return monitorIds[monitorIds.length - 1]; + } + + /** + * @return the current lock depth + */ + public int lockDepth() { + assert lockedObjects.length == monitorIds.length; + return lockedObjects.length; + } + + @Override + public ValueNode loadLocal(int i) { + ValueNode x = locals[i]; + assert !x.isDeleted(); + assert !isTwoSlot(x.kind()) || locals[i + 1] == null; + assert i == 0 || locals[i - 1] == null || !isTwoSlot(locals[i - 1].kind()); + return x; + } + + @Override + public void storeLocal(int i, ValueNode x) { + assert x == null || x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x; + locals[i] = x; + if (x != null && isTwoSlot(x.kind())) { + // if this is a double word, then kill i+1 + locals[i + 1] = null; + } + if (x != null && i > 0) { + ValueNode p = locals[i - 1]; + if (p != null && isTwoSlot(p.kind())) { + // if there was a double word at i - 1, then kill it + locals[i - 1] = null; + } + } + } + + @Override + public void storeStack(int i, ValueNode x) { + assert x == null || x.isAlive() && (stack[i] == null || x.kind() == stack[i].kind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; + stack[i] = x; + } + + @Override + public void push(Kind kind, ValueNode x) { + assert x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal; + xpush(assertKind(kind, x)); + if (isTwoSlot(kind)) { + xpush(null); + } + } + + @Override + public void xpush(ValueNode x) { + assert x == null || (x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal); + stack[stackSize++] = x; + } + + @Override + public void ipush(ValueNode x) { + xpush(assertInt(x)); + } + + @Override + public void fpush(ValueNode x) { + xpush(assertFloat(x)); + } + + @Override + public void apush(ValueNode x) { + xpush(assertObject(x)); + } + + @Override + public void lpush(ValueNode x) { + xpush(assertLong(x)); + xpush(null); + } + + @Override + public void dpush(ValueNode x) { + xpush(assertDouble(x)); + xpush(null); + } + + @Override + public void pushReturn(Kind kind, ValueNode x) { + if (kind != Kind.Void) { + push(kind.getStackKind(), x); + } + } + + @Override + public ValueNode pop(Kind kind) { + assert kind != Kind.Void; + if (isTwoSlot(kind)) { + xpop(); + } + return assertKind(kind, xpop()); + } + + @Override + public ValueNode xpop() { + ValueNode result = stack[--stackSize]; + assert result == null || !result.isDeleted(); + return result; + } + + @Override + public ValueNode ipop() { + return assertInt(xpop()); + } + + @Override + public ValueNode fpop() { + return assertFloat(xpop()); + } + + @Override + public ValueNode apop() { + return assertObject(xpop()); + } + + @Override + public ValueNode lpop() { + assertHigh(xpop()); + return assertLong(xpop()); + } + + @Override + public ValueNode dpop() { + assertHigh(xpop()); + return assertDouble(xpop()); + } + + @Override + public ValueNode[] popArguments(int slotSize, int argSize) { + int base = stackSize - slotSize; + ValueNode[] r = new ValueNode[argSize]; + int argIndex = 0; + int stackindex = 0; + while (stackindex < slotSize) { + ValueNode element = stack[base + stackindex]; + assert element != null; + r[argIndex++] = element; + stackindex += stackSlots(element.kind()); + } + stackSize = base; + return r; + } + + @Override + public ValueNode peek(int argumentNumber) { + int idx = stackSize() - 1; + for (int i = 0; i < argumentNumber; i++) { + if (stackAt(idx) == null) { + idx--; + assert isTwoSlot(stackAt(idx).kind()); + } + idx--; + } + return stackAt(idx); + } + + public static int stackSlots(Kind kind) { + return isTwoSlot(kind) ? 2 : 1; + } + + public static boolean isTwoSlot(Kind kind) { + assert kind != Kind.Void && kind != Kind.Illegal; + return kind == Kind.Long || kind == Kind.Double; + } + + public boolean contains(ValueNode value) { + for (int i = 0; i < localsSize(); i++) { + if (localAt(i) == value) { + return true; + } + } + for (int i = 0; i < stackSize(); i++) { + if (stackAt(i) == value) { + return true; + } + } + assert lockedObjects.length == monitorIds.length; + for (int i = 0; i < lockedObjects.length; i++) { + if (lockedObjects[i] == value || monitorIds[i] == value) { + return true; + } + } + return false; + } +}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java Fri Mar 14 17:19:52 2014 +0100 @@ -37,9 +37,8 @@ /** * Performs control flow optimizations on the given LIR graph. */ - public static void optimize(LIR lir) { - List<Block> blocks = lir.codeEmittingOrder(); - ControlFlowOptimizer.deleteEmptyBlocks(lir, blocks); + public static <T extends AbstractBlock<T>> void optimize(LIR lir, List<T> codeEmittingOrder) { + ControlFlowOptimizer.deleteEmptyBlocks(lir, codeEmittingOrder); } private ControlFlowOptimizer() { @@ -54,8 +53,8 @@ * @param block the block checked for deletion * @return whether the block can be deleted */ - private static boolean canDeleteBlock(LIR lir, Block block) { - if (block.getSuccessorCount() != 1 || block.getPredecessorCount() == 0 || block.getFirstSuccessor() == block) { + private static boolean canDeleteBlock(LIR lir, AbstractBlock<?> block) { + if (block.getSuccessorCount() != 1 || block.getPredecessorCount() == 0 || block.getSuccessors().iterator().next() == block) { return false; } @@ -64,13 +63,13 @@ assert instructions.size() >= 2 : "block must have label and branch"; assert instructions.get(0) instanceof StandardOp.LabelOp : "first instruction must always be a label"; assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "last instruction must always be a branch"; - assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) lir.lir(block.getFirstSuccessor()).get(0)).getLabel() : "branch target must be the successor"; + assert ((StandardOp.JumpOp) instructions.get(instructions.size() - 1)).destination().label() == ((StandardOp.LabelOp) lir.lir(block.getSuccessors().iterator().next()).get(0)).getLabel() : "branch target must be the successor"; // Block must have exactly one successor. return instructions.size() == 2 && !instructions.get(instructions.size() - 1).hasState() && !block.isExceptionEntry(); } - private static void alignBlock(LIR lir, Block block) { + private static void alignBlock(LIR lir, AbstractBlock<?> block) { if (!block.isAligned()) { block.setAlign(true); List<LIRInstruction> instructions = lir.lir(block); @@ -80,15 +79,15 @@ } } - private static void deleteEmptyBlocks(LIR lir, List<Block> blocks) { + private static <T extends AbstractBlock<T>> void deleteEmptyBlocks(LIR lir, List<T> blocks) { assert verifyBlocks(lir, blocks); - Iterator<Block> iterator = blocks.iterator(); + Iterator<T> iterator = blocks.iterator(); while (iterator.hasNext()) { - Block block = iterator.next(); + T block = iterator.next(); if (canDeleteBlock(lir, block)) { // adjust successor and predecessor lists - Block other = block.getFirstSuccessor(); - for (Block pred : block.getPredecessors()) { + T other = block.getSuccessors().iterator().next(); + for (AbstractBlock<T> pred : block.getPredecessors()) { Collections.replaceAll(pred.getSuccessors(), block, other); } for (int i = 0; i < other.getPredecessorCount(); i++) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/EdgeMoveOptimizer.java Fri Mar 14 17:19:52 2014 +0100 @@ -53,10 +53,10 @@ public static void optimize(LIR ir) { EdgeMoveOptimizer optimizer = new EdgeMoveOptimizer(ir); - List<Block> blockList = ir.linearScanOrder(); + List<? extends AbstractBlock<?>> blockList = ir.linearScanOrder(); // ignore the first block in the list (index 0 is not processed) for (int i = blockList.size() - 1; i >= 1; i--) { - Block block = blockList.get(i); + AbstractBlock<?> block = blockList.get(i); if (block.getPredecessorCount() > 1) { optimizer.optimizeMovesAtBlockEnd(block); @@ -103,8 +103,8 @@ * Moves the longest {@linkplain #same common} subsequence at the end all predecessors of * {@code block} to the start of {@code block}. */ - private void optimizeMovesAtBlockEnd(Block block) { - for (Block pred : block.getPredecessors()) { + private void optimizeMovesAtBlockEnd(AbstractBlock<?> block) { + for (AbstractBlock<?> pred : block.getPredecessors()) { if (pred == block) { // currently we can't handle this correctly. return; @@ -118,7 +118,7 @@ assert numPreds > 1 : "do not call otherwise"; // setup a list with the LIR instructions of all predecessors - for (Block pred : block.getPredecessors()) { + for (AbstractBlock<?> pred : block.getPredecessors()) { assert pred != null; assert ir.lir(pred) != null; List<LIRInstruction> predInstructions = ir.lir(pred); @@ -129,7 +129,7 @@ return; } - assert pred.getFirstSuccessor() == block : "invalid control flow"; + assert pred.getSuccessors().iterator().next() == block : "invalid control flow"; assert predInstructions.get(predInstructions.size() - 1) instanceof StandardOp.JumpOp : "block must end with unconditional jump"; if (predInstructions.get(predInstructions.size() - 1).hasState()) { @@ -173,7 +173,7 @@ * {@code block} to the end of {@code block} just prior to the branch instruction ending * {@code block}. */ - private void optimizeMovesAtBlockBegin(Block block) { + private void optimizeMovesAtBlockBegin(AbstractBlock<?> block) { edgeInstructionSeqences.clear(); int numSux = block.getSuccessorCount(); @@ -203,7 +203,7 @@ int insertIdx = instructions.size() - 1; // setup a list with the lir-instructions of all successors - for (Block sux : block.getSuccessors()) { + for (AbstractBlock<?> sux : block.getSuccessors()) { List<LIRInstruction> suxInstructions = ir.lir(sux); assert suxInstructions.get(0) instanceof StandardOp.LabelOp : "block must start with label"; @@ -213,7 +213,7 @@ // the same blocks. return; } - assert sux.getFirstPredecessor() == block : "invalid control flow"; + assert sux.getPredecessors().iterator().next() == block : "invalid control flow"; // ignore the label at the beginning of the block List<LIRInstruction> seq = suxInstructions.subList(1, suxInstructions.size());
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Mar 14 17:19:52 2014 +0100 @@ -35,17 +35,17 @@ */ public class LIR { - private final ControlFlowGraph cfg; + private final AbstractControlFlowGraph<?> cfg; /** * The linear-scan ordered list of blocks. */ - private final List<Block> linearScanOrder; + private final List<? extends AbstractBlock<?>> linearScanOrder; /** * The order in which the code is emitted. */ - private final List<Block> codeEmittingOrder; + private final List<? extends AbstractBlock<?>> codeEmittingOrder; private int firstVariableNumber; @@ -65,14 +65,14 @@ /** * Creates a new LIR instance for the specified compilation. */ - public LIR(ControlFlowGraph cfg, List<Block> linearScanOrder, List<Block> codeEmittingOrder) { + public LIR(AbstractControlFlowGraph<?> cfg, List<? extends AbstractBlock<?>> linearScanOrder, List<? extends AbstractBlock<?>> codeEmittingOrder) { this.cfg = cfg; this.codeEmittingOrder = codeEmittingOrder; this.linearScanOrder = linearScanOrder; this.lirInstructions = new BlockMap<>(cfg); } - public ControlFlowGraph getControlFlowGraph() { + public AbstractControlFlowGraph<?> getControlFlowGraph() { return cfg; } @@ -80,7 +80,7 @@ * Determines if any instruction in the LIR has debug info associated with it. */ public boolean hasDebugInfo() { - for (Block b : linearScanOrder()) { + for (AbstractBlock<?> b : linearScanOrder()) { for (LIRInstruction op : lir(b)) { if (op.hasState()) { return true; @@ -98,7 +98,7 @@ return lirInstructions.get(block); } - public void setLir(Block block, List<LIRInstruction> list) { + public void setLir(AbstractBlock<?> block, List<LIRInstruction> list) { assert lir(block) == null : "lir instruction list should only be initialized once"; lirInstructions.put(block, list); } @@ -108,11 +108,11 @@ * * @return the blocks in linear scan order */ - public List<Block> linearScanOrder() { + public List<? extends AbstractBlock<?>> linearScanOrder() { return linearScanOrder; } - public List<Block> codeEmittingOrder() { + public List<? extends AbstractBlock<?>> codeEmittingOrder() { return codeEmittingOrder; } @@ -169,7 +169,7 @@ */ public static final int MAX_EXCEPTION_EDGE_OP_DISTANCE_FROM_END = 3; - public static boolean verifyBlock(LIR lir, Block block) { + public static boolean verifyBlock(LIR lir, AbstractBlock<?> block) { List<LIRInstruction> ops = lir.lir(block); if (ops.size() == 0) { return false; @@ -193,12 +193,12 @@ return true; } - public static boolean verifyBlocks(LIR lir, List<Block> blocks) { - for (Block block : blocks) { - for (Block sux : block.getSuccessors()) { + public static boolean verifyBlocks(LIR lir, List<? extends AbstractBlock<?>> blocks) { + for (AbstractBlock<?> block : blocks) { + for (AbstractBlock<?> sux : block.getSuccessors()) { assert blocks.contains(sux) : "missing successor from: " + block + "to: " + sux; } - for (Block pred : block.getPredecessors()) { + for (AbstractBlock<?> pred : block.getPredecessors()) { assert blocks.contains(pred) : "missing predecessor from: " + block + "to: " + pred; } if (!verifyBlock(lir, block)) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Mar 14 17:19:52 2014 +0100 @@ -46,11 +46,11 @@ private final BitSet[] blockLiveOut; private final Object[] variableDefinitions; - private BitSet liveOutFor(Block block) { + private BitSet liveOutFor(AbstractBlock<?> block) { return blockLiveOut[block.getId()]; } - private void setLiveOutFor(Block block, BitSet liveOut) { + private void setLiveOutFor(AbstractBlock<?> block, BitSet liveOut) { blockLiveOut[block.getId()] = liveOut; } @@ -98,7 +98,7 @@ private BitSet curVariablesLive; private Value[] curRegistersLive; - private Block curBlock; + private AbstractBlock<?> curBlock; private Object curInstruction; private BitSet curRegistersDefined; @@ -120,7 +120,7 @@ int maxRegisterNum = maxRegisterNum(); curRegistersDefined = new BitSet(); - for (Block block : lir.linearScanOrder()) { + for (AbstractBlock<?> block : lir.linearScanOrder()) { curBlock = block; curVariablesLive = new BitSet(); curRegistersLive = new Value[maxRegisterNum];
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/NullCheckOptimizer.java Fri Mar 14 17:19:52 2014 +0100 @@ -31,15 +31,15 @@ public final class NullCheckOptimizer { public static void optimize(LIR ir, int implicitNullCheckLimit) { - List<Block> blocks = ir.codeEmittingOrder(); + List<? extends AbstractBlock<?>> blocks = ir.codeEmittingOrder(); NullCheckOptimizer.foldNullChecks(ir, blocks, implicitNullCheckLimit); } private NullCheckOptimizer() { } - private static void foldNullChecks(LIR ir, List<Block> blocks, int implicitNullCheckLimit) { - for (Block block : blocks) { + private static void foldNullChecks(LIR ir, List<? extends AbstractBlock<?>> blocks, int implicitNullCheckLimit) { + for (AbstractBlock<?> block : blocks) { List<LIRInstruction> list = ir.lir(block); if (!list.isEmpty()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Fri Mar 14 17:19:52 2014 +0100 @@ -79,7 +79,7 @@ int entryValueNum; } - Map<Block, BlockData> blockData = new HashMap<>(); + Map<AbstractBlock<?>, BlockData> blockData = new HashMap<>(); Register[] callerSaveRegs; @@ -134,7 +134,7 @@ private void initBlockData(LIR lir) { - List<Block> blocks = lir.linearScanOrder(); + List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); numRegs = 0; int maxStackLocations = COMPLEXITY_LIMIT / blocks.size(); @@ -143,7 +143,7 @@ * Search for relevant locations which can be optimized. These are register or stack slots * which occur as destinations of move instructions. */ - for (Block block : blocks) { + for (AbstractBlock<?> block : blocks) { List<LIRInstruction> instructions = lir.lir(block); for (LIRInstruction op : instructions) { if (isEligibleMove(op)) { @@ -168,7 +168,7 @@ */ int numLocations = numRegs + stackIndices.size(); Debug.log("num locations = %d (regs = %d, stack = %d)", numLocations, numRegs, stackIndices.size()); - for (Block block : blocks) { + for (AbstractBlock<?> block : blocks) { BlockData data = new BlockData(numLocations); blockData.put(block, data); } @@ -183,7 +183,7 @@ Indent indent = Debug.logAndIndent("solve data flow"); - List<Block> blocks = lir.linearScanOrder(); + List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); int numIter = 0; @@ -197,7 +197,7 @@ changed = false; Indent indent2 = indent.logAndIndent("new iteration"); - for (Block block : blocks) { + for (AbstractBlock<?> block : blocks) { BlockData data = blockData.get(block); /* @@ -226,7 +226,7 @@ /* * Merge the states of predecessor blocks */ - for (Block predecessor : block.getPredecessors()) { + for (AbstractBlock<?> predecessor : block.getPredecessors()) { BlockData predData = blockData.get(predecessor); newState |= mergeState(data.entryState, predData.exitState, valueNum); } @@ -281,9 +281,9 @@ Indent indent = Debug.logAndIndent("eliminate moves"); - List<Block> blocks = lir.linearScanOrder(); + List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder(); - for (Block block : blocks) { + for (AbstractBlock<?> block : blocks) { Indent indent2 = indent.logAndIndent("eliminate moves in block %d", block.getId());
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Fri Mar 14 17:19:52 2014 +0100 @@ -298,7 +298,7 @@ */ public boolean isSuccessorEdge(LabelRef edge) { assert lir != null; - List<Block> order = lir.codeEmittingOrder(); + List<? extends AbstractBlock<?>> order = lir.codeEmittingOrder(); assert order.get(currentBlockIndex) == edge.getSourceBlock(); return currentBlockIndex < order.size() - 1 && order.get(currentBlockIndex + 1) == edge.getTargetBlock(); } @@ -312,7 +312,7 @@ this.lir = lir; this.currentBlockIndex = 0; frameContext.enter(this); - for (Block b : lir.codeEmittingOrder()) { + for (AbstractBlock<?> b : lir.codeEmittingOrder()) { emitBlock(b); currentBlockIndex++; } @@ -320,7 +320,7 @@ this.currentBlockIndex = 0; } - private void emitBlock(Block block) { + private void emitBlock(AbstractBlock<?> block) { if (Debug.isDumpEnabled()) { blockComment(String.format("block B%d %s", block.getId(), block.getLoop())); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java Fri Mar 14 17:19:52 2014 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.cfg; +import java.util.*; + import com.oracle.graal.nodes.*; public interface AbstractBlock<T extends AbstractBlock<?>> { @@ -40,11 +42,11 @@ boolean isExceptionEntry(); - Iterable<T> getPredecessors(); + List<T> getPredecessors(); int getPredecessorCount(); - Iterable<T> getSuccessors(); + List<T> getSuccessors(); int getSuccessorCount(); @@ -55,4 +57,6 @@ boolean isAligned(); void setAlign(boolean align); + + T getDominator(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlockBase.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009, 2012, 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.nodes.cfg; + +import java.util.*; + +public abstract class AbstractBlockBase<T extends AbstractBlock<T>> implements AbstractBlock<T> { + + protected int id; + + protected List<T> predecessors; + protected List<T> successors; + + protected T dominator; + + private boolean align; + private int linearScanNumber; + + protected AbstractBlockBase() { + this.id = ControlFlowGraph.BLOCK_ID_INITIAL; + this.linearScanNumber = -1; + } + + public int getId() { + return id; + } + + public List<T> getPredecessors() { + return predecessors; + } + + public List<T> getSuccessors() { + return successors; + } + + public T getDominator() { + return dominator; + } + + @Override + public String toString() { + return "B" + id; + } + + public int getPredecessorCount() { + return getPredecessors().size(); + } + + public int getSuccessorCount() { + return getSuccessors().size(); + } + + public int getLinearScanNumber() { + return linearScanNumber; + } + + public void setLinearScanNumber(int linearScanNumber) { + this.linearScanNumber = linearScanNumber; + } + + public boolean isAligned() { + return align; + } + + public void setAlign(boolean align) { + this.align = align; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, 2014, 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.nodes.cfg; + +public interface AbstractControlFlowGraph<T extends AbstractBlock<T>> { + + T[] getBlocks(); + + Loop[] getLoops(); + + T getStartBlock(); +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Fri Mar 14 17:19:52 2014 +0100 @@ -27,34 +27,18 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -public final class Block implements AbstractBlock<Block> { +public final class Block extends AbstractBlockBase<Block> { protected final AbstractBeginNode beginNode; - protected int id; - protected FixedNode endNode; protected Loop loop; - protected List<Block> predecessors; - protected List<Block> successors; - - protected Block dominator; protected List<Block> dominated; protected Block postdominator; - private boolean align; - private int linearScanNumber; - protected Block(AbstractBeginNode node) { this.beginNode = node; - - this.id = ControlFlowGraph.BLOCK_ID_INITIAL; - this.linearScanNumber = -1; - } - - public int getId() { - return id; } public AbstractBeginNode getBeginNode() { @@ -89,22 +73,10 @@ return predecessors.get(0); } - public List<Block> getPredecessors() { - return predecessors; - } - public Block getFirstSuccessor() { return successors.get(0); } - public List<Block> getSuccessors() { - return successors; - } - - public Block getDominator() { - return dominator; - } - public Block getEarliestPostDominated() { Block b = this; while (true) { @@ -187,14 +159,6 @@ return "B" + id; } - public int getPredecessorCount() { - return getPredecessors().size(); - } - - public int getSuccessorCount() { - return getSuccessors().size(); - } - public boolean dominates(Block block) { return block.isDominatedBy(this); } @@ -209,19 +173,4 @@ return dominator.isDominatedBy(block); } - public int getLinearScanNumber() { - return linearScanNumber; - } - - public void setLinearScanNumber(int linearScanNumber) { - this.linearScanNumber = linearScanNumber; - } - - public boolean isAligned() { - return align; - } - - public void setAlign(boolean align) { - this.align = align; - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlockMap.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlockMap.java Fri Mar 14 17:19:52 2014 +0100 @@ -27,7 +27,7 @@ private final T[] data; @SuppressWarnings("unchecked") - public BlockMap(ControlFlowGraph cfg) { + public BlockMap(AbstractControlFlowGraph<?> cfg) { data = (T[]) new Object[cfg.getBlocks().length]; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/BlocksToDoubles.java Fri Mar 14 17:19:52 2014 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013, 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.nodes.cfg; + +import java.util.*; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.util.*; + +public class BlocksToDoubles { + + private final IdentityHashMap<AbstractBlock<?>, Double> nodeProbabilities; + + public BlocksToDoubles(int numberOfNodes) { + this.nodeProbabilities = new IdentityHashMap<>(numberOfNodes); + } + + public void put(AbstractBlock<?> n, double value) { + assert value >= 0.0 : value; + nodeProbabilities.put(n, value); + } + + public boolean contains(AbstractBlock<?> n) { + return nodeProbabilities.containsKey(n); + } + + public double get(AbstractBlock<?> n) { + Double value = nodeProbabilities.get(n); + assert value != null; + return value; + } + + public static BlocksToDoubles createFromNodeProbability(NodesToDoubles nodeProbabilities, ControlFlowGraph cfg) { + BlocksToDoubles blockProbabilities = new BlocksToDoubles(cfg.getBlocks().length); + for (AbstractBlock<?> block : cfg.getBlocks()) { + blockProbabilities.put(block, nodeProbabilities.get(block.getBeginNode())); + } + assert verify(nodeProbabilities, cfg, blockProbabilities) : "Probabilities differ for nodes in the same block."; + return blockProbabilities; + } + + static private boolean verify(NodesToDoubles nodeProbabilities, ControlFlowGraph cfg, BlocksToDoubles blockProbabilities) { + for (Block b : cfg.getBlocks()) { + double p = blockProbabilities.get(b); + for (FixedNode n : b.getNodes()) { + if (nodeProbabilities.get(n) != p) { + return false; + } + } + } + return true; + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Fri Mar 14 17:19:52 2014 +0100 @@ -28,7 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -public class ControlFlowGraph { +public class ControlFlowGraph implements AbstractControlFlowGraph<Block> { public final StructuredGraph graph;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Mar 14 17:19:52 2014 +0100 @@ -127,10 +127,11 @@ * @param label A label describing the compilation phase that produced the control flow graph. * @param blocks The list of blocks to be printed. */ - public void printCFG(String label, List<Block> blocks, boolean printNodes) { + public void printCFG(String label, List<? extends AbstractBlock<?>> blocks, boolean printNodes) { if (lir == null) { latestScheduling = new NodeMap<>(cfg.getNodeToBlock()); - for (Block block : blocks) { + for (AbstractBlock<?> abstractBlock : blocks) { + Block block = (Block) abstractBlock; Node cur = block.getBeginNode(); while (true) { assert inFixedSchedule(cur) && latestScheduling.get(cur) == block; @@ -148,7 +149,8 @@ begin("cfg"); out.print("name \"").print(label).println('"'); - for (Block block : blocks) { + for (AbstractBlock<?> abstractBlock : blocks) { + Block block = (Block) abstractBlock; printBlock(block, printNodes); } end("cfg"); @@ -299,7 +301,7 @@ out.print("tid ").print(nodeToString(node)).println(COLUMN_END); if (lirGenerator != null) { - Value operand = lirGenerator.nodeOperands.get(node); + Value operand = lirGenerator.getNodeOperands().get(node); if (operand != null) { out.print("result ").print(operand.toString()).println(COLUMN_END); } @@ -403,8 +405,8 @@ private String stateValueToString(ValueNode value) { String result = nodeToString(value); - if (lirGenerator != null && lirGenerator.nodeOperands != null && value != null) { - Value operand = lirGenerator.nodeOperands.get(value); + if (lirGenerator != null && lirGenerator.getNodeOperands() != null && value != null) { + Value operand = lirGenerator.getNodeOperands().get(value); if (operand != null) { result += ": " + operand; }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Mar 14 17:19:52 2014 +0100 @@ -141,7 +141,8 @@ cfgPrinter.target = cfgPrinter.lirGenerator.target(); } if (cfgPrinter.lir != null) { - cfgPrinter.cfg = cfgPrinter.lir.getControlFlowGraph(); + assert cfgPrinter.lir.getControlFlowGraph() instanceof ControlFlowGraph; + cfgPrinter.cfg = (ControlFlowGraph) cfgPrinter.lir.getControlFlowGraph(); } CodeCacheProvider codeCache = Debug.contextLookup(CodeCacheProvider.class);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Fri Mar 14 15:29:17 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Fri Mar 14 17:19:52 2014 +0100 @@ -106,7 +106,7 @@ * @param name the name of the invoked method * @param args the arguments to the invocation */ - public InvokeNode createInvoke(Class<?> declaringClass, String name, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) { + public InvokeNode createInvoke(Class<?> declaringClass, String name, InvokeKind invokeKind, HIRFrameStateBuilder frameStateBuilder, int bci, ValueNode... args) { boolean isStatic = invokeKind == InvokeKind.Static; ResolvedJavaMethod method = null; for (Method m : declaringClass.getDeclaredMethods()) { @@ -123,7 +123,7 @@ * Creates and appends an {@link InvokeNode} for a call to a given method with a given set of * arguments. */ - public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) { + public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, HIRFrameStateBuilder frameStateBuilder, int bci, ValueNode... args) { assert Modifier.isStatic(method.getModifiers()) == (invokeKind == InvokeKind.Static); Signature signature = method.getSignature(); JavaType returnType = signature.getReturnType(null);
--- a/mx/projects Fri Mar 14 15:29:17 2014 +0100 +++ b/mx/projects Fri Mar 14 17:19:52 2014 +0100 @@ -482,7 +482,7 @@ # graal.baseline project@com.oracle.graal.baseline@subDir=graal project@com.oracle.graal.baseline@sourceDirs=src -project@com.oracle.graal.baseline@dependencies=com.oracle.graal.java,com.oracle.graal.lir +project@com.oracle.graal.baseline@dependencies=com.oracle.graal.java,com.oracle.graal.lir,com.oracle.graal.compiler project@com.oracle.graal.baseline@checkstyle=com.oracle.graal.graph project@com.oracle.graal.baseline@javaCompliance=1.7 project@com.oracle.graal.baseline@workingSets=Graal,Java