changeset 3033:ebd1d48a1ae1

Local value numbering for inserted null check guards.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Mon, 20 Jun 2011 17:59:37 +0200
parents 2433838f0414
children 077f999e3583
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java
diffstat 7 files changed, 68 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Mon Jun 20 17:59:37 2011 +0200
@@ -36,6 +36,9 @@
     private static final boolean ____ = false;
     // Checkstyle: resume
 
+
+    public static boolean Lower                              = true;
+
     // inlining settings
     public static boolean Inline                             = true;
     public static boolean CacheGraphs                        = ____;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Mon Jun 20 17:59:37 2011 +0200
@@ -104,7 +104,9 @@
 
         new LoopPhase().apply(graph);
 
-        new LoweringPhase(compilation.runtime).apply(graph);
+        if (GraalOptions.Lower) {
+            new LoweringPhase(compilation.runtime).apply(graph);
+        }
 
         IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true);
         schedule.apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Anchor.java	Mon Jun 20 17:59:37 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -52,6 +54,42 @@
         out.print("anchor ").print(next());
     }
 
+    public Iterable<GuardNode> happensAfterGuards() {
+        final Iterator<Node> usages = this.usages().iterator();
+        return new Iterable<GuardNode>() {
+            public Iterator<GuardNode> iterator() {
+                return new Iterator<GuardNode>() {
+                    private GuardNode next;
+                    @Override
+                    public boolean hasNext() {
+                        if (next == null) {
+                            while (usages.hasNext()) {
+                                Node cur = usages.next();
+                                if (cur instanceof GuardNode) {
+                                    next = ((GuardNode) cur);
+                                    break;
+                                }
+                            }
+                        }
+                        return next != null;
+                    }
+
+                    @Override
+                    public GuardNode next() {
+                        GuardNode result = next;
+                        next = null;
+                        return result;
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new IllegalStateException();
+                    }
+                };
+            }
+        };
+    }
+
     @Override
     public Node copy(Graph into) {
         return new Anchor(into);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Mon Jun 20 17:59:37 2011 +0200
@@ -27,50 +27,13 @@
 import com.sun.cri.ci.*;
 
 
-public final class MemoryRead extends Instruction {
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_NODE = 0;
-    private static final int INPUT_GUARD = 1;
-
+public final class MemoryRead extends MemoryAccess {
+    private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
 
-    private int displacement;
-    private CiKind valueKind;
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value location() {
-        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
-    }
-
-    public Value setLocation(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_NODE, n);
-    }
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public GuardNode guard() {
-        return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD);
-    }
-
-    public void setGuard(GuardNode n) {
-        inputs().set(super.inputCount() + INPUT_GUARD, n);
-    }
-
-    public int displacement() {
-        return displacement;
-    }
-
-    public CiKind valueKind() {
-        return valueKind;
-    }
 
     public MemoryRead(CiKind kind, int displacement, Graph graph) {
-        super(kind.stackKind(), INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        this.displacement = displacement;
-        this.valueKind = kind;
+        super(kind, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Mon Jun 20 17:59:37 2011 +0200
@@ -154,28 +154,6 @@
     }
 
     /**
-     * Compute the value number of this Instruction. Local and global value numbering
-     * optimizations use a hash map, and the value number provides a hash code.
-     * If the instruction cannot be value numbered, then this method should return
-     * {@code 0}.
-     * @return the hashcode of this instruction
-     */
-    public int valueNumber() {
-        return 0;
-    }
-
-    /**
-     * Checks that this instruction is equal to another instruction for the purposes
-     * of value numbering.
-     * @param i the other instruction
-     * @return {@code true} if this instruction is equivalent to the specified
-     * instruction w.r.t. value numbering
-     */
-    public boolean valueEqual(Node i) {
-        return false;
-    }
-
-    /**
      * This method supports the visitor pattern by accepting a visitor and calling the
      * appropriate {@code visit()} method.
      *
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Mon Jun 20 17:59:37 2011 +0200
@@ -52,6 +52,7 @@
     public abstract void visitLogic(Logic i);
     public abstract void visitLookupSwitch(LookupSwitch i);
     public abstract void visitMemoryRead(MemoryRead i);
+    public abstract void visitMemoryWrite(MemoryWrite i);
     public abstract void visitMonitorAddress(MonitorAddress monitorAddress);
     public abstract void visitMonitorEnter(MonitorEnter i);
     public abstract void visitMonitorExit(MonitorExit i);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 20 15:14:36 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Mon Jun 20 17:59:37 2011 +0200
@@ -61,9 +61,16 @@
                         firstNode.graph().start().setStart(a);
                         firstNodeValue[0] = a;
                         return a;
-                    } else if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) {
+                    } else if (firstNode instanceof Merge) {
+                        Merge merge = (Merge) firstNode;
                         Anchor a = new Anchor(graph);
-                        assert firstNode.predecessors().size() == 1;
+                        a.setNext(merge.next());
+                        merge.setNext(a);
+                        firstNodeValue[0] = a;
+                        return a;
+                    } else if (!(firstNode instanceof Anchor)) {
+                        Anchor a = new Anchor(graph);
+                        assert firstNode.predecessors().size() == 1 : firstNode;
                         Node pred = firstNode.predecessors().get(0);
                         int predIndex = pred.successors().indexOf(firstNode);
                         pred.successors().set(predIndex, a);
@@ -81,10 +88,17 @@
 
                 @Override
                 public Node createGuard(Node condition) {
-                    GuardNode guard = new GuardNode(graph);
-                    guard.setAnchor((FixedNode) getGuardAnchor());
-                    guard.setNode((BooleanNode) condition);
-                    return guard;
+                    Anchor anchor = (Anchor) getGuardAnchor();
+                    for (GuardNode guard : anchor.happensAfterGuards()) {
+                        if (guard.node().valueEqual(condition)) {
+                            condition.delete();
+                            return guard;
+                        }
+                    }
+                    GuardNode newGuard = new GuardNode(graph);
+                    newGuard.setAnchor(anchor);
+                    newGuard.setNode((BooleanNode) condition);
+                    return newGuard;
                 }
             };