259 |
259 |
260 // Fixup self |
260 // Fixup self |
261 set_early_ctrl( n ); |
261 set_early_ctrl( n ); |
262 } |
262 } |
263 |
263 |
|
264 // Create a skeleton strip mined outer loop: a Loop head before the |
|
265 // inner strip mined loop, a safepoint and an exit condition guarded |
|
266 // by an opaque node after the inner strip mined loop with a backedge |
|
267 // to the loop head. The inner strip mined loop is left as it is. Only |
|
268 // once loop optimizations are over, do we adjust the inner loop exit |
|
269 // condition to limit its number of iterations, set the outer loop |
|
270 // exit condition and add Phis to the outer loop head. Some loop |
|
271 // optimizations that operate on the inner strip mined loop need to be |
|
272 // aware of the outer strip mined loop: loop unswitching needs to |
|
273 // clone the outer loop as well as the inner, unrolling needs to only |
|
274 // clone the inner loop etc. No optimizations need to change the outer |
|
275 // strip mined loop as it is only a skeleton. |
|
276 IdealLoopTree* PhaseIdealLoop::create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control, |
|
277 IdealLoopTree* loop, float cl_prob, float le_fcnt, |
|
278 Node*& entry_control, Node*& iffalse) { |
|
279 Node* outer_test = _igvn.intcon(0); |
|
280 set_ctrl(outer_test, C->root()); |
|
281 Node *orig = iffalse; |
|
282 iffalse = iffalse->clone(); |
|
283 _igvn.register_new_node_with_optimizer(iffalse); |
|
284 set_idom(iffalse, idom(orig), dom_depth(orig)); |
|
285 |
|
286 IfNode *outer_le = new OuterStripMinedLoopEndNode(iffalse, outer_test, cl_prob, le_fcnt); |
|
287 Node *outer_ift = new IfTrueNode (outer_le); |
|
288 Node* outer_iff = orig; |
|
289 _igvn.replace_input_of(outer_iff, 0, outer_le); |
|
290 |
|
291 LoopNode *outer_l = new OuterStripMinedLoopNode(C, init_control, outer_ift); |
|
292 entry_control = outer_l; |
|
293 |
|
294 IdealLoopTree* outer_ilt = new IdealLoopTree(this, outer_l, outer_ift); |
|
295 IdealLoopTree* parent = loop->_parent; |
|
296 IdealLoopTree* sibling = parent->_child; |
|
297 if (sibling == loop) { |
|
298 parent->_child = outer_ilt; |
|
299 } else { |
|
300 while (sibling->_next != loop) { |
|
301 sibling = sibling->_next; |
|
302 } |
|
303 sibling->_next = outer_ilt; |
|
304 } |
|
305 outer_ilt->_next = loop->_next; |
|
306 outer_ilt->_parent = parent; |
|
307 outer_ilt->_child = loop; |
|
308 outer_ilt->_nest = loop->_nest; |
|
309 loop->_parent = outer_ilt; |
|
310 loop->_next = NULL; |
|
311 loop->_nest++; |
|
312 |
|
313 set_loop(iffalse, outer_ilt); |
|
314 register_control(outer_le, outer_ilt, iffalse); |
|
315 register_control(outer_ift, outer_ilt, outer_le); |
|
316 set_idom(outer_iff, outer_le, dom_depth(outer_le)); |
|
317 _igvn.register_new_node_with_optimizer(outer_l); |
|
318 set_loop(outer_l, outer_ilt); |
|
319 set_idom(outer_l, init_control, dom_depth(init_control)+1); |
|
320 |
|
321 return outer_ilt; |
|
322 } |
|
323 |
264 //------------------------------is_counted_loop-------------------------------- |
324 //------------------------------is_counted_loop-------------------------------- |
265 bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) { |
325 bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) { |
266 PhaseGVN *gvn = &_igvn; |
326 PhaseGVN *gvn = &_igvn; |
267 |
327 |
268 // Counted loop head must be a good RegionNode with only 3 not NULL |
328 // Counted loop head must be a good RegionNode with only 3 not NULL |
269 // control input edges: Self, Entry, LoopBack. |
329 // control input edges: Self, Entry, LoopBack. |
270 if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) { |
330 if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) { |
774 |
860 |
775 //------------------------------Ideal------------------------------------------ |
861 //------------------------------Ideal------------------------------------------ |
776 // Return a node which is more "ideal" than the current node. |
862 // Return a node which is more "ideal" than the current node. |
777 // Attempt to convert into a counted-loop. |
863 // Attempt to convert into a counted-loop. |
778 Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
864 Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
779 if (!can_be_counted_loop(phase)) { |
865 if (!can_be_counted_loop(phase) && !is_OuterStripMinedLoop()) { |
780 phase->C->set_major_progress(); |
866 phase->C->set_major_progress(); |
781 } |
867 } |
782 return RegionNode::Ideal(phase, can_reshape); |
868 return RegionNode::Ideal(phase, can_reshape); |
783 } |
869 } |
784 |
870 |
|
871 void LoopNode::verify_strip_mined(int expect_skeleton) const { |
|
872 #ifdef ASSERT |
|
873 const OuterStripMinedLoopNode* outer = NULL; |
|
874 const CountedLoopNode* inner = NULL; |
|
875 if (is_strip_mined()) { |
|
876 assert(is_CountedLoop(), "no Loop should be marked strip mined"); |
|
877 inner = as_CountedLoop(); |
|
878 outer = inner->in(LoopNode::EntryControl)->as_OuterStripMinedLoop(); |
|
879 } else if (is_OuterStripMinedLoop()) { |
|
880 outer = this->as_OuterStripMinedLoop(); |
|
881 inner = outer->unique_ctrl_out()->as_CountedLoop(); |
|
882 assert(!is_strip_mined(), "outer loop shouldn't be marked strip mined"); |
|
883 } |
|
884 if (inner != NULL || outer != NULL) { |
|
885 assert(inner != NULL && outer != NULL, "missing loop in strip mined nest"); |
|
886 Node* outer_tail = outer->in(LoopNode::LoopBackControl); |
|
887 Node* outer_le = outer_tail->in(0); |
|
888 assert(outer_le->Opcode() == Op_OuterStripMinedLoopEnd, "tail of outer loop should be an If"); |
|
889 Node* sfpt = outer_le->in(0); |
|
890 assert(sfpt->Opcode() == Op_SafePoint, "where's the safepoint?"); |
|
891 Node* inner_out = sfpt->in(0); |
|
892 if (inner_out->outcnt() != 1) { |
|
893 ResourceMark rm; |
|
894 Unique_Node_List wq; |
|
895 |
|
896 for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) { |
|
897 Node* u = inner_out->fast_out(i); |
|
898 if (u == sfpt) { |
|
899 continue; |
|
900 } |
|
901 wq.clear(); |
|
902 wq.push(u); |
|
903 bool found_sfpt = false; |
|
904 for (uint next = 0; next < wq.size() && !found_sfpt; next++) { |
|
905 Node *n = wq.at(next); |
|
906 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) { |
|
907 Node* u = n->fast_out(i); |
|
908 if (u == sfpt) { |
|
909 found_sfpt = true; |
|
910 } |
|
911 if (!u->is_CFG()) { |
|
912 wq.push(u); |
|
913 } |
|
914 } |
|
915 } |
|
916 assert(found_sfpt, "no node in loop that's not input to safepoint"); |
|
917 } |
|
918 } |
|
919 CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd(); |
|
920 assert(cle == inner->loopexit(), "mismatch"); |
|
921 bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0; |
|
922 if (has_skeleton) { |
|
923 assert(expect_skeleton == 1 || expect_skeleton == -1, "unexpected skeleton node"); |
|
924 assert(outer->outcnt() == 2, "only phis"); |
|
925 } else { |
|
926 assert(expect_skeleton == 0 || expect_skeleton == -1, "no skeleton node?"); |
|
927 uint phis = 0; |
|
928 for (DUIterator_Fast imax, i = inner->fast_outs(imax); i < imax; i++) { |
|
929 Node* u = inner->fast_out(i); |
|
930 if (u->is_Phi()) { |
|
931 phis++; |
|
932 } |
|
933 } |
|
934 for (DUIterator_Fast imax, i = outer->fast_outs(imax); i < imax; i++) { |
|
935 Node* u = outer->fast_out(i); |
|
936 assert(u == outer || u == inner || u->is_Phi(), "nothing between inner and outer loop"); |
|
937 } |
|
938 uint stores = 0; |
|
939 for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) { |
|
940 Node* u = inner_out->fast_out(i); |
|
941 if (u->is_Store()) { |
|
942 stores++; |
|
943 } |
|
944 } |
|
945 assert(outer->outcnt() >= phis + 2 && outer->outcnt() <= phis + 2 + stores + 1, "only phis"); |
|
946 } |
|
947 assert(sfpt->outcnt() == 1, "no data node"); |
|
948 assert(outer_tail->outcnt() == 1 || !has_skeleton, "no data node"); |
|
949 } |
|
950 #endif |
|
951 } |
785 |
952 |
786 //============================================================================= |
953 //============================================================================= |
787 //------------------------------Ideal------------------------------------------ |
954 //------------------------------Ideal------------------------------------------ |
788 // Return a node which is more "ideal" than the current node. |
955 // Return a node which is more "ideal" than the current node. |
789 // Attempt to convert into a counted-loop. |
956 // Attempt to convert into a counted-loop. |
988 |
1156 |
989 // failed |
1157 // failed |
990 return NULL; |
1158 return NULL; |
991 } |
1159 } |
992 |
1160 |
|
1161 LoopNode* CountedLoopNode::skip_strip_mined(int expect_opaq) { |
|
1162 if (is_strip_mined()) { |
|
1163 verify_strip_mined(expect_opaq); |
|
1164 return in(EntryControl)->as_Loop(); |
|
1165 } |
|
1166 return this; |
|
1167 } |
|
1168 |
|
1169 OuterStripMinedLoopNode* CountedLoopNode::outer_loop() const { |
|
1170 assert(is_strip_mined(), "not a strip mined loop"); |
|
1171 Node* c = in(EntryControl); |
|
1172 if (c == NULL || c->is_top() || !c->is_OuterStripMinedLoop()) { |
|
1173 return NULL; |
|
1174 } |
|
1175 return c->as_OuterStripMinedLoop(); |
|
1176 } |
|
1177 |
|
1178 IfTrueNode* OuterStripMinedLoopNode::outer_loop_tail() const { |
|
1179 Node* c = in(LoopBackControl); |
|
1180 if (c == NULL || c->is_top()) { |
|
1181 return NULL; |
|
1182 } |
|
1183 return c->as_IfTrue(); |
|
1184 } |
|
1185 |
|
1186 IfTrueNode* CountedLoopNode::outer_loop_tail() const { |
|
1187 LoopNode* l = outer_loop(); |
|
1188 if (l == NULL) { |
|
1189 return NULL; |
|
1190 } |
|
1191 return l->outer_loop_tail(); |
|
1192 } |
|
1193 |
|
1194 OuterStripMinedLoopEndNode* OuterStripMinedLoopNode::outer_loop_end() const { |
|
1195 IfTrueNode* proj = outer_loop_tail(); |
|
1196 if (proj == NULL) { |
|
1197 return NULL; |
|
1198 } |
|
1199 Node* c = proj->in(0); |
|
1200 if (c == NULL || c->is_top() || c->outcnt() != 2) { |
|
1201 return NULL; |
|
1202 } |
|
1203 return c->as_OuterStripMinedLoopEnd(); |
|
1204 } |
|
1205 |
|
1206 OuterStripMinedLoopEndNode* CountedLoopNode::outer_loop_end() const { |
|
1207 LoopNode* l = outer_loop(); |
|
1208 if (l == NULL) { |
|
1209 return NULL; |
|
1210 } |
|
1211 return l->outer_loop_end(); |
|
1212 } |
|
1213 |
|
1214 IfFalseNode* OuterStripMinedLoopNode::outer_loop_exit() const { |
|
1215 IfNode* le = outer_loop_end(); |
|
1216 if (le == NULL) { |
|
1217 return NULL; |
|
1218 } |
|
1219 Node* c = le->proj_out(false); |
|
1220 if (c == NULL) { |
|
1221 return NULL; |
|
1222 } |
|
1223 return c->as_IfFalse(); |
|
1224 } |
|
1225 |
|
1226 IfFalseNode* CountedLoopNode::outer_loop_exit() const { |
|
1227 LoopNode* l = outer_loop(); |
|
1228 if (l == NULL) { |
|
1229 return NULL; |
|
1230 } |
|
1231 return l->outer_loop_exit(); |
|
1232 } |
|
1233 |
|
1234 SafePointNode* OuterStripMinedLoopNode::outer_safepoint() const { |
|
1235 IfNode* le = outer_loop_end(); |
|
1236 if (le == NULL) { |
|
1237 return NULL; |
|
1238 } |
|
1239 Node* c = le->in(0); |
|
1240 if (c == NULL || c->is_top()) { |
|
1241 return NULL; |
|
1242 } |
|
1243 assert(c->Opcode() == Op_SafePoint, "broken outer loop"); |
|
1244 return c->as_SafePoint(); |
|
1245 } |
|
1246 |
|
1247 SafePointNode* CountedLoopNode::outer_safepoint() const { |
|
1248 LoopNode* l = outer_loop(); |
|
1249 if (l == NULL) { |
|
1250 return NULL; |
|
1251 } |
|
1252 return l->outer_safepoint(); |
|
1253 } |
|
1254 |
|
1255 void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) { |
|
1256 // Look for the outer & inner strip mined loop, reduce number of |
|
1257 // iterations of the inner loop, set exit condition of outer loop, |
|
1258 // construct required phi nodes for outer loop. |
|
1259 CountedLoopNode* inner_cl = unique_ctrl_out()->as_CountedLoop(); |
|
1260 assert(inner_cl->is_strip_mined(), "inner loop should be strip mined"); |
|
1261 Node* inner_iv_phi = inner_cl->phi(); |
|
1262 if (inner_iv_phi == NULL) { |
|
1263 return; |
|
1264 } |
|
1265 CountedLoopEndNode* inner_cle = inner_cl->loopexit(); |
|
1266 |
|
1267 int stride = inner_cl->stride_con(); |
|
1268 jlong scaled_iters_long = ((jlong)LoopStripMiningIter) * ABS(stride); |
|
1269 int scaled_iters = (int)scaled_iters_long; |
|
1270 int short_scaled_iters = LoopStripMiningIterShortLoop* ABS(stride); |
|
1271 const TypeInt* inner_iv_t = igvn->type(inner_iv_phi)->is_int(); |
|
1272 jlong iter_estimate = (jlong)inner_iv_t->_hi - (jlong)inner_iv_t->_lo; |
|
1273 assert(iter_estimate > 0, "broken"); |
|
1274 if ((jlong)scaled_iters != scaled_iters_long || iter_estimate <= short_scaled_iters) { |
|
1275 // Remove outer loop and safepoint (too few iterations) |
|
1276 Node* outer_sfpt = outer_safepoint(); |
|
1277 Node* outer_out = outer_loop_exit(); |
|
1278 igvn->replace_node(outer_out, outer_sfpt->in(0)); |
|
1279 igvn->replace_input_of(outer_sfpt, 0, igvn->C->top()); |
|
1280 inner_cl->clear_strip_mined(); |
|
1281 return; |
|
1282 } |
|
1283 if (iter_estimate <= scaled_iters_long) { |
|
1284 // We would only go through one iteration of |
|
1285 // the outer loop: drop the outer loop but |
|
1286 // keep the safepoint so we don't run for |
|
1287 // too long without a safepoint |
|
1288 IfNode* outer_le = outer_loop_end(); |
|
1289 Node* iff = igvn->transform(new IfNode(outer_le->in(0), outer_le->in(1), outer_le->_prob, outer_le->_fcnt)); |
|
1290 igvn->replace_node(outer_le, iff); |
|
1291 inner_cl->clear_strip_mined(); |
|
1292 return; |
|
1293 } |
|
1294 |
|
1295 Node* cle_tail = inner_cle->proj_out(true); |
|
1296 ResourceMark rm; |
|
1297 Node_List old_new; |
|
1298 if (cle_tail->outcnt() > 1) { |
|
1299 // Look for nodes on backedge of inner loop and clone them |
|
1300 Unique_Node_List backedge_nodes; |
|
1301 for (DUIterator_Fast imax, i = cle_tail->fast_outs(imax); i < imax; i++) { |
|
1302 Node* u = cle_tail->fast_out(i); |
|
1303 if (u != inner_cl) { |
|
1304 assert(!u->is_CFG(), "control flow on the backedge?"); |
|
1305 backedge_nodes.push(u); |
|
1306 } |
|
1307 } |
|
1308 uint last = igvn->C->unique(); |
|
1309 for (uint next = 0; next < backedge_nodes.size(); next++) { |
|
1310 Node* n = backedge_nodes.at(next); |
|
1311 old_new.map(n->_idx, n->clone()); |
|
1312 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
|
1313 Node* u = n->fast_out(i); |
|
1314 assert(!u->is_CFG(), "broken"); |
|
1315 if (u->_idx >= last) { |
|
1316 continue; |
|
1317 } |
|
1318 if (!u->is_Phi()) { |
|
1319 backedge_nodes.push(u); |
|
1320 } else { |
|
1321 assert(u->in(0) == inner_cl, "strange phi on the backedge"); |
|
1322 } |
|
1323 } |
|
1324 } |
|
1325 // Put the clones on the outer loop backedge |
|
1326 Node* le_tail = outer_loop_tail(); |
|
1327 for (uint next = 0; next < backedge_nodes.size(); next++) { |
|
1328 Node *n = old_new[backedge_nodes.at(next)->_idx]; |
|
1329 for (uint i = 1; i < n->req(); i++) { |
|
1330 if (n->in(i) != NULL && old_new[n->in(i)->_idx] != NULL) { |
|
1331 n->set_req(i, old_new[n->in(i)->_idx]); |
|
1332 } |
|
1333 } |
|
1334 if (n->in(0) != NULL) { |
|
1335 assert(n->in(0) == cle_tail, "node not on backedge?"); |
|
1336 n->set_req(0, le_tail); |
|
1337 } |
|
1338 igvn->register_new_node_with_optimizer(n); |
|
1339 } |
|
1340 } |
|
1341 |
|
1342 Node* iv_phi = NULL; |
|
1343 // Make a clone of each phi in the inner loop |
|
1344 // for the outer loop |
|
1345 for (uint i = 0; i < inner_cl->outcnt(); i++) { |
|
1346 Node* u = inner_cl->raw_out(i); |
|
1347 if (u->is_Phi()) { |
|
1348 assert(u->in(0) == inner_cl, "inconsistent"); |
|
1349 Node* phi = u->clone(); |
|
1350 phi->set_req(0, this); |
|
1351 Node* be = old_new[phi->in(LoopNode::LoopBackControl)->_idx]; |
|
1352 if (be != NULL) { |
|
1353 phi->set_req(LoopNode::LoopBackControl, be); |
|
1354 } |
|
1355 phi = igvn->transform(phi); |
|
1356 igvn->replace_input_of(u, LoopNode::EntryControl, phi); |
|
1357 if (u == inner_iv_phi) { |
|
1358 iv_phi = phi; |
|
1359 } |
|
1360 } |
|
1361 } |
|
1362 Node* cle_out = inner_cle->proj_out(false); |
|
1363 if (cle_out->outcnt() > 1) { |
|
1364 // Look for chains of stores that were sunk |
|
1365 // out of the inner loop and are in the outer loop |
|
1366 for (DUIterator_Fast imax, i = cle_out->fast_outs(imax); i < imax; i++) { |
|
1367 Node* u = cle_out->fast_out(i); |
|
1368 if (u->is_Store()) { |
|
1369 Node* first = u; |
|
1370 for(;;) { |
|
1371 Node* next = first->in(MemNode::Memory); |
|
1372 if (!next->is_Store() || next->in(0) != cle_out) { |
|
1373 break; |
|
1374 } |
|
1375 first = next; |
|
1376 } |
|
1377 Node* last = u; |
|
1378 for(;;) { |
|
1379 Node* next = NULL; |
|
1380 for (DUIterator_Fast jmax, j = last->fast_outs(jmax); j < jmax; j++) { |
|
1381 Node* uu = last->fast_out(j); |
|
1382 if (uu->is_Store() && uu->in(0) == cle_out) { |
|
1383 assert(next == NULL, "only one in the outer loop"); |
|
1384 next = uu; |
|
1385 } |
|
1386 } |
|
1387 if (next == NULL) { |
|
1388 break; |
|
1389 } |
|
1390 last = next; |
|
1391 } |
|
1392 Node* phi = NULL; |
|
1393 for (DUIterator_Fast jmax, j = fast_outs(jmax); j < jmax; j++) { |
|
1394 Node* uu = fast_out(j); |
|
1395 if (uu->is_Phi()) { |
|
1396 Node* be = uu->in(LoopNode::LoopBackControl); |
|
1397 while (be->is_Store() && old_new[be->_idx] != NULL) { |
|
1398 ShouldNotReachHere(); |
|
1399 be = be->in(MemNode::Memory); |
|
1400 } |
|
1401 if (be == last || be == first->in(MemNode::Memory)) { |
|
1402 assert(phi == NULL, "only one phi"); |
|
1403 phi = uu; |
|
1404 } |
|
1405 } |
|
1406 } |
|
1407 #ifdef ASSERT |
|
1408 for (DUIterator_Fast jmax, j = fast_outs(jmax); j < jmax; j++) { |
|
1409 Node* uu = fast_out(j); |
|
1410 if (uu->is_Phi() && uu->bottom_type() == Type::MEMORY) { |
|
1411 if (uu->adr_type() == igvn->C->get_adr_type(igvn->C->get_alias_index(u->adr_type()))) { |
|
1412 assert(phi == uu, "what's that phi?"); |
|
1413 } else if (uu->adr_type() == TypePtr::BOTTOM) { |
|
1414 Node* n = uu->in(LoopNode::LoopBackControl); |
|
1415 uint limit = igvn->C->live_nodes(); |
|
1416 uint i = 0; |
|
1417 while (n != uu) { |
|
1418 i++; |
|
1419 assert(i < limit, "infinite loop"); |
|
1420 if (n->is_Proj()) { |
|
1421 n = n->in(0); |
|
1422 } else if (n->is_SafePoint() || n->is_MemBar()) { |
|
1423 n = n->in(TypeFunc::Memory); |
|
1424 } else if (n->is_Phi()) { |
|
1425 n = n->in(1); |
|
1426 } else if (n->is_MergeMem()) { |
|
1427 n = n->as_MergeMem()->memory_at(igvn->C->get_alias_index(u->adr_type())); |
|
1428 } else if (n->is_Store() || n->is_LoadStore() || n->is_ClearArray()) { |
|
1429 n = n->in(MemNode::Memory); |
|
1430 } else { |
|
1431 n->dump(); |
|
1432 ShouldNotReachHere(); |
|
1433 } |
|
1434 } |
|
1435 } |
|
1436 } |
|
1437 } |
|
1438 #endif |
|
1439 if (phi == NULL) { |
|
1440 // If the an entire chains was sunk, the |
|
1441 // inner loop has no phi for that memory |
|
1442 // slice, create one for the outer loop |
|
1443 phi = PhiNode::make(this, first->in(MemNode::Memory), Type::MEMORY, |
|
1444 igvn->C->get_adr_type(igvn->C->get_alias_index(u->adr_type()))); |
|
1445 phi->set_req(LoopNode::LoopBackControl, last); |
|
1446 phi = igvn->transform(phi); |
|
1447 igvn->replace_input_of(first, MemNode::Memory, phi); |
|
1448 } else { |
|
1449 // Or fix the outer loop fix to include |
|
1450 // that chain of stores. |
|
1451 Node* be = phi->in(LoopNode::LoopBackControl); |
|
1452 while (be->is_Store() && old_new[be->_idx] != NULL) { |
|
1453 ShouldNotReachHere(); |
|
1454 be = be->in(MemNode::Memory); |
|
1455 } |
|
1456 if (be == first->in(MemNode::Memory)) { |
|
1457 if (be == phi->in(LoopNode::LoopBackControl)) { |
|
1458 igvn->replace_input_of(phi, LoopNode::LoopBackControl, last); |
|
1459 } else { |
|
1460 igvn->replace_input_of(be, MemNode::Memory, last); |
|
1461 } |
|
1462 } else { |
|
1463 #ifdef ASSERT |
|
1464 if (be == phi->in(LoopNode::LoopBackControl)) { |
|
1465 assert(phi->in(LoopNode::LoopBackControl) == last, ""); |
|
1466 } else { |
|
1467 assert(be->in(MemNode::Memory) == last, ""); |
|
1468 } |
|
1469 #endif |
|
1470 } |
|
1471 } |
|
1472 } |
|
1473 } |
|
1474 } |
|
1475 |
|
1476 if (iv_phi != NULL) { |
|
1477 // Now adjust the inner loop's exit condition |
|
1478 Node* limit = inner_cl->limit(); |
|
1479 Node* sub = NULL; |
|
1480 if (stride > 0) { |
|
1481 sub = igvn->transform(new SubINode(limit, iv_phi)); |
|
1482 } else { |
|
1483 sub = igvn->transform(new SubINode(iv_phi, limit)); |
|
1484 } |
|
1485 Node* min = igvn->transform(new MinINode(sub, igvn->intcon(scaled_iters))); |
|
1486 Node* new_limit = NULL; |
|
1487 if (stride > 0) { |
|
1488 new_limit = igvn->transform(new AddINode(min, iv_phi)); |
|
1489 } else { |
|
1490 new_limit = igvn->transform(new SubINode(iv_phi, min)); |
|
1491 } |
|
1492 igvn->replace_input_of(inner_cle->cmp_node(), 2, new_limit); |
|
1493 Node* cmp = inner_cle->cmp_node()->clone(); |
|
1494 Node* bol = inner_cle->in(CountedLoopEndNode::TestValue)->clone(); |
|
1495 cmp->set_req(2, limit); |
|
1496 bol->set_req(1, igvn->transform(cmp)); |
|
1497 igvn->replace_input_of(outer_loop_end(), 1, igvn->transform(bol)); |
|
1498 } else { |
|
1499 assert(false, "should be able to adjust outer loop"); |
|
1500 IfNode* outer_le = outer_loop_end(); |
|
1501 Node* iff = igvn->transform(new IfNode(outer_le->in(0), outer_le->in(1), outer_le->_prob, outer_le->_fcnt)); |
|
1502 igvn->replace_node(outer_le, iff); |
|
1503 inner_cl->clear_strip_mined(); |
|
1504 } |
|
1505 } |
|
1506 |
|
1507 const Type* OuterStripMinedLoopEndNode::Value(PhaseGVN* phase) const { |
|
1508 if (!in(0)) return Type::TOP; |
|
1509 if (phase->type(in(0)) == Type::TOP) |
|
1510 return Type::TOP; |
|
1511 |
|
1512 return TypeTuple::IFBOTH; |
|
1513 } |
|
1514 |
|
1515 Node *OuterStripMinedLoopEndNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
|
1516 if (remove_dead_region(phase, can_reshape)) return this; |
|
1517 |
|
1518 return NULL; |
|
1519 } |
993 |
1520 |
994 //------------------------------filtered_type-------------------------------- |
1521 //------------------------------filtered_type-------------------------------- |
995 // Return a type based on condition control flow |
1522 // Return a type based on condition control flow |
996 // A successful return will be a type that is restricted due |
1523 // A successful return will be a type that is restricted due |
997 // to a series of dominating if-tests, such as: |
1524 // to a series of dominating if-tests, such as: |