# HG changeset patch # User Stefan Anzinger # Date 1425385175 -3600 # Node ID 87d5316e171b81f24432c15581546a2b7e5e4ba6 # Parent 96ab2078eeaff57b70a9e6e7a0369d6ad40ed6c8# Parent 9669f6a5624b236c1a7c53c9e45cb9a8d2d5b616 Merge diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Tue Mar 03 13:19:35 2015 +0100 @@ -66,7 +66,7 @@ * Note that the number of locals and the number of stack slots may be smaller than the maximum * number of locals and stack slots as specified in the compiled method. */ - public final JavaValue[] values; + public final Value[] values; /** * The number of locals in the values array. @@ -144,7 +144,7 @@ * @param numStack the depth of the stack * @param numLocks the number of locked objects */ - public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, int numLocals, int numStack, int numLocks) { + public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks) { super(caller, method, bci); assert values != null; this.rethrowException = rethrowException; @@ -183,7 +183,7 @@ * @param i the local variable index * @return the value that can be used to reconstruct the local's current value */ - public JavaValue getLocalValue(int i) { + public Value getLocalValue(int i) { return values[i]; } @@ -193,7 +193,7 @@ * @param i the stack index * @return the value that can be used to reconstruct the stack slot's current value */ - public JavaValue getStackValue(int i) { + public Value getStackValue(int i) { return values[i + numLocals]; } @@ -203,7 +203,7 @@ * @param i the lock index * @return the value that can be used to reconstruct the lock's current value */ - public JavaValue getLockValue(int i) { + public Value getLockValue(int i) { return values[i + numLocals + numStack]; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java Tue Mar 03 13:19:35 2015 +0100 @@ -33,22 +33,22 @@ private static final long serialVersionUID = 8241681800464483691L; - private JavaValue owner; + private Value owner; private StackSlotValue slot; private final boolean eliminated; - public StackLockValue(JavaValue owner, StackSlotValue slot, boolean eliminated) { + public StackLockValue(Value object, StackSlotValue slot, boolean eliminated) { super(LIRKind.Illegal); - this.owner = owner; + this.owner = object; this.slot = slot; this.eliminated = eliminated; } - public JavaValue getOwner() { + public Value getOwner() { return owner; } - public void setOwner(JavaValue newOwner) { + public void setOwner(Value newOwner) { this.owner = newOwner; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Tue Mar 03 13:19:35 2015 +0100 @@ -36,7 +36,7 @@ private static final long serialVersionUID = -2907197776426346021L; private final ResolvedJavaType type; - private JavaValue[] values; + private Value[] values; private final int id; /** @@ -54,18 +54,18 @@ * position in the compiled code. * @return a new {@link VirtualObject} instance. */ - public static VirtualObject get(ResolvedJavaType type, JavaValue[] values, int id) { + public static VirtualObject get(ResolvedJavaType type, Value[] values, int id) { return new VirtualObject(type, values, id); } - private VirtualObject(ResolvedJavaType type, JavaValue[] values, int id) { + private VirtualObject(ResolvedJavaType type, Value[] values, int id) { super(LIRKind.reference(Kind.Object)); this.type = type; this.values = values; this.id = id; } - private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set visited) { + private static StringBuilder appendValue(StringBuilder buf, Value value, Set visited) { if (value instanceof VirtualObject) { VirtualObject vo = (VirtualObject) value; buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id); @@ -120,7 +120,7 @@ /** * Returns an array containing all the values to be stored into the object when it is recreated. */ - public JavaValue[] getValues() { + public Value[] getValues() { return values; } @@ -132,7 +132,7 @@ return id; } - private static boolean checkValues(ResolvedJavaType type, JavaValue[] values) { + private static boolean checkValues(ResolvedJavaType type, Value[] values) { if (values != null) { if (!type.isArray()) { ResolvedJavaField[] fields = type.getInstanceFields(true); @@ -140,8 +140,8 @@ for (int i = 0; i < values.length; i++) { ResolvedJavaField field = fields[fieldIndex++]; Kind valKind = values[i].getKind().getStackKind(); - if (field.getKind() == Kind.Object && values[i] instanceof Value) { - assert ((Value) values[i]).getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind(); + if (field.getKind() == Kind.Object) { + assert values[i].getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind(); } else { if ((valKind == Kind.Double || valKind == Kind.Long) && field.getKind() == Kind.Int) { assert fields[fieldIndex].getKind() == Kind.Int; @@ -156,9 +156,7 @@ Kind componentKind = type.getComponentType().getKind().getStackKind(); if (componentKind == Kind.Object) { for (int i = 0; i < values.length; i++) { - if (values[i] instanceof Value) { - assert ((Value) values[i]).getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind; - } + assert values[i].getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind; } } else { for (int i = 0; i < values.length; i++) { @@ -177,7 +175,7 @@ * @param values an array containing all the values to be stored into the object when it is * recreated. */ - public void setValues(JavaValue[] values) { + public void setValues(Value[] values) { assert checkValues(type, values); this.values = values; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Tue Mar 03 13:19:35 2015 +0100 @@ -34,6 +34,8 @@ private T dominator; private List dominated; + private int domNumber; + private int maxChildDomNumber; private boolean align; private int linearScanNumber; @@ -43,6 +45,19 @@ this.linearScanNumber = -1; } + public void setDominatorNumbers(int domNumber, int maxChildDomNumber) { + this.domNumber = domNumber; + this.maxChildDomNumber = maxChildDomNumber; + } + + public int getDominatorNumber() { + return domNumber; + } + + public int getMaxChildDominatorNumber() { + return this.maxChildDomNumber; + } + public int getId() { return id; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Tue Mar 03 13:19:35 2015 +0100 @@ -46,6 +46,7 @@ /** * Computes the dominators of control flow graph. */ + @SuppressWarnings("unchecked") static > void computeDominators(AbstractControlFlowGraph cfg) { List reversePostOrder = cfg.getBlocks(); assert reversePostOrder.get(0).getPredecessorCount() == 0 : "start block has no predecessor and therefore no dominator"; @@ -55,7 +56,7 @@ T dominator = null; for (T pred : block.getPredecessors()) { if (!pred.isLoopEnd()) { - dominator = commonDominatorTyped(dominator, pred); + dominator = (T) ((dominator == null) ? pred : commonDominatorRaw(dominator, pred)); } } // set dominator @@ -65,21 +66,26 @@ } dominator.getDominated().add(block); } + calcDominatorRanges(cfg.getStartBlock(), 0); + } + + static > int calcDominatorRanges(T block, int next) { + int myNumber = next; + int maxNumber = myNumber; + for (T dominated : block.getDominated()) { + maxNumber = calcDominatorRanges(dominated, maxNumber + 1); + } + block.setDominatorNumbers(myNumber, maxNumber); + return maxNumber; } /** * True if block {@code a} is dominated by block {@code b}. */ static boolean isDominatedBy(AbstractBlockBase a, AbstractBlockBase b) { - assert a != null && b != null; - if (a == b) { - return true; - } - if (a.getDominatorDepth() < b.getDominatorDepth()) { - return false; - } - - return b == (AbstractBlockBase) a.getDominator(a.getDominatorDepth() - b.getDominatorDepth()); + int domNumberA = a.getDominatorNumber(); + int domNumberB = b.getDominatorNumber(); + return domNumberA >= domNumberB && domNumberA <= b.getMaxChildDominatorNumber(); } /** @@ -101,21 +107,49 @@ static AbstractBlockBase commonDominator(AbstractBlockBase a, AbstractBlockBase b) { if (a == null) { return b; - } - if (b == null) { + } else if (b == null) { return a; + } else { + int aDomDepth = a.getDominatorDepth(); + int bDomDepth = b.getDominatorDepth(); + AbstractBlockBase aTemp; + AbstractBlockBase bTemp; + if (aDomDepth > bDomDepth) { + aTemp = a; + bTemp = b; + } else { + aTemp = b; + bTemp = a; + } + return commonDominatorHelper(aTemp, bTemp); } + } - AbstractBlockBase iterA = a; - AbstractBlockBase iterB = b; + static AbstractBlockBase commonDominatorHelper(AbstractBlockBase a, AbstractBlockBase b) { + int domNumberA = a.getDominatorNumber(); + AbstractBlockBase result = b; + while (domNumberA < result.getDominatorNumber()) { + result = result.getDominator(); + } + while (domNumberA > result.getMaxChildDominatorNumber()) { + result = result.getDominator(); + } + return result; + } + + static AbstractBlockBase commonDominatorRaw(AbstractBlockBase a, AbstractBlockBase b) { int aDomDepth = a.getDominatorDepth(); int bDomDepth = b.getDominatorDepth(); if (aDomDepth > bDomDepth) { - iterA = a.getDominator(aDomDepth - bDomDepth); + return commonDominatorRawSameDepth(a.getDominator(aDomDepth - bDomDepth), b); } else { - iterB = b.getDominator(bDomDepth - aDomDepth); + return commonDominatorRawSameDepth(a, b.getDominator(bDomDepth - aDomDepth)); } + } + static AbstractBlockBase commonDominatorRawSameDepth(AbstractBlockBase a, AbstractBlockBase b) { + AbstractBlockBase iterA = a; + AbstractBlockBase iterB = b; while (iterA != iterB) { iterA = iterA.getDominator(); iterB = iterB.getDominator(); diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 03 13:19:35 2015 +0100 @@ -60,6 +60,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.schedule.SchedulePhase.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; @@ -302,7 +303,8 @@ } protected static String getCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) { - SchedulePhase schedule = new SchedulePhase(); + SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); + schedule.setScheduleConstants(true); schedule.apply(graph); NodeMap canonicalId = graph.createNodeMap(); diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Tue Mar 03 13:19:35 2015 +0100 @@ -28,6 +28,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; @@ -36,9 +37,10 @@ public class LongNodeChainTest extends GraalCompilerTest { - public static final int N = 100000; + public static final int N = 10000; - @Ignore + private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST}; + @Test public void testLongAddChain() { longAddChain(true); @@ -51,6 +53,9 @@ ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1)); ValueNode value = null; if (reverse) { + // Make sure the constant's stamp is not used to infer the add node's stamp. + OpaqueNode opaque = graph.unique(new OpaqueNode(constant)); + constant = opaque; AddNode addNode = graph.unique(new AddNode(constant, constant)); value = addNode; for (int i = 1; i < N; ++i) { @@ -58,6 +63,7 @@ addNode.setY(newAddNode); addNode = newAddNode; } + opaque.replaceAndDelete(opaque.getValue()); } else { value = constant; for (int i = 0; i < N; ++i) { @@ -67,7 +73,7 @@ ReturnNode returnNode = graph.add(new ReturnNode(value)); graph.start().setNext(returnNode); - for (SchedulingStrategy s : SchedulingStrategy.values()) { + for (SchedulingStrategy s : Strategies) { new SchedulePhase(s).apply(graph); } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 03 13:19:35 2015 +0100 @@ -43,10 +43,10 @@ import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.lir.phases.*; +import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext; -import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext; -import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.spi.*; @@ -64,6 +64,8 @@ private static final DebugTimer FrontEnd = Debug.timer("FrontEnd"); private static final DebugTimer BackEnd = Debug.timer("BackEnd"); + private static final DebugTimer EmitLIR = Debug.timer("EmitLIR"); + private static final DebugTimer EmitCode = Debug.timer("EmitCode"); /** * The set of positive filters specified by the {@code -G:IntrinsificationsEnabled} option. To @@ -93,6 +95,9 @@ @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + "See MethodFilter class for pattern syntax.", type = OptionType.Debug) public static final OptionValue IntrinsificationsDisabled = new OptionValue<>(null); + + @Option(help = "Repeatedly run the LIR code generation pass to improve statistical profiling results.", type = OptionType.Debug) + public static final OptionValue EmitLIRRepeatCount = new OptionValue<>(0); // @formatter:on } @@ -276,10 +281,18 @@ public static void emitBackEnd(StructuredGraph graph, Object stub, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Backend backend, TargetDescription target, T compilationResult, CompilationResultBuilderFactory factory, SchedulePhase schedule, RegisterConfig registerConfig, LIRSuites lirSuites) { - try (TimerCloseable a = BackEnd.start()) { + try (Scope s = Debug.scope("BackEnd"); TimerCloseable a = BackEnd.start()) { + // Repeatedly run the LIR code generation pass to improve statistical profiling results. + for (int i = 0; i < EmitLIRRepeatCount.getValue(); i++) { + SchedulePhase dummySchedule = new SchedulePhase(); + dummySchedule.setScheduleConstants(true); + dummySchedule.apply(graph); + emitLIR(backend, target, dummySchedule, graph, stub, cc, registerConfig, lirSuites); + } + LIRGenerationResult lirGen = null; lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites); - try (Scope s = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { + try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), lirGen, compilationResult, installedCodeOwner, factory); } catch (Throwable e) { throw Debug.handle(e); @@ -300,18 +313,21 @@ } } + private static final DebugTimer lirGenTimeTracker = Debug.timer("LIRGenTime"); + private static final DebugMemUseTracker lirGenMemUseTracker = Debug.memUseTracker("LIRGenMemUse"); + public static LIRGenerationResult emitLIR(Backend backend, TargetDescription target, SchedulePhase schedule, StructuredGraph graph, Object stub, CallingConvention cc, RegisterConfig registerConfig, LIRSuites lirSuites) { - List blocks = schedule.getCFG().getBlocks(); - Block startBlock = schedule.getCFG().getStartBlock(); - assert startBlock != null; - assert startBlock.getPredecessorCount() == 0; + try (Scope ds = Debug.scope("EmitLIR"); TimerCloseable a = EmitLIR.start()) { + List blocks = schedule.getCFG().getBlocks(); + Block startBlock = schedule.getCFG().getStartBlock(); + assert startBlock != null; + assert startBlock.getPredecessorCount() == 0; - LIR lir = null; - List codeEmittingOrder = null; - List linearScanOrder = null; - try (Scope ds = Debug.scope("MidEnd")) { - try (Scope s = Debug.scope("ComputeLinearScanOrder")) { + LIR lir = null; + List codeEmittingOrder = null; + List linearScanOrder = null; + try (Scope s = Debug.scope("ComputeLinearScanOrder", lir)) { codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.size(), startBlock); linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.size(), startBlock); @@ -320,16 +336,12 @@ } catch (Throwable e) { throw Debug.handle(e); } - } catch (Throwable e) { - throw Debug.handle(e); - } - try (Scope ds = Debug.scope("BackEnd", lir)) { FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig); LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, graph.method(), stub); LIRGeneratorTool lirGen = backend.newLIRGenerator(cc, lirGenRes); NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen); - try (Scope s = Debug.scope("LIRGen", lirGen)) { + try (Scope s = Debug.scope("LIRGen", lir, lirGen); AutoCloseable c = lirGenMemUseTracker.start(); AutoCloseable t = lirGenTimeTracker.start()) { for (Block b : linearScanOrder) { emitBlock(nodeLirGen, lirGenRes, b, graph, schedule.getBlockToNodesMap()); } @@ -366,45 +378,49 @@ public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set inlinedMethods, LIRGenerationResult lirGenRes, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { - FrameMap frameMap = lirGenRes.getFrameMap(); - CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory); - backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner); - crb.finish(); - if (assumptions != null && !assumptions.isEmpty()) { - compilationResult.setAssumptions(assumptions.toArray()); - } - if (inlinedMethods != null) { - compilationResult.setMethods(rootMethod, inlinedMethods); - } - - if (Debug.isMeterEnabled()) { - List ldp = compilationResult.getDataPatches(); - Kind[] kindValues = Kind.values(); - DebugMetric[] dms = new DebugMetric[kindValues.length]; - for (int i = 0; i < dms.length; i++) { - dms[i] = Debug.metric("DataPatches-%s", kindValues[i]); + try (TimerCloseable a = EmitCode.start()) { + FrameMap frameMap = lirGenRes.getFrameMap(); + CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory); + backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner); + crb.finish(); + if (assumptions != null && !assumptions.isEmpty()) { + compilationResult.setAssumptions(assumptions.toArray()); + } + if (inlinedMethods != null) { + compilationResult.setMethods(rootMethod, inlinedMethods); } - for (DataPatch dp : ldp) { - Kind kind = Kind.Illegal; - if (dp.reference instanceof ConstantReference) { - VMConstant constant = ((ConstantReference) dp.reference).getConstant(); - kind = ((JavaConstant) constant).getKind(); + if (Debug.isMeterEnabled()) { + List ldp = compilationResult.getDataPatches(); + Kind[] kindValues = Kind.values(); + DebugMetric[] dms = new DebugMetric[kindValues.length]; + for (int i = 0; i < dms.length; i++) { + dms[i] = Debug.metric("DataPatches-%s", kindValues[i]); } - dms[kind.ordinal()].add(1); + + for (DataPatch dp : ldp) { + Kind kind = Kind.Illegal; + if (dp.reference instanceof ConstantReference) { + VMConstant constant = ((ConstantReference) dp.reference).getConstant(); + kind = ((JavaConstant) constant).getKind(); + } + dms[kind.ordinal()].add(1); + } + + Debug.metric("CompilationResults").increment(); + Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize()); + Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size()); + Debug.metric("DataPatches").add(ldp.size()); + Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); } - Debug.metric("CompilationResults").increment(); - Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize()); - Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size()); - Debug.metric("DataPatches").add(ldp.size()); - Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size()); + if (Debug.isLogEnabled()) { + Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null)); + } + + Debug.dump(compilationResult, "After code generation"); + } catch (Throwable e) { + throw Debug.handle(e); } - - if (Debug.isLogEnabled()) { - Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null)); - } - - Debug.dump(compilationResult, "After code generation"); } } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Mar 03 13:19:35 2015 +0100 @@ -83,7 +83,7 @@ for (Entry entry : virtualObjectsCopy.entrySet()) { if (entry.getValue().getValues() == null) { VirtualObjectNode vobj = entry.getKey(); - JavaValue[] values = new JavaValue[vobj.entryCount()]; + Value[] values = new Value[vobj.entryCount()]; if (values.length > 0) { changed = true; VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj); @@ -98,7 +98,7 @@ } } if (pos != vobj.entryCount()) { - JavaValue[] newValues = new JavaValue[pos]; + Value[] newValues = new Value[pos]; System.arraycopy(values, 0, newValues, 0, pos); values = newValues; } @@ -136,7 +136,7 @@ int numStack = state.stackSize(); int numLocks = state.locksSize(); - JavaValue[] values = new JavaValue[numLocals + numStack + numLocks]; + Value[] values = new Value[numLocals + numStack + numLocks]; computeLocals(state, numLocals, values); computeStack(state, numLocals, numStack, values); computeLocks(state, values); @@ -151,33 +151,33 @@ } } - protected void computeLocals(FrameState state, int numLocals, JavaValue[] values) { + protected void computeLocals(FrameState state, int numLocals, Value[] values) { for (int i = 0; i < numLocals; i++) { values[i] = computeLocalValue(state, i); } } - protected JavaValue computeLocalValue(FrameState state, int i) { + protected Value computeLocalValue(FrameState state, int i) { return toValue(state.localAt(i)); } - protected void computeStack(FrameState state, int numLocals, int numStack, JavaValue[] values) { + protected void computeStack(FrameState state, int numLocals, int numStack, Value[] values) { for (int i = 0; i < numStack; i++) { values[numLocals + i] = computeStackValue(state, i); } } - protected JavaValue computeStackValue(FrameState state, int i) { + protected Value computeStackValue(FrameState state, int i) { return toValue(state.stackAt(i)); } - protected void computeLocks(FrameState state, JavaValue[] values) { + protected void computeLocks(FrameState state, Value[] values) { for (int i = 0; i < state.locksSize(); i++) { values[state.localsSize() + state.stackSize() + i] = computeLockValue(state, i); } } - protected JavaValue computeLockValue(FrameState state, int i) { + protected Value computeLockValue(FrameState state, int i) { return toValue(state.lockAt(i)); } @@ -186,7 +186,7 @@ private static final DebugMetric STATE_VARIABLES = Debug.metric("StateVariables"); private static final DebugMetric STATE_CONSTANTS = Debug.metric("StateConstants"); - protected JavaValue toValue(ValueNode value) { + protected Value toValue(ValueNode value) { try { if (value instanceof VirtualObjectNode) { VirtualObjectNode obj = (VirtualObjectNode) value; @@ -218,7 +218,7 @@ STATE_VARIABLES.increment(); Value operand = nodeOperands.get(value); assert operand != null && (operand instanceof Variable || operand instanceof JavaConstant) : operand + " for " + value; - return (JavaValue) operand; + return operand; } else { // return a dummy value because real value not needed diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Tue Mar 03 13:19:35 2015 +0100 @@ -32,6 +32,7 @@ private long[] bits; private int nodeCount; private final NodeIdAccessor nodeIdAccessor; + private int counter; public NodeBitMap(Graph graph) { nodeCount = graph.nodeIdCount(); @@ -43,6 +44,10 @@ return (nodeCount + Long.SIZE - 1) >> SHIFT; } + public int getCounter() { + return counter; + } + private NodeBitMap(NodeBitMap other) { this.bits = other.bits.clone(); this.nodeCount = other.nodeCount; @@ -63,6 +68,16 @@ return isMarked(id); } + public boolean checkAndMarkInc(Node node) { + if (!isMarked(node)) { + this.counter++; + this.mark(node); + return true; + } else { + return false; + } + } + public boolean isMarked(int id) { return (bits[id >> SHIFT] & (1L << id)) != 0; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Tue Mar 03 13:19:35 2015 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; -import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; /** @@ -46,25 +45,20 @@ } @Override - protected JavaValue computeLockValue(FrameState state, int lockIndex) { + protected Value computeLockValue(FrameState state, int lockIndex) { int lockDepth = lockIndex; if (state.outerFrameState() != null) { lockDepth += state.outerFrameState().nestedLockDepth(); } StackSlotValue slot = lockStack.makeLockSlot(lockDepth); ValueNode lock = state.lockAt(lockIndex); - JavaValue object = toValue(lock); + Value object = toValue(lock); boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null; assert state.monitorIdAt(lockIndex) == null || state.monitorIdAt(lockIndex).getLockDepth() == lockDepth; return new StackLockValue(object, slot, eliminated); } @Override - protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) { - return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge); - } - - @Override protected BytecodeFrame computeFrameForState(FrameState state) { assert state.bci >= 0 || state.bci == BytecodeFrame.BEFORE_BCI : state.bci; return super.computeFrameForState(state); diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Mon Mar 02 19:11:22 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013, 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.hotspot; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandMode; - -/** - * Extends {@link LIRFrameState} to handle {@link StackLockValue}s correctly. - */ -class HotSpotLIRFrameState extends LIRFrameState { - - public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) { - super(topFrame, virtualObjects, exceptionEdge); - } - - @Override - protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { - if (value instanceof StackLockValue) { - StackLockValue monitor = (StackLockValue) value; - if (monitor.getOwner() instanceof Value) { - Value owner = (Value) monitor.getOwner(); - if (processed(owner)) { - monitor.setOwner((JavaValue) proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); - } - } - Value slot = monitor.getSlot(); - if (isVirtualStackSlot(slot) && processed(slot)) { - monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); - } - return value; - } else { - return super.processValue(inst, proc, value); - } - } -} diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Tue Mar 03 13:19:35 2015 +0100 @@ -80,39 +80,51 @@ */ protected static final EnumSet STATE_FLAGS = EnumSet.of(OperandFlag.REG, OperandFlag.STACK); - protected void processValues(LIRInstruction inst, JavaValue[] values, InstructionValueProcedure proc) { + protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) { for (int i = 0; i < values.length; i++) { - if (values[i] instanceof Value) { - Value value = (Value) values[i]; - values[i] = (JavaValue) processValue(inst, proc, value); - } + Value value = values[i]; + values[i] = processValue(inst, proc, value); } } protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { - if (processed(value)) { - return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + if (value instanceof StackLockValue) { + StackLockValue monitor = (StackLockValue) value; + Value owner = monitor.getOwner(); + if (owner instanceof AllocatableValue) { + monitor.setOwner(proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); + } + Value slot = monitor.getSlot(); + if (isVirtualStackSlot(slot)) { + monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); + } + } else { + if (!isIllegal(value) && value instanceof AllocatableValue) { + return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + } else { + assert unprocessed(value); + } } return value; } - protected boolean processed(Value value) { + private boolean unprocessed(Value value) { if (isIllegal(value)) { // Ignore dead local variables. - return false; + return true; } else if (isConstant(value)) { // Ignore constants, the register allocator does not need to see them. - return false; + return true; } else if (isVirtualObject(value)) { assert Arrays.asList(virtualObjects).contains(value); - return false; + return true; } else { - return true; + return false; } } /** - * Called by the register allocator before {@link #markLocation} to initialize the frame state. + * Called by the register allocator before {@link #updateUnion} to initialize the frame state. * * @param frameMap The frame map. * @param canHaveRegisters True if there can be any register map entries. @@ -122,18 +134,6 @@ } /** - * Called by the register allocator to mark the specified location as a reference in the - * reference map of the debug information. The tracked location can be a {@link RegisterValue} - * or a {@link StackSlot}. Note that a {@link JavaConstant} is automatically tracked. - * - * @param location The location to be added to the reference map. - * @param frameMap The frame map. - */ - public void markLocation(Value location, FrameMap frameMap) { - frameMap.setReference(location, debugInfo.getReferenceMap()); - } - - /** * Updates this reference map with all references that are marked in {@code refMap}. */ public void updateUnion(ReferenceMap refMap) { diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -39,4 +39,12 @@ } public abstract double probability(AbstractBeginNode successor); + + /** + * Primary successor of the control split. Data dependencies on the node have to be scheduled in + * the primary successor. + * + * @return the primary successor + */ + public abstract AbstractBeginNode getPrimarySuccessor(); } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -1128,4 +1128,9 @@ return null; } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.trueSuccessor(); + } } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -232,4 +232,9 @@ updateUsagesInterface(this.guard, guard); this.guard = guard; } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.next(); + } } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Mar 03 13:19:35 2015 +0100 @@ -30,7 +30,6 @@ public final class Block extends AbstractBlockBase { - public static final int DISTANCED_DOMINATOR_CACHE = 5; protected final AbstractBeginNode beginNode; protected FixedNode endNode; @@ -177,28 +176,10 @@ this.probability = probability; } - public Block getDistancedDominatorCache() { - Block result = this.distancedDominatorCache; - if (result == null) { - Block current = this; - for (int i = 0; i < DISTANCED_DOMINATOR_CACHE; ++i) { - current = current.getDominator(); - } - distancedDominatorCache = current; - return current; - } else { - return result; - } - } - @Override public Block getDominator(int distance) { Block result = this; - int i = 0; - for (; i < distance - (DISTANCED_DOMINATOR_CACHE - 1); i += DISTANCED_DOMINATOR_CACHE) { - result = result.getDistancedDominatorCache(); - } - for (; i < distance; ++i) { + for (int i = 0; i < distance; ++i) { result = result.getDominator(); } return result; diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Mar 03 13:19:35 2015 +0100 @@ -78,6 +78,10 @@ return reversePostOrder.get(0); } + public Iterable reversePostOrder() { + return reversePostOrder; + } + public Iterable postOrder() { return new Iterable() { diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -32,13 +32,17 @@ public final class OpaqueNode extends FloatingNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(OpaqueNode.class); - @Input ValueNode value; + @Input protected ValueNode value; public OpaqueNode(ValueNode value) { super(TYPE, value.stamp().unrestricted()); this.value = value; } + public ValueNode getValue() { + return value; + } + @Override public void generate(NodeLIRBuilderTool gen) { gen.setResult(this, gen.operand(value)); diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -159,4 +159,9 @@ } return successors.get(defaultSuccessorIndex()); } + + @Override + public AbstractBeginNode getPrimarySuccessor() { + return this.defaultSuccessor(); + } } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 03 13:19:35 2015 +0100 @@ -42,7 +42,6 @@ import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; -import com.oracle.graal.phases.util.*; public final class SchedulePhase extends Phase { @@ -321,7 +320,7 @@ @Override protected void run(StructuredGraph graph) { - assert GraphOrder.assertNonCyclicGraph(graph); + // assert GraphOrder.assertNonCyclicGraph(graph); cfg = ControlFlowGraph.compute(graph, true, true, true, false); earliestCache = graph.createNodeMap(); blockToNodesMap = new BlockMap<>(cfg); @@ -330,6 +329,11 @@ blockToKillSet = new BlockMap<>(cfg); } + if (selectedStrategy == SchedulingStrategy.EARLIEST) { + scheduleEarliestIterative(blockToNodesMap, graph); + return; + } + assignBlockToNodes(graph, selectedStrategy); printSchedule("after assign nodes to blocks"); @@ -337,6 +341,146 @@ printSchedule("after sorting nodes within blocks"); } + private void scheduleEarliestIterative(BlockMap> blockToNodes, StructuredGraph graph) { + NodeMap nodeToBlock = graph.createNodeMap(); + NodeBitMap visited = graph.createNodeBitMap(); + + // Add begin nodes as the first entry and set the block for phi nodes. + for (Block b : cfg.getBlocks()) { + AbstractBeginNode beginNode = b.getBeginNode(); + ArrayList nodes = new ArrayList<>(); + nodeToBlock.set(beginNode, b); + nodes.add(beginNode); + blockToNodes.put(b, nodes); + + if (beginNode instanceof AbstractMergeNode) { + AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode; + for (PhiNode phi : mergeNode.phis()) { + nodeToBlock.set(phi, b); + } + } + } + + Stack stack = new Stack<>(); + + // Start analysis with control flow ends. + for (Block b : cfg.postOrder()) { + FixedNode endNode = b.getEndNode(); + stack.push(endNode); + nodeToBlock.set(endNode, b); + } + + processStack(blockToNodes, nodeToBlock, visited, stack); + + // Visit back input edges of loop phis. + for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) { + for (PhiNode phi : loopBegin.phis()) { + if (visited.isMarked(phi)) { + for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) { + Node node = phi.valueAt(i + loopBegin.forwardEndCount()); + if (!visited.isMarked(node)) { + stack.push(node); + processStack(blockToNodes, nodeToBlock, visited, stack); + } + } + } + } + } + + // Check for dead nodes. + if (visited.getCounter() < graph.getNodeCount()) { + for (Node n : graph.getNodes()) { + if (!visited.isMarked(n)) { + n.clearInputs(); + n.markDeleted(); + } + } + } + + // Add end nodes as the last nodes in each block. + for (Block b : cfg.getBlocks()) { + FixedNode endNode = b.getEndNode(); + if (endNode != b.getBeginNode()) { + addNode(blockToNodes, b, endNode); + } + } + + this.blockToNodesMap = blockToNodes; + } + + private static void addNode(BlockMap> blockToNodes, Block b, ValueNode endNode) { + assert !blockToNodes.get(b).contains(endNode) : endNode; + blockToNodes.get(b).add(endNode); + } + + private void processStack(BlockMap> blockToNodes, NodeMap nodeToBlock, NodeBitMap visited, Stack stack) { + Block startBlock = cfg.getStartBlock(); + while (!stack.isEmpty()) { + Node current = stack.peek(); + if (visited.checkAndMarkInc(current)) { + + // Push inputs and predecessor. + Node predecessor = current.predecessor(); + if (predecessor != null) { + stack.push(predecessor); + } + + if (current instanceof PhiNode) { + PhiNode phiNode = (PhiNode) current; + AbstractMergeNode merge = phiNode.merge(); + for (int i = 0; i < merge.forwardEndCount(); ++i) { + Node input = phiNode.valueAt(i); + stack.push(input); + } + } else { + for (Node input : current.inputs()) { + if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) { + // Ignore the cycle. + } else { + stack.push(input); + } + } + } + } else { + + stack.pop(); + + if (nodeToBlock.get(current) == null) { + Node predecessor = current.predecessor(); + Block curBlock; + if (predecessor != null) { + // Predecessor determines block. + curBlock = nodeToBlock.get(predecessor); + } else { + Block earliest = startBlock; + for (Node input : current.inputs()) { + if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) { + // ignore + } else { + Block inputEarliest; + if (input instanceof ControlSplitNode) { + inputEarliest = nodeToBlock.get(((ControlSplitNode) input).getPrimarySuccessor()); + } else { + inputEarliest = nodeToBlock.get(input); + } + assert inputEarliest != null : current + " / " + input; + if (earliest.getDominatorDepth() < inputEarliest.getDominatorDepth()) { + earliest = inputEarliest; + } + } + } + curBlock = earliest; + } + assert curBlock != null; + if (current instanceof ValueNode) { + addNode(blockToNodes, curBlock, (ValueNode) current); + } + nodeToBlock.set(current, curBlock); + } + } + } + } + private Block blockForMemoryNode(MemoryNode memory) { MemoryNode current = memory; while (current instanceof MemoryProxy) { @@ -982,25 +1126,8 @@ List sortedInstructions = state.getSortedInstructions(); Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1); if (lastSorted != b.getEndNode()) { - int idx = sortedInstructions.indexOf(b.getEndNode()); - boolean canNotMove = false; - for (int i = idx + 1; i < sortedInstructions.size(); i++) { - if (sortedInstructions.get(i).inputs().contains(b.getEndNode())) { - canNotMove = true; - break; - } - } - if (canNotMove) { - if (b.getEndNode() instanceof ControlSplitNode) { - throw new GraalGraphInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").addContext(lastSorted).addContext( - b.getEndNode()); - } - - // b.setLastNode(lastSorted); - } else { - sortedInstructions.remove(b.getEndNode()); - sortedInstructions.add(b.getEndNode()); - } + sortedInstructions.remove(b.getEndNode()); + sortedInstructions.add(b.getEndNode()); } return sortedInstructions; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Mar 03 13:19:35 2015 +0100 @@ -182,7 +182,7 @@ return sb.toString(); } - protected String valueToString(JavaValue value, List virtualObjects) { + protected String valueToString(Value value, List virtualObjects) { if (value == null) { return "-"; } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Mar 03 13:19:35 2015 +0100 @@ -259,6 +259,7 @@ memoryRead.setStateAfter(n.stateAfter()); ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead); + n.stateAfter().replaceFirstInput(n, memoryRead); n.replaceAtUsages(readValue); graph.replaceFixedWithFixed(n, memoryRead); } diff -r 96ab2078eeaf -r 87d5316e171b graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Mon Mar 02 19:11:22 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Tue Mar 03 13:19:35 2015 +0100 @@ -34,8 +34,8 @@ public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(IntegerExactArithmeticSplitNode.class); + @Successor AbstractBeginNode next; @Successor AbstractBeginNode overflowSuccessor; - @Successor AbstractBeginNode next; @Input ValueNode x; @Input ValueNode y; @@ -48,6 +48,11 @@ } @Override + public AbstractBeginNode getPrimarySuccessor() { + return next; + } + + @Override public double probability(AbstractBeginNode successor) { return successor == next ? 1 : 0; } diff -r 96ab2078eeaf -r 87d5316e171b src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Mar 02 19:11:22 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 03 13:19:35 2015 +0100 @@ -169,7 +169,7 @@ typeArrayOop_field(BitSet, words, "[J") \ end_class \ start_class(BytecodeFrame) \ - objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/JavaValue;") \ + objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/Value;") \ int_field(BytecodeFrame, numLocals) \ int_field(BytecodeFrame, numStack) \ int_field(BytecodeFrame, numLocks) \ @@ -241,10 +241,10 @@ start_class(VirtualObject) \ int_field(VirtualObject, id) \ oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ - objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/JavaValue;") \ + objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/Value;") \ end_class \ - start_class(StackLockValue) \ - oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;") \ + start_class(StackLockValue) \ + oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/Value;") \ oop_field(StackLockValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;") \ boolean_field(StackLockValue, eliminated) \ end_class \ diff -r 96ab2078eeaf -r 87d5316e171b src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon Mar 02 19:11:22 2015 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Tue Mar 03 13:19:35 2015 +0100 @@ -1405,6 +1405,7 @@ ScopeDesc* trap_scope = cvf->scope(); if (TraceDeoptimization) { + ttyLocker ttyl; tty->print_cr(" bci=%d pc=" INTPTR_FORMAT ", relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string() #ifdef GRAAL , debug_id