changeset 15033:c6cf3474351c

BaselineBytecodeParser: add createTarget.
author Josef Eisl <josef.eisl@jku.at>
date Mon, 07 Apr 2014 21:03:31 +0200
parents c9bf91560c82
children 136d1f3f1371
files graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java
diffstat 1 files changed, 54 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Mon Apr 07 20:19:01 2014 +0200
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Mon Apr 07 21:03:31 2014 +0200
@@ -40,6 +40,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.BciBlockMapping.BciBlock;
+import com.oracle.graal.java.BciBlockMapping.LocalLiveness;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
@@ -51,6 +52,8 @@
     protected LIRGenerator gen;
     private LIRGenerationResult lirGenRes;
     private BytecodeLIRBuilder lirBuilder;
+    @SuppressWarnings("unused") private BciBlock[] loopHeaders;
+    private LocalLiveness liveness;
 
     public BaselineBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
                     LIRFrameStateBuilder frameState, BytecodeStream stream, ProfilingInfo profilingInfo, ConstantPool constantPool, int entryBCI, Backend backend) {
@@ -74,6 +77,8 @@
 
             // compute the block map, setup exception handlers and get the entrypoint(s)
             BciBlockMapping blockMap = BciBlockMapping.create(method);
+            loopHeaders = blockMap.loopHeaders;
+            liveness = blockMap.liveness;
             // add predecessors
             for (BciBlock block : blockMap.blocks) {
                 for (BciBlock successor : block.getSuccessors()) {
@@ -390,8 +395,8 @@
             }
         }
 
-        LabelRef trueDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0);
-        LabelRef falseDestination = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 1);
+        LabelRef trueDestination = getSuccessor(0);
+        LabelRef falseDestination = getSuccessor(1);
 
         gen.emitCompareBranch(x.getKind(), x, y, cond, false, trueDestination, falseDestination, probability);
     }
@@ -558,6 +563,47 @@
         return v;
     }
 
+    private void createTarget(BciBlock block, LIRFrameStateBuilder state) {
+        assert block != null && state != null;
+        assert !block.isExceptionEntry || state.stackSize() == 1;
+
+        if (block.firstInstruction == null) {
+            /*
+             * This is the first time we see this block as a branch target. Create and return a
+             * placeholder that later can be replaced with a MergeNode when we see this block again.
+             */
+            block.entryState = state.copy();
+            block.entryState.clearNonLiveLocals(block, liveness, true);
+
+            Debug.log("createTarget %s: first visit, result: %s", block, block.firstInstruction);
+        }
+
+        // We already saw this block before, so we have to merge states.
+        if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(state)) {
+            throw new BailoutException("stacks do not match; bytecodes would not verify");
+        }
+
+        if (block.isLoopHeader) {
+            assert currentBlock.getId() >= block.getId() : "must be backward branch";
+            GraalInternalError.unimplemented("Loops not yet supported");
+        }
+        assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
+
+        GraalInternalError.unimplemented("second block visit not yet implemented");
+        // if second visit
+        {
+            /*
+             * This is the second time we see this block. Create the actual MergeNode and the End
+             * Node for the already existing edge. For simplicity, we leave the placeholder in the
+             * graph and just append the new nodes after the placeholder.
+             */
+        }
+
+        // merge frame states e.g. block.entryState.merge(mergeNode, target.state);
+
+        Debug.log("createTarget %s: merging state", block);
+    }
+
     @Override
     protected void processBlock(BciBlock block) {
         iterateBytecodesForBlock(block);
@@ -612,10 +658,14 @@
         frameState.storeLocal(i, x);
     }
 
+    LabelRef getSuccessor(int index) {
+        createTarget(currentBlock.getSuccessor(index), frameState);
+        return LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0);
+    }
+
     @Override
     protected void genGoto() {
-        LabelRef label = LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, 0);
-        gen.emitJump(label);
+        gen.emitJump(getSuccessor(0));
     }
 
 }
\ No newline at end of file