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"); |