< prev index next >

src/share/vm/opto/ifnode.cpp

Print this page

        

*** 363,375 **** Node *phi_s = NULL; // do not construct unless needed Node *phi_f = NULL; // do not construct unless needed for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) { Node* v = phi->last_out(i2);// User of the phi igvn->rehash_node_delayed(v); // Have to fixup other Phi users ! uint vop = v->Opcode(); Node *proj = NULL; ! if( vop == Op_Phi ) { // Remote merge point Node *r = v->in(0); for (uint i3 = 1; i3 < r->req(); i3++) if (r->in(i3) && r->in(i3)->in(0) == iff) { proj = r->in(i3); break; --- 363,375 ---- Node *phi_s = NULL; // do not construct unless needed Node *phi_f = NULL; // do not construct unless needed for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) { Node* v = phi->last_out(i2);// User of the phi igvn->rehash_node_delayed(v); // Have to fixup other Phi users ! Opcodes vop = v->Opcode(); Node *proj = NULL; ! if( vop == Opcodes::Op_Phi ) { // Remote merge point Node *r = v->in(0); for (uint i3 = 1; i3 < r->req(); i3++) if (r->in(i3) && r->in(i3)->in(0) == iff) { proj = r->in(i3); break;
*** 379,389 **** } else { assert( 0, "do not know how to handle this guy" ); } Node *proj_path_data, *proj_path_ctrl; ! if( proj->Opcode() == Op_IfTrue ) { if( phi_s == NULL ) { // Only construct phi_s if needed, otherwise provides // interfering use. phi_s = PhiNode::make_blank(region_s,phi); phi_s->init_req( 1, phi_c ); --- 379,389 ---- } else { assert( 0, "do not know how to handle this guy" ); } Node *proj_path_data, *proj_path_ctrl; ! if( proj->Opcode() == Opcodes::Op_IfTrue ) { if( phi_s == NULL ) { // Only construct phi_s if needed, otherwise provides // interfering use. phi_s = PhiNode::make_blank(region_s,phi); phi_s->init_req( 1, phi_c );
*** 406,416 **** proj_path_data = phi_f; proj_path_ctrl = region_f; } // Fixup 'v' for for the split ! if( vop == Op_Phi ) { // Remote merge point uint i; for( i = 1; i < v->req(); i++ ) if( v->in(i) == phi ) break; v->set_req(i, proj_path_data ); --- 406,416 ---- proj_path_data = phi_f; proj_path_ctrl = region_f; } // Fixup 'v' for for the split ! if( vop == Opcodes::Op_Phi ) { // Remote merge point uint i; for( i = 1; i < v->req(); i++ ) if( v->in(i) == phi ) break; v->set_req(i, proj_path_data );
*** 423,434 **** // Now replace the original iff's True/False with region_s/region_t. // This makes the original iff go dead. for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) { Node* p = iff->last_out(i3); ! assert( p->Opcode() == Op_IfTrue || p->Opcode() == Op_IfFalse, "" ); ! Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f; // Replace p with u igvn->add_users_to_worklist(p); for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { Node* x = p->last_out(l); igvn->hash_delete(x); --- 423,434 ---- // Now replace the original iff's True/False with region_s/region_t. // This makes the original iff go dead. for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) { Node* p = iff->last_out(i3); ! assert( p->Opcode() == Opcodes::Op_IfTrue || p->Opcode() == Opcodes::Op_IfFalse, "" ); ! Node *u = (p->Opcode() == Opcodes::Op_IfTrue) ? region_s : region_f; // Replace p with u igvn->add_users_to_worklist(p); for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { Node* x = p->last_out(l); igvn->hash_delete(x);
*** 473,483 **** Node* b = in(1); if (b == NULL || !b->is_Bool()) return NULL; BoolNode* bn = b->as_Bool(); Node* cmp = bn->in(1); if (cmp == NULL) return NULL; ! if (cmp->Opcode() != Op_CmpU) return NULL; l = cmp->in(1); r = cmp->in(2); flip_test = 1; if (bn->_test._test == BoolTest::le) { --- 473,483 ---- Node* b = in(1); if (b == NULL || !b->is_Bool()) return NULL; BoolNode* bn = b->as_Bool(); Node* cmp = bn->in(1); if (cmp == NULL) return NULL; ! if (cmp->Opcode() != Opcodes::Op_CmpU) return NULL; l = cmp->in(1); r = cmp->in(2); flip_test = 1; if (bn->_test._test == BoolTest::le) {
*** 486,496 **** flip_test = 2; } else if (bn->_test._test != BoolTest::lt) { return NULL; } if (l->is_top()) return NULL; // Top input means dead test ! if (r->Opcode() != Op_LoadRange && !is_RangeCheck()) return NULL; // We have recognized one of these forms: // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ... --- 486,496 ---- flip_test = 2; } else if (bn->_test._test != BoolTest::lt) { return NULL; } if (l->is_top()) return NULL; // Top input means dead test ! if (r->Opcode() != Opcodes::Op_LoadRange && !is_RangeCheck()) return NULL; // We have recognized one of these forms: // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ...
*** 524,534 **** // Look for index+offset form Node* ind = l; jint off = 0; if (l->is_top()) { return 0; ! } else if (l->Opcode() == Op_AddI) { if ((off = l->in(1)->find_int_con(0)) != 0) { ind = l->in(2)->uncast(); } else if ((off = l->in(2)->find_int_con(0)) != 0) { ind = l->in(1)->uncast(); } --- 524,534 ---- // Look for index+offset form Node* ind = l; jint off = 0; if (l->is_top()) { return 0; ! } else if (l->Opcode() == Opcodes::Op_AddI) { if ((off = l->in(1)->find_int_con(0)) != 0) { ind = l->in(2)->uncast(); } else if ((off = l->in(2)->find_int_con(0)) != 0) { ind = l->in(1)->uncast(); }
*** 625,635 **** //------------------------------filtered_int_type-------------------------------- // Return a possibly more restrictive type for val based on condition control flow for an if const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { assert(if_proj && ! (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); if (if_proj->in(0) && if_proj->in(0)->is_If()) { IfNode* iff = if_proj->in(0)->as_If(); if (iff->in(1) && iff->in(1)->is_Bool()) { BoolNode* bol = iff->in(1)->as_Bool(); if (bol->in(1) && bol->in(1)->is_Cmp()) { --- 625,635 ---- //------------------------------filtered_int_type-------------------------------- // Return a possibly more restrictive type for val based on condition control flow for an if const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { assert(if_proj && ! (if_proj->Opcode() == Opcodes::Op_IfTrue || if_proj->Opcode() == Opcodes::Op_IfFalse), "expecting an if projection"); if (if_proj->in(0) && if_proj->in(0)->is_If()) { IfNode* iff = if_proj->in(0)->as_If(); if (iff->in(1) && iff->in(1)->is_Bool()) { BoolNode* bol = iff->in(1)->as_Bool(); if (bol->in(1) && bol->in(1)->is_Cmp()) {
*** 637,647 **** if (cmp->in(1) == val) { const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); if (cmp2_t != NULL) { jint lo = cmp2_t->_lo; jint hi = cmp2_t->_hi; ! BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); switch (msk) { case BoolTest::ne: // Can't refine type return NULL; case BoolTest::eq: --- 637,647 ---- if (cmp->in(1) == val) { const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); if (cmp2_t != NULL) { jint lo = cmp2_t->_lo; jint hi = cmp2_t->_hi; ! BoolTest::mask msk = if_proj->Opcode() == Opcodes::Op_IfTrue ? bol->_test._test : bol->_test.negate(); switch (msk) { case BoolTest::ne: // Can't refine type return NULL; case BoolTest::eq:
*** 717,727 **** // Is the comparison for this If suitable for folding? bool IfNode::cmpi_folds(PhaseIterGVN* igvn) { return in(1) != NULL && in(1)->is_Bool() && in(1)->in(1) != NULL && ! in(1)->in(1)->Opcode() == Op_CmpI && in(1)->in(1)->in(2) != NULL && in(1)->in(1)->in(2) != igvn->C->top() && (in(1)->as_Bool()->_test.is_less() || in(1)->as_Bool()->_test.is_greater()); } --- 717,727 ---- // Is the comparison for this If suitable for folding? bool IfNode::cmpi_folds(PhaseIterGVN* igvn) { return in(1) != NULL && in(1)->is_Bool() && in(1)->in(1) != NULL && ! in(1)->in(1)->Opcode() == Opcodes::Op_CmpI && in(1)->in(1)->in(2) != NULL && in(1)->in(1)->in(2) != igvn->C->top() && (in(1)->as_Bool()->_test.is_less() || in(1)->as_Bool()->_test.is_greater()); }
*** 729,739 **** // Is a dominating control suitable for folding with this if? bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) { return ctrl != NULL && ctrl->is_Proj() && ctrl->in(0) != NULL && ! ctrl->in(0)->Opcode() == Op_If && ctrl->in(0)->outcnt() == 2 && ctrl->in(0)->as_If()->cmpi_folds(igvn) && // Must compare same value ctrl->in(0)->in(1)->in(1)->in(1) != NULL && ctrl->in(0)->in(1)->in(1)->in(1) == in(1)->in(1)->in(1); --- 729,739 ---- // Is a dominating control suitable for folding with this if? bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) { return ctrl != NULL && ctrl->is_Proj() && ctrl->in(0) != NULL && ! ctrl->in(0)->Opcode() == Opcodes::Op_If && ctrl->in(0)->outcnt() == 2 && ctrl->in(0)->as_If()->cmpi_folds(igvn) && // Must compare same value ctrl->in(0)->in(1)->in(1)->in(1) != NULL && ctrl->in(0)->in(1)->in(1)->in(1) == in(1)->in(1)->in(1);
*** 1075,1085 **** void IfNode::improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn) { #ifdef _LP64 ResourceMark rm; Node_Stack stack(2); ! assert(r->Opcode() == Op_LoadRange, "unexpected range check"); const TypeInt* array_size = igvn->type(r)->is_int(); stack.push(l, 0); while(stack.size() > 0) { --- 1075,1085 ---- void IfNode::improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn) { #ifdef _LP64 ResourceMark rm; Node_Stack stack(2); ! assert(r->Opcode() == Opcodes::Op_LoadRange, "unexpected range check"); const TypeInt* array_size = igvn->type(r)->is_int(); stack.push(l, 0); while(stack.size() > 0) {
*** 1088,1098 **** uint i = start; for (; i < n->outcnt(); i++) { Node* use = n->raw_out(i); if (stack.size() == 1) { ! if (use->Opcode() == Op_ConvI2L) { const TypeLong* bounds = use->as_Type()->type()->is_long(); if (bounds->_lo <= array_size->_lo && bounds->_hi >= array_size->_hi && (bounds->_lo != array_size->_lo || bounds->_hi != array_size->_hi)) { stack.set_index(i+1); stack.push(use, 0); --- 1088,1098 ---- uint i = start; for (; i < n->outcnt(); i++) { Node* use = n->raw_out(i); if (stack.size() == 1) { ! if (use->Opcode() == Opcodes::Op_ConvI2L) { const TypeLong* bounds = use->as_Type()->type()->is_long(); if (bounds->_lo <= array_size->_lo && bounds->_hi >= array_size->_hi && (bounds->_lo != array_size->_lo || bounds->_hi != array_size->_hi)) { stack.set_index(i+1); stack.push(use, 0);
*** 1104,1114 **** for (int i = 0; i < 10 && ctrl != NULL && ctrl != fail; i++) { ctrl = up_one_dom(ctrl); } if (ctrl == fail) { Node* init_n = stack.node_at(1); ! assert(init_n->Opcode() == Op_ConvI2L, "unexpected first node"); // Create a new narrow ConvI2L node that is dependent on the range check Node* new_n = igvn->C->conv_I2X_index(igvn, l, array_size, fail); // The type of the ConvI2L may be widen and so the new // ConvI2L may not be better than an existing ConvI2L --- 1104,1114 ---- for (int i = 0; i < 10 && ctrl != NULL && ctrl != fail; i++) { ctrl = up_one_dom(ctrl); } if (ctrl == fail) { Node* init_n = stack.node_at(1); ! assert(init_n->Opcode() == Opcodes::Op_ConvI2L, "unexpected first node"); // Create a new narrow ConvI2L node that is dependent on the range check Node* new_n = igvn->C->conv_I2X_index(igvn, l, array_size, fail); // The type of the ConvI2L may be widen and so the new // ConvI2L may not be better than an existing ConvI2L
*** 1148,1164 **** bool IfNode::is_cmp_with_loadrange(ProjNode* proj) { if (in(1) != NULL && in(1)->in(1) != NULL && in(1)->in(1)->in(2) != NULL) { Node* other = in(1)->in(1)->in(2); ! if (other->Opcode() == Op_LoadRange && ((other->in(0) != NULL && other->in(0) == proj) || (other->in(0) == NULL && other->in(2) != NULL && other->in(2)->is_AddP() && other->in(2)->in(1) != NULL && ! other->in(2)->in(1)->Opcode() == Op_CastPP && other->in(2)->in(1)->in(0) == proj))) { return true; } } return false; --- 1148,1164 ---- bool IfNode::is_cmp_with_loadrange(ProjNode* proj) { if (in(1) != NULL && in(1)->in(1) != NULL && in(1)->in(1)->in(2) != NULL) { Node* other = in(1)->in(1)->in(2); ! if (other->Opcode() == Opcodes::Op_LoadRange && ((other->in(0) != NULL && other->in(0) == proj) || (other->in(0) == NULL && other->in(2) != NULL && other->in(2)->is_AddP() && other->in(2)->in(1) != NULL && ! other->in(2)->in(1)->Opcode() == Opcodes::Op_CastPP && other->in(2)->in(1)->in(0) == proj))) { return true; } } return false;
*** 1168,1178 **** Node* other = in(1)->in(1)->in(2); if (other->in(MemNode::Address) != NULL && proj->in(0)->in(1) != NULL && proj->in(0)->in(1)->is_Bool() && proj->in(0)->in(1)->in(1) != NULL && ! proj->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && proj->in(0)->in(1)->in(1)->in(2) != NULL && proj->in(0)->in(1)->in(1)->in(1) == other->in(MemNode::Address)->in(AddPNode::Address)->uncast() && igvn->type(proj->in(0)->in(1)->in(1)->in(2)) == TypePtr::NULL_PTR) { return true; } --- 1168,1178 ---- Node* other = in(1)->in(1)->in(2); if (other->in(MemNode::Address) != NULL && proj->in(0)->in(1) != NULL && proj->in(0)->in(1)->is_Bool() && proj->in(0)->in(1)->in(1) != NULL && ! proj->in(0)->in(1)->in(1)->Opcode() == Opcodes::Op_CmpP && proj->in(0)->in(1)->in(1)->in(2) != NULL && proj->in(0)->in(1)->in(1)->in(1) == other->in(MemNode::Address)->in(AddPNode::Address)->uncast() && igvn->type(proj->in(0)->in(1)->in(1)->in(2)) == TypePtr::NULL_PTR) { return true; }
*** 1238,1248 **** igvn->replace_node(otherproj, igvn->C->top()); igvn->C->root()->add_req(halt); } Node* IfNode::fold_compares(PhaseIterGVN* igvn) { ! if (Opcode() != Op_If) return NULL; if (cmpi_folds(igvn)) { Node* ctrl = in(0); if (is_ctrl_folds(ctrl, igvn) && ctrl->outcnt() == 1) { --- 1238,1248 ---- igvn->replace_node(otherproj, igvn->C->top()); igvn->C->root()->add_req(halt); } Node* IfNode::fold_compares(PhaseIterGVN* igvn) { ! if (Opcode() != Opcodes::Op_If) return NULL; if (cmpi_folds(igvn)) { Node* ctrl = in(0); if (is_ctrl_folds(ctrl, igvn) && ctrl->outcnt() == 1) {
*** 1293,1303 **** Node *i1 = iff->in(1); if( !i1->is_Bool() ) return NULL; BoolNode *bol = i1->as_Bool(); Node *cmp = bol->in(1); ! if( cmp->Opcode() != Op_CmpI ) return NULL; // Must be comparing against a bool const Type *cmp2_t = phase->type( cmp->in(2) ); if( cmp2_t != TypeInt::ZERO && cmp2_t != TypeInt::ONE ) --- 1293,1303 ---- Node *i1 = iff->in(1); if( !i1->is_Bool() ) return NULL; BoolNode *bol = i1->as_Bool(); Node *cmp = bol->in(1); ! if( cmp->Opcode() != Opcodes::Op_CmpI ) return NULL; // Must be comparing against a bool const Type *cmp2_t = phase->type( cmp->in(2) ); if( cmp2_t != TypeInt::ZERO && cmp2_t != TypeInt::ONE )
*** 1409,1421 **** } // Scan for an equivalent test Node *cmp; int dist = 0; // Cutoff limit for search ! int op = Opcode(); ! if( op == Op_If && ! (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) { if( cmp->in(2) != NULL && // make sure cmp is not already dead cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { dist = 64; // Limit for null-pointer scans } else { dist = 4; // Do not bother for random pointer tests --- 1409,1421 ---- } // Scan for an equivalent test Node *cmp; int dist = 0; // Cutoff limit for search ! Opcodes op = Opcode(); ! if( op == Opcodes::Op_If && ! (cmp=in(1)->in(1))->Opcode() == Opcodes::Op_CmpP ) { if( cmp->in(2) != NULL && // make sure cmp is not already dead cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { dist = 64; // Limit for null-pointer scans } else { dist = 4; // Do not bother for random pointer tests
*** 1449,1459 **** #endif igvn->hash_delete(this); // Remove self to prevent spurious V-N Node *idom = in(0); // Need opcode to decide which way 'this' test goes ! int prev_op = prev_dom->Opcode(); Node *top = igvn->C->top(); // Shortcut to top // Loop predicates may have depending checks which should not // be skipped. For example, range check predicate has two checks // for lower and upper bounds. --- 1449,1459 ---- #endif igvn->hash_delete(this); // Remove self to prevent spurious V-N Node *idom = in(0); // Need opcode to decide which way 'this' test goes ! Opcodes prev_op = prev_dom->Opcode(); Node *top = igvn->C->top(); // Shortcut to top // Loop predicates may have depending checks which should not // be skipped. For example, range check predicate has two checks // for lower and upper bounds.
*** 1503,1513 **** Node* IfNode::search_identical(int dist) { // Setup to scan up the CFG looking for a dominating test Node* dom = in(0); Node* prev_dom = this; ! int op = Opcode(); // Search up the dominator tree for an If with an identical test while (dom->Opcode() != op || // Not same opcode? dom->in(1) != in(1) || // Not same input 1? (req() == 3 && dom->in(2) != in(2)) || // Not same input 2? prev_dom->in(0) != dom) { // One path of test does not dominate? --- 1503,1513 ---- Node* IfNode::search_identical(int dist) { // Setup to scan up the CFG looking for a dominating test Node* dom = in(0); Node* prev_dom = this; ! Opcodes op = Opcode(); // Search up the dominator tree for an If with an identical test while (dom->Opcode() != op || // Not same opcode? dom->in(1) != in(1) || // Not same input 1? (req() == 3 && dom->in(2) != in(2)) || // Not same input 2? prev_dom->in(0) != dom) { // One path of test does not dominate?
*** 1688,1698 **** bool found_immediate_dominator = false; // Scan for the top checks and collect range of offsets for (int dist = 0; dist < 999; dist++) { // Range-Check scan limit ! if (dom->Opcode() == Op_RangeCheck && // Not same opcode? prev_dom->in(0) == dom) { // One path of test does dominate? if (dom == this) return NULL; // dead loop // See if this is a range check Node* index2; Node* range2; --- 1688,1698 ---- bool found_immediate_dominator = false; // Scan for the top checks and collect range of offsets for (int dist = 0; dist < 999; dist++) { // Range-Check scan limit ! if (dom->Opcode() == Opcodes::Op_RangeCheck && // Not same opcode? prev_dom->in(0) == dom) { // One path of test does dominate? if (dom == this) return NULL; // dead loop // See if this is a range check Node* index2; Node* range2;
< prev index next >