changeset 2532:3fca504f28ba

Reinsert phi simplifier (does not seem to be optional). Disabled canonicalizer.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 19:00:40 +0200
parents eca17668badf
children c480605ef068
files graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java
diffstat 4 files changed, 232 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed Apr 27 18:17:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed Apr 27 19:00:40 2011 +0200
@@ -204,6 +204,8 @@
 
         this.operands = new OperandPool(compilation.target);
 
+        new PhiSimplifier(ir);
+
         // mark the liveness of all instructions if it hasn't already been done by the optimizer
         LivenessMarker livenessMarker = new LivenessMarker(ir);
         C1XMetrics.LiveHIRInstructions += livenessMarker.liveCount();
@@ -1275,7 +1277,7 @@
         if (suxVal instanceof Phi) {
             Phi phi = (Phi) suxVal;
             // curVal can be null without phi being null in conjunction with inlining
-            if (phi.isLive() && curVal != null && curVal != phi) {
+            if (phi.isLive() && !phi.isDeadPhi() && curVal != null && curVal != phi) {
                 assert curVal.isLive() : "value not live: " + curVal + ", suxVal=" + suxVal;
                 assert !phi.isIllegal() : "illegal phi cannot be marked as live";
                 if (curVal instanceof Phi) {
@@ -1349,6 +1351,7 @@
     }
 
     private CiValue operandForPhi(Phi phi) {
+        assert !phi.isDeadPhi();
         if (phi.operand().isIllegal()) {
             // allocate a variable for this phi
             CiVariable operand = newVariable(phi.kind);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java	Wed Apr 27 19:00:40 2011 +0200
@@ -0,0 +1,99 @@
+/*
+ * 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.sun.c1x.opt;
+
+import com.sun.c1x.ir.*;
+import com.sun.c1x.value.*;
+import com.sun.c1x.graph.IR;
+
+/**
+ * This class allows instructions to be substituted within an IR graph. It allows
+ * registering substitutions and iterates over the instructions of a program and replaces
+ * the occurrence of each instruction with its substitution, if it has one.
+ *
+ * @author Ben L. Titzer
+ */
+public final class InstructionSubstituter implements BlockClosure, ValueClosure {
+
+    final IR ir;
+    boolean hasSubstitution;
+
+    public InstructionSubstituter(IR ir) {
+        this.ir = ir;
+    }
+
+    public void apply(BlockBegin block) {
+        Instruction last = null;
+        if (block.exceptionHandlerStates() != null) {
+            for (FrameState s : block.exceptionHandlerStates()) {
+                s.valuesDo(this);
+            }
+        }
+        for (Instruction n = block; n != null; n = last.next()) {
+            n.allValuesDo(this);
+            if (n.subst != null && last != null) {
+                // this instruction has a substitution, skip it
+                last.resetNext(n.next());
+            } else {
+                last = n;
+            }
+        }
+    }
+
+    public void finish() {
+        if (hasSubstitution) {
+            ir.startBlock.iterateAnyOrder(this, false);
+        }
+    }
+
+    public boolean hasSubst(Value i) {
+        return i.subst != null;
+    }
+
+    public void setSubst(Value i, Value n) {
+        if (i == n) {
+            i.subst = null;
+        } else {
+            hasSubstitution = true;
+            i.subst = n;
+        }
+    }
+
+    public Value getSubst(Value i) {
+        Value p = i;
+        while (true) {
+            if (p.subst == null) {
+                break;
+            }
+            p = p.subst;
+        }
+        return p;
+    }
+
+    public Value apply(Value i) {
+        if (i != null) {
+            return getSubst(i);
+        }
+        return i;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java	Wed Apr 27 19:00:40 2011 +0200
@@ -0,0 +1,128 @@
+/*
+ * 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.sun.c1x.opt;
+
+import com.sun.c1x.graph.IR;
+import com.sun.c1x.ir.*;
+import com.sun.c1x.value.*;
+
+/**
+ * The {@code PhiSimplifier} class is a helper class that can reduce phi instructions.
+ *
+ * @author Ben L. Titzer
+ */
+public final class PhiSimplifier implements BlockClosure {
+
+    final IR ir;
+    final InstructionSubstituter subst;
+
+    public PhiSimplifier(IR ir) {
+        this.ir = ir;
+        this.subst = new InstructionSubstituter(ir);
+        ir.startBlock.iterateAnyOrder(this, false);
+        subst.finish();
+    }
+
+    /**
+     * This method is called for each block and processes any phi statements in the block.
+     * @param block the block to apply the simplification to
+     */
+    public void apply(BlockBegin block) {
+        FrameState state = block.stateBefore();
+        for (int i = 0; i < state.stackSize(); i++) {
+            simplify(state.stackAt(i));
+        }
+        for (int i = 0; i < state.localsSize(); i++) {
+            simplify(state.localAt(i));
+        }
+    }
+
+    Value simplify(Value x) {
+        if (x == null || !(x instanceof Phi)) {
+            return x;
+        }
+        Phi phi = (Phi) x;
+        if (phi.hasSubst()) {
+            // already substituted, but the subst could be a phi itself, so simplify
+            return simplify(subst.getSubst(phi));
+        } else if (phi.checkFlag(Value.Flag.PhiCannotSimplify)) {
+            // already tried, cannot simplify this phi
+            return phi;
+        } else if (phi.checkFlag(Value.Flag.PhiVisited)) {
+            // break cycles in phis
+            return phi;
+        } else if (phi.isIllegal()) {
+            // don't bother with illegals
+            return phi;
+        } else {
+            // attempt to simplify the phi by recursively simplifying its operands
+            phi.setFlag(Value.Flag.PhiVisited);
+            Value phiSubst = null;
+            int max = phi.inputCount();
+            boolean cannotSimplify = false;
+            for (int i = 0; i < max; i++) {
+                Value oldInstr = phi.inputAt(i);
+
+                if (oldInstr == null || oldInstr.isIllegal() || oldInstr.isDeadPhi()) {
+                    // if one operand is illegal, make the entire phi illegal
+                    phi.makeDead();
+                    phi.clearFlag(Value.Flag.PhiVisited);
+                    return phi;
+                }
+
+                Value newInstr = simplify(oldInstr);
+
+                if (newInstr == null || newInstr.isIllegal() || newInstr.isDeadPhi()) {
+                    // if the subst instruction is illegal, make the entire phi illegal
+                    phi.makeDead();
+                    phi.clearFlag(Value.Flag.PhiVisited);
+                    return phi;
+                }
+
+                // attempt to simplify this operand
+                if (!cannotSimplify) {
+
+                    if (newInstr != phi && newInstr != phiSubst) {
+                        if (phiSubst == null) {
+                            phiSubst = newInstr;
+                            continue;
+                        }
+                        // this phi cannot be simplified
+                        cannotSimplify = true;
+                    }
+                }
+            }
+            if (cannotSimplify) {
+                phi.setFlag(Value.Flag.PhiCannotSimplify);
+                phi.clearFlag(Value.Flag.PhiVisited);
+                return phi;
+            }
+
+            // successfully simplified the phi
+            assert phiSubst != null : "illegal phi function";
+            phi.clearFlag(Value.Flag.PhiVisited);
+            subst.setSubst(phi, phiSubst);
+            return phiSubst;
+        }
+    }
+}
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Wed Apr 27 18:17:18 2011 +0200
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Wed Apr 27 19:00:40 2011 +0200
@@ -38,6 +38,7 @@
         C1XOptions.CommentedAssembly = false;
         C1XOptions.MethodEndBreakpointGuards = 2;
         C1XOptions.ResolveClassBeforeStaticInvoke = false;
+        C1XOptions.OptCanonicalize = false;
     }
 
     public static boolean setOption(String option) {