# HG changeset patch # User Lukas Stadler # Date 1307643938 -7200 # Node ID 1e13559b112db496b8a3013b8b38988d9687c6ce # Parent f9c6d9bc4fbcbb220583ff3fc13f799f2f146610 small fix in deopt stub, more branch prediction code diff -r f9c6d9bc4fbc -r 1e13559b112d graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- 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 = ____; diff -r f9c6d9bc4fbc -r 1e13559b112d graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java --- 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) { diff -r f9c6d9bc4fbc -r 1e13559b112d graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- 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(" "); stream.println(" "); + flush(); } private List printNodes(Collection nodes, boolean shortNames, NodeMap nodeToBlock) { diff -r f9c6d9bc4fbc -r 1e13559b112d graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java --- 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 branchOverride; + private Block[] blockMap; private BitSet canTrap; @@ -167,6 +175,7 @@ } this.blocks = new ArrayList(); this.storesInLoops = new BitSet(method.maxLocals()); + branchOverride = new HashMap(); } /** @@ -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; } diff -r f9c6d9bc4fbc -r 1e13559b112d graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- 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 blockList; + private HashMap 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(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)); } diff -r f9c6d9bc4fbc -r 1e13559b112d src/cpu/x86/vm/c1_globals_x86.hpp --- 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 ); diff -r f9c6d9bc4fbc -r 1e13559b112d src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- 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))); diff -r f9c6d9bc4fbc -r 1e13559b112d src/share/vm/runtime/java.cpp --- 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.