src/share/vm/opto/parse2.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/parse2.cpp

src/share/vm/opto/parse2.cpp

Print this page
rev 7652 : 8063137: Never-taken branches should be pruned when GWT LambdaForms are shared
Reviewed-by: ?
rev 7653 : [mq]: branch.freq.1
rev 7655 : [mq]: branch.freq.3

*** 35,44 **** --- 35,45 ---- #include "opto/divnode.hpp" #include "opto/idealGraphPrinter.hpp" #include "opto/matcher.hpp" #include "opto/memnode.hpp" #include "opto/mulnode.hpp" + #include "opto/opaquenode.hpp" #include "opto/parse.hpp" #include "opto/runtime.hpp" #include "runtime/deoptimization.hpp" #include "runtime/sharedRuntime.hpp"
*** 765,796 **** //--------------------------dynamic_branch_prediction-------------------------- // Try to gather dynamic branch prediction behavior. Return a probability // of the branch being taken and set the "cnt" field. Returns a -1.0 // if we need to use static prediction for some reason. ! float Parse::dynamic_branch_prediction(float &cnt) { ResourceMark rm; cnt = COUNT_UNKNOWN; // Use MethodData information if it is available // FIXME: free the ProfileData structure ciMethodData* methodData = method()->method_data(); if (!methodData->is_mature()) return PROB_UNKNOWN; ciProfileData* data = methodData->bci_to_data(bci()); if (!data->is_JumpData()) return PROB_UNKNOWN; // get taken and not taken values ! int taken = data->as_JumpData()->taken(); ! int not_taken = 0; if (data->is_BranchData()) { not_taken = data->as_BranchData()->not_taken(); } // scale the counts to be commensurate with invocation counts: taken = method()->scale_count(taken); not_taken = method()->scale_count(not_taken); // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful. // We also check that individual counters are positive first, overwise the sum can become positive. if (taken < 0 || not_taken < 0 || taken + not_taken < 40) { if (C->log() != NULL) { --- 766,821 ---- //--------------------------dynamic_branch_prediction-------------------------- // Try to gather dynamic branch prediction behavior. Return a probability // of the branch being taken and set the "cnt" field. Returns a -1.0 // if we need to use static prediction for some reason. ! float Parse::dynamic_branch_prediction(float &cnt, BoolTest::mask btest, Node* test) { ResourceMark rm; cnt = COUNT_UNKNOWN; + int taken = 0; + int not_taken = 0; + + ProfileBranchNode* profile = NULL; + if (btest == BoolTest::eq && test->is_Cmp()) { + Node* n = test->in(1); + switch (n->Opcode()) { + case Op_ProfileBranch: + profile = (ProfileBranchNode*) n; + break; + case Op_AndI: { + if (n->in(1)->Opcode() == Op_ProfileBranch) { + profile = (ProfileBranchNode*) n->in(1); + } + break; + } + } + } + if (profile != NULL) { + taken = profile->taken(); + not_taken = profile->not_taken(); + profile->consume(); + } else { // Use MethodData information if it is available // FIXME: free the ProfileData structure ciMethodData* methodData = method()->method_data(); if (!methodData->is_mature()) return PROB_UNKNOWN; ciProfileData* data = methodData->bci_to_data(bci()); if (!data->is_JumpData()) return PROB_UNKNOWN; // get taken and not taken values ! taken = data->as_JumpData()->taken(); ! not_taken = 0; if (data->is_BranchData()) { not_taken = data->as_BranchData()->not_taken(); } // scale the counts to be commensurate with invocation counts: taken = method()->scale_count(taken); not_taken = method()->scale_count(not_taken); + } // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful. // We also check that individual counters are positive first, overwise the sum can become positive. if (taken < 0 || not_taken < 0 || taken + not_taken < 40) { if (C->log() != NULL) {
*** 839,850 **** } //-----------------------------branch_prediction------------------------------- float Parse::branch_prediction(float& cnt, BoolTest::mask btest, ! int target_bci) { ! float prob = dynamic_branch_prediction(cnt); // If prob is unknown, switch to static prediction if (prob != PROB_UNKNOWN) return prob; prob = PROB_FAIR; // Set default value if (btest == BoolTest::eq) // Exactly equal test? --- 864,876 ---- } //-----------------------------branch_prediction------------------------------- float Parse::branch_prediction(float& cnt, BoolTest::mask btest, ! int target_bci, ! Node* test) { ! float prob = dynamic_branch_prediction(cnt, btest, test); // If prob is unknown, switch to static prediction if (prob != PROB_UNKNOWN) return prob; prob = PROB_FAIR; // Set default value if (btest == BoolTest::eq) // Exactly equal test?
*** 930,940 **** Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci()); float cnt; ! float prob = branch_prediction(cnt, btest, target_bci); if (prob == PROB_UNKNOWN) { // (An earlier version of do_ifnull omitted this trap for OSR methods.) #ifndef PRODUCT if (PrintOpto && Verbose) tty->print_cr("Never-taken edge stops compilation at bci %d",bci()); --- 956,966 ---- Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci()); float cnt; ! float prob = branch_prediction(cnt, btest, target_bci, c); if (prob == PROB_UNKNOWN) { // (An earlier version of do_ifnull omitted this trap for OSR methods.) #ifndef PRODUCT if (PrintOpto && Verbose) tty->print_cr("Never-taken edge stops compilation at bci %d",bci());
*** 1011,1021 **** Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci()); float cnt; ! float prob = branch_prediction(cnt, btest, target_bci); float untaken_prob = 1.0 - prob; if (prob == PROB_UNKNOWN) { #ifndef PRODUCT if (PrintOpto && Verbose) --- 1037,1047 ---- Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci()); float cnt; ! float prob = branch_prediction(cnt, btest, target_bci, c); float untaken_prob = 1.0 - prob; if (prob == PROB_UNKNOWN) { #ifndef PRODUCT if (PrintOpto && Verbose)
src/share/vm/opto/parse2.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File