# HG changeset patch # User Thomas Wuerthinger # Date 1307735539 -7200 # Node ID c76db61fbb73204f90fed308f9df602593d77c15 # Parent e86e83c5adbc41b3e978a74a552fb699b107c97a# Parent 668603cb3263109f5a7d181ad3c47c14ab196147 Merge. diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Fri Jun 10 21:52:19 2011 +0200 @@ -112,9 +112,9 @@ public void print(Graph graph, String title, boolean shortNames) { stream.printf(" %n", escape(title)); noBlockNodes.clear(); - Schedule schedule = null; + IdentifyBlocksPhase schedule = null; try { - schedule = new Schedule(); + schedule = new IdentifyBlocksPhase(true); schedule.apply(graph); } catch (Throwable t) { // nothing to do here... diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Jun 10 21:52:19 2011 +0200 @@ -275,7 +275,7 @@ } private static boolean jumpsToNextBlock(Node node) { - return node instanceof BlockEnd; + return node instanceof BlockEnd || node instanceof Anchor; } @Override @@ -422,6 +422,9 @@ DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); deoptimizationStubs.add(stub); + + emitCompare(x.node()); + //emitBranch(x.node(), stub.label) throw new RuntimeException(); //lir.branch(x.condition.negate(), stub.label, stub.info); } @@ -457,7 +460,7 @@ // describing the state at the safepoint. moveToPhi(); - lir.jump(getLIRBlock(x.defaultSuccessor())); + lir.jump(getLIRBlock(x.next())); } @Override @@ -706,10 +709,14 @@ } @Override - public void visitNullCheck(FixedNullCheck x) { - CiValue value = load(x.object()); - LIRDebugInfo info = stateFor(x); - lir.nullCheck(value, info); + public void visitFixedGuard(FixedGuard fixedGuard) { + Node comp = fixedGuard.node(); + if (comp instanceof IsNonNull) { + IsNonNull x = (IsNonNull) comp; + CiValue value = load(x.object()); + LIRDebugInfo info = stateFor(x); + lir.nullCheck(value, info); + } } @Override diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Fri Jun 10 21:52:19 2011 +0200 @@ -91,9 +91,11 @@ printGraph("After Canonicalization", graph); } + new LoweringPhase().apply(graph); + new SplitCriticalEdgesPhase().apply(graph); - Schedule schedule = new Schedule(); + IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); schedule.apply(graph); diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java Fri Jun 10 21:52:19 2011 +0200 @@ -74,6 +74,8 @@ super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); this.field = field; setObject(object); + assert field.isResolved(); + assert field.holder().isResolved(); } /** @@ -93,18 +95,10 @@ } /** - * Checks whether the class of the field of this access is loaded. - * @return {@code true} if the class is loaded - */ - public boolean isLoaded() { - return field.isResolved(); - } - - /** * Checks whether this field is declared volatile. * @return {@code true} if the field is resolved and declared volatile */ public boolean isVolatile() { - return isLoaded() && Modifier.isVolatile(field.accessFlags()); + return Modifier.isVolatile(field.accessFlags()); } } diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java Fri Jun 10 21:52:19 2011 +0200 @@ -29,7 +29,7 @@ /** * The {@code Anchor} instruction represents the end of a block with an unconditional jump to another block. */ -public final class Anchor extends BlockEnd { +public final class Anchor extends Instruction { private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; @@ -39,7 +39,7 @@ * @param graph */ public Anchor(Graph graph) { - super(CiKind.Illegal, 1, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); } @Override @@ -49,12 +49,11 @@ @Override public void print(LogStream out) { - out.print("anchor ").print(defaultSuccessor()); + out.print("anchor ").print(next()); } @Override public Node copy(Graph into) { - Anchor x = new Anchor(into); - return x; + return new Anchor(into); } } diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Fri Jun 10 21:52:19 2011 +0200 @@ -126,9 +126,7 @@ return length; } CiConstant constantValue = null; - if (array instanceof LoadField) { - constantValue = ((LoadField) array).constantValue(); - } else if (array.isConstant()) { + if (array.isConstant()) { constantValue = array.asConstant(); } if (constantValue != null && constantValue.isNonNull()) { diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ClipNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ClipNode.java Fri Jun 10 19:50:32 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * 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.compiler.debug.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public final class ClipNode extends Instruction { - private static final int INPUT_COUNT = 1; - private static final int INPUT_NODE = 0; - - private static final int SUCCESSOR_COUNT = 0; - - /** - * The instruction that produces the object tested against null. - */ - public FloatingNode node() { - return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE); - } - - public FloatingNode setNode(FloatingNode n) { - return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n); - } - - public ClipNode(Graph graph) { - super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); - } - - @Override - public void accept(ValueVisitor v) { - // Do nothing. - } - - @Override - public void print(LogStream out) { - out.print("clip node ").print(node()); - } - - @Override - public Node copy(Graph into) { - return new ClipNode(into); - } -} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.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/FixedGuard.java Fri Jun 10 21:52:19 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 com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class FixedGuard extends Instruction { + private static final int INPUT_COUNT = 1; + private static final int INPUT_NODE = 0; + + private static final int SUCCESSOR_COUNT = 0; + + /** + * The instruction that produces the object tested against null. + */ + public FloatingNode node() { + return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE); + } + + public FloatingNode setNode(FloatingNode n) { + return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n); + } + + public FixedGuard(Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + } + + @Override + public void accept(ValueVisitor v) { + v.visitFixedGuard(this); + } + + @Override + public void print(LogStream out) { + out.print("clip node ").print(node()); + } + + @Override + public Node copy(Graph into) { + return new FixedGuard(into); + } +} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNullCheck.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedNullCheck.java Fri Jun 10 19:50:32 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2009, 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.compiler.debug.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.bytecode.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code NullCheck} class represents an explicit null check instruction. - */ -public final class FixedNullCheck extends Instruction { - - private static final int INPUT_COUNT = 1; - private static final int INPUT_OBJECT = 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; - } - - /** - * The instruction that produces the object tested against null. - */ - public Value object() { - return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); - } - - public Value setObject(Value n) { - return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n); - } - - /** - * Constructs a new NullCheck instruction. - * @param object the instruction producing the object to check against null - * @param stateBefore the state before executing the null check - * @param graph - */ - public FixedNullCheck(Value object, Graph graph) { - super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph); - assert object == null || object.kind == CiKind.Object; - setObject(object); - } - - @Override - public void accept(ValueVisitor v) { - v.visitNullCheck(this); - } - - @Override - public int valueNumber() { - return Util.hash1(Bytecodes.IFNONNULL, object()); - } - - @Override - public boolean valueEqual(Node i) { - if (i instanceof FixedNullCheck) { - FixedNullCheck o = (FixedNullCheck) i; - return object() == o.object(); - } - return false; - } - - @Override - public RiType declaredType() { - // null check does not alter the type of the object - return object().declaredType(); - } - - @Override - public RiType exactType() { - // null check does not alter the type of the object - return object().exactType(); - } - - @Override - public void print(LogStream out) { - out.print("null_check(").print(object()).print(')'); - } - - @Override - public Node copy(Graph into) { - return new FixedNullCheck(null, into); - } -} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Fri Jun 10 21:52:19 2011 +0200 @@ -36,12 +36,12 @@ /** * The instruction that produces the object tested against null. */ - public FloatingNode node() { - return (FloatingNode) inputs().get(super.inputCount() + INPUT_NODE); + public Compare node() { + return (Compare) inputs().get(super.inputCount() + INPUT_NODE); } - public FloatingNode setNode(FloatingNode n) { - return (FloatingNode) inputs().set(super.inputCount() + INPUT_NODE, n); + public Compare setNode(Compare n) { + return (Compare) inputs().set(super.inputCount() + INPUT_NODE, n); } public GuardNode(Graph graph) { diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.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/IsNonNull.java Fri Jun 10 21:52:19 2011 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009, 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.compiler.debug.*; +import com.oracle.max.graal.compiler.util.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.bytecode.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * The {@code NullCheck} class represents an explicit null check instruction. + */ +public final class IsNonNull extends FloatingNode { + + private static final int INPUT_COUNT = 1; + private static final int INPUT_OBJECT = 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; + } + + /** + * The instruction that produces the object tested against null. + */ + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public Value setObject(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n); + } + + /** + * Constructs a new NullCheck instruction. + * @param object the instruction producing the object to check against null + * @param stateBefore the state before executing the null check + * @param graph + */ + public IsNonNull(Value object, Graph graph) { + super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph); + assert object == null || object.kind == CiKind.Object; + setObject(object); + } + + @Override + public void accept(ValueVisitor v) { + // Nothing to do. + } + + @Override + public int valueNumber() { + return Util.hash1(Bytecodes.IFNONNULL, object()); + } + + @Override + public boolean valueEqual(Node i) { + if (i instanceof IsNonNull) { + IsNonNull o = (IsNonNull) i; + return object() == o.object(); + } + return false; + } + + @Override + public RiType declaredType() { + // null check does not alter the type of the object + return object().declaredType(); + } + + @Override + public RiType exactType() { + // null check does not alter the type of the object + return object().exactType(); + } + + @Override + public void print(LogStream out) { + out.print("null_check(").print(object()).print(')'); + } + + @Override + public Node copy(Graph into) { + return new IsNonNull(null, into); + } +} diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Fri Jun 10 21:52:19 2011 +0200 @@ -25,6 +25,8 @@ 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.LoweringPhase.LoweringOp; +import com.oracle.max.graal.compiler.phases.LoweringPhase.LoweringTool; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -68,8 +70,8 @@ */ @Override public RiType exactType() { - RiType declaredType = declaredType(); - return declaredType.isResolved() ? declaredType.exactType() : null; + RiType declared = declaredType(); + return declared != null && declared.isResolved() ? declared.exactType() : null; } @Override @@ -97,7 +99,7 @@ * * @return {@code null} if this load cannot be reduced to a constant */ - public CiConstant constantValue() { + private CiConstant constantValue() { if (isStatic()) { return field.constantValue(null); } else if (object().isConstant()) { @@ -108,8 +110,7 @@ @Override public Node copy(Graph into) { - LoadField x = new LoadField(null, field, into); - return x; + return new LoadField(null, field, into); } @SuppressWarnings("unchecked") @@ -121,6 +122,16 @@ return super.lookup(clazz); } + private static class LoadFieldLoweringOp implements LoweringOp { + + @Override + public Node lower(Node n, LoweringTool tool) { + LoadField field = (LoadField) n; + return null;//field.field().createLoad(tool); + } + + } + private static class LoadFieldCanonicalizerOp implements CanonicalizerOp { @Override public Node canonical(Node node) { diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Fri Jun 10 21:52:19 2011 +0200 @@ -30,7 +30,7 @@ * The {@code Phi} instruction represents the merging of dataflow * in the instruction graph. It refers to a join block and a variable. */ -public final class Phi extends FixedNode { +public final class Phi extends FloatingNode { private static final int DEFAULT_MAX_VALUES = 2; diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Fri Jun 10 21:52:19 2011 +0200 @@ -58,7 +58,7 @@ public abstract void visitNewMultiArray(NewMultiArray i); public abstract void visitNewObjectArray(NewObjectArray i); public abstract void visitNewTypeArray(NewTypeArray i); - public abstract void visitNullCheck(FixedNullCheck i); + public abstract void visitFixedGuard(FixedGuard fixedGuard); public abstract void visitPhi(Phi i); public abstract void visitRegisterFinalizer(RegisterFinalizer i); public abstract void visitReturn(Return i); diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Fri Jun 10 21:52:19 2011 +0200 @@ -694,7 +694,9 @@ private void genThrow(int bci) { Value exception = frameState.apop(); - append(new FixedNullCheck(exception, graph)); + FixedGuard node = new FixedGuard(graph); + node.setNode(new IsNonNull(exception, graph)); + append(node); Instruction entry = handleException(exception, bci); if (entry != null) { @@ -1282,7 +1284,7 @@ traceInstruction(bci, opcode, blockStart); processBytecode(bci, opcode); - if (Schedule.isBlockEnd(lastInstr) || lastInstr.next() != null) { + if (IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) { break; } diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Fri Jun 10 21:52:19 2011 +0200 @@ -239,7 +239,9 @@ assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size(); Instruction pred; if (withReceiver) { - pred = new FixedNullCheck(parameters[0], compilation.graph); + FixedGuard clipNode = new FixedGuard(compilation.graph); + clipNode.setNode(new IsNonNull(parameters[0], compilation.graph)); + pred = clipNode; } else { pred = new Merge(compilation.graph); } diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Fri Jun 10 21:52:19 2011 +0200 @@ -0,0 +1,75 @@ +/* + * 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.phases; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.schedule.*; +import com.oracle.max.graal.graph.*; + +public class LoweringPhase extends Phase { + @Override + protected void run(final Graph graph) { + final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); + s.apply(graph); + + for (Block b : s.getBlocks()) { + final Node firstNode = b.firstNode(); + + final LoweringTool loweringTool = new LoweringTool() { + @Override + public Node createStructuredBlockAnchor() { + if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) { + Anchor a = new Anchor(graph); + assert firstNode.predecessors().size() == 1; + Node pred = firstNode.predecessors().get(0); + int predIndex = firstNode.predecessorsIndex().get(0); + a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, pred, predIndex); + pred.successors().set(predIndex, a); + return a; + } + return firstNode; + } + }; + + for (final Node n : b.getInstructions()) { + if (n instanceof FixedNode) { + LoweringOp op = n.lookup(LoweringOp.class); + if (op != null) { + Node newNode = op.lower(n, loweringTool); + if (newNode != null) { + n.replace(newNode); + } + } + } + } + } + } + + public interface LoweringTool { + Node createStructuredBlockAnchor(); + } + + public interface LoweringOp extends Op { + Node lower(Node n, LoweringTool tool); + } +} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SplitCriticalEdgesPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SplitCriticalEdgesPhase.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SplitCriticalEdgesPhase.java Fri Jun 10 21:52:19 2011 +0200 @@ -36,12 +36,12 @@ List nodes = graph.getNodes(); for (int i = 0; i < nodes.size(); ++i) { Node n = nodes.get(i); - if (Schedule.trueSuccessorCount(n) > 1) { + if (IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { for (int j = 0; j < n.successors().size(); ++j) { Node succ = n.successors().get(j); - if (Schedule.truePredecessorCount(succ) > 1) { + if (IdentifyBlocksPhase.truePredecessorCount(succ) > 1) { Anchor a = new Anchor(graph); - a.successors().setAndClear(1, n, j); + a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, n, j); n.successors().set(j, a); } } diff -r 668603cb3263 -r c76db61fbb73 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 Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Fri Jun 10 21:52:19 2011 +0200 @@ -35,6 +35,7 @@ private final List predecessors = new ArrayList(); private List instructions = new ArrayList(); private Block dominator; + private Block javaBlock; private final List dominators = new ArrayList(); private Node firstNode; @@ -48,6 +49,14 @@ this.firstNode = node; } + public Block javaBlock() { + return javaBlock; + } + + public void setJavaBlock(Block javaBlock) { + this.javaBlock = javaBlock; + } + public Node lastNode() { return lastNode; } diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Fri Jun 10 21:52:19 2011 +0200 @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2011, 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.schedule; + +import java.util.*; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.value.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public class IdentifyBlocksPhase extends Phase { + private final List blocks = new ArrayList(); + private NodeMap nodeToBlock; + private Graph graph; + private boolean scheduleAllNodes; + + public IdentifyBlocksPhase(boolean scheduleAllNodes) { + super(scheduleAllNodes ? "FullSchedule" : "PartSchedule"); + this.scheduleAllNodes = scheduleAllNodes; + } + + + @Override + protected void run(Graph graph) { + this.graph = graph; + nodeToBlock = graph.createNodeMap(); + identifyBlocks(); + } + + public List getBlocks() { + return Collections.unmodifiableList(blocks); + } + + public NodeMap getNodeToBlock() { + return nodeToBlock; + } + + private Block createBlock() { + Block b = new Block(blocks.size()); + blocks.add(b); + return b; + } + + private Block assignBlock(Node n) { + Block curBlock = nodeToBlock.get(n); + if (curBlock == null) { + curBlock = createBlock(); + return assignBlock(n, curBlock); + } + return curBlock; + } + + + private Block assignBlock(Node n, Block b) { + assert nodeToBlock.get(n) == null; + nodeToBlock.set(n, b); + if (b.firstNode() == null) { + b.setFirstNode(n); + b.setLastNode(n); + } else { + if (b.lastNode() != null) { + b.getInstructions().add(b.lastNode()); + } + b.setLastNode(n); + } + b.setLastNode(n); + return b; + } + + public static boolean isFixed(Node n) { + return n != null && ((n instanceof FixedNode) || n == n.graph().start()); + } + + public static boolean isBlockEnd(Node n) { + return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Unwind; + } + + private void identifyBlocks() { + // Identify blocks. + final ArrayList blockBeginNodes = new ArrayList(); + NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() { + @Override + public boolean visit(Node n) { + if (!isFixed(n)) { + return false; + } + + if (n instanceof LoopBegin) { + // a LoopBegin is always a merge + assignBlock(n); + blockBeginNodes.add(n); + return true; + } + + Node singlePred = null; + for (Node pred : n.predecessors()) { + if (isFixed(pred)) { + if (singlePred == null) { + singlePred = pred; + } else { + // We have more than one predecessor => we are a merge block. + assignBlock(n); + blockBeginNodes.add(n); + return true; + } + } + } + + if (singlePred == null) { + // We have no predecessor => we are the start block. + assignBlock(n); + blockBeginNodes.add(n); + } else { + // We have a single predecessor => check its successor count. + if (isBlockEnd(singlePred)) { + assignBlock(n); + blockBeginNodes.add(n); + } else { + assignBlock(n, nodeToBlock.get(singlePred)); + } + } + return true; + }} + ); + + // Connect blocks. + for (Node n : blockBeginNodes) { + Block block = nodeToBlock.get(n); + for (Node pred : n.predecessors()) { + if (isFixed(pred)) { + Block predBlock = nodeToBlock.get(pred); + predBlock.addSuccessor(block); + } + } + + if (n instanceof Merge) { + for (Node usage : n.usages()) { + if (usage instanceof Phi) { + nodeToBlock.set(usage, block); + } + } + } + } + + for (Node n : graph.getNodes()) { + if (n instanceof FrameState) { + FrameState f = (FrameState) n; + if (f.predecessors().size() == 1) { + Block predBlock = nodeToBlock.get(f.predecessors().get(0)); + assert predBlock != null; + nodeToBlock.set(f, predBlock); + predBlock.getInstructions().add(f); + } else { + assert f.predecessors().size() == 0; + } + } + } + + computeDominators(); + + + if (scheduleAllNodes) { + + // Add successors of loop end nodes. Makes the graph cyclic. + for (Node n : blockBeginNodes) { + Block block = nodeToBlock.get(n); + if (n instanceof LoopBegin) { + LoopBegin loopBegin = (LoopBegin) n; + nodeToBlock.get(loopBegin.loopEnd()).addSuccessor(block); + } + } + + assignLatestPossibleBlockToNodes(); + sortNodesWithinBlocks(); + } else { + computeJavaBlocks(); + } + } + + private void computeJavaBlocks() { + + for (Block b : blocks) { + computeJavaBlock(b); + } + } + + private Block computeJavaBlock(Block b) { + if (b.javaBlock() == null) { + if (b.getPredecessors().size() == 0) { + b.setJavaBlock(b); + } else if (b.getPredecessors().size() == 1) { + Block pred = b.getPredecessors().get(0); + if (pred.getSuccessors().size() > 1) { + b.setJavaBlock(b); + } else { + b.setJavaBlock(computeJavaBlock(pred)); + } + } else { + Block dominatorBlock = b.getPredecessors().get(0); + for (int i=1; i instructions = b.getInstructions(); + List sortedInstructions = new ArrayList(); + assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; + + boolean scheduleFirst = true; + + if (b.firstNode() == b.lastNode()) { + Node node = b.firstNode(); + if (!(node instanceof Merge)) { + scheduleFirst = false; + } + } + if (scheduleFirst) { + addToSorting(b, b.firstNode(), sortedInstructions, map); + } + for (Node i : instructions) { + addToSorting(b, i, sortedInstructions, map); + } + addToSorting(b, b.lastNode(), sortedInstructions, map); + b.setInstructions(sortedInstructions); + } + + private void addToSorting(Block b, Node i, List sortedInstructions, NodeBitMap map) { + if (i == null || map.isMarked(i) || nodeToBlock.get(i) != b || i instanceof Phi || i instanceof Local) { + return; + } + + for (Node input : i.inputs()) { + addToSorting(b, input, sortedInstructions, map); + } + + for (Node pred : i.predecessors()) { + addToSorting(b, pred, sortedInstructions, map); + } + + map.mark(i); + + for (Node succ : i.successors()) { + if (succ instanceof FrameState) { + addToSorting(b, succ, sortedInstructions, map); + } + } + + // Now predecessors and inputs are scheduled => we can add this node. + if (!(i instanceof FrameState)) { + sortedInstructions.add(i); + } + } + + private void computeDominators() { + Block dominatorRoot = nodeToBlock.get(graph.start()); + assert dominatorRoot.getPredecessors().size() == 0; + CiBitMap visited = new CiBitMap(blocks.size()); + visited.set(dominatorRoot.blockID()); + LinkedList workList = new LinkedList(); + workList.add(dominatorRoot); + + while (!workList.isEmpty()) { + Block b = workList.remove(); + + List predecessors = b.getPredecessors(); + if (predecessors.size() == 1) { + b.setDominator(predecessors.get(0)); + } else if (predecessors.size() > 0) { + boolean delay = false; + for (Block pred : predecessors) { + if (pred != dominatorRoot && pred.dominator() == null) { + delay = true; + break; + } + } + + if (delay) { + workList.add(b); + continue; + } + + Block dominator = null; + for (Block pred : predecessors) { + if (dominator == null) { + dominator = pred; + } else { + dominator = commonDominator(dominator, pred); + } + } + b.setDominator(dominator); + } + + for (Block succ : b.getSuccessors()) { + if (!visited.get(succ.blockID())) { + visited.set(succ.blockID()); + workList.add(succ); + } + } + } + } + + public Block commonDominator(Block a, Block b) { + CiBitMap bitMap = new CiBitMap(blocks.size()); + Block cur = a; + while (cur != null) { + bitMap.set(cur.blockID()); + cur = cur.dominator(); + } + + cur = b; + while (cur != null) { + if (bitMap.get(cur.blockID())) { + return cur; + } + cur = cur.dominator(); + } + + throw new IllegalStateException("no common dominator between " + a + " and " + b); + } + + public static int trueSuccessorCount(Node n) { + if (n == null) { + return 0; + } + int i = 0; + for (Node s : n.successors()) { + if (isFixed(s)) { + i++; + } + } + return i; + } + + public static int truePredecessorCount(Node n) { + if (n == null) { + return 0; + } + int i = 0; + for (Node s : n.predecessors()) { + if (isFixed(s)) { + i++; + } + } + + if (n instanceof LoopBegin) { + i++; + } + return i; + } +} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Schedule.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Schedule.java Fri Jun 10 19:50:32 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,467 +0,0 @@ -/* - * Copyright (c) 2011, 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.schedule; - -import java.util.*; - -import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.compiler.value.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public class Schedule extends Phase { - private final List blocks = new ArrayList(); - private NodeMap nodeToBlock; - private Graph graph; - - - @Override - protected void run(Graph graph) { - this.graph = graph; - nodeToBlock = graph.createNodeMap(); - identifyBlocks(); - } - - public List getBlocks() { - return Collections.unmodifiableList(blocks); - } - - public NodeMap getNodeToBlock() { - return nodeToBlock; - } - - private Block createBlock() { - Block b = new Block(blocks.size()); - blocks.add(b); - return b; - } - - private Block assignBlock(Node n) { - Block curBlock = nodeToBlock.get(n); - if (curBlock == null) { - curBlock = createBlock(); - return assignBlock(n, curBlock); - } - return curBlock; - } - - - private Block assignBlock(Node n, Block b) { - assert nodeToBlock.get(n) == null; - nodeToBlock.set(n, b); - if (b.firstNode() == null) { - b.setFirstNode(n); - b.setLastNode(n); - } else { - if (b.lastNode() != null) { - b.getInstructions().add(b.lastNode()); - } - b.setLastNode(n); - } - b.setLastNode(n); - return b; - } - - public static boolean isFixed(Node n) { - return n != null && ((n instanceof FixedNode) || n == n.graph().start()); - } - - public static boolean isBlockEnd(Node n) { - return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Unwind; - } - - private void identifyBlocks() { - // Identify blocks. - final ArrayList blockBeginNodes = new ArrayList(); - NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() { - @Override - public boolean visit(Node n) { - if (!isFixed(n)) { - return false; - } - - if (n instanceof LoopBegin) { - // a LoopBegin is always a merge - assignBlock(n); - blockBeginNodes.add(n); - return true; - } - - Node singlePred = null; - for (Node pred : n.predecessors()) { - if (isFixed(pred)) { - if (singlePred == null) { - singlePred = pred; - } else { - // We have more than one predecessor => we are a merge block. - assignBlock(n); - blockBeginNodes.add(n); - return true; - } - } - } - - if (singlePred == null) { - // We have no predecessor => we are the start block. - assignBlock(n); - blockBeginNodes.add(n); - } else { - // We have a single predecessor => check its successor count. - if (isBlockEnd(singlePred)) { - assignBlock(n); - blockBeginNodes.add(n); - } else { - assignBlock(n, nodeToBlock.get(singlePred)); - } - } - return true; - }} - ); - - // Connect blocks. - for (Node n : blockBeginNodes) { - Block block = nodeToBlock.get(n); - for (Node pred : n.predecessors()) { - if (isFixed(pred)) { - Block predBlock = nodeToBlock.get(pred); - predBlock.addSuccessor(block); - } - } - - if (n instanceof Merge) { - for (Node usage : n.usages()) { - if (usage instanceof Phi) { - nodeToBlock.set(usage, block); - } - } - } - } - - for (Node n : graph.getNodes()) { - if (n instanceof FrameState) { - FrameState f = (FrameState) n; - if (f.predecessors().size() == 1) { - Block predBlock = nodeToBlock.get(f.predecessors().get(0)); - assert predBlock != null; - nodeToBlock.set(f, predBlock); - predBlock.getInstructions().add(f); - } else { - assert f.predecessors().size() == 0; - } - } - } - - computeDominators(); - - - - // Add successors of loop end nodes. Makes the graph cyclic. - for (Node n : blockBeginNodes) { - Block block = nodeToBlock.get(n); - if (n instanceof LoopBegin) { - LoopBegin loopBegin = (LoopBegin) n; - nodeToBlock.get(loopBegin.loopEnd()).addSuccessor(block); - } - } - - assignLatestPossibleBlockToNodes(); - sortNodesWithinBlocks(); - - //print(); - } - - private void assignLatestPossibleBlockToNodes() { - for (Node n : graph.getNodes()) { - assignLatestPossibleBlockToNode(n); - } - } - - private Block assignLatestPossibleBlockToNode(Node n) { - if (n == null) { - return null; - } - - Block prevBlock = nodeToBlock.get(n); - if (prevBlock != null) { - return prevBlock; - } - - Block block = null; - for (Node succ : n.successors()) { - block = getCommonDominator(block, assignLatestPossibleBlockToNode(succ)); - } - for (Node usage : n.usages()) { - if (usage instanceof Phi) { - Phi phi = (Phi) usage; - Merge merge = phi.merge(); - Block mergeBlock = nodeToBlock.get(merge); - assert mergeBlock != null : "no block for merge " + merge.id(); - for (int i = 0; i < phi.valueCount(); ++i) { - if (phi.valueAt(i) == n) { - if (mergeBlock.getPredecessors().size() == 0) { - TTY.println(merge.toString()); - TTY.println(phi.toString()); - TTY.println(merge.predecessors().toString()); - TTY.println("value count: " + phi.valueCount()); - } - block = getCommonDominator(block, mergeBlock.getPredecessors().get(i)); - } - } - } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { - Merge merge = ((FrameState) usage).block(); - for (Node pred : merge.predecessors()) { - if (isFixed(pred)) { - block = getCommonDominator(block, nodeToBlock.get(pred)); - } - } - } else { - block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); - } - } - - nodeToBlock.set(n, block); - if (block != null) { - block.getInstructions().add(n); - } - return block; - } - - private Block getCommonDominator(Block a, Block b) { - if (a == null) { - return b; - } - if (b == null) { - return a; - } - return commonDominator(a, b); - } - - private void sortNodesWithinBlocks() { - NodeBitMap map = graph.createNodeBitMap(); - for (Block b : blocks) { - sortNodesWithinBlocks(b, map); - } - } - - private void sortNodesWithinBlocks(Block b, NodeBitMap map) { - List instructions = b.getInstructions(); - List sortedInstructions = new ArrayList(); - assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; - - boolean scheduleFirst = true; - - if (b.firstNode() == b.lastNode()) { - Node node = b.firstNode(); - if (!(node instanceof Merge)) { - scheduleFirst = false; - } - } - if (scheduleFirst) { - addToSorting(b, b.firstNode(), sortedInstructions, map); - } - for (Node i : instructions) { - addToSorting(b, i, sortedInstructions, map); - } - addToSorting(b, b.lastNode(), sortedInstructions, map); - //assert b.firstNode() == sortedInstructions.get(0) : b.firstNode(); - // assert b.lastNode() == sortedInstructions.get(sortedInstructions.size() - 1); - b.setInstructions(sortedInstructions); -// TTY.println("Block " + b); -// for (Node n : sortedInstructions) { -// TTY.println("Node: " + n); -// } - } - - private void addToSorting(Block b, Node i, List sortedInstructions, NodeBitMap map) { - if (i == null || map.isMarked(i) || nodeToBlock.get(i) != b || i instanceof Phi || i instanceof Local) { - return; - } - - for (Node input : i.inputs()) { - addToSorting(b, input, sortedInstructions, map); - } - - for (Node pred : i.predecessors()) { - addToSorting(b, pred, sortedInstructions, map); - } - - map.mark(i); - - for (Node succ : i.successors()) { - if (succ instanceof FrameState) { - addToSorting(b, succ, sortedInstructions, map); - } - } - - // Now predecessors and inputs are scheduled => we can add this node. - if (!(i instanceof FrameState)) { - sortedInstructions.add(i); - } - } - - private void computeDominators() { - Block dominatorRoot = nodeToBlock.get(graph.start()); - assert dominatorRoot.getPredecessors().size() == 0; - CiBitMap visited = new CiBitMap(blocks.size()); - visited.set(dominatorRoot.blockID()); - LinkedList workList = new LinkedList(); - workList.add(dominatorRoot); - - while (!workList.isEmpty()) { - Block b = workList.remove(); - - List predecessors = b.getPredecessors(); - if (predecessors.size() == 1) { - b.setDominator(predecessors.get(0)); - } else if (predecessors.size() > 0) { - boolean delay = false; - for (Block pred : predecessors) { - if (pred != dominatorRoot && pred.dominator() == null) { - delay = true; - break; - } - } - - if (delay) { - workList.add(b); - continue; - } - - Block dominator = null; - for (Block pred : predecessors) { - if (dominator == null) { - dominator = pred; - } else { - dominator = commonDominator(dominator, pred); - } - } - b.setDominator(dominator); - } - - for (Block succ : b.getSuccessors()) { - if (!visited.get(succ.blockID())) { - visited.set(succ.blockID()); - workList.add(succ); - } - } - } - } - - public Block commonDominator(Block a, Block b) { - CiBitMap bitMap = new CiBitMap(blocks.size()); - Block cur = a; - while (cur != null) { - bitMap.set(cur.blockID()); - cur = cur.dominator(); - } - - cur = b; - while (cur != null) { - if (bitMap.get(cur.blockID())) { - return cur; - } - cur = cur.dominator(); - } - - print(); - assert false : "no common dominator between " + a + " and " + b; - return null; - } - - private void print() { - TTY.println("============================================"); - TTY.println("%d blocks", blocks.size()); - - for (Block b : blocks) { - TTY.println(); - TTY.print(b.toString()); - - TTY.print(" succs="); - for (Block succ : b.getSuccessors()) { - TTY.print(succ + ";"); - } - - TTY.print(" preds="); - for (Block pred : b.getPredecessors()) { - TTY.print(pred + ";"); - } - - if (b.dominator() != null) { - TTY.print(" dom=" + b.dominator()); - } - TTY.println(); - - if (b.getInstructions().size() > 0) { - TTY.print("first instr: " + b.getInstructions().get(0)); - TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1)); - } - } - -/* - TTY.println("============================================"); - TTY.println("%d nodes", nodeToBlock.size()); - for (Node n : graph.getNodes()) { - if (n != null) { - TTY.print("Node %d: %s", n.id(), n.getClass().toString()); - Block curBlock = nodeToBlock.get(n); - if (curBlock != null) { - TTY.print(" %s", curBlock); - } - TTY.println(); - } - }*/ - } - - public static int trueSuccessorCount(Node n) { - if (n == null) { - return 0; - } - int i = 0; - for (Node s : n.successors()) { - if (isFixed(s)) { - i++; - } - } - return i; - } - - public static int truePredecessorCount(Node n) { - if (n == null) { - return 0; - } - int i = 0; - for (Node s : n.predecessors()) { - if (isFixed(s)) { - i++; - } - } - - if (n instanceof LoopBegin) { - i++; - } - return i; - } -} diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java Fri Jun 10 21:52:19 2011 +0200 @@ -65,6 +65,10 @@ check(node); bitMap.clear(node.id()); } + + public void clearAll() { + bitMap.clearAll(); + } public void grow(Node node) { bitMap.grow(node.id() + 1); diff -r 668603cb3263 -r c76db61fbb73 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java Fri Jun 10 19:50:32 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java Fri Jun 10 21:52:19 2011 +0200 @@ -77,7 +77,6 @@ public void startCompiler() { originalOut = System.out; originalErr = System.err; - //TTY.println("startCompiler: " + originalOut); } public void shutdownCompiler() throws Throwable { diff -r 668603cb3263 -r c76db61fbb73 runfop.sh --- a/runfop.sh Fri Jun 10 19:50:32 2011 +0200 +++ b/runfop.sh Fri Jun 10 21:52:19 2011 +0200 @@ -15,4 +15,4 @@ echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." exit 1; fi -${JDK7}/bin/java -client -d64 -graal -XX:-GraalBailoutIsFatal -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve fop +${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve fop