Mercurial > hg > graal-jvmci-8
changeset 5209:7378314d3e06
Merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Fri, 06 Apr 2012 17:58:00 +0200 |
parents | ae5504e366df (diff) 887b45f6aa02 (current diff) |
children | e3e7542d78b7 |
files | |
diffstat | 23 files changed, 531 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Apr 06 17:58:00 2012 +0200 @@ -128,46 +128,38 @@ new PhiStampPhase().apply(graph); + if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) { + new ComputeProbabilityPhase().apply(graph); + } + + if (GraalOptions.PropagateTypes) { + new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph); + } + if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase(target, runtime, assumptions).apply(graph); } - if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) { - new ComputeProbabilityPhase().apply(graph); - } - if (GraalOptions.Intrinsify) { new IntrinsificationPhase(runtime).apply(graph); } - if (GraalOptions.PropagateTypes) { - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions).apply(graph); - } - - new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph); - } - if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { new InliningPhase(target, runtime, null, assumptions, cache, plan, optimisticOpts).apply(graph); new DeadCodeEliminationPhase().apply(graph); new PhiStampPhase().apply(graph); - } + if (GraalOptions.PropagateTypes) { + new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph); + } - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + } } - if (GraalOptions.PropagateTypes) { - new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph); - } plan.runPhases(PhasePosition.HIGH_LEVEL, graph); - if (GraalOptions.OptLoops) { - new SafepointPollingEliminationPhase().apply(graph); - } - if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) { new EscapeAnalysisPhase(target, runtime, assumptions, cache, plan, optimisticOpts).apply(graph); new PhiStampPhase().apply(graph); @@ -175,7 +167,9 @@ new CanonicalizerPhase(target, runtime, assumptions).apply(graph); } } - + if (GraalOptions.OptLoops) { + new SafepointPollingEliminationPhase().apply(graph); + } if (GraalOptions.OptGVN) { new GlobalValueNumberingPhase().apply(graph); } @@ -197,6 +191,9 @@ if (GraalOptions.PropagateTypes) { new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph); } + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); + } if (GraalOptions.OptGVN) { new GlobalValueNumberingPhase().apply(graph); }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Fri Apr 06 17:58:00 2012 +0200 @@ -143,6 +143,7 @@ public static boolean PrintAssembly = ____; public static boolean PrintCodeBytes = ____; public static int PrintAssemblyBytesPerLine = 16; + public static boolean PrintBailout = ____; public static int TraceLinearScanLevel = 0; public static boolean TraceRegisterAllocation = false; public static int TraceLIRGeneratorLevel = 0;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Apr 06 17:58:00 2012 +0200 @@ -860,7 +860,7 @@ for (int operandNum = 0; operandNum < blockData.get(ir.cfg.getStartBlock()).liveIn.size(); operandNum++) { if (blockData.get(ir.cfg.getStartBlock()).liveIn.get(operandNum)) { CiValue operand = operandFor(operandNum); - TTY.println(" var %d; operand=%s", operandNum, operand.toString()); + TTY.println(" var %d; operand=%s; node=%s", operandNum, operand.toString(), gen.valueForOperand(operand)); for (int j = 0; j < numBlocks; j++) { Block block = blockAt(j);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Fri Apr 06 17:58:00 2012 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.virtual.*; public class DebugInfoBuilder { @@ -54,7 +55,13 @@ FrameState current = topState; do { for (Node n : current.virtualObjectMappings()) { - VirtualObjectFieldNode field = (VirtualObjectFieldNode) n; + Node p = n; + while (p instanceof PhiNode) { + PhiNode phi = (PhiNode) p; + assert phi.type() == PhiType.Virtual; + p = phi.valueAt(0); + } + VirtualObjectFieldNode field = (VirtualObjectFieldNode) p; // null states occur for objects with 0 fields if (field != null && !objectStates.containsKey(field.object())) { objectStates.put(field.object(), field);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Apr 06 17:58:00 2012 +0200 @@ -27,6 +27,7 @@ import static com.oracle.max.cri.ci.CiValue.*; import java.util.*; +import java.util.Map.Entry; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.util.*; @@ -173,6 +174,15 @@ return nodeOperands.get(node); } + public ValueNode valueForOperand(CiValue value) { + for (Entry<Node, CiValue> entry : nodeOperands.entries()) { + if (entry.getValue() == value) { + return (ValueNode) entry.getKey(); + } + } + return null; + } + /** * Creates a new {@linkplain Variable variable}. * @param kind The kind of the new variable.
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Fri Apr 06 17:58:00 2012 +0200 @@ -130,8 +130,12 @@ @Override public void loopEnds(LoopBeginNode loopBegin, List<BlockExitState> loopEndStates) { - while (!(virtualObjectField instanceof PhiNode)) { - virtualObjectField = ((VirtualObjectFieldNode) virtualObjectField).lastState(); + while (!loopBegin.isPhiAtMerge(virtualObjectField)) { + if (virtualObjectField instanceof PhiNode) { + virtualObjectField = ((PhiNode) virtualObjectField).valueAt(0); + } else { + virtualObjectField = ((VirtualObjectFieldNode) virtualObjectField).lastState(); + } } for (BlockExitState loopEndState : loopEndStates) { ((PhiNode) virtualObjectField).addInput(loopEndState.virtualObjectField); @@ -195,7 +199,17 @@ } if (!curNode.isDeleted() && curNode instanceof StateSplit && ((StateSplit) curNode).stateAfter() != null) { if (state.virtualObjectField != null) { - ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(state.virtualObjectField); + ValueNode v = state.virtualObjectField; + if (curNode instanceof LoopBeginNode) { + while (!((LoopBeginNode) curNode).isPhiAtMerge(v)) { + if (v instanceof PhiNode) { + v = ((PhiNode) v).valueAt(0); + } else { + v = ((VirtualObjectFieldNode) v).lastState(); + } + } + } + ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(v); } } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Apr 06 17:58:00 2012 +0200 @@ -132,8 +132,12 @@ } catch (CiBailout bailout) { Debug.metric("Bailouts").increment(); if (GraalOptions.ExitVMOnBailout) { + TTY.cachedOut.println(CiUtil.format("%H.%n(%p)", method)); bailout.printStackTrace(TTY.cachedOut); System.exit(-1); + } else if (GraalOptions.PrintBailout) { + TTY.cachedOut.println(CiUtil.format("%H.%n(%p)", method)); + bailout.printStackTrace(TTY.cachedOut); } } catch (Throwable t) { if (GraalOptions.ExitVMOnException) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop15.java Fri Apr 06 17:58:00 2012 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 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.jtt.loop; + +import org.junit.*; + +public class Loop15 { + + public static int test(int arg) { + Object o = null; + int result = 10; + for (int k = 0; k < arg; ++k) { + if (o == null) { + o = new Object(); + } + if (k >= 5) { + break; + } + result++; + } + return result + (o == null ? 0 : 1); + } + + @Test + public void run0() throws Throwable { + Assert.assertEquals(16, test(5)); + } + + @Test + public void run1() throws Throwable { + Assert.assertEquals(10, test(0)); + } + + @Test + public void run2() throws Throwable { + Assert.assertEquals(12, test(1)); + } + + @Test + public void run3() throws Throwable { + Assert.assertEquals(16, test(10)); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop16.java Fri Apr 06 17:58:00 2012 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, 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. + */ +// Checkstyle: stop +package com.oracle.graal.jtt.loop; + +import org.junit.*; + +/* + * Tests exiting 2 loops at the same time with escape-analysed values flowing out of loops + */ +public class Loop16 { + + public int a; + public int b; + public int c; + + public static int test(int count) { + return new Loop16().run(count); + } + + public int run(int count) { + l1: for (int i = 0; i <= count; i++) { + if (i > 5) { + for (int j = 0; j < i; j++) { + a += i; + if (a > 500) { + break l1; + } + } + } else if (i > 7) { + b += i; + } else { + c += i; + } + } + return a + b + c; + } + + @Test + public void run0() throws Throwable { + Assert.assertEquals(526, test(40)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop17.java Fri Apr 06 17:58:00 2012 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2007, 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. + */ +// Checkstyle: stop +package com.oracle.graal.jtt.loop; + +import org.junit.*; + +/* + * Test around an object that escapes directly from inside a loop (no virtual phi on the loop) + */ +public class Loop17 { + + private static class L { + public int a; + public int b; + public int c; + public L(int a, int b, int c) { + this.a = a; + this.b = b; + this.c = c; + } + } + + + public static int test(int count) { + int i = 0; + L l; + do { + l = new L(i, i+1, i+2); + } while (++i < count); + + return l.a + l.b * 10 + l.c * 100; + } + + @Test + public void run0() throws Throwable { + Assert.assertEquals(543, test(new L(4,4,4).a)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopLastIndexOf.java Fri Apr 06 17:58:00 2012 +0200 @@ -0,0 +1,100 @@ +/* + * 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.jtt.loop; + +import org.junit.*; + +/* + * see java.lang.String.lastIndexOf(char[], int, int, char[], int ,int, int) + */ +public class LoopLastIndexOf { + + private final char[] v1 = new char[]{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + private final char[] v2 = new char[]{'d', 'a'}; + private final char[] v3 = new char[]{'d', 'b', 'c'}; + private final char[] v4 = new char[]{'z', 'a', 'b', 'c'}; + + public static int test(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { + int rightIndex = sourceCount - targetCount; + if (fromIndex < 0) { + return -1; + } + if (fromIndex > rightIndex) { + fromIndex = rightIndex; + } + /* Empty string always matches. */ + if (targetCount == 0) { + return fromIndex; + } + + int strLastIndex = targetOffset + targetCount - 1; + char strLastChar = target[strLastIndex]; + int min = sourceOffset + targetCount - 1; + int i = min + fromIndex; + + startSearchForLastChar: while (true) { + while (i >= min && source[i] != strLastChar) { + i--; + } + if (i < min) { + return -1; + } + int j = i - 1; + int start = j - (targetCount - 1); + int k = strLastIndex - 1; + + while (j > start) { + if (source[j--] != target[k--]) { + i--; + continue startSearchForLastChar; + } + } + return start - sourceOffset + 1; + } + } + + @Test + public void run0() throws Throwable { + Assert.assertEquals(7, test(v1, 0, v1.length, v2, 0, v2.length, 10)); + } + + @Test + public void run1() throws Throwable { + Assert.assertEquals(-1, test(v1, 0, v1.length, v3, 0, v3.length, 10)); + } + + @Test + public void run2() throws Throwable { + Assert.assertEquals(-1, test(v1, 0, v1.length, v4, 0, v4.length, 10)); + } + + @Test + public void run3() throws Throwable { + Assert.assertEquals(-1, test(v1, 1, v1.length - 1, v3, 0, v3.length, 10)); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void run4() throws Throwable { + Assert.assertEquals(-1, test(v1, 1, v1.length, v3, 0, v3.length, 10)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopParseLong.java Fri Apr 06 17:58:00 2012 +0200 @@ -0,0 +1,86 @@ +/* + * 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.jtt.loop; + +import org.junit.*; + +public class LoopParseLong { + + public static long test(String s, int radix) throws NumberFormatException { + if (s == null) { + throw new NumberFormatException("null"); + } + if (radix < Character.MIN_RADIX) { + throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); + } + if (radix > Character.MAX_RADIX) { + throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); + } + long result = 0; + boolean negative = false; + int i = 0; + int len = s.length(); + long limit = -Long.MAX_VALUE; + long multmin; + int digit; + if (len > 0) { + char firstChar = s.charAt(0); + if (firstChar < '0') { + if (firstChar == '-') { + negative = true; + limit = Long.MIN_VALUE; + } else if (firstChar != '+') { + throw new NumberFormatException(); + } + if (len == 1) { + throw new NumberFormatException(); + } + i++; + } + multmin = limit / radix; + while (i < len) { + digit = Character.digit(s.charAt(i++), radix); + if (digit < 0) { + throw new NumberFormatException(); + } + if (result < multmin) { + throw new NumberFormatException(); + } + result *= radix; + if (result < limit + digit) { + throw new NumberFormatException(); + } + result -= digit; + } + } else { + throw new NumberFormatException(); + } + return negative ? result : -result; + } + + @Test + public void run0() throws Throwable { + Assert.assertEquals(Character.digit('7', 10), test("7", 10)); + Assert.assertEquals(-100, test("-100", 10)); + } +}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/CFGVerifier.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/CFGVerifier.java Fri Apr 06 17:58:00 2012 +0200 @@ -46,7 +46,7 @@ assert dominated.getDominator() == block; } - assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block; + assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block : block.beginNode; } if (cfg.getLoops() != null) { @@ -58,8 +58,16 @@ Loop blockLoop = block.getLoop(); while (blockLoop != loop) { + assert blockLoop != null; blockLoop = blockLoop.parent; - assert blockLoop != null; + } + + if (!(block.isLoopHeader() && block.getLoop() == loop)) { + for (Block pred : block.getPredecessors()) { + if (!loop.blocks.contains(pred)) { + return false; + } + } } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -73,17 +73,27 @@ } } - public void evacuateGuards() { + public void evacuateGuards(FixedNode evacuateFrom) { if (!usages().isEmpty()) { - Node prevBegin = predecessor(); + Node prevBegin = evacuateFrom; assert prevBegin != null; while (!(prevBegin instanceof BeginNode)) { prevBegin = prevBegin.predecessor(); } - replaceAtUsages(prevBegin); + for (Node anchored : anchored().snapshot()) { + anchored.replaceFirstInput(this, prevBegin); + } } } + public void prepareDelete() { + prepareDelete((FixedNode) predecessor()); + } + + public void prepareDelete(FixedNode evacuateFrom) { + evacuateGuards(evacuateFrom); + } + @Override public boolean verify() { assertTrue(predecessor() != null || this == ((StructuredGraph) graph()).start() || this instanceof MergeNode, "begin nodes must be connected"); @@ -98,4 +108,8 @@ public NodeIterable<GuardNode> guards() { return usages().filter(GuardNode.class); } + + public NodeIterable<Node> anchored() { + return usages(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -161,14 +161,16 @@ EndNode falseEnd = (EndNode) falseSuccessor.next(); assert trueEnd.merge() == falseEnd.merge(); + FixedWithNextNode pred = (FixedWithNextNode) predecessor(); MergeNode merge = trueEnd.merge(); + merge.prepareDelete(pred); assert merge.usages().isEmpty(); FixedNode next = merge.next(); merge.setNext(null); setTrueSuccessor(null); setFalseSuccessor(null); - ((FixedWithNextNode) predecessor()).setNext(next); + pred.setNext(next); safeDelete(); trueSuccessor.safeDelete(); falseSuccessor.safeDelete();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.graph.iterators.NodePredicates.*; + import java.util.*; import com.oracle.graal.graph.*; @@ -49,8 +51,13 @@ return usages().filter(LoopEndNode.class); } + @Override + public NodeIterable<Node> anchored() { + return super.anchored().filter(isNotA(LoopEndNode.class)); + } + public List<LoopEndNode> orderedLoopEnds() { - List<LoopEndNode> snapshot = usages().filter(LoopEndNode.class).snapshot(); + List<LoopEndNode> snapshot = loopEnds().snapshot(); Collections.sort(snapshot, new Comparator<LoopEndNode>() { @Override public int compare(LoopEndNode o1, LoopEndNode o2) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.util.*; /** * Denotes the merging of multiple control-flow paths. @@ -115,12 +116,22 @@ } public NodeIterable<PhiNode> phis() { - return this.usages().filter(new NodePredicate() { + return this.usages().filter(PhiNode.class).filter(new NodePredicate() { @Override public boolean apply(Node n) { - return n instanceof PhiNode && ((PhiNode) n).merge() == MergeNode.this; + return ((PhiNode) n).merge() == MergeNode.this; } - }).filter(PhiNode.class); + }); + } + + @Override + public NodeIterable<Node> anchored() { + return super.anchored().filter(isNotA(PhiNode.class).or(new NodePredicate() { + @Override + public boolean apply(Node n) { + return ((PhiNode) n).merge() != MergeNode.this; + } + })); } @Override @@ -136,7 +147,9 @@ } } } - Debug.log("Split %s into loop ends for %s", this, begin); + FixedNode evacuateAnchoredTo = new ComputeImmediateDominator(this).compute(); + Debug.log("Split %s into loop ends for %s. Evacuate to %s", this, begin, evacuateAnchoredTo); + this.prepareDelete(evacuateAnchoredTo); int numEnds = this.forwardEndCount(); StructuredGraph graph = (StructuredGraph) graph(); for (int i = 0; i < numEnds - 1; i++) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -33,22 +33,15 @@ * and a variable. */ public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType { - - @Input(notDataflow = true) private MergeNode merge; - - @Input private final NodeInputList<ValueNode> values = new NodeInputList<>(this); - - public MergeNode merge() { - return merge; - } - public static enum PhiType { Value, // normal value phis Memory, // memory phis Virtual // phis used for VirtualObjectField merges } - private final PhiType type; + @Input(notDataflow = true) private MergeNode merge; + @Input private final NodeInputList<ValueNode> values = new NodeInputList<>(this); + @Data private final PhiType type; public PhiNode(CiKind kind, MergeNode merge, PhiType type) { super(StampFactory.forKind(kind)); @@ -60,6 +53,10 @@ return type; } + public MergeNode merge() { + return merge; + } + public NodeInputList<ValueNode> values() { return values; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Apr 06 17:58:00 2012 +0200 @@ -168,6 +168,9 @@ public void removeFixed(FixedWithNextNode node) { assert node != null; + if (node instanceof BeginNode) { + ((BeginNode) node).prepareDelete(); + } assert node.usages().isEmpty() : node + " " + node.usages(); FixedNode next = node.next(); node.setNext(null); @@ -208,15 +211,11 @@ assert node.usages().isEmpty(); assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(next); + node.replaceAtPredecessors(begin); node.safeDelete(); - begin.safeDelete(); } public void removeSplitPropagate(ControlSplitNode node, int survivingSuccessor) { @@ -224,9 +223,6 @@ assert node.usages().isEmpty(); assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { BeginNode successor = node.blockSuccessor(i); node.setBlockSuccessor(i, null); @@ -234,10 +230,9 @@ GraphUtil.killCFG(successor); } } - if (next.isAlive()) { - node.replaceAtPredecessors(next); + if (begin.isAlive()) { + node.replaceAtPredecessors(begin); node.safeDelete(); - begin.safeDelete(); } else { assert node.isDeleted(); } @@ -257,31 +252,23 @@ assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - replacement.setNext(next); + replacement.setNext(begin); node.replaceAndDelete(replacement); - begin.safeDelete(); } public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, int survivingSuccessor) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node; BeginNode begin = node.blockSuccessor(survivingSuccessor); - begin.evacuateGuards(); - FixedNode next = begin.next(); - begin.setNext(null); for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(next); + node.replaceAtPredecessors(begin); node.replaceAtUsages(replacement); node.safeDelete(); - begin.safeDelete(); } public void addAfterFixed(FixedWithNextNode node, FixedWithNextNode newNode) { @@ -326,13 +313,7 @@ FixedNode sux = merge.next(); FrameState stateAfter = merge.stateAfter(); // evacuateGuards - Node prevBegin = singleEnd.predecessor(); - assert prevBegin != null; - while (!(prevBegin instanceof BeginNode)) { - prevBegin = prevBegin.predecessor(); - } - merge.replaceAtUsages(prevBegin); - + merge.prepareDelete((FixedNode) singleEnd.predecessor()); merge.safeDelete(); if (stateAfter != null && stateAfter.usages().isEmpty()) { stateAfter.safeDelete();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -52,7 +52,7 @@ return x(); } if (c == 0) { - return ConstantNode.forInt(0, graph()); + return ConstantNode.defaultForKind(kind(), graph()); } if (c > 0 && CiUtil.isPowerOf2(c)) { return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CiUtil.log2(c), graph())));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -36,6 +36,8 @@ @Input private ValueNode index; @Input private ValueNode length; + @Data private final CiKind elementType; + private final long leafGraphId; public ValueNode index() { return index; @@ -45,9 +47,6 @@ return length; } - private final CiKind elementType; - private final long leafGraphId; - /** * Create an new AccessIndexedNode. * @param kind the result kind of the access
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Apr 06 17:58:00 2012 +0200 @@ -27,8 +27,10 @@ import java.util.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.virtual.*; public class GraphUtil { @@ -40,7 +42,11 @@ killEnd(end); } else { // Normal control flow node. - for (Node successor : node.successors().snapshot()) { + /* We do not take a successor snapshot because this iterator supports concurrent modifications + * as long as they do not change the size of the successor list. Not tasking a snapshot allows + * us to see modifications to other branches that may happen while processing one branch. + */ + for (Node successor : node.successors()) { killCFG((FixedNode) successor); } } @@ -50,6 +56,7 @@ private static void killEnd(EndNode end) { MergeNode merge = end.merge(); merge.removeEnd(end); + StructuredGraph graph = (StructuredGraph) end.graph(); if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { //dead loop for (PhiNode phi : merge.phis().snapshot()) { propagateKill(phi); @@ -63,15 +70,19 @@ killCFG(begin.next()); begin.safeDelete(); } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not a loop anymore - ((StructuredGraph) end.graph()).reduceDegenerateLoopBegin((LoopBeginNode) merge); + graph.reduceDegenerateLoopBegin((LoopBeginNode) merge); } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore - ((StructuredGraph) end.graph()).reduceTrivialMerge(merge); + graph.reduceTrivialMerge(merge); } } + public static NodePredicate isFloatingNode() { + return isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class).or(VirtualObjectFieldNode.class).or(VirtualObjectNode.class); + } + public static void propagateKill(Node node) { if (node != null && node.isAlive()) { - List<Node> usagesSnapshot = node.usages().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot(); + List<Node> usagesSnapshot = node.usages().filter(isFloatingNode()).snapshot(); // null out remaining usages node.replaceAtUsages(null); @@ -91,7 +102,7 @@ } public static void killUnusedFloatingInputs(Node node) { - List<Node> floatingInputs = node.inputs().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot(); + List<Node> floatingInputs = node.inputs().filter(isFloatingNode()).snapshot(); node.safeDelete(); for (Node in : floatingInputs) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectFieldNode.java Fri Apr 06 17:24:47 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectFieldNode.java Fri Apr 06 17:58:00 2012 +0200 @@ -66,6 +66,13 @@ } @Override + public boolean verify() { + assertTrue(object != null, "No object"); + assertTrue(input != null, "No input"); + return super.verify(); + } + + @Override public Map<Object, Object> getDebugProperties() { Map<Object, Object> properties = super.getDebugProperties(); properties.put("index", index); @@ -74,7 +81,7 @@ @Override public String toString(Verbosity verbosity) { - if (verbosity == Verbosity.Name && object().fields() != null) { + if (verbosity == Verbosity.Name && object() != null && object().fields() != null) { return super.toString(Verbosity.Name) + " " + object().fields()[index].name(); } else { return super.toString(verbosity);