src/share/vm/opto/parse2.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/parse2.cpp Tue Jan 27 18:25:27 2015
--- new/src/share/vm/opto/parse2.cpp Tue Jan 27 18:25:27 2015
*** 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"
*** 761,799 ****
--- 762,846 ----
profile_ret(target->flow()->start());
int pnum = target->next_path_num();
merge_common(target, pnum);
}
+ static bool has_injected_profile(BoolTest::mask btest, Node* test, int& taken, int& not_taken) {
+ ProfileBooleanNode* profile = NULL;
+
+ if (btest != BoolTest::eq && btest != BoolTest::ne) {
+ // Only ::eq and ::ne are supported for profile injection.
+ return false;
+ }
+
+ if (test->is_Cmp()) {
+ Node* n = test->in(1);
+ switch (n->Opcode()) {
+ case Op_ProfileBoolean:
+ profile = (ProfileBooleanNode*) n;
+ break;
+ case Op_AndI:
+ // Look for the following shape: AndI (ProfileBoolean) (ConI 1))
+ const TypeInt* t = NULL;
+ if (n->in(1)->Opcode() == Op_ProfileBoolean &&
+ n->in(2)->is_Con() &&
+ (t = n->in(2)->bottom_type()->isa_int()) != NULL &&
+ t->get_con() == 1) {
+ profile = (ProfileBooleanNode*) n->in(1);
+ }
+ break;
+ }
+ }
+ if (profile != NULL) {
+ int false_cnt = profile->false_count();
+ int true_cnt = profile->true_count();
+
+ // Counts matching depends on the actual test operation (::eq or ::ne).
+ taken = (btest == BoolTest::eq) ? false_cnt : true_cnt;
+ not_taken = (btest == BoolTest::eq) ? true_cnt : false_cnt;
+
+ profile->consume();
+ return true;
+ }
+ return false;
+ }
//--------------------------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;
+
+ bool use_mdo = !has_injected_profile(btest, test, taken, not_taken);
+
+ if (use_mdo) {
// 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;
! 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.
! // We also check that individual counters are positive first, otherwise the sum can become positive.
if (taken < 0 || not_taken < 0 || taken + not_taken < 40) {
if (C->log() != NULL) {
C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d'", iter().get_dest(), taken, not_taken);
}
return PROB_UNKNOWN;
*** 839,850 ****
--- 886,898 ----
}
//-----------------------------branch_prediction-------------------------------
float Parse::branch_prediction(float& cnt,
BoolTest::mask btest,
! int target_bci) {
float prob = dynamic_branch_prediction(cnt);
! 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 ****
--- 978,988 ----
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 ****
--- 1059,1069 ----
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