changeset 3121:17d96a6af824

Introduced NotInstanceOf node. Optimize instanceof statements (i.e. do not materialize).
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Thu, 30 Jun 2011 17:53:23 +0200
parents 6930b31c2fd5
children ab218bdf7077
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NotInstanceOf.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java
diffstat 7 files changed, 123 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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);
         }
     }
 
--- 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;
         }
--- 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);
     }
--- 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);
     }
 }
--- /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);
+    }
+}
--- 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;
--- 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));
         }