< 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 >