# HG changeset patch # User Thomas Wuerthinger # Date 1309449203 -7200 # Node ID 17d96a6af824b1d6108cef893bcdab981975f711 # Parent 6930b31c2fd52a61928063c96e6ec0aebe88de2f Introduced NotInstanceOf node. Optimize instanceof statements (i.e. do not materialize). diff -r 6930b31c2fd5 -r 17d96a6af824 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 Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 30 17:53:23 2011 +0200 @@ -455,7 +455,7 @@ @Override public void visitIf(If x) { assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination"; - emitBooleanBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor())); + emitBooleanBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), null); } public void emitBranch(BooleanNode n, Condition cond, LIRBlock trueSuccessor, LIRBlock falseSucc) { @@ -473,20 +473,22 @@ lir.branch(cond, trueSuccessor); } - public void emitBooleanBranch(Node node, LIRBlock trueSuccessor, LIRBlock falseSuccessor) { + public void emitBooleanBranch(Node node, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) { if (node instanceof Compare) { emitCompare((Compare) node, trueSuccessor, falseSuccessor); } else if (node instanceof InstanceOf) { - emitInstanceOf((InstanceOf) node, trueSuccessor, falseSuccessor); + emitInstanceOf((TypeCheck) node, trueSuccessor, falseSuccessor, info); + } else if (node instanceof NotInstanceOf) { + emitInstanceOf((TypeCheck) node, falseSuccessor, trueSuccessor, info); } else { throw Util.unimplemented(node.toString()); } } - private void emitInstanceOf(InstanceOf x, LIRBlock trueSuccessor, LIRBlock falseSuccessor) { + private void emitInstanceOf(TypeCheck x, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) { XirArgument obj = toXirArgument(x.object()); XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass()); - emitXir(snippet, x, stateFor(x), null, false); + emitXir(snippet, x, info, null, false); LIRXirInstruction instr = (LIRXirInstruction) lir.instructionsList().get(lir.instructionsList().size() - 1); instr.setTrueSuccessor(trueSuccessor); instr.setFalseSuccessor(falseSuccessor); @@ -767,7 +769,7 @@ DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); deoptimizationStubs.add(stub); - emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info)); + emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); } } diff -r 6930b31c2fd5 -r 17d96a6af824 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Thu Jun 30 17:53:23 2011 +0200 @@ -180,6 +180,30 @@ TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind); } } + } else if (compare.x().isConstant() && compare.y() instanceof MaterializeNode) { + return optimizeMaterialize(compare, compare.x().asConstant(), (MaterializeNode) compare.y()); + } else if (compare.y().isConstant() && compare.x() instanceof MaterializeNode) { + return optimizeMaterialize(compare, compare.y().asConstant(), (MaterializeNode) compare.x()); + } + return compare; + } + + private Node optimizeMaterialize(Compare compare, CiConstant constant, MaterializeNode materializeNode) { + if (constant.kind == CiKind.Int) { + boolean isFalseCheck = (constant.asInt() == 0); + if (compare.condition == Condition.EQ || compare.condition == Condition.NE) { + if (compare.condition == Condition.NE) { + isFalseCheck = !isFalseCheck; + } + BooleanNode result = materializeNode.value(); + if (isFalseCheck) { + result = result.negate(); + } + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Removed materialize replacing with " + result); + } + return result; + } } return compare; } diff -r 6930b31c2fd5 -r 17d96a6af824 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java Thu Jun 30 17:53:23 2011 +0200 @@ -66,6 +66,11 @@ } @Override + public BooleanNode negate() { + return new NotInstanceOf(targetClassInstruction(), object(), graph()); + } + + @Override public Node copy(Graph into) { return new InstanceOf(null, null, into); } diff -r 6930b31c2fd5 -r 17d96a6af824 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java Thu Jun 30 17:53:23 2011 +0200 @@ -26,9 +26,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; -import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; /** @@ -54,11 +52,11 @@ /** * The instruction which produces the input value to this instruction. */ - public Node value() { - return inputs().get(super.inputCount() + INPUT_VALUE); + public BooleanNode value() { + return (BooleanNode) inputs().get(super.inputCount() + INPUT_VALUE); } - public void setValue(Value n) { + public void setValue(BooleanNode n) { inputs().set(super.inputCount() + INPUT_VALUE, n); } @@ -69,7 +67,7 @@ * @param kind the result type of this instruction * @param graph */ - public MaterializeNode(Value value, Graph graph) { + public MaterializeNode(BooleanNode value, Graph graph) { super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph); setValue(value); } @@ -80,7 +78,7 @@ @Override public boolean valueEqual(Node i) { - return (i instanceof Materialize); + return (i instanceof MaterializeNode); } @SuppressWarnings("unchecked") @@ -97,7 +95,7 @@ @Override public void generate(Node n, LIRGenerator generator) { LIRBlock trueSuccessor = new LIRBlock(new Label(), null); - generator.emitBooleanBranch(((Materialize) n).value(), trueSuccessor, null); + generator.emitBooleanBranch(((MaterializeNode) n).value(), trueSuccessor, null, null); CiValue result = generator.createResultVariable((Value) n); LIRList lir = generator.lir(); lir.move(CiConstant.FALSE, result); @@ -116,6 +114,6 @@ @Override public Node copy(Graph into) { - return new Materialize(null, into); + return new MaterializeNode(null, into); } } diff -r 6930b31c2fd5 -r 17d96a6af824 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NotInstanceOf.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/NotInstanceOf.java Thu Jun 30 17:53:23 2011 +0200 @@ -0,0 +1,77 @@ +/* + * 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.*; + +/** + * The {@code InstanceOf} instruction represents an instanceof test. + */ +public final class NotInstanceOf extends TypeCheck { + + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + + /** + * Constructs a new InstanceOf instruction. + * @param targetClass the target class of the instanceof check + * @param object the instruction producing the object input to this instruction + * @param graph + */ + public NotInstanceOf(Constant targetClassInstruction, Value object, Graph graph) { + super(targetClassInstruction, object, CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + } + + @Override + public void accept(ValueVisitor v) { + } + + @Override + public int valueNumber() { + return Util.hash1(Bytecodes.INSTANCEOF, object()); + } + + @Override + public boolean valueEqual(Node i) { + return i instanceof NotInstanceOf; + } + + @Override + public void print(LogStream out) { + out.print("instanceof(").print(object()).print(") ").print(CiUtil.toJavaName(targetClass())); + } + + @Override + public BooleanNode negate() { + return new InstanceOf(targetClassInstruction(), object(), graph()); + } + + @Override + public Node copy(Graph into) { + return new NotInstanceOf(null, null, into); + } +} diff -r 6930b31c2fd5 -r 17d96a6af824 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Thu Jun 30 17:53:23 2011 +0200 @@ -29,7 +29,7 @@ /** * The {@code TypeCheck} instruction is the base class of casts and instanceof tests. */ -public abstract class TypeCheck extends FloatingNode { +public abstract class TypeCheck extends BooleanNode { private static final int INPUT_COUNT = 2; private static final int INPUT_OBJECT = 0; diff -r 6930b31c2fd5 -r 17d96a6af824 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 Thu Jun 30 17:03:10 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 30 17:53:23 2011 +0200 @@ -754,7 +754,7 @@ Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi); Value object = frameState.apop(); if (typeInstruction != null) { - frameState.ipush(append(new Materialize(new InstanceOf(typeInstruction, object, graph), graph))); + frameState.ipush(append(new MaterializeNode(new InstanceOf(typeInstruction, object, graph), graph))); } else { frameState.ipush(appendConstant(CiConstant.INT_0)); }