< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

*** 1571,1581 **** adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob, next_block); } } //------------------------------------do_if------------------------------------ ! void Parse::do_if(BoolTest::mask btest, Node* c) { int target_bci = iter().get_dest(); Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci()); --- 1571,1581 ---- adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob, next_block); } } //------------------------------------do_if------------------------------------ ! void Parse::do_if(BoolTest::mask btest, Node* c, bool new_path, Node** ctrl_taken) { int target_bci = iter().get_dest(); Block* branch_block = successor_for_bci(target_bci); Block* next_block = successor_for_bci(iter().next_bci());
*** 1669,1682 **** --- 1669,1689 ---- } else { // Update method data profile_taken_branch(target_bci); adjust_map_after_if(taken_btest, c, prob, branch_block); if (!stopped()) { + if (ctrl_taken != NULL) { + // Don't merge but save taken branch to be wired by caller + *ctrl_taken = control(); + } else if (new_path) { + merge_new_path(target_bci); + } else { merge(target_bci); } } } + } untaken_branch = _gvn.transform(untaken_branch); set_control(untaken_branch); // Branch not taken.
*** 1690,1700 **** profile_not_taken_branch(); adjust_map_after_if(untaken_btest, c, untaken_prob, next_block); } } ! void Parse::do_acmp(BoolTest::mask& btest, Node* a, Node* b) { // In the case were both operands might be value types, we need to // use the new acmp implementation. Otherwise, i.e. if one operand // is not a value type, we can use the old acmp implementation. Node* cmp = C->optimize_acmp(&_gvn, a, b); if (cmp != NULL) { --- 1697,1707 ---- profile_not_taken_branch(); adjust_map_after_if(untaken_btest, c, untaken_prob, next_block); } } ! void Parse::do_acmp(BoolTest::mask btest, Node* a, Node* b) { // In the case were both operands might be value types, we need to // use the new acmp implementation. Otherwise, i.e. if one operand // is not a value type, we can use the old acmp implementation. Node* cmp = C->optimize_acmp(&_gvn, a, b); if (cmp != NULL) {
*** 1702,1711 **** --- 1709,1753 ---- cmp = optimize_cmp_with_klass(_gvn.transform(cmp)); do_if(btest, cmp); return; } + Node* ctrl = NULL; + bool safe_for_replace = true; + if (!UsePointerPerturbation) { + // Emit old acmp before new acmp for quick a != b check + cmp = CmpP(a, b); + cmp = optimize_cmp_with_klass(_gvn.transform(cmp)); + if (btest == BoolTest::ne) { + do_if(btest, cmp, true); + if (stopped()) { + return; // Never equal + } + } else if (btest == BoolTest::eq) { + Node* is_equal = NULL; + { + PreserveJVMState pjvms(this); + do_if(btest, cmp, true, &is_equal); + if (!stopped()) { + // Not equal, skip valuetype check + ctrl = new RegionNode(3); + ctrl->init_req(1, control()); + _gvn.set_type(ctrl, Type::CONTROL); + record_for_igvn(ctrl); + safe_for_replace = false; + } + } + if (is_equal == NULL) { + assert(ctrl != NULL, "no control left"); + set_control(_gvn.transform(ctrl)); + return; // Never equal + } + set_control(is_equal); + } + } + + // Null check operand before loading the is_value bit bool speculate = false; if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(b))) { // Operand 'b' is never null, swap operands to avoid null check swap(a, b); } else if (!too_many_traps(Deoptimization::Reason_speculate_null_check)) {
*** 1715,1751 **** } else if (!_gvn.type(b)->speculative_maybe_null()) { speculate = true; swap(a, b); } } - - // Null check operand before loading the is_value bit - Node* region = new RegionNode(2); - Node* is_value = new PhiNode(region, TypeX_X); - Node* null_ctl = top(); inc_sp(2); ! Node* not_null_a = null_check_oop(a, &null_ctl, speculate, true, speculate); assert(!stopped(), "operand is always null"); dec_sp(2); if (null_ctl != top()) { assert(!speculate, "should never be null"); region->add_req(null_ctl); is_value->add_req(_gvn.MakeConX(0)); } ! Node* value_bit = C->load_is_value_bit(&_gvn, not_null_a); region->init_req(1, control()); - is_value->set_req(1, value_bit); set_control(_gvn.transform(region)); is_value = _gvn.transform(is_value); // Perturbe oop if operand is a value type to make comparison fail Node* pert = _gvn.transform(new AddPNode(a, a, is_value)); cmp = _gvn.transform(new CmpPNode(pert, b)); cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); } bool Parse::path_is_suitable_for_uncommon_trap(float prob) const { // Don't want to speculate on uncommon traps when running with -Xcomp if (!UseInterpreter) { --- 1757,1811 ---- } else if (!_gvn.type(b)->speculative_maybe_null()) { speculate = true; swap(a, b); } } inc_sp(2); ! Node* null_ctl = top(); ! Node* not_null_a = null_check_oop(a, &null_ctl, speculate, safe_for_replace, speculate); assert(!stopped(), "operand is always null"); dec_sp(2); + Node* region = new RegionNode(2); + Node* is_value = new PhiNode(region, TypeX_X); if (null_ctl != top()) { assert(!speculate, "should never be null"); region->add_req(null_ctl); is_value->add_req(_gvn.MakeConX(0)); } ! Node* value_mask = _gvn.MakeConX(markOopDesc::always_locked_pattern); ! if (UsePointerPerturbation) { ! Node* mark_addr = basic_plus_adr(not_null_a, oopDesc::mark_offset_in_bytes()); ! Node* mark = make_load(NULL, mark_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); ! Node* not_mark = _gvn.transform(new XorXNode(mark, _gvn.MakeConX(-1))); ! Node* andn = _gvn.transform(new AndXNode(not_mark, value_mask)); ! Node* neg_if_value = _gvn.transform(new SubXNode(andn, _gvn.MakeConX(1))); ! is_value->init_req(1, _gvn.transform(new RShiftXNode(neg_if_value, _gvn.intcon(63)))); ! } else { ! is_value->init_req(1, is_always_locked(not_null_a)); ! } region->init_req(1, control()); set_control(_gvn.transform(region)); is_value = _gvn.transform(is_value); + if (UsePointerPerturbation) { // Perturbe oop if operand is a value type to make comparison fail Node* pert = _gvn.transform(new AddPNode(a, a, is_value)); cmp = _gvn.transform(new CmpPNode(pert, b)); + } else { + // Check for a value type because we already know that operands are equal + cmp = _gvn.transform(new CmpXNode(is_value, value_mask)); + btest = (btest == BoolTest::eq) ? BoolTest::ne : BoolTest::eq; + } cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); + + if (ctrl != NULL) { + ctrl->init_req(2, control()); + set_control(_gvn.transform(ctrl)); + } } bool Parse::path_is_suitable_for_uncommon_trap(float prob) const { // Don't want to speculate on uncommon traps when running with -Xcomp if (!UseInterpreter) {
< prev index next >