changeset 2928:1e13559b112d

small fix in deopt stub, more branch prediction code
author Lukas Stadler <lukas.stadler@jku.at>
date Thu, 09 Jun 2011 20:25:38 +0200
parents f9c6d9bc4fbc
children 7300d86deac2 9b8f30608e62
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/alloc/ControlFlowOptimizer.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java src/cpu/x86/vm/c1_globals_x86.hpp src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/share/vm/runtime/java.cpp
diffstat 8 files changed, 58 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Thu Jun 09 17:33:08 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Thu Jun 09 20:25:38 2011 +0200
@@ -104,8 +104,9 @@
     // Code generator settings
     public static boolean GenLIR                             = true;
     public static boolean GenCode                            = true;
+    public static boolean UseBranchPrediction                = ____;
 
-    public static boolean UseConstDirectCall                 = false;
+    public static boolean UseConstDirectCall                 = ____;
 
     public static boolean GenSpecialDivChecks                = ____;
     public static boolean GenAssertionCode                   = ____;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Thu Jun 09 17:33:08 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Thu Jun 09 20:25:38 2011 +0200
@@ -164,7 +164,12 @@
                 assert lastOp instanceof LIRBranch : "branch must be of type LIRBranch";
                 LIRBranch lastBranch = (LIRBranch) lastOp;
 
-                assert lastBranch.block() != null : "last branch must always have a block as target";
+                if (lastBranch.block() == null) {
+                    // this might target a deoptimization stub...
+                    // TODO check if the target is really a deopt stub...
+//                    assert lastBranch.block() != null : "last branch must always have a block as target, current block #" + block.blockID();
+                    continue;
+                }
                 assert lastBranch.label() == lastBranch.block().label() : "must be equal";
 
                 if (lastBranch.info == null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Thu Jun 09 17:33:08 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Thu Jun 09 20:25:38 2011 +0200
@@ -140,6 +140,7 @@
         stream.println("  </controlFlow>");
 
         stream.println(" </graph>");
+        flush();
     }
 
     private List<Edge> printNodes(Collection<Node> nodes, boolean shortNames, NodeMap<Block> nodeToBlock) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 09 17:33:08 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java	Thu Jun 09 20:25:38 2011 +0200
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.sun.cri.bytecode.*;
@@ -136,6 +137,11 @@
     public static class DeoptBlock  extends Block {
     }
 
+    public static class BranchOverride {
+        public DeoptBlock block;
+        public boolean taken;
+    }
+
     private static final Block[] NO_SUCCESSORS = new Block[0];
 
     /**
@@ -151,6 +157,8 @@
 
     private final RiMethod method;
 
+    public final HashMap<Integer, BranchOverride> branchOverride;
+
     private Block[] blockMap;
 
     private BitSet canTrap;
@@ -167,6 +175,7 @@
         }
         this.blocks = new ArrayList<Block>();
         this.storesInLoops = new BitSet(method.maxLocals());
+        branchOverride = new HashMap<Integer, BranchOverride>();
     }
 
     /**
@@ -260,15 +269,12 @@
                 case IF_ACMPNE: // fall through
                 case IFNULL:    // fall through
                 case IFNONNULL: {
-                    int probability = method.branchProbability(bci);
-//                    if (probability == 0 || probability == 100) {
-//                        System.out.println("prob: " + probability);
-//                    }
                     current = null;
-                    Block b1 = makeBlock(bci + 3);
-                    Block b2 = makeBlock(bci + Bytes.beS2(code, bci + 1));
-//                    Block b1 = probability == 100 ? makeDeoptBlock(bci + 3) : makeBlock(bci + 3);
-//                    Block b2 = probability == 0 ? makeDeoptBlock(bci + Bytes.beS2(code, bci + 1)) : makeBlock(bci + Bytes.beS2(code, bci + 1));
+
+                    int probability = GraalOptions.UseBranchPrediction ? method.branchProbability(bci) : -1;
+
+                    Block b1 = probability == 100 ? makeBranchOverrideBlock(bci, bci + 3, false) : makeBlock(bci + 3);
+                    Block b2 = probability == 0 ? makeBranchOverrideBlock(bci, bci + Bytes.beS2(code, bci + 1), true) : makeBlock(bci + Bytes.beS2(code, bci + 1));
                     setSuccessors(bci, b1, b2);
 
                     assert lengthOf(code, bci) == 3;
@@ -385,11 +391,14 @@
         }
     }
 
-    private Block makeDeoptBlock(int startBci) {
-        System.out.println("Deopt block created");
+    private Block makeBranchOverrideBlock(int branchBci, int startBci, boolean taken) {
         DeoptBlock newBlock = new DeoptBlock();
         newBlock.startBci = startBci;
-        blockMap[startBci] = newBlock;
+        BranchOverride override = new BranchOverride();
+        override.block = newBlock;
+        override.taken = taken;
+        assert branchOverride.get(branchBci) == null;
+        branchOverride.put(branchBci, override);
         return newBlock;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 09 17:33:08 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jun 09 20:25:38 2011 +0200
@@ -31,7 +31,6 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
-import com.oracle.max.graal.compiler.graph.BlockMap.DeoptBlock;
 import com.oracle.max.graal.compiler.graph.BlockMap.*;
 import com.oracle.max.graal.compiler.graph.BlockMap.Block;
 import com.oracle.max.graal.compiler.ir.*;
@@ -78,6 +77,7 @@
     // bci-to-block mapping
     private Block[] blockFromBci;
     private ArrayList<Block> blockList;
+    private HashMap<Integer, BranchOverride> branchOverride;
 
     private int nextBlockNumber;
 
@@ -145,6 +145,7 @@
 
         // 2. compute the block map, setup exception handlers and get the entrypoint(s)
         BlockMap blockMap = compilation.getBlockMap(method);
+        this.branchOverride = blockMap.branchOverride;
 
         blockList = new ArrayList<Block>(blockMap.blocks);
         blockFromBci = new Block[method.code().length];
@@ -152,7 +153,7 @@
             int blockID = nextBlockNumber();
             assert blockID == i;
             Block block = blockList.get(i);
-            if (block.startBci >= 0) {
+            if (block.startBci >= 0 && !(block instanceof BlockMap.DeoptBlock)) {
                 blockFromBci[block.startBci] = block;
             }
         }
@@ -654,9 +655,20 @@
         assert !x.isDeleted() && !y.isDeleted();
         If ifNode = new If(new Compare(x, cond, y, graph), graph);
         append(ifNode);
-        Instruction tsucc = createTargetAt(stream().readBranchDest(), frameState);
+        BlockMap.BranchOverride override = branchOverride.get(bci());
+        Instruction tsucc;
+        if (override == null || override.taken == false) {
+            tsucc = createTargetAt(stream().readBranchDest(), frameState);
+        } else {
+            tsucc = createTarget(override.block, frameState);
+        }
         ifNode.setBlockSuccessor(0, tsucc);
-        Instruction fsucc = createTargetAt(stream().nextBCI(), frameState);
+        Instruction fsucc;
+        if (override == null || override.taken == true) {
+            fsucc = createTargetAt(stream().nextBCI(), frameState);
+        } else {
+            fsucc = createTarget(override.block, frameState);
+        }
         ifNode.setBlockSuccessor(1, fsucc);
     }
 
@@ -1094,7 +1106,8 @@
 
     private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
         assert block != null && stateAfter != null;
-        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors";
+        assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null :
+            "non-loop block must be iterated after all its predecessors. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next();
 
         if (block.isExceptionEntry) {
             assert stateAfter.stackSize() == 1;
@@ -1186,6 +1199,9 @@
     }
 
     private void createDeoptBlock(DeoptBlock block) {
+//        Merge x = new Merge(graph);
+//        x.setStateBefore(((StateSplit) block.firstInstruction).stateBefore());
+//        append(x);
         append(new Deoptimize(graph));
     }
 
--- a/src/cpu/x86/vm/c1_globals_x86.hpp	Thu Jun 09 17:33:08 2011 +0200
+++ b/src/cpu/x86/vm/c1_globals_x86.hpp	Thu Jun 09 20:25:38 2011 +0200
@@ -40,7 +40,7 @@
 define_pd_global(bool, ProfileTraps,                 false);
 define_pd_global(bool, UseOnStackReplacement,        true );
 define_pd_global(bool, TieredCompilation,            false);
-define_pd_global(intx, CompileThreshold,             1500 );
+define_pd_global(intx, CompileThreshold,             10000 );   // changed for GRAAL
 define_pd_global(intx, BackEdgeThreshold,            100000);
 
 define_pd_global(intx, OnStackReplacePercentage,     933  );
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Jun 09 17:33:08 2011 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Jun 09 20:25:38 2011 +0200
@@ -2669,8 +2669,10 @@
   // fetch_unroll_info needs to call last_java_frame()
   __ set_last_Java_frame(noreg, noreg, NULL);
 
-  __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute);
-  __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames
+  //  __ movl(c_rarg1, (int32_t)Deoptimization::Unpack_reexecute);
+  //  __ movl(r14, c_rarg1); // save into r14 for later call to unpack_frames
+  __ movl(c_rarg1, (int32_t)-1);
+  __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
   __ mov(c_rarg0, r15_thread);
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
 
--- a/src/share/vm/runtime/java.cpp	Thu Jun 09 17:33:08 2011 +0200
+++ b/src/share/vm/runtime/java.cpp	Thu Jun 09 20:25:38 2011 +0200
@@ -419,9 +419,9 @@
   #define BEFORE_EXIT_DONE    2
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
-  if (UseGraal) {
-    GraalCompiler::instance()->exit();
-  }
+//  if (UseGraal) {
+//    GraalCompiler::instance()->exit();
+//  }
 
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.