# HG changeset patch # User Thomas Wuerthinger # Date 1357666211 -3600 # Node ID c41c58f93f7551e1198a96475f52d756e4e4f5c4 # Parent 570d8e4c6dfbcb9805364f0f3866099ec8f21b12# Parent 91b52ccdb8b7c7d16201b978bd58b1e9ee6af867 Merge. diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Jan 08 18:30:11 2013 +0100 @@ -702,6 +702,8 @@ newObjectSnippets.lower((InitializeArrayNode) n, tool); } else if (n instanceof NewMultiArrayNode) { newObjectSnippets.lower((NewMultiArrayNode) n, tool); + } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { + // Nothing to do for division nodes. The HotSpot signal handler catches divisions by zero and the MIN_VALUE / -1 cases. } else { assert false : "Node implementing Lowerable not handled: " + n; throw GraalInternalError.shouldNotReachHere(); diff -r 570d8e4c6dfb -r c41c58f93f75 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 Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Jan 08 18:30:11 2013 +0100 @@ -409,7 +409,7 @@ } - private void genArithmeticOp(Kind result, int opcode, boolean canTrap) { + private void genArithmeticOp(Kind result, int opcode) { ValueNode y = frameState.pop(result); ValueNode x = frameState.pop(result); boolean isStrictFP = isStrict(method.getModifiers()); @@ -427,21 +427,30 @@ case LMUL: v = new IntegerMulNode(result, x, y); break; case FMUL: case DMUL: v = new FloatMulNode(result, x, y, isStrictFP); break; - case IDIV: - case LDIV: v = new IntegerDivNode(result, x, y); break; case FDIV: case DDIV: v = new FloatDivNode(result, x, y, isStrictFP); break; - case IREM: - case LREM: v = new IntegerRemNode(result, x, y); break; case FREM: case DREM: v = new FloatRemNode(result, x, y, isStrictFP); break; default: throw new GraalInternalError("should not reach"); } ValueNode result1 = append(currentGraph.unique(v)); - if (canTrap) { - append(currentGraph.add(new ValueAnchorNode(result1))); + frameState.push(result, result1); + } + + private void genIntegerDivOp(Kind result, int opcode) { + ValueNode y = frameState.pop(result); + ValueNode x = frameState.pop(result); + FixedWithNextNode v; + switch(opcode){ + case IDIV: + case LDIV: v = new IntegerDivNode(result, x, y); break; + case IREM: + case LREM: v = new IntegerRemNode(result, x, y); break; + default: + throw new GraalInternalError("should not reach"); } + ValueNode result1 = append(currentGraph.add(v)); frameState.push(result, result1); } @@ -1680,24 +1689,24 @@ case SWAP : stackOp(opcode); break; case IADD : // fall through case ISUB : // fall through - case IMUL : genArithmeticOp(Kind.Int, opcode, false); break; + case IMUL : genArithmeticOp(Kind.Int, opcode); break; case IDIV : // fall through - case IREM : genArithmeticOp(Kind.Int, opcode, true); break; + case IREM : genIntegerDivOp(Kind.Int, opcode); break; case LADD : // fall through case LSUB : // fall through - case LMUL : genArithmeticOp(Kind.Long, opcode, false); break; + case LMUL : genArithmeticOp(Kind.Long, opcode); break; case LDIV : // fall through - case LREM : genArithmeticOp(Kind.Long, opcode, true); break; + case LREM : genIntegerDivOp(Kind.Long, opcode); break; case FADD : // fall through case FSUB : // fall through case FMUL : // fall through case FDIV : // fall through - case FREM : genArithmeticOp(Kind.Float, opcode, false); break; + case FREM : genArithmeticOp(Kind.Float, opcode); break; case DADD : // fall through case DSUB : // fall through case DMUL : // fall through case DDIV : // fall through - case DREM : genArithmeticOp(Kind.Double, opcode, false); break; + case DREM : genArithmeticOp(Kind.Double, opcode); break; case INEG : genNegateOp(Kind.Int); break; case LNEG : genNegateOp(Kind.Long); break; case FNEG : genNegateOp(Kind.Float); break; diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Tue Jan 08 18:30:11 2013 +0100 @@ -319,22 +319,9 @@ case LDIV: case LREM: - Label continuation = new Label(); - if (opcode == LDIV) { - // check for special case of Long.MIN_VALUE / -1 - Label normalCase = new Label(); - masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE); - masm.cmpq(AMD64.rax, AMD64.rdx); - masm.jcc(ConditionFlag.notEqual, normalCase); - masm.cmpq(asRegister(src), -1); - masm.jcc(ConditionFlag.equal, continuation); - masm.bind(normalCase); - } - masm.cdqq(); exceptionOffset = masm.codeBuffer.position(); masm.idivq(asRegister(src)); - masm.bind(continuation); break; case IUDIV: diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Tue Jan 08 18:30:11 2013 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.loop; -import com.oracle.graal.loop.InductionVariable.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.loop.InductionVariable.Direction; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; public class CountedLoopInfo { private final LoopEx loop; @@ -41,7 +41,8 @@ public ValueNode maxTripCountNode() { //TODO (gd) stuarte and respect oneOff - return IntegerArithmeticNode.div(IntegerArithmeticNode.sub(end, iv.initNode()), iv.strideNode()); + throw GraalInternalError.unimplemented("division is a fixed node that needs to be inserted into the control flow"); + // return IntegerArithmeticNode.div(IntegerArithmeticNode.sub(end, iv.initNode()), iv.strideNode()); } public boolean isConstantMaxTripCount() { diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -0,0 +1,49 @@ +/* + * 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.calc; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(shortName = "/") +public class FixedBinaryNode extends FixedWithNextNode { + + @Input private ValueNode x; + @Input private ValueNode y; + + public ValueNode x() { + return x; + } + + public ValueNode y() { + return y; + } + + public FixedBinaryNode(Kind kind, ValueNode x, ValueNode y) { + super(StampFactory.forKind(kind)); + this.x = x; + this.y = y; + } +} diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -72,17 +72,4 @@ throw ValueNodeUtil.shouldNotReachHere(); } } - - public static IntegerDivNode div(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - switch(v1.kind()) { - case Int: - return graph.unique(new IntegerDivNode(Kind.Int, v1, v2)); - case Long: - return graph.unique(new IntegerDivNode(Kind.Long, v1, v2)); - default: - throw ValueNodeUtil.shouldNotReachHere(); - } - } } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -30,7 +30,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "/") -public final class IntegerDivNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class IntegerDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { public IntegerDivNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); @@ -91,6 +91,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y()))); } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "%") -public final class IntegerRemNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { public IntegerRemNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); @@ -60,6 +60,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()))); } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "|/|") -public final class UnsignedDivNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class UnsignedDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { public UnsignedDivNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); @@ -61,6 +61,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.setResult(this, gen.emitUDiv(gen.operand(x()), gen.operand(y()))); } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Tue Jan 08 18:30:11 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "|%|") -public final class UnsignedRemNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class UnsignedRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { public UnsignedRemNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); @@ -60,7 +60,12 @@ } @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitURem(gen.operand(x()), gen.operand(y()))); } } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Jan 08 18:30:11 2013 +0100 @@ -92,6 +92,12 @@ for (Node input : node.inputs()) { visitForward(visited, input); } + if (node instanceof LoopBeginNode) { + LoopBeginNode loopBegin = (LoopBeginNode) node; + for (LoopEndNode loopEnd : loopBegin.loopEnds()) { + visitForward(visited, loopEnd); + } + } nodes.add(node); } } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Tue Jan 08 18:30:11 2013 +0100 @@ -202,11 +202,11 @@ return signedDivide((Word) val); } @Override - @Operation(node = IntegerMulNode.class) + @Operation(node = IntegerDivNode.class) public Word signedDivide(int val) { return signedDivide(intParam(val)); } - @Operation(node = IntegerMulNode.class) + @Operation(node = IntegerDivNode.class) public Word signedDivide(Word val) { return box(unbox() / val.unbox()); } diff -r 570d8e4c6dfb -r c41c58f93f75 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Jan 07 13:04:04 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Tue Jan 08 18:30:11 2013 +0100 @@ -121,7 +121,7 @@ assert arguments.size() == 2; ValueNode left = arguments.get(0); ValueNode right = operation.rightOperandIsInt() ? toUnsigned(graph, arguments.get(1), Kind.Int) : fromSigned(graph, arguments.get(1)); - replace(invoke, nodeClassOp(graph, operation.node(), left, right)); + replace(invoke, nodeClassOp(graph, operation.node(), left, right, invoke)); break; case COMPARISON: @@ -215,10 +215,14 @@ } } - private ValueNode nodeClassOp(StructuredGraph graph, Class nodeClass, ValueNode left, ValueNode right) { + private ValueNode nodeClassOp(StructuredGraph graph, Class nodeClass, ValueNode left, ValueNode right, Invoke invoke) { try { Constructor< ? extends ValueNode> constructor = nodeClass.getConstructor(Kind.class, ValueNode.class, ValueNode.class); - return graph.add(constructor.newInstance(wordKind, left, right)); + ValueNode result = graph.add(constructor.newInstance(wordKind, left, right)); + if (result instanceof FixedWithNextNode) { + graph.addBeforeFixed(invoke.node(), (FixedWithNextNode) result); + } + return result; } catch (Throwable ex) { throw new GraalInternalError(ex).addContext(nodeClass.getName()); }