# HG changeset patch # User Doug Simon # Date 1334869073 -7200 # Node ID 38feba3e8526138b5d97671890fee50bd99f8d55 # Parent 9c2b6cc9de45f454c6ce336cfbf1a0a6d8ae55b1 separated safepoints out of LoopEndNodes into SafepointNodes diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SafepointPollingEliminationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SafepointPollingEliminationPhase.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SafepointPollingEliminationPhase.java Thu Apr 19 22:57:53 2012 +0200 @@ -26,16 +26,23 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.util.*; +/** + * Removes safepoints from loops that include calls. + * This optimization is conservative; it does not try to remove safepoints from outer loops. + */ public class SafepointPollingEliminationPhase extends Phase { @Override protected void run(StructuredGraph graph) { - for (LoopEndNode loopEnd : graph.getNodes(LoopEndNode.class)) { - NodeIterable it = NodeIterators.dominators(loopEnd).until(loopEnd.loopBegin()); - for (FixedNode n : it) { - if (n instanceof Invoke) { - loopEnd.setSafepointPolling(false); - break; + for (SafepointNode safepoint : graph.getNodes(SafepointNode.class)) { + LoopEndNode loopEnd = safepoint.loopEnd(); + if (loopEnd != null) { + NodeIterable it = NodeIterators.dominators(loopEnd).until(loopEnd.loopBegin()); + for (FixedNode n : it) { + if (n instanceof Invoke) { + graph.removeFixed(safepoint); + break; + } } } } diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java Thu Apr 19 22:57:53 2012 +0200 @@ -59,15 +59,13 @@ @Override public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) { return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir) { + @Override - public void visitLoopEnd(LoopEndNode x) { - if (GraalOptions.GenLoopSafepoints && x.hasSafepointPolling()) { - LIRDebugInfo info = state(); - if (!info.topFrame.method.noSafepointPolls()) { - append(new AMD64SafepointOp(info, ((HotSpotRuntime) runtime).config)); - } - } + public void visitSafepointNode(SafepointNode i) { + LIRDebugInfo info = state(); + append(new AMD64SafepointOp(info, ((HotSpotRuntime) runtime).config)); } + @Override public void visitExceptionObject(ExceptionObjectNode x) { HotSpotVMConfig config = ((HotSpotRuntime) runtime).config; @@ -181,10 +179,10 @@ // Emit the prefix tasm.recordMark(MARK_OSR_ENTRY); - tasm.recordMark(MARK_UNVERIFIED_ENTRY); boolean isStatic = Modifier.isStatic(method.accessFlags()); if (!isStatic) { + tasm.recordMark(MARK_UNVERIFIED_ENTRY); CiCallingConvention cc = regConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false); CiRegister inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp CiRegister receiver = asRegister(cc.locations[0]); diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Apr 19 22:57:53 2012 +0200 @@ -194,6 +194,14 @@ currentGraph.removeFixed(n); } + // Add safepoints to loop ends + if (GraalOptions.GenLoopSafepoints) { + for (LoopEndNode loopEnd : currentGraph.getNodes(LoopEndNode.class)) { + SafepointNode safepoint = currentGraph.add(new SafepointNode(loopEnd)); + currentGraph.addBeforeFixed(loopEnd, safepoint); + } + } + // remove dead FrameStates for (Node n : currentGraph.getNodes(FrameState.class)) { if (n.usages().size() == 0 && n.predecessor() == null) { @@ -1210,7 +1218,7 @@ } } - private Target checkLoopExit(FixedNode traget, Block targetBlock, FrameStateBuilder state) { + private Target checkLoopExit(FixedNode target, Block targetBlock, FrameStateBuilder state) { if (currentBlock != null) { long exits = currentBlock.loops & ~targetBlock.loops; if (exits != 0) { @@ -1250,16 +1258,16 @@ firstLoopExit = loopExit; } lastLoopExit = loopExit; - Debug.log("Traget %s (%s) Exits %s, scanning framestates...", targetBlock, traget, loop); + Debug.log("Target %s (%s) Exits %s, scanning framestates...", targetBlock, target, loop); newState.insertProxies(loopExit, loop.entryState); loopExit.setStateAfter(newState.create(bci)); } - lastLoopExit.setNext(traget); + lastLoopExit.setNext(target); return new Target(firstLoopExit, newState); } } - return new Target(traget, state); + return new Target(target, state); } private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Thu Apr 19 22:57:53 2012 +0200 @@ -31,13 +31,11 @@ public final class LoopEndNode extends EndNode { @Input(notDataflow = true) private LoopBeginNode loopBegin; - @Data private boolean safepointPolling; @Data private int endIndex; public LoopEndNode(LoopBeginNode begin) { int idx = begin.nextEndIndex(); assert idx >= 0; - this.safepointPolling = true; this.endIndex = idx; this.loopBegin = begin; } @@ -56,15 +54,6 @@ this.loopBegin = x; } - - public void setSafepointPolling(boolean safePointPolling) { - this.safepointPolling = safePointPolling; - } - - public boolean hasSafepointPolling() { - return safepointPolling; - } - @Override public void generate(LIRGeneratorTool gen) { gen.visitLoopEnd(this); diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Thu Apr 19 22:57:53 2012 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Marks a position in the graph where a safepoint should be emitted. + */ +public final class SafepointNode extends FixedWithNextNode implements LIRLowerable, Node.IterableNodeType { + + /** + * Will be null if this safepoint is not associated with a loop end. + */ + @Data private final LoopEndNode loopEnd; + + public SafepointNode(LoopEndNode loopEnd) { + super(StampFactory.illegal()); + this.loopEnd = loopEnd; + } + + + @Override + public void generate(LIRGeneratorTool gen) { + gen.visitSafepointNode(this); + } + + /** + * Gets the loop end (if any) associated with this safepoint. + */ + public LoopEndNode loopEnd() { + return loopEnd; + } +} diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Apr 19 22:57:53 2012 +0200 @@ -97,6 +97,7 @@ public abstract void visitMerge(MergeNode i); public abstract void visitEndNode(EndNode i); public abstract void visitLoopEnd(LoopEndNode i); + public abstract void visitSafepointNode(SafepointNode i); public abstract void visitCompareAndSwap(CompareAndSwapNode i); diff -r 9c2b6cc9de45 -r 38feba3e8526 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Thu Apr 19 22:45:50 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Thu Apr 19 22:57:53 2012 +0200 @@ -25,8 +25,6 @@ import java.lang.reflect.*; import java.util.concurrent.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.compiler.util.*; @@ -37,6 +35,8 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; /** * Utilities for snippet installation and management. @@ -126,10 +126,11 @@ new CanonicalizerPhase(target, runtime, null).apply(graph); } - // TODO (gdub) remove when we have good safepoint polling elimination - for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { - end.setSafepointPolling(false); + // Snippets must have no safepoints + for (SafepointNode s : graph.getNodes(SafepointNode.class)) { + graph.removeFixed(s); } + new InsertStateAfterPlaceholderPhase().apply(graph); Debug.dump(graph, "%s: Final", snippetRiMethod.name());