690 return new (Compile::current(), r->req()) PhiNode(r, t, at);
691 }
692
693
694 //------------------------slice_memory-----------------------------------------
695 // create a new phi with narrowed memory type
696 PhiNode* PhiNode::slice_memory(const TypePtr* adr_type) const {
697 PhiNode* mem = (PhiNode*) clone();
698 *(const TypePtr**)&mem->_adr_type = adr_type;
699 // convert self-loops, or else we get a bad graph
700 for (uint i = 1; i < req(); i++) {
701 if ((const Node*)in(i) == this) mem->set_req(i, mem);
702 }
703 mem->verify_adr_type();
704 return mem;
705 }
706
707 //------------------------split_out_instance-----------------------------------
708 // Split out an instance type from a bottom phi.
709 PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
710 assert(type() == Type::MEMORY && (adr_type() == TypePtr::BOTTOM ||
711 adr_type() == TypeRawPtr::BOTTOM) , "bottom or raw memory required");
712
713 // Check if an appropriate node already exists.
714 Node *region = in(0);
715 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
716 Node* use = region->fast_out(k);
717 if( use->is_Phi()) {
718 PhiNode *phi2 = use->as_Phi();
719 if (phi2->type() == Type::MEMORY && phi2->adr_type() == at) {
720 return phi2;
721 }
722 }
723 }
724 Compile *C = igvn->C;
725 Arena *a = Thread::current()->resource_area();
726 Node_Array node_map = new Node_Array(a);
727 Node_Stack stack(a, C->unique() >> 4);
728 PhiNode *nphi = slice_memory(at);
729 igvn->register_new_node_with_optimizer( nphi );
730 node_map.map(_idx, nphi);
731 stack.push((Node *)this, 1);
1325 // Now I can point to the new node.
1326 n->add_req(newn);
1327 igvn->_worklist.push(n);
1328 }
1329
1330 //------------------------------split_flow_path--------------------------------
1331 // Check for merging identical values and split flow paths
1332 static Node* split_flow_path(PhaseGVN *phase, PhiNode *phi) {
1333 BasicType bt = phi->type()->basic_type();
1334 if( bt == T_ILLEGAL || type2size[bt] <= 0 )
1335 return NULL; // Bail out on funny non-value stuff
1336 if( phi->req() <= 3 ) // Need at least 2 matched inputs and a
1337 return NULL; // third unequal input to be worth doing
1338
1339 // Scan for a constant
1340 uint i;
1341 for( i = 1; i < phi->req()-1; i++ ) {
1342 Node *n = phi->in(i);
1343 if( !n ) return NULL;
1344 if( phase->type(n) == Type::TOP ) return NULL;
1345 if( n->Opcode() == Op_ConP )
1346 break;
1347 }
1348 if( i >= phi->req() ) // Only split for constants
1349 return NULL;
1350
1351 Node *val = phi->in(i); // Constant to split for
1352 uint hit = 0; // Number of times it occurs
1353
1354 for( ; i < phi->req(); i++ ){ // Count occurances of constant
1355 Node *n = phi->in(i);
1356 if( !n ) return NULL;
1357 if( phase->type(n) == Type::TOP ) return NULL;
1358 if( phi->in(i) == val )
1359 hit++;
1360 }
1361
1362 if( hit <= 1 || // Make sure we find 2 or more
1363 hit == phi->req()-1 ) // and not ALL the same value
1364 return NULL;
1365
|
690 return new (Compile::current(), r->req()) PhiNode(r, t, at);
691 }
692
693
694 //------------------------slice_memory-----------------------------------------
695 // create a new phi with narrowed memory type
696 PhiNode* PhiNode::slice_memory(const TypePtr* adr_type) const {
697 PhiNode* mem = (PhiNode*) clone();
698 *(const TypePtr**)&mem->_adr_type = adr_type;
699 // convert self-loops, or else we get a bad graph
700 for (uint i = 1; i < req(); i++) {
701 if ((const Node*)in(i) == this) mem->set_req(i, mem);
702 }
703 mem->verify_adr_type();
704 return mem;
705 }
706
707 //------------------------split_out_instance-----------------------------------
708 // Split out an instance type from a bottom phi.
709 PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
710 const TypeOopPtr *t_oop = at->isa_oopptr();
711 assert(t_oop != NULL && t_oop->is_instance(), "expecting instance oopptr");
712 const TypePtr *t = adr_type();
713 assert(type() == Type::MEMORY &&
714 (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
715 t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
716 t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop),
717 "bottom or raw memory required");
718
719 // Check if an appropriate node already exists.
720 Node *region = in(0);
721 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
722 Node* use = region->fast_out(k);
723 if( use->is_Phi()) {
724 PhiNode *phi2 = use->as_Phi();
725 if (phi2->type() == Type::MEMORY && phi2->adr_type() == at) {
726 return phi2;
727 }
728 }
729 }
730 Compile *C = igvn->C;
731 Arena *a = Thread::current()->resource_area();
732 Node_Array node_map = new Node_Array(a);
733 Node_Stack stack(a, C->unique() >> 4);
734 PhiNode *nphi = slice_memory(at);
735 igvn->register_new_node_with_optimizer( nphi );
736 node_map.map(_idx, nphi);
737 stack.push((Node *)this, 1);
1331 // Now I can point to the new node.
1332 n->add_req(newn);
1333 igvn->_worklist.push(n);
1334 }
1335
1336 //------------------------------split_flow_path--------------------------------
1337 // Check for merging identical values and split flow paths
1338 static Node* split_flow_path(PhaseGVN *phase, PhiNode *phi) {
1339 BasicType bt = phi->type()->basic_type();
1340 if( bt == T_ILLEGAL || type2size[bt] <= 0 )
1341 return NULL; // Bail out on funny non-value stuff
1342 if( phi->req() <= 3 ) // Need at least 2 matched inputs and a
1343 return NULL; // third unequal input to be worth doing
1344
1345 // Scan for a constant
1346 uint i;
1347 for( i = 1; i < phi->req()-1; i++ ) {
1348 Node *n = phi->in(i);
1349 if( !n ) return NULL;
1350 if( phase->type(n) == Type::TOP ) return NULL;
1351 if( n->Opcode() == Op_ConP || n->Opcode() == Op_ConN )
1352 break;
1353 }
1354 if( i >= phi->req() ) // Only split for constants
1355 return NULL;
1356
1357 Node *val = phi->in(i); // Constant to split for
1358 uint hit = 0; // Number of times it occurs
1359
1360 for( ; i < phi->req(); i++ ){ // Count occurances of constant
1361 Node *n = phi->in(i);
1362 if( !n ) return NULL;
1363 if( phase->type(n) == Type::TOP ) return NULL;
1364 if( phi->in(i) == val )
1365 hit++;
1366 }
1367
1368 if( hit <= 1 || // Make sure we find 2 or more
1369 hit == phi->req()-1 ) // and not ALL the same value
1370 return NULL;
1371
|