< prev index next >

src/hotspot/share/opto/loopopts.cpp

Print this page




1197 
1198   return true;
1199 }
1200 
1201 // Detect if the node is the inner strip-mined loop
1202 // Return: NULL if it's not the case, or the exit of outer strip-mined loop
1203 static Node* is_inner_of_stripmined_loop(const Node* out) {
1204   Node* out_le = NULL;
1205 
1206   if (out->is_CountedLoopEnd()) {
1207       const CountedLoopNode* loop = out->as_CountedLoopEnd()->loopnode();
1208 
1209       if (loop != NULL && loop->is_strip_mined()) {
1210         out_le = loop->in(LoopNode::EntryControl)->as_OuterStripMinedLoop()->outer_loop_exit();
1211       }
1212   }
1213 
1214   return out_le;
1215 }
1216 
































































































1217 //------------------------------split_if_with_blocks_post----------------------
1218 // Do the real work in a non-recursive function.  CFG hackery wants to be
1219 // in the post-order, so it can dirty the I-DOM info and not use the dirtied
1220 // info.
1221 void PhaseIdealLoop::split_if_with_blocks_post(Node *n) {
1222 




1223   // Cloning Cmp through Phi's involves the split-if transform.
1224   // FastLock is not used by an If
1225   if (n->is_Cmp() && !n->is_FastLock()) {
1226     Node *n_ctrl = get_ctrl(n);
1227     // Determine if the Node has inputs from some local Phi.
1228     // Returns the block to clone thru.
1229     Node *n_blk = has_local_phi_input(n);
1230     if (n_blk != n_ctrl) {
1231       return;
1232     }
1233 
1234     if (!can_split_if(n_ctrl)) {
1235       return;
1236     }
1237 
1238     if (n->outcnt() != 1) {
1239       return; // Multiple bool's from 1 compare?
1240     }
1241     Node *bol = n->unique_out();
1242     assert(bol->is_Bool(), "expect a bool here");




1197 
1198   return true;
1199 }
1200 
1201 // Detect if the node is the inner strip-mined loop
1202 // Return: NULL if it's not the case, or the exit of outer strip-mined loop
1203 static Node* is_inner_of_stripmined_loop(const Node* out) {
1204   Node* out_le = NULL;
1205 
1206   if (out->is_CountedLoopEnd()) {
1207       const CountedLoopNode* loop = out->as_CountedLoopEnd()->loopnode();
1208 
1209       if (loop != NULL && loop->is_strip_mined()) {
1210         out_le = loop->in(LoopNode::EntryControl)->as_OuterStripMinedLoop()->outer_loop_exit();
1211       }
1212   }
1213 
1214   return out_le;
1215 }
1216 
1217 bool PhaseIdealLoop::flatten_array_element_type_check(Node *n) {
1218   // If the CmpP is a subtype check for a value that has just been
1219   // loaded from an array, the subtype checks guarantees the value
1220   // can't be stored in a flattened array and the load of the value
1221   // happens with a flattened array check then: push the type check
1222   // through the phi of the flattened array check. This needs special
1223   // logic because the subtype check's input is not a phi but a
1224   // LoadKlass that must first be cloned through the phi.
1225   if (n->Opcode() != Op_CmpP) {
1226     return false;
1227   }
1228   
1229   Node* klassptr = n->in(1);
1230   Node* klasscon = n->in(2);
1231 
1232   if (klassptr->is_DecodeNarrowPtr()) {
1233     klassptr = klassptr->in(1);
1234   }
1235   
1236   if (klassptr->Opcode() != Op_LoadKlass && klassptr->Opcode() != Op_LoadNKlass) {
1237     return false;
1238   }
1239   
1240   if (!klasscon->is_Con()) {
1241     return false;
1242   }
1243   
1244   Node* addr = klassptr->in(MemNode::Address);
1245   
1246   if (!addr->is_AddP()) {
1247     return false;
1248   }
1249   
1250   intptr_t offset;
1251   Node* obj = AddPNode::Ideal_base_and_offset(addr, &_igvn, offset);
1252 
1253   if (obj == NULL) {
1254     return false;
1255   }
1256   
1257   assert(obj != NULL && addr->in(AddPNode::Base) == addr->in(AddPNode::Address), "malformed AddP?");
1258   if (obj->Opcode() == Op_CastPP) {
1259     obj = obj->in(1);
1260   }
1261 
1262   if (!obj->is_Phi()) {
1263     return false;
1264   }
1265 
1266   Node* region = obj->in(0);
1267   
1268   Node* phi = PhiNode::make_blank(region, n->in(1));
1269   for (uint i = 1; i < region->req(); i++) {
1270     Node* in = obj->in(i);
1271     Node* ctrl = get_ctrl(in);
1272     if (addr->in(AddPNode::Base) != obj) {
1273       Node* cast = addr->in(AddPNode::Base);
1274       assert(cast->Opcode() == Op_CastPP && cast->in(0) != NULL, "inconsistent subgraph");
1275       Node* cast_clone = cast->clone();
1276       cast_clone->set_req(0, region->in(i));
1277       cast_clone->set_req(1, in);
1278       register_new_node(cast_clone, region->in(i));
1279       _igvn.set_type(cast_clone, cast_clone->Value(&_igvn));
1280       in = cast_clone;
1281     }
1282     Node* addr_clone = addr->clone();
1283     addr_clone->set_req(AddPNode::Base, in);
1284     addr_clone->set_req(AddPNode::Address, in);
1285     register_new_node(addr_clone, ctrl);
1286     _igvn.set_type(addr_clone, addr_clone->Value(&_igvn));
1287     Node* klassptr_clone = klassptr->clone();
1288     klassptr_clone->set_req(2, addr_clone);
1289     register_new_node(klassptr_clone, ctrl);
1290     _igvn.set_type(klassptr_clone, klassptr_clone->Value(&_igvn));
1291     if (klassptr != n->in(1)) {
1292       Node* decode = n->in(1);
1293       assert(decode->is_DecodeNarrowPtr(), "inconcistent subgraph");
1294       Node* decode_clone = decode->clone();
1295       decode_clone->set_req(1, klassptr_clone);
1296       register_new_node(decode_clone, ctrl);
1297       _igvn.set_type(decode_clone, decode_clone->Value(&_igvn));
1298       klassptr_clone = decode_clone;
1299     }
1300     phi->set_req(i, klassptr_clone);
1301   }
1302   register_new_node(phi, region);
1303   Node* orig = n->in(1);
1304   _igvn.replace_input_of(n, 1, phi);
1305   split_if_with_blocks_post(n);
1306   if (n->outcnt() != 0) {
1307     _igvn.replace_input_of(n, 1, orig);
1308     _igvn.remove_dead_node(phi);
1309   }
1310   return true;
1311 }
1312 
1313 //------------------------------split_if_with_blocks_post----------------------
1314 // Do the real work in a non-recursive function.  CFG hackery wants to be
1315 // in the post-order, so it can dirty the I-DOM info and not use the dirtied
1316 // info.
1317 void PhaseIdealLoop::split_if_with_blocks_post(Node *n) {
1318 
1319   if (flatten_array_element_type_check(n)) {
1320     return;
1321   }
1322   
1323   // Cloning Cmp through Phi's involves the split-if transform.
1324   // FastLock is not used by an If
1325   if (n->is_Cmp() && !n->is_FastLock()) {
1326     Node *n_ctrl = get_ctrl(n);
1327     // Determine if the Node has inputs from some local Phi.
1328     // Returns the block to clone thru.
1329     Node *n_blk = has_local_phi_input(n);
1330     if (n_blk != n_ctrl) {
1331       return;
1332     }
1333 
1334     if (!can_split_if(n_ctrl)) {
1335       return;
1336     }
1337 
1338     if (n->outcnt() != 1) {
1339       return; // Multiple bool's from 1 compare?
1340     }
1341     Node *bol = n->unique_out();
1342     assert(bol->is_Bool(), "expect a bool here");


< prev index next >