changeset 15110:ca92d97bb0d6

BaselineCompiler: do not pass constants to blocks with multiple predecessors.
author Josef Eisl <josef.eisl@jku.at>
date Mon, 14 Apr 2014 16:47:36 +0200
parents e17fe8c1287d
children a775a766a3c8
files graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java
diffstat 1 files changed, 43 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Thu Apr 10 15:47:41 2014 +0200
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Mon Apr 14 16:47:36 2014 +0200
@@ -261,8 +261,7 @@
 
     @Override
     protected Value genIntegerMul(Kind kind, Value x, Value y) {
-        // TODO Auto-generated method stub
-        throw GraalInternalError.unimplemented("Auto-generated method stub");
+        return gen.emitMul(x, y);
     }
 
     @Override
@@ -584,9 +583,9 @@
         return v;
     }
 
-    private void createTarget(BciBlock block, LIRFrameStateBuilder state) {
-        assert block != null && state != null;
-        assert !block.isExceptionEntry || state.stackSize() == 1;
+    private void createTarget(BciBlock block) {
+        assert block != null && frameState != null;
+        assert !block.isExceptionEntry || frameState.stackSize() == 1;
 
         if (!blockVisited.get(block)) {
             /*
@@ -594,7 +593,14 @@
              * placeholder that later can be replaced with a MergeNode when we see this block again.
              */
             blockVisited.set(block);
-            block.entryState = state.copy();
+            if (block.getPredecessorCount() > 1) {
+                /*
+                 * If there are more than one predecessors we have to ensure that we are not passing
+                 * constants to the new framestate otherwise we will get interfacing problems.
+                 */
+                moveConstantsToVariables();
+            }
+            block.entryState = frameState.copy();
             block.entryState.clearNonLiveLocals(block, liveness, true);
 
             Debug.log("createTarget %s: first visit", block);
@@ -602,12 +608,17 @@
         }
 
         // We already saw this block before, so we have to merge states.
-        if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(state)) {
+        if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(frameState)) {
             throw new BailoutException("stacks do not match; bytecodes would not verify");
         }
 
         if (block.isLoopHeader) {
             assert currentBlock.getId() >= block.getId() : "must be backward branch";
+            if (currentBlock != null && currentBlock.numNormalSuccessors() == 1) {
+                // this is the only successor of the current block so we can adjust
+                adaptFramestate((LIRFrameStateBuilder) block.entryState);
+                return;
+            }
             GraalInternalError.unimplemented("Loops not yet supported");
         }
         assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
@@ -629,6 +640,29 @@
         Debug.log("createTarget %s: merging state", block);
     }
 
+    private void moveConstantsToVariables() {
+        Debug.log("moveConstantsToVariables: framestate before: %s", frameState);
+        for (int i = 0; i < frameState.stackSize(); i++) {
+            Value src = frameState.stackAt(i);
+            if (src instanceof Constant) {
+                AllocatableValue dst = gen.newVariable(src.getPlatformKind());
+                gen.emitMove(dst, src);
+                frameState.storeStack(i, dst);
+                Debug.log("introduce new variabe %s for stackslot %d (end of block %s", dst, i, currentBlock);
+            }
+        }
+        for (int i = 0; i < frameState.localsSize(); i++) {
+            Value src = frameState.localAt(i);
+            if (src instanceof Constant) {
+                AllocatableValue dst = gen.newVariable(src.getPlatformKind());
+                gen.emitMove(dst, src);
+                frameState.storeLocal(i, dst);
+                Debug.log("introduce new variabe %s for local %d (end of block %s", dst, i, currentBlock);
+            }
+        }
+        Debug.log("moveConstantsToVariables: framestate after: %s", frameState);
+    }
+
     private void adaptValues(Value dst, Value src) {
         if (dst == null) {
             return;
@@ -636,7 +670,7 @@
         assert src != null : "Source is null but Destination is not!";
 
         if (!dst.equals(src)) {
-            assert dst instanceof AllocatableValue;
+            assert dst instanceof AllocatableValue : "Not an AllocatableValue: " + dst;
             gen.emitMove((AllocatableValue) dst, src);
         }
     }
@@ -725,7 +759,7 @@
     }
 
     LabelRef getSuccessor(int index) {
-        createTarget(currentBlock.getSuccessor(index), frameState);
+        createTarget(currentBlock.getSuccessor(index));
         return LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, index);
     }