# HG changeset patch # User Thomas Wuerthinger # Date 1309798582 -7200 # Node ID 92b24e9e7e88e4f64c15b82c959bb026cff84cd6 # Parent a8db5b0e499fd39b96cb8a08190f1f0ce2cefd6e# Parent 33794640fc148a4f30e78638d6ffbad40435000d Merge. diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Mon Jul 04 18:56:22 2011 +0200 @@ -52,10 +52,9 @@ public final RiMethod method; public final RiRegisterConfig registerConfig; public final CiStatistics stats; - public final CiAssumptions assumptions = new CiAssumptions(); public final FrameState placeholderState; - public CompilerGraph graph = new CompilerGraph(this); + public final CompilerGraph graph; private boolean hasExceptionHandlers; private final GraalCompilation parent; @@ -92,6 +91,7 @@ this.compiler = compiler; this.target = compiler.target; this.runtime = compiler.runtime; + this.graph = new CompilerGraph(runtime); this.method = method; this.stats = stats == null ? new CiStatistics() : stats; this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method); @@ -139,16 +139,6 @@ } /** - * Records an assumption that the specified type has no finalizable subclasses. - * - * @param receiverType the type that is assumed to have no finalizable subclasses - * @return {@code true} if the assumption was recorded and can be assumed; {@code false} otherwise - */ - public boolean recordNoFinalizableSubclassAssumption(RiType receiverType) { - return false; - } - - /** * Converts this compilation to a string. * * @return a string representation of this compilation @@ -285,8 +275,8 @@ lirAssembler.emitTraps(); CiTargetMethod targetMethod = assembler().finishTargetMethod(method, runtime, lirAssembler.registerRestoreEpilogueOffset, false); - if (assumptions.count() > 0) { - targetMethod.setAssumptions(assumptions); + if (graph.assumptions().count() > 0) { + targetMethod.setAssumptions(graph.assumptions()); } if (compiler.isObserved()) { diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Jul 04 18:56:22 2011 +0200 @@ -201,6 +201,10 @@ this.operands = new OperandPool(compilation.target); } + public CiTarget target() { + return compilation.target; + } + public LIRList lir() { return lir; } @@ -580,11 +584,7 @@ } protected FrameState stateBeforeInvokeWithArguments(Invoke invoke) { - Value[] args = new Value[invoke.argumentCount()]; - for (int i = 0; i < invoke.argumentCount(); i++) { - args[i] = invoke.argument(i); - } - return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind, args); + return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind, invoke.arguments().toArray(new Value[0])); } private int getBeforeInvokeBci(Invoke invoke) { @@ -742,8 +742,11 @@ @Override public void visitFixedGuard(FixedGuard fixedGuard) { - BooleanNode comp = fixedGuard.node(); - emitGuardComp(comp); + for (Node n : fixedGuard.inputs()) { + if (n != null) { + emitGuardComp((BooleanNode) n); + } + } } public void emitGuardComp(BooleanNode comp) { @@ -1074,7 +1077,7 @@ lastState = fs; } else if (block.blockPredecessors().size() == 1) { FrameState fs = block.blockPredecessors().get(0).lastState(); - assert fs != null; + //assert fs != null : "B" + block.blockID() + ", pred=B" + block.blockPredecessors().get(0).blockID(); if (GraalOptions.TraceLIRGeneratorLevel >= 2) { TTY.println("STATE CHANGE (singlePred)"); if (GraalOptions.TraceLIRGeneratorLevel >= 3) { @@ -1461,8 +1464,11 @@ @Override public void visitEndNode(EndNode end) { setNoResult(end); + assert end.merge() != null; moveToPhi(end.merge(), end); - lir.jump(getLIRBlock(end.merge())); + LIRBlock lirBlock = getLIRBlock(end.merge()); + assert lirBlock != null : end; + lir.jump(lirBlock); } @Override @@ -1676,10 +1682,9 @@ List visitInvokeArguments(CiCallingConvention cc, Invoke x, List pointerSlots) { // for each argument, load it into the correct location - List argList = new ArrayList(x.argumentCount()); + List argList = new ArrayList(); int j = 0; - for (int i = 0; i < x.argumentCount(); i++) { - Value arg = x.argument(i); + for (Value arg : x.arguments()) { if (arg != null) { CiValue operand = cc.locations[j++]; if (operand.isRegister()) { diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java Mon Jul 04 18:56:22 2011 +0200 @@ -22,21 +22,22 @@ */ package com.oracle.max.graal.compiler.graph; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; import com.sun.cri.ri.*; public class CompilerGraph extends Graph { + private RiRuntime runtime; private Return returnSingleton; private Unwind unwindSingleton; - private GraalCompilation compilation; + private CiAssumptions assumptions = new CiAssumptions(); - public CompilerGraph(GraalCompilation compilation) { - this.compilation = compilation; + public CompilerGraph(RiRuntime runtime) { + this.runtime = runtime; } public void setReturn(Return returnNode) { @@ -58,10 +59,10 @@ } public RiRuntime runtime() { - return compilation.runtime; + return runtime; } - public GraalCompilation getCompilation() { - return compilation; + public CiAssumptions assumptions() { + return assumptions; } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,94 @@ +/* + * 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public abstract class AbstractVectorNode extends FixedNodeWithNext { + + private static final int INPUT_COUNT = 1; + private static final int INPUT_VECTOR = 0; + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + public void setVector(AbstractVectorNode length) { + inputs().set(super.inputCount() + INPUT_VECTOR, length); + } + + public AbstractVectorNode vector() { + return (AbstractVectorNode) inputs().get(super.inputCount() + INPUT_VECTOR); + } + + public AbstractVectorNode(CiKind kind, int inputCount, int successorCount, AbstractVectorNode vector, Graph graph) { + super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); + setVector(vector); + } + + protected static AbstractVectorNode findCommonNode(AbstractVectorNode left, AbstractVectorNode right, List leftList, List rightList) { + Set occured = new HashSet(); + AbstractVectorNode common = null; + AbstractVectorNode cur = left; + while (cur != null) { + occured.add(cur); + cur = cur.vector(); + } + + cur = right; + while (cur != null) { + if (occured.contains(cur)) { + common = cur; + break; + } + cur = cur.vector(); + } + + fillUntil(left, cur, leftList); + fillUntil(right, cur, rightList); + return common; + } + + private static void fillUntil(AbstractVectorNode left, AbstractVectorNode until, List leftList) { + AbstractVectorNode cur = left; + while (cur != null && cur != until) { + leftList.add(cur); + cur = cur.vector(); + } + } + + public void addToLoop(LoopBegin loop, IdentityHashMap nodes) { + throw new IllegalStateException("unimplemented"); + } +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,66 @@ +/* + * 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.max.graal.compiler.ir; + +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public abstract class AccessVectorNode extends AbstractVectorNode { + private static final int INPUT_COUNT = 2; + private static final int INPUT_OBJECT = 0; + private static final int INPUT_LOCATION = 1; + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + public void setObject(Value object) { + inputs().set(super.inputCount() + INPUT_OBJECT, object); + } + + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public void setLocation(LocationNode object) { + inputs().set(super.inputCount() + INPUT_LOCATION, object); + } + + public LocationNode location() { + return (LocationNode) inputs().get(super.inputCount() + INPUT_LOCATION); + } + + public AccessVectorNode(CiKind kind, int inputCount, int successorCount, AbstractVectorNode vector, Value object, LocationNode location, Graph graph) { + super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, vector, graph); + setObject(object); + setLocation(location); + } +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Mon Jul 04 18:56:22 2011 +0200 @@ -128,7 +128,7 @@ if (constantValue != null && constantValue.isNonNull()) { Graph graph = node.graph(); if (graph instanceof CompilerGraph) { - RiRuntime runtime = ((CompilerGraph) graph).getCompilation().runtime; + RiRuntime runtime = ((CompilerGraph) graph).runtime(); return Constant.forInt(runtime.getArrayLength(constantValue), graph); } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Mon Jul 04 18:56:22 2011 +0200 @@ -173,10 +173,10 @@ case LE: return x <= y; case GT: return x > y; case GE: return x >= y; - case AE: return UnsignedComparisons.aboveOrEqual(x, y); - case BE: return UnsignedComparisons.belowOrEqual(x, y); - case AT: return UnsignedComparisons.aboveThan(x, y); - case BT: return UnsignedComparisons.belowThan(x, y); + case AE: return toUnsigned(x) >= toUnsigned(y); + case BE: return toUnsigned(x) <= toUnsigned(y); + case AT: return toUnsigned(x) > toUnsigned(y); + case BT: return toUnsigned(x) < toUnsigned(y); } break; } @@ -204,4 +204,11 @@ } return null; } + + private long toUnsigned(int x) { + if (x < 0) { + return ((long) (x & 0x7FFFFFFF)) + ((long) Integer.MAX_VALUE) + 1; + } + return x; + } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java Mon Jul 04 18:56:22 2011 +0200 @@ -179,7 +179,7 @@ public RiType declaredType() { RiRuntime runtime = compilation().runtime; if (kind.isPrimitive()) { - runtime.asRiType(kind); + return runtime.asRiType(kind); } return runtime.getTypeOf(asConstant()); } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CreateVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CreateVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,165 @@ +/* + * 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.phases.LoweringPhase.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class CreateVectorNode extends AbstractVectorNode { + private static final int INPUT_COUNT = 1; + private static final int INPUT_LENGTH = 0; + private static final int SUCCESSOR_COUNT = 0; + + private boolean reversed; + + public void setLength(Value length) { + assert length == null || length.kind == CiKind.Int; + inputs().set(super.inputCount() + INPUT_LENGTH, length); + } + + public boolean reversed() { + return reversed; + } + + public void setReversed(boolean r) { + reversed = r; + } + + public Value length() { + return (Value) inputs().get(super.inputCount() + INPUT_LENGTH); + } + + public CreateVectorNode(boolean reversed, Value length, Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, null, graph); + setLength(length); + setReversed(reversed); + } + + @Override + public Map getDebugProperties() { + Map debugProperties = super.getDebugProperties(); + debugProperties.put("reversed", reversed); + return debugProperties; + } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } else if (clazz == LoweringOp.class) { + return (T) LOWERING_OP; + } + return super.lookup(clazz); + } + + @Override + public void print(LogStream out) { + out.print("vector with length ").print(length().toString()); + } + + @Override + public Node copy(Graph into) { + return new CreateVectorNode(reversed, null, into); + } + + @Override + public boolean valueEqual(Node i) { + return (i instanceof CreateVectorNode); + } + + private LoopBegin createLoop(Map map) { + EndNode end = new EndNode(graph()); + LoopBegin loopBegin = new LoopBegin(graph()); + loopBegin.addEnd(end); + Phi loopVariable = new Phi(CiKind.Int, loopBegin, graph()); + + if (reversed) { + IntegerSub add = new IntegerSub(CiKind.Int, loopVariable, Constant.forInt(1, graph()), graph()); + loopVariable.addInput(new IntegerSub(CiKind.Int, length(), Constant.forInt(1, graph()), graph())); + loopVariable.addInput(add); + } else { + IntegerAdd add = new IntegerAdd(CiKind.Int, loopVariable, Constant.forInt(1, graph()), graph()); + loopVariable.addInput(Constant.forInt(0, graph())); + loopVariable.addInput(add); + } + + LoopEnd loopEnd = new LoopEnd(graph()); + loopEnd.setLoopBegin(loopBegin); + Compare condition; + if (reversed) { + condition = new Compare(loopVariable, Condition.GE, Constant.forInt(0, graph()), graph()); + } else { + condition = new Compare(loopVariable, Condition.LT, length(), graph()); + } + If ifNode = new If(condition, graph()); + loopBegin.setNext(ifNode); + ifNode.setTrueSuccessor(loopEnd); + this.replaceAtPredecessors(end); + ifNode.setFalseSuccessor(this); + map.put(this, loopVariable); + return loopBegin; + } + + private static final LoweringOp LOWERING_OP = new LoweringOp() { + @Override + public void lower(Node n, CiLoweringTool tool) { + CreateVectorNode vectorNode = (CreateVectorNode) n; + + IdentityHashMap nodes = new IdentityHashMap(); + LoopBegin begin = vectorNode.createLoop(nodes); + for (Node use : vectorNode.usages()) { + processUse(begin, use, nodes); + } + } + + private void processUse(LoopBegin loop, Node use, IdentityHashMap nodes) { + AbstractVectorNode vectorNode = (AbstractVectorNode) use; + if (nodes.containsKey(vectorNode)) { + return; + } + nodes.put(vectorNode, null); + + // Make sure inputs are evaluated. + for (Node input : use.inputs()) { + if (input instanceof AbstractVectorNode) { + AbstractVectorNode abstractVectorNodeInput = (AbstractVectorNode) input; + processUse(loop, abstractVectorNodeInput, nodes); + } + } + + vectorNode.addToLoop(loop, nodes); + + // Go on to usages. + for (Node usage : use.usages()) { + processUse(loop, usage, nodes); + } + } + }; +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java Mon Jul 04 18:56:22 2011 +0200 @@ -31,25 +31,16 @@ public final class FixedGuard extends FixedNodeWithNext { - private static final int INPUT_COUNT = 1; - private static final int INPUT_NODE = 0; - + private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; - /** - * The instruction that produces the object tested against null. - */ - public BooleanNode node() { - return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE); + public FixedGuard(BooleanNode node, Graph graph) { + this(graph); + addNode(node); } - public void setNode(BooleanNode n) { - inputs().set(super.inputCount() + INPUT_NODE, n); - } - - public FixedGuard(BooleanNode node, Graph graph) { + public FixedGuard(Graph graph) { super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); - setNode(node); } @Override @@ -59,12 +50,16 @@ @Override public void print(LogStream out) { - out.print("clip node ").print(node()); + out.print("clip node ").print(inputs().toString()); + } + + public void addNode(BooleanNode node) { + inputs().add(node); } @Override public Node copy(Graph into) { - return new FixedGuard(null, into); + return new FixedGuard(into); } @SuppressWarnings("unchecked") @@ -80,20 +75,26 @@ @Override public Node canonical(Node node) { FixedGuard fixedGuard = (FixedGuard) node; - if (fixedGuard.node() instanceof Constant) { - Constant c = (Constant) fixedGuard.node(); - if (c.asConstant().asBoolean()) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Removing redundant fixed guard " + fixedGuard); + for (Node n : fixedGuard.inputs()) { + if (n instanceof Constant) { + Constant c = (Constant) n; + if (c.asConstant().asBoolean()) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Removing redundant fixed guard " + fixedGuard); + } + fixedGuard.inputs().remove(c); + } else { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Replacing fixed guard " + fixedGuard + " with deoptimization node"); + } + return new Deoptimize(DeoptAction.InvalidateRecompile, fixedGuard.graph()); } - return fixedGuard.next(); - } else { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Replacing fixed guard " + fixedGuard + " with deoptimization node"); - } - return new Deoptimize(DeoptAction.InvalidateRecompile, fixedGuard.graph()); } } + + if (fixedGuard.inputs().size() == 0) { + return fixedGuard.next(); + } return fixedGuard; } }; diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Mon Jul 04 18:56:22 2011 +0200 @@ -81,6 +81,16 @@ return blockSuccessor(1); } + + public void setTrueSuccessor(FixedNode node) { + setBlockSuccessor(0, node); + } + + + public void setFalseSuccessor(FixedNode node) { + setBlockSuccessor(1, node); + } + /** * Gets the block corresponding to the specified outcome of the branch. * @param istrue {@code true} if the true successor is requested, {@code false} otherwise diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAddVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAddVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,67 @@ +/* + * 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class IntegerAddVectorNode extends AbstractVectorNode { + private static final int INPUT_COUNT = 1; + private static final int INPUT_VALUE = 0; + private static final int SUCCESSOR_COUNT = 0; + + public Value value() { + return (Value) inputs().get(super.inputCount() + INPUT_VALUE); + } + + public void setValue(Value v) { + inputs().set(super.inputCount() + INPUT_VALUE, v); + } + + public IntegerAddVectorNode(AbstractVectorNode vector, Value value, Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, graph); + setValue(value); + } + + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } + return super.lookup(clazz); + } + + @Override + public Node copy(Graph into) { + return new IntegerAddVectorNode(null, null, into); + } + + @Override + public void addToLoop(LoopBegin loop, IdentityHashMap nodes) { + nodes.put(this, new IntegerAdd(CiKind.Int, nodes.get(vector()), value(), graph())); + } +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Mon Jul 04 18:56:22 2011 +0200 @@ -51,21 +51,24 @@ return super.successorCount() + SUCCESSOR_COUNT; } - /** - * The list of instructions that produce input for this instruction. - */ - public Value argument(int index) { - assert index >= 0 && index < argumentCount; - return (Value) inputs().get(super.inputCount() + index); - } + public List arguments() { + return new AbstractList() { + @Override + public int size() { + return argumentCount; + } - public Value setArgument(int index, Value n) { - assert index >= 0 && index < argumentCount; - return (Value) inputs().set(super.inputCount() + index, n); - } + @Override + public Value get(int index) { + return (Value) inputs().get(Invoke.super.inputCount() + index); + } - public int argumentCount() { - return argumentCount; + @Override + public Value set(int index, Value node) { + return (Value) inputs().set(Invoke.super.inputCount() + index, node); + } + }; + } /** @@ -103,7 +106,7 @@ this.argumentCount = args.length; for (int i = 0; i < args.length; i++) { - setArgument(i, args[i]); + arguments().set(i, args[i]); } } @@ -135,7 +138,7 @@ */ public Value receiver() { assert !isStatic(); - return argument(0); + return arguments().get(0); } /** @@ -179,7 +182,7 @@ if (i > argStart) { out.print(", "); } - out.print(argument(i)); + out.print(arguments().get(i)); } out.print(CiUtil.format(") [method: %H.%n(%p):%r]", target, false)); } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Mon Jul 04 18:56:22 2011 +0200 @@ -23,7 +23,6 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; import com.oracle.max.graal.compiler.phases.*; import com.oracle.max.graal.compiler.phases.LoweringPhase.LoweringOp; @@ -130,13 +129,9 @@ LoadField loadField = (LoadField) node; Graph graph = node.graph(); CiConstant constant = null; - if (graph instanceof CompilerGraph) { - RiMethod method = ((CompilerGraph) graph).getCompilation().method; - if (loadField.isStatic() && !method.isClassInitializer()) { + if (loadField.isStatic()) { constant = loadField.field().constantValue(null); - } - } - if (!loadField.isStatic()) { + } else { Value object = loadField.object(); if (object.isConstant()) { constant = loadField.field().constantValue(object.asConstant()); diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java Mon Jul 04 18:56:22 2011 +0200 @@ -64,10 +64,10 @@ private final int index; private RiType declaredType; - public Local(CiKind kind, int javaIndex, StartNode start, Graph graph) { + public Local(CiKind kind, int javaIndex, Graph graph) { super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.index = javaIndex; - setStart(start); + setStart(graph.start()); } /** @@ -114,7 +114,7 @@ @Override public Node copy(Graph into) { - Local x = new Local(kind, index, null, into); + Local x = new Local(kind, index, into); x.setDeclaredType(declaredType()); return x; } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -26,16 +26,36 @@ import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; +import com.sun.cri.ci.CiAddress.*; public final class LocationNode extends FloatingNode { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_INDEX = 0; private static final int SUCCESSOR_COUNT = 0; + public static final Object FINAL_LOCATION = new Object(); + + public static Object getArrayLocation(CiKind elementKind) { + return elementKind; + } + private int displacement; private CiKind valueKind; private Object locationIdentity; + public int displacement() { + return displacement; + } + + public Value index() { + return (Value) inputs().get(super.inputCount() + INPUT_INDEX); + } + + public void setIndex(Value index) { + inputs().set(super.inputCount() + INPUT_INDEX, index); + } + public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) { LocationNode result = new LocationNode(identity, kind, displacement, graph); return graph.ideal(result); @@ -71,7 +91,13 @@ } public CiValue createAddress(LIRGenerator lirGenerator, Value object) { - return new CiAddress(valueKind, lirGenerator.load(object), displacement); + CiValue indexValue = CiValue.IllegalValue; + Scale indexScale = Scale.Times1; + if (this.index() != null) { + indexValue = lirGenerator.load(this.index()); + indexScale = Scale.fromInt(valueKind.sizeInBytes(lirGenerator.target().wordSize)); + } + return new CiAddress(valueKind, lirGenerator.load(object), indexValue, indexScale, displacement); } public Object locationIdentity() { diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,65 @@ +/* + * 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class ReadVectorNode extends AccessVectorNode { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + + public ReadVectorNode(AbstractVectorNode vector, Value object, LocationNode location, Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, object, location, graph); + } + + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } + return super.lookup(clazz); + } + + @Override + public Node copy(Graph into) { + return new ReadVectorNode(null, null, null, into); + } + + + @Override + public void addToLoop(LoopBegin loop, IdentityHashMap nodes) { + LocationNode newLocation = LocationNode.create(LocationNode.getArrayLocation(location().getValueKind()), location().getValueKind(), location().displacement(), graph()); + Value index = nodes.get(vector()); + assert index != null; + newLocation.setIndex(index); + ReadNode readNode = new ReadNode(location().getValueKind().stackKind(), object(), newLocation, graph()); + loop.loopEnd().replaceAtPredecessors(readNode); + readNode.setNext(loop.loopEnd()); + nodes.put(this, readNode); + } +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Mon Jul 04 18:56:22 2011 +0200 @@ -93,7 +93,6 @@ exactType = declaredType.exactType(); } - GraalCompilation compilation = ((CompilerGraph) node.graph()).getCompilation(); boolean needsCheck = true; if (exactType != null) { // we have an exact type @@ -101,7 +100,7 @@ } else { // if either the declared type of receiver or the holder can be assumed to have no finalizers if (declaredType != null && !declaredType.hasFinalizableSubclass()) { - if (compilation.recordNoFinalizableSubclassAssumption(declaredType)) { + if (((CompilerGraph) node.graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) { needsCheck = false; } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Mon Jul 04 18:56:22 2011 +0200 @@ -53,7 +53,7 @@ */ public Value(CiKind kind, int inputCount, int successorCount, Graph graph) { super(inputCount, successorCount, graph); - assert kind == kind.stackKind() : kind + " != " + kind.stackKind(); + assert kind != null && kind == kind.stackKind() : kind + " != " + kind.stackKind(); this.kind = kind; } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteVectorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteVectorNode.java Mon Jul 04 18:56:22 2011 +0200 @@ -0,0 +1,82 @@ +/* + * 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class WriteVectorNode extends AccessVectorNode { + private static final int INPUT_COUNT = 1; + private static final int INPUT_VALUES = 0; + private static final int SUCCESSOR_COUNT = 0; + + public void setValues(AbstractVectorNode length) { + inputs().set(super.inputCount() + INPUT_VALUES, length); + } + + public AbstractVectorNode values() { + return (AbstractVectorNode) inputs().get(super.inputCount() + INPUT_VALUES); + } + + public WriteVectorNode(AbstractVectorNode vector, Value object, LocationNode location, AbstractVectorNode values, Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, object, location, graph); + setValues(values); + } + + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } + return super.lookup(clazz); + } + + @Override + public void print(LogStream out) { + out.print("write vector node " + values()); + } + + @Override + public Node copy(Graph into) { + return new WriteVectorNode(null, null, null, null, into); + } + + + @Override + public void addToLoop(LoopBegin loop, IdentityHashMap nodes) { + LocationNode newLocation = LocationNode.create(LocationNode.getArrayLocation(location().getValueKind()), location().getValueKind(), location().displacement(), graph()); + Value index = nodes.get(vector()); + Value value = nodes.get(values()); + assert index != null; + assert value != null; + newLocation.setIndex(index); + WriteNode writeNode = new WriteNode(location().getValueKind().stackKind(), object(), value, newLocation, graph()); + loop.loopEnd().replaceAtPredecessors(writeNode); + writeNode.setNext(loop.loopEnd()); + } +} diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -73,6 +73,12 @@ flood.add(successor); } } + + if (current instanceof AbstractVectorNode) { + for (Node usage : current.usages()) { + flood.add(usage); + } + } } } @@ -147,17 +153,6 @@ } for (Node node : graph.getNodes()) { if (!flood.isMarked(node)) { - if (node.predecessors().size() > 0) { - for (Node pred : node.predecessors()) { - TTY.println("!PRED! " + pred + " (" + flood.isMarked(pred) + ")"); - for (int i=0; isucc: " + pred.successors().get(i)); - } - for (int i=0; iusage: " + pred.usages().get(i)); - } - } - } node.delete(); } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.graph.*; @@ -36,13 +35,8 @@ @Override protected void run(Graph graph) { - GraalCompilation compilation = null; - if (graph instanceof CompilerGraph) { - compilation = ((CompilerGraph) graph).getCompilation(); - } - // Create duplicate graph. - CompilerGraph duplicate = new CompilerGraph(compilation); + CompilerGraph duplicate = new CompilerGraph(((CompilerGraph) graph).runtime()); Map replacements = new HashMap(); replacements.put(graph.start(), duplicate.start()); duplicate.addDuplicate(graph.getNodes(), replacements); diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -152,7 +152,7 @@ Node current; if (block.firstNode() instanceof StartNode) { - current = ((StartNode) block.firstNode()).start(); + current = ((StartNode) block.firstNode()).next(); } else { current = block.firstNode(); } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -172,7 +172,7 @@ Block startBlock = nextBlock(FixedNodeWithNext.SYNCHRONIZATION_ENTRY_BCI); markOnWorkList(startBlock); lastInstr = (FixedNodeWithNext) createTarget(startBlock, frameState); - graph.start().setStart(lastInstr); + graph.start().setNext(lastInstr); if (isSynchronized(method.accessFlags())) { // 4A.1 add a monitor enter to the start block diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -54,11 +54,11 @@ } private Queue newInvokes = new ArrayDeque(); - private Graph graph; + private CompilerGraph graph; @Override protected void run(Graph graph) { - this.graph = graph; + this.graph = (CompilerGraph) graph; float ratio = GraalOptions.MaximumInlineRatio; inliningSize = compilation.method.codeSize(); @@ -118,13 +118,13 @@ private RiMethod inlineInvoke(Invoke invoke, int iterations, float ratio) { RiMethod parent = invoke.stateAfter().method(); RiTypeProfile profile = parent.typeProfile(invoke.bci); + if (GraalOptions.Intrinsify && compilation.runtime.intrinsicGraph(invoke.target, invoke.arguments()) != null) { + // Always intrinsify. + return invoke.target; + } if (!checkInvokeConditions(invoke)) { return null; } - if (invoke.target.hasIntrinsicGraph() && GraalOptions.Intrinsify) { - // Always intrinsify. - return invoke.target; - } if (invoke.opcode() == Bytecodes.INVOKESPECIAL || invoke.target.canBeStaticallyBound()) { if (checkTargetConditions(invoke.target, iterations) && checkSizeConditions(invoke.target, invoke, profile, ratio)) { return invoke.target; @@ -159,7 +159,7 @@ String concreteName = CiUtil.format("%H.%n(%p):%r", concrete, false); TTY.println("recording concrete method assumption: %s -> %s", targetName, concreteName); } - compilation.assumptions.recordConcreteMethod(invoke.target, concrete); + graph.assumptions().recordConcreteMethod(invoke.target, concrete); return concrete; } return null; @@ -323,33 +323,41 @@ exceptionEdge = ((Placeholder) exceptionEdge).next(); } - boolean withReceiver = !Modifier.isStatic(method.accessFlags()); + boolean withReceiver = !invoke.isStatic(); int argumentCount = method.signature().argumentCount(false); Value[] parameters = new Value[argumentCount + (withReceiver ? 1 : 0)]; int slot = withReceiver ? 1 : 0; int param = withReceiver ? 1 : 0; for (int i = 0; i < argumentCount; i++) { - parameters[param++] = invoke.argument(slot); + parameters[param++] = invoke.arguments().get(slot); slot += method.signature().argumentKindAt(i).sizeInSlots(); } if (withReceiver) { - parameters[0] = invoke.argument(0); + parameters[0] = invoke.arguments().get(0); } CompilerGraph graph = null; if (GraalOptions.Intrinsify) { - graph = (CompilerGraph) method.intrinsicGraph(parameters); + graph = (CompilerGraph) compilation.runtime.intrinsicGraph(method, invoke.arguments()); + if (graph != null && graph.getNodes(Merge.class).iterator().hasNext()) { + WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(invoke.graph()); + checkpoint.setStateAfter(invoke.stateAfter()); + checkpoint.setNext(invoke.next()); + invoke.setNext(checkpoint); + } } if (graph != null) { - TTY.println("Using intrinsic graph"); + if (GraalOptions.TraceInlining) { + TTY.println("Using intrinsic graph"); + } } else { graph = GraphBuilderPhase.cachedGraphs.get(method); } if (graph != null) { if (GraalOptions.TraceInlining) { - TTY.println("Reusing graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize()); + TTY.println("Reusing graph for %s", methodName(method, invoke)); } } else { if (GraalOptions.TraceInlining) { diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -71,8 +71,8 @@ StartNode startNode = b.firstNode().graph().start(); if (b.firstNode() == startNode) { WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(startNode.graph()); - checkpoint.setNext((FixedNode) startNode.start()); - startNode.setStart(checkpoint); + checkpoint.setNext((FixedNode) startNode.next()); + startNode.setNext(checkpoint); mergeForWrite = checkpoint; mergeForRead = checkpoint; } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java Mon Jul 04 18:56:22 2011 +0200 @@ -35,14 +35,16 @@ @Override protected void run(Graph graph) { for (ReadNode n : graph.getNodes(ReadNode.class)) { - Node memoryInput = n.inputs().variablePart().get(0); - if (memoryInput instanceof WriteNode) { - WriteNode other = (WriteNode) memoryInput; - if (other.object() == n.object() && other.location() == n.location()) { - if (GraalOptions.TraceReadElimination) { - TTY.println("Eliminated memory read " + n + "and replaced with node " + other.value()); + if (n.inputs().variablePart().size() > 0) { + Node memoryInput = n.inputs().variablePart().get(0); + if (memoryInput instanceof WriteNode) { + WriteNode other = (WriteNode) memoryInput; + if (other.object() == n.object() && other.location() == n.location()) { + if (GraalOptions.TraceReadElimination) { + TTY.println("Eliminated memory read " + n + "and replaced with node " + other.value()); + } + n.replaceAndDelete(other.value()); } - n.replaceAndDelete(other.value()); } } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Mon Jul 04 18:56:22 2011 +0200 @@ -69,12 +69,12 @@ this.anchor = (Anchor) firstNode; } else if (firstNode == firstNode.graph().start()) { StartNode start = (StartNode) firstNode; - if (start.start() instanceof Anchor) { - this.anchor = (Anchor) start.start(); + if (start.next() instanceof Anchor) { + this.anchor = (Anchor) start.next(); } else { Anchor a = new Anchor(firstNode.graph()); - a.setNext((FixedNode) firstNode.graph().start().start()); - firstNode.graph().start().setStart(a); + a.setNext((FixedNode) firstNode.graph().start().next()); + firstNode.graph().start().setNext(a); this.anchor = a; } } else if (firstNode instanceof Merge) { diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Mon Jul 04 18:56:22 2011 +0200 @@ -554,6 +554,8 @@ case GT : acond = ConditionFlag.greater; break; case BE : acond = ConditionFlag.belowEqual; break; case AE : acond = ConditionFlag.aboveEqual; break; + case AT : acond = ConditionFlag.above; break; + case BT : acond = ConditionFlag.below; break; default : throw Util.shouldNotReachHere(); } // Checkstyle: on diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Mon Jul 04 18:56:22 2011 +0200 @@ -58,7 +58,7 @@ int index = 0; if (!isStatic(method.accessFlags())) { // add the receiver and assume it is non null - Local local = new Local(method.holder().kind(), javaIndex, graph.start(), graph); + Local local = new Local(method.holder().kind(), javaIndex, graph); local.setDeclaredType(method.holder()); storeLocal(javaIndex, local); javaIndex = 1; @@ -70,7 +70,7 @@ for (int i = 0; i < max; i++) { RiType type = sig.argumentTypeAt(i, accessingClass); CiKind kind = type.kind().stackKind(); - Local local = new Local(kind, index, graph.start(), graph); + Local local = new Local(kind, index, graph); if (type.isResolved()) { local.setDeclaredType(type); } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Mon Jul 04 18:56:22 2011 +0200 @@ -223,14 +223,4 @@ } } } - - @Override - public Graph intrinsicGraph(Node[] parameters) { - return null; - } - - @Override - public boolean hasIntrinsicGraph() { - return false; - } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java Mon Jul 04 18:56:22 2011 +0200 @@ -177,14 +177,4 @@ public int branchProbability(int bci) { return -1; } - - @Override - public Graph intrinsicGraph(Node[] parameters) { - return null; - } - - @Override - public boolean hasIntrinsicGraph() { - return false; - } } diff -r 33794640fc14 -r 92b24e9e7e88 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Jul 04 17:44:07 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Jul 04 18:56:22 2011 +0200 @@ -26,6 +26,9 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.runtime.nodes.*; @@ -46,6 +49,7 @@ final HotSpotRegisterConfig regConfig; final HotSpotRegisterConfig globalStubRegConfig; private final Compiler compiler; + private IdentityHashMap intrinsicGraphs = new IdentityHashMap(); public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) { @@ -276,4 +280,111 @@ field.replaceAndDelete(memoryWrite); } } + + @Override + public Graph intrinsicGraph(RiMethod method, List parameters) { + if (!intrinsicGraphs.containsKey(method)) { + RiType holder = method.holder(); + String fullName = method.name() + method.signature().asString(); + String holderName = holder.name(); + if (holderName.equals("Ljava/lang/Object;")) { + if (fullName.equals("getClass()Ljava/lang/Class;")) { + CompilerGraph graph = new CompilerGraph(this); + Local receiver = new Local(CiKind.Object, 0, graph); + ReadNode klassOop = new ReadNode(CiKind.Object, receiver, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), graph); + Return ret = new Return(new ReadNode(CiKind.Object, klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.classMirrorOffset, graph), graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } + } else if (holderName.equals("Ljava/lang/System;")) { + if (fullName.equals("arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V")) { + CompilerGraph graph = new CompilerGraph(this); + Local src = new Local(CiKind.Object, 0, graph); + Local srcPos = new Local(CiKind.Int, 1, graph); + Local dest = new Local(CiKind.Object, 2, graph); + Local destPos = new Local(CiKind.Int, 3, graph); + Local length = new Local(CiKind.Int, 4, graph); + src.setDeclaredType(((Value) parameters.get(0)).declaredType()); + dest.setDeclaredType(((Value) parameters.get(2)).declaredType()); + + if (src.declaredType() == null || dest.declaredType() == null) { + return null; + } + + if (src.declaredType() != dest.declaredType()) { + return null; + } + + if (!src.declaredType().isArrayClass()) { + return null; + } + + CiKind componentType = src.declaredType().componentType().kind(); + + if (componentType == CiKind.Object) { + return null; + } + + // Add preconditions. + FixedGuard guard = new FixedGuard(graph); + ArrayLength srcLength = new ArrayLength(src, graph); + ArrayLength destLength = new ArrayLength(dest, graph); + IntegerAdd upperLimitSrc = new IntegerAdd(CiKind.Int, srcPos, length, graph); + IntegerAdd upperLimitDest = new IntegerAdd(CiKind.Int, destPos, length, graph); + guard.addNode(new Compare(srcPos, Condition.BE, srcLength, graph)); + guard.addNode(new Compare(destPos, Condition.BE, destLength, graph)); + guard.addNode(new Compare(length, Condition.GE, Constant.forInt(0, graph), graph)); + guard.addNode(new Compare(upperLimitSrc, Condition.LE, srcLength, graph)); + guard.addNode(new Compare(upperLimitDest, Condition.LE, destLength, graph)); + graph.start().setNext(guard); + + LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, componentType, config.getArrayOffset(componentType), graph); + + // Build normal vector instruction. + CreateVectorNode normalVector = new CreateVectorNode(false, length, graph); + ReadVectorNode values = new ReadVectorNode(new IntegerAddVectorNode(normalVector, srcPos, graph), src, location, graph); + new WriteVectorNode(new IntegerAddVectorNode(normalVector, destPos, graph), dest, location, values, graph); + + // Build reverse vector instruction. + CreateVectorNode reverseVector = new CreateVectorNode(true, length, graph); + ReadVectorNode reverseValues = new ReadVectorNode(new IntegerAddVectorNode(reverseVector, srcPos, graph), src, location, graph); + new WriteVectorNode(new IntegerAddVectorNode(reverseVector, destPos, graph), dest, location, reverseValues, graph); + + If ifNode = new If(new Compare(src, Condition.EQ, dest, graph), graph); + guard.setNext(ifNode); + + If secondIf = new If(new Compare(srcPos, Condition.LT, destPos, graph), graph); + ifNode.setTrueSuccessor(secondIf); + + secondIf.setTrueSuccessor(reverseVector); + + Merge merge1 = new Merge(graph); + merge1.addEnd(new EndNode(graph)); + merge1.addEnd(new EndNode(graph)); + + ifNode.setFalseSuccessor(merge1.endAt(0)); + secondIf.setFalseSuccessor(merge1.endAt(1)); + merge1.setNext(normalVector); + + Merge merge2 = new Merge(graph); + merge2.addEnd(new EndNode(graph)); + merge2.addEnd(new EndNode(graph)); + + normalVector.setNext(merge2.endAt(0)); + reverseVector.setNext(merge2.endAt(1)); + + Return ret = new Return(null, graph); + merge2.setNext(ret); + graph.setReturn(ret); + return graph; + } + } + + if (!intrinsicGraphs.containsKey(method)) { + intrinsicGraphs.put(method, null); + } + } + return intrinsicGraphs.get(method); + } }