src/share/vm/opto/cfgnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6695810 Sdiff src/share/vm/opto

src/share/vm/opto/cfgnode.cpp

Print this page




 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 


src/share/vm/opto/cfgnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File