< prev index next >

src/hotspot/share/opto/loopopts.cpp

Print this page

        

*** 1405,1477 **** //------------------------------clone_iff-------------------------------------- // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps. // "Nearly" because all Nodes have been cloned from the original in the loop, // but the fall-in edges to the Cmp are different. Clone bool/Cmp pairs // through the Phi recursively, and return a Bool. ! BoolNode *PhaseIdealLoop::clone_iff( PhiNode *phi, IdealLoopTree *loop ) { // Convert this Phi into a Phi merging Bools uint i; ! for( i = 1; i < phi->req(); i++ ) { Node *b = phi->in(i); ! if( b->is_Phi() ) { ! _igvn.replace_input_of(phi, i, clone_iff( b->as_Phi(), loop )); } else { ! assert( b->is_Bool(), "" ); } } ! Node *sample_bool = phi->in(1); Node *sample_cmp = sample_bool->in(1); // Make Phis to merge the Cmp's inputs. ! PhiNode *phi1 = new PhiNode( phi->in(0), Type::TOP ); ! PhiNode *phi2 = new PhiNode( phi->in(0), Type::TOP ); ! for( i = 1; i < phi->req(); i++ ) { ! Node *n1 = phi->in(i)->in(1)->in(1); ! Node *n2 = phi->in(i)->in(1)->in(2); ! phi1->set_req( i, n1 ); ! phi2->set_req( i, n2 ); ! phi1->set_type( phi1->type()->meet_speculative(n1->bottom_type())); ! phi2->set_type( phi2->type()->meet_speculative(n2->bottom_type())); } // See if these Phis have been made before. // Register with optimizer Node *hit1 = _igvn.hash_find_insert(phi1); ! if( hit1 ) { // Hit, toss just made Phi _igvn.remove_dead_node(phi1); // Remove new phi ! assert( hit1->is_Phi(), "" ); phi1 = (PhiNode*)hit1; // Use existing phi } else { // Miss _igvn.register_new_node_with_optimizer(phi1); } Node *hit2 = _igvn.hash_find_insert(phi2); ! if( hit2 ) { // Hit, toss just made Phi _igvn.remove_dead_node(phi2); // Remove new phi ! assert( hit2->is_Phi(), "" ); phi2 = (PhiNode*)hit2; // Use existing phi } else { // Miss _igvn.register_new_node_with_optimizer(phi2); } // Register Phis with loop/block info set_ctrl(phi1, phi->in(0)); set_ctrl(phi2, phi->in(0)); // Make a new Cmp Node *cmp = sample_cmp->clone(); ! cmp->set_req( 1, phi1 ); ! cmp->set_req( 2, phi2 ); _igvn.register_new_node_with_optimizer(cmp); set_ctrl(cmp, phi->in(0)); // Make a new Bool Node *b = sample_bool->clone(); b->set_req(1,cmp); _igvn.register_new_node_with_optimizer(b); set_ctrl(b, phi->in(0)); ! assert( b->is_Bool(), "" ); ! return (BoolNode*)b; } //------------------------------clone_bool------------------------------------- // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps. // "Nearly" because all Nodes have been cloned from the original in the loop, --- 1405,1494 ---- //------------------------------clone_iff-------------------------------------- // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps. // "Nearly" because all Nodes have been cloned from the original in the loop, // but the fall-in edges to the Cmp are different. Clone bool/Cmp pairs // through the Phi recursively, and return a Bool. ! Node* PhaseIdealLoop::clone_iff(PhiNode *phi, IdealLoopTree *loop) { // Convert this Phi into a Phi merging Bools uint i; ! for (i = 1; i < phi->req(); i++) { Node *b = phi->in(i); ! if (b->is_Phi()) { ! _igvn.replace_input_of(phi, i, clone_iff(b->as_Phi(), loop)); } else { ! assert(b->is_Bool() || b->Opcode() == Op_Opaque4, ""); } } ! Node* n = phi->in(1); ! Node* sample_opaque = NULL; ! Node *sample_bool = NULL; ! if (n->Opcode() == Op_Opaque4) { ! sample_opaque = n; ! sample_bool = n->in(1); ! assert(sample_bool->is_Bool(), "wrong type"); ! } else { ! sample_bool = n; ! } Node *sample_cmp = sample_bool->in(1); // Make Phis to merge the Cmp's inputs. ! PhiNode *phi1 = new PhiNode(phi->in(0), Type::TOP); ! PhiNode *phi2 = new PhiNode(phi->in(0), Type::TOP); ! for (i = 1; i < phi->req(); i++) { ! Node *n1 = sample_opaque == NULL ? phi->in(i)->in(1)->in(1) : phi->in(i)->in(1)->in(1)->in(1); ! Node *n2 = sample_opaque == NULL ? phi->in(i)->in(1)->in(2) : phi->in(i)->in(1)->in(1)->in(2); ! phi1->set_req(i, n1); ! phi2->set_req(i, n2); ! phi1->set_type(phi1->type()->meet_speculative(n1->bottom_type())); ! phi2->set_type(phi2->type()->meet_speculative(n2->bottom_type())); } // See if these Phis have been made before. // Register with optimizer Node *hit1 = _igvn.hash_find_insert(phi1); ! if (hit1) { // Hit, toss just made Phi _igvn.remove_dead_node(phi1); // Remove new phi ! assert(hit1->is_Phi(), "" ); phi1 = (PhiNode*)hit1; // Use existing phi } else { // Miss _igvn.register_new_node_with_optimizer(phi1); } Node *hit2 = _igvn.hash_find_insert(phi2); ! if (hit2) { // Hit, toss just made Phi _igvn.remove_dead_node(phi2); // Remove new phi ! assert(hit2->is_Phi(), "" ); phi2 = (PhiNode*)hit2; // Use existing phi } else { // Miss _igvn.register_new_node_with_optimizer(phi2); } // Register Phis with loop/block info set_ctrl(phi1, phi->in(0)); set_ctrl(phi2, phi->in(0)); // Make a new Cmp Node *cmp = sample_cmp->clone(); ! cmp->set_req(1, phi1); ! cmp->set_req(2, phi2); _igvn.register_new_node_with_optimizer(cmp); set_ctrl(cmp, phi->in(0)); // Make a new Bool Node *b = sample_bool->clone(); b->set_req(1,cmp); _igvn.register_new_node_with_optimizer(b); set_ctrl(b, phi->in(0)); ! if (sample_opaque != NULL) { ! Node* opaque = sample_opaque->clone(); ! opaque->set_req(1, b); ! _igvn.register_new_node_with_optimizer(opaque); ! set_ctrl(opaque, phi->in(0)); ! return opaque; ! } ! ! assert(b->is_Bool(), ""); ! return b; } //------------------------------clone_bool------------------------------------- // Passed in a Phi merging (recursively) some nearly equivalent Bool/Cmps. // "Nearly" because all Nodes have been cloned from the original in the loop,
*** 1747,1771 **** // loop that is switching on a condition that is set inside of the // loop. Happens if people set a loop-exit flag; then test the flag // in the loop to break the loop, then test is again outside of the // loop to determine which way the loop exited. // Loop predicate If node connects to Bool node through Opaque1 node. ! if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use)) { // Since this code is highly unlikely, we lazily build the worklist // of such Nodes to go split. ! if( !split_if_set ) split_if_set = new Node_List(area); split_if_set->push(use); } ! if( use->is_Bool() ) { ! if( !split_bool_set ) split_bool_set = new Node_List(area); split_bool_set->push(use); } ! if( use->Opcode() == Op_CreateEx ) { ! if( !split_cex_set ) split_cex_set = new Node_List(area); split_cex_set->push(use); } // Get "block" use is in --- 1764,1791 ---- // loop that is switching on a condition that is set inside of the // loop. Happens if people set a loop-exit flag; then test the flag // in the loop to break the loop, then test is again outside of the // loop to determine which way the loop exited. // Loop predicate If node connects to Bool node through Opaque1 node. ! if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use) || use->Opcode() == Op_Opaque4) { // Since this code is highly unlikely, we lazily build the worklist // of such Nodes to go split. ! if (!split_if_set) { split_if_set = new Node_List(area); + } split_if_set->push(use); } ! if (use->is_Bool()) { ! if (!split_bool_set) { split_bool_set = new Node_List(area); + } split_bool_set->push(use); } ! if (use->Opcode() == Op_CreateEx) { ! if (!split_cex_set) { split_cex_set = new Node_List(area); + } split_cex_set->push(use); } // Get "block" use is in
*** 1850,1884 **** // Check for IFs that need splitting/cloning. Happens if an IF outside of // the loop uses a condition set in the loop. The original IF probably // takes control from one or more OLD Regions (which in turn get from NEW // Regions). In any case, there will be a set of Phis for each merge point // from the IF up to where the original BOOL def exists the loop. ! if( split_if_set ) { ! while( split_if_set->size() ) { Node *iff = split_if_set->pop(); ! if( iff->in(1)->is_Phi() ) { ! BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop ); _igvn.replace_input_of(iff, 1, b); } } } ! if( split_bool_set ) { ! while( split_bool_set->size() ) { Node *b = split_bool_set->pop(); Node *phi = b->in(1); ! assert( phi->is_Phi(), "" ); ! CmpNode *cmp = clone_bool( (PhiNode*)phi, loop ); _igvn.replace_input_of(b, 1, cmp); } } ! if( split_cex_set ) { ! while( split_cex_set->size() ) { Node *b = split_cex_set->pop(); ! assert( b->in(0)->is_Region(), "" ); ! assert( b->in(1)->is_Phi(), "" ); ! assert( b->in(0)->in(0) == b->in(1)->in(0), "" ); ! split_up( b, b->in(0), NULL ); } } } --- 1870,1904 ---- // Check for IFs that need splitting/cloning. Happens if an IF outside of // the loop uses a condition set in the loop. The original IF probably // takes control from one or more OLD Regions (which in turn get from NEW // Regions). In any case, there will be a set of Phis for each merge point // from the IF up to where the original BOOL def exists the loop. ! if (split_if_set) { ! while (split_if_set->size()) { Node *iff = split_if_set->pop(); ! if (iff->in(1)->is_Phi()) { ! Node *b = clone_iff(iff->in(1)->as_Phi(), loop); _igvn.replace_input_of(iff, 1, b); } } } ! if (split_bool_set) { ! while (split_bool_set->size()) { Node *b = split_bool_set->pop(); Node *phi = b->in(1); ! assert(phi->is_Phi(), ""); ! CmpNode *cmp = clone_bool((PhiNode*)phi, loop); _igvn.replace_input_of(b, 1, cmp); } } ! if (split_cex_set) { ! while (split_cex_set->size()) { Node *b = split_cex_set->pop(); ! assert(b->in(0)->is_Region(), ""); ! assert(b->in(1)->is_Phi(), ""); ! assert(b->in(0)->in(0) == b->in(1)->in(0), ""); ! split_up(b, b->in(0), NULL); } } }
< prev index next >