changeset 2763:5e8a69041cd7

Model phi inputs as direct inputs in the graph instead of referring to the framestates of the predecessors.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Mon, 23 May 2011 14:51:18 +0200
parents ca31e84ff154
children 99912abb3ff7
files graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java
diffstat 6 files changed, 94 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Mon May 23 14:51:18 2011 +0200
@@ -270,6 +270,10 @@
 
 
     private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) {
+        mergeOrClone(first, stateAfter, loopHeader, false);
+    }
+
+    private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader, boolean blockAppended) {
         if (first instanceof BlockBegin) {
             BlockBegin block = (BlockBegin) first;
             FrameState existingState = block.stateBefore();
@@ -293,7 +297,7 @@
                 assert existingState.localsSize() == stateAfter.localsSize();
                 assert existingState.stackSize() == stateAfter.stackSize();
 
-                existingState.merge(block, stateAfter);
+                existingState.merge(block, stateAfter, blockAppended);
             }
         } else {
             assert false;
@@ -304,13 +308,16 @@
         int stackSize = newState.stackSize();
         for (int i = 0; i < stackSize; i++) {
             // always insert phis for the stack
-            newState.setupPhiForStack(merge, i);
+            Value x = newState.stackAt(i);
+            if (x != null) {
+                newState.setupPhiForStack(merge, i).addInput(x);
+            }
         }
         int localsSize = newState.localsSize();
         for (int i = 0; i < localsSize; i++) {
             Value x = newState.localAt(i);
             if (x != null) {
-                newState.setupPhiForLocal(merge, i);
+                newState.setupPhiForLocal(merge, i).addInput(x);
             }
         }
     }
@@ -438,7 +445,7 @@
         if (oldState != null && dispatchEntry.predecessors().size() == 1) {
             dispatchEntry.setStateBefore(null);
         }
-        mergeOrClone(dispatchEntry, state, false);
+        mergeOrClone(dispatchEntry, state, false, true);
         FrameState mergedState = dispatchEntry.stateBefore();
 
         if (dispatchEntry.next() instanceof ExceptionDispatch) {
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Mon May 23 14:51:18 2011 +0200
@@ -40,7 +40,7 @@
 
     @Override
     protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+        return super.inputCount() + INPUT_COUNT + maxValues;
     }
 
     @Override
@@ -56,11 +56,13 @@
         return (BlockBegin) inputs().get(super.inputCount() + INPUT_BLOCK);
     }
 
-    public BlockBegin setBlock(Value n) {
+    public Value setBlock(Value n) {
         return (BlockBegin) inputs().set(super.inputCount() + INPUT_BLOCK, n);
     }
 
     private final int index;
+    private final int maxValues;
+    private int usedInputCount;
 
     /**
      * Create a new Phi for the specified join block and local variable (or operand stack) slot.
@@ -70,7 +72,13 @@
      * @param graph
      */
     public Phi(CiKind kind, BlockBegin block, int index, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this(kind, block, index, 2, graph);
+    }
+
+    public Phi(CiKind kind, BlockBegin block, int index, int maxValues, Graph graph) {
+        super(kind, INPUT_COUNT + maxValues, SUCCESSOR_COUNT, graph);
+        usedInputCount = 1;
+        this.maxValues = maxValues;
         this.index = index;
         setBlock(block);
     }
@@ -116,7 +124,7 @@
      * @return the instruction that produced the value in the i'th predecessor
      */
     public Value inputAt(int i) {
-        return inputIn(block().blockPredecessors().get(i).stateAfter());
+        return (Value) inputs().get(i + INPUT_COUNT);
     }
 
     /**
@@ -137,7 +145,7 @@
      * @return the number of inputs in this phi
      */
     public int phiInputCount() {
-        return block().blockPredecessors().size();
+        return usedInputCount - 1;
     }
 
     @Override
@@ -163,5 +171,21 @@
         return "Phi: " + index + " (" + phiInputCount() + ")";
     }
 
+    public Phi addInput(Value y) {
+        assert !this.isDeleted() && !y.isDeleted();
+        Phi phi = this;
+        if (usedInputCount == inputs().size()) {
+            phi = new Phi(kind, block(), index, maxValues * 2, graph());
+            for (int i = 0; i < phiInputCount(); ++i) {
+                phi.addInput(inputAt(i));
+            }
+            phi.addInput(y);
+            this.replace(phi);
+        } else {
+            phi.inputs().set(usedInputCount++, y);
+        }
+        return phi;
+    }
+
 
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java	Mon May 23 14:51:18 2011 +0200
@@ -22,7 +22,6 @@
  */
 package com.sun.c1x.lir;
 
-import com.sun.c1x.ir.*;
 import com.sun.cri.ci.*;
 
 /**
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Mon May 23 14:51:18 2011 +0200
@@ -256,17 +256,20 @@
      * @param block the block begin for which we are creating the phi
      * @param i the index into the stack for which to create a phi
      */
-    public void setupPhiForStack(BlockBegin block, int i) {
+    public Phi setupPhiForStack(BlockBegin block, int i) {
         Value p = stackAt(i);
         if (p != null) {
             if (p instanceof Phi) {
                 Phi phi = (Phi) p;
                 if (phi.block() == block && phi.isOnStack() && phi.stackIndex() == i) {
-                    return;
+                    return phi;
                 }
             }
-            inputs().set(localsSize + i, new Phi(p.kind, block, -i - 1, graph()));
+            Phi phi = new Phi(p.kind, block, -i - 1, graph());
+            inputs().set(localsSize + i, phi);
+            return phi;
         }
+        return null;
     }
 
     /**
@@ -274,15 +277,17 @@
      * @param block the block begin for which we are creating the phi
      * @param i the index of the local variable for which to create the phi
      */
-    public void setupPhiForLocal(BlockBegin block, int i) {
+    public Phi setupPhiForLocal(BlockBegin block, int i) {
         Value p = localAt(i);
         if (p instanceof Phi) {
             Phi phi = (Phi) p;
             if (phi.block() == block && phi.isLocal() && phi.localIndex() == i) {
-                return;
+                return phi;
             }
         }
-        storeLocal(i, new Phi(p.kind, block, i, graph()));
+        Phi phi = new Phi(p.kind, block, i, graph());
+        storeLocal(i, phi);
+        return phi;
     }
 
     /**
@@ -312,28 +317,6 @@
         return localsSize + stackSize;
     }
 
-    public void checkPhis(BlockBegin block, FrameState other) {
-        checkSize(other);
-        for (int i = 0; i < valuesSize(); i++) {
-            Value x = valueAt(i);
-            Value y = other.valueAt(i);
-            if (x != null && x != y) {
-                if (x instanceof Phi) {
-                    Phi phi = (Phi) x;
-                    if (phi.block() == block) {
-                        for (int j = 0; j < phi.phiInputCount(); j++) {
-                            if (phi.inputIn(other) == null) {
-                                throw new CiBailout("phi " + phi + " has null operand at new predecessor");
-                            }
-                        }
-                        continue;
-                    }
-                }
-                throw new CiBailout("instruction is not a phi or null at " + i);
-            }
-        }
-    }
-
     private void checkSize(FrameStateAccess other) {
         if (other.stackSize() != stackSize()) {
             throw new CiBailout("stack sizes do not match");
@@ -342,7 +325,7 @@
         }
     }
 
-    public void merge(BlockBegin block, FrameStateAccess other) {
+    public void merge(BlockBegin block, FrameStateAccess other, boolean blockAppended) {
         checkSize(other);
         for (int i = 0; i < valuesSize(); i++) {
             Value x = valueAt(i);
@@ -359,12 +342,34 @@
                         inputs().set(i, null);
                         continue;
                     }
+                    Phi phi = null;
                     if (i < localsSize) {
                         // this a local
-                        setupPhiForLocal(block, i);
+                        phi = setupPhiForLocal(block, i);
                     } else {
                         // this is a stack slot
-                        setupPhiForStack(block, i - localsSize);
+                        phi = setupPhiForStack(block, i - localsSize);
+                    }
+
+                    Phi originalPhi = phi;
+                    if (phi.phiInputCount() == 0) {
+                        int size = block.predecessors().size();
+                        if (blockAppended) {
+                            size--;
+                        }
+                        for (int j = 0; j < size; ++j) {
+                            phi = phi.addInput(x);
+                        }
+                        phi = phi.addInput(y);
+                    } else {
+                        phi = phi.addInput(y);
+                    }
+                    if (originalPhi != phi) {
+                        for (int j = 0; j < other.localsSize() + other.stackSize(); ++j) {
+                            if (other.valueAt(j) == originalPhi) {
+                                other.setValueAt(j, phi);
+                            }
+                        }
                     }
                 }
             }
@@ -467,4 +472,9 @@
     public void visitFrameState(FrameState i) {
         // nothing to do for now
     }
+
+    @Override
+    public void setValueAt(int j, Value v) {
+        inputs().set(j, v);
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java	Mon May 23 14:51:18 2011 +0200
@@ -44,4 +44,6 @@
 
     FrameState duplicateWithEmptyStack(int bci);
 
+    void setValueAt(int j, Value v);
+
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java	Sat May 21 17:56:11 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java	Mon May 23 14:51:18 2011 +0200
@@ -477,4 +477,15 @@
         }
     }
 
+    @Override
+    public void setValueAt(int i, Value v) {
+        if (i < locals.length) {
+            locals[i] = v;
+        } else if (i < locals.length + stackIndex) {
+            stack[i - locals.length] = v;
+        } else {
+            locks.set(i - locals.length - stack.length, v);
+        }
+    }
+
 }