115 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
116
117 // Find first invariant test that doesn't exit the loop
118 LoopNode *head = loop->_head->as_Loop();
119
120 IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
121 assert(unswitch_iff != NULL, "should be at least one");
122
123 #ifndef PRODUCT
124 if (TraceLoopOpts) {
125 tty->print("Unswitch %d ", head->unswitch_count()+1);
126 loop->dump_head();
127 }
128 #endif
129
130 // Need to revert back to normal loop
131 if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
132 head->as_CountedLoop()->set_normal_loop();
133 }
134
135 ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode());
136
137 #ifdef ASSERT
138 Node* uniqc = proj_true->unique_ctrl_out();
139 Node* entry = head->in(LoopNode::EntryControl);
140 Node* predicate = find_predicate(entry);
141 if (predicate != NULL && UseLoopPredicate) {
142 // We may have two predicates, find first.
143 entry = find_predicate(entry->in(0)->in(0));
144 if (entry != NULL) predicate = entry;
145 }
146 if (predicate != NULL) predicate = predicate->in(0);
147 assert(proj_true->is_IfTrue() &&
148 (predicate == NULL && uniqc == head ||
149 predicate != NULL && uniqc == predicate), "by construction");
150 #endif
151 // Increment unswitch count
152 LoopNode* head_clone = old_new[head->_idx]->as_Loop();
153 int nct = head->unswitch_count() + 1;
154 head->set_unswitch_count(nct);
155 head_clone->set_unswitch_count(nct);
156
157 // Add test to new "if" outside of loop
158 IfNode* invar_iff = proj_true->in(0)->as_If();
159 Node* invar_iff_c = invar_iff->in(0);
160 BoolNode* bol = unswitch_iff->in(1)->as_Bool();
161 invar_iff->set_req(1, bol);
162 invar_iff->_prob = unswitch_iff->_prob;
163
164 ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
165
166 // Hoist invariant casts out of each loop to the appropriate
167 // control projection.
168
206 _igvn._worklist.push(n_clone);
207 }
208
209 #ifndef PRODUCT
210 if (TraceLoopUnswitching) {
211 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
212 head->_idx, unswitch_iff->_idx,
213 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
214 }
215 #endif
216
217 C->set_major_progress();
218 }
219
220 //-------------------------create_slow_version_of_loop------------------------
221 // Create a slow version of the loop by cloning the loop
222 // and inserting an if to select fast-slow versions.
223 // Return control projection of the entry to the fast version.
224 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
225 Node_List &old_new,
226 int opcode) {
227 LoopNode* head = loop->_head->as_Loop();
228 bool counted_loop = head->is_CountedLoop();
229 Node* entry = head->in(LoopNode::EntryControl);
230 _igvn.rehash_node_delayed(entry);
231 IdealLoopTree* outer_loop = loop->_parent;
232
233 Node *cont = _igvn.intcon(1);
234 set_ctrl(cont, C->root());
235 Node* opq = new Opaque1Node(C, cont);
236 register_node(opq, outer_loop, entry, dom_depth(entry));
237 Node *bol = new Conv2BNode(opq);
238 register_node(bol, outer_loop, entry, dom_depth(entry));
239 IfNode* iff = (opcode == Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
240 new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
241 register_node(iff, outer_loop, entry, dom_depth(entry));
242 ProjNode* iffast = new IfTrueNode(iff);
243 register_node(iffast, outer_loop, iff, dom_depth(iff));
244 ProjNode* ifslow = new IfFalseNode(iff);
245 register_node(ifslow, outer_loop, iff, dom_depth(iff));
246
247 // Clone the loop body. The clone becomes the fast loop. The
248 // original pre-header will (illegally) have 3 control users
249 // (old & new loops & new if).
250 clone_loop(loop, old_new, dom_depth(head), iff);
251 assert(old_new[head->_idx]->is_Loop(), "" );
252
253 // Fast (true) control
254 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
255 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
256 set_idom(head, iffast_pred, dom_depth(head));
257
258 // Slow (false) control
259 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
260 LoopNode* slow_head = old_new[head->_idx]->as_Loop();
261 _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
262 set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
263
264 recompute_dom_depth();
265
266 return iffast;
267 }
268
269 LoopNode* PhaseIdealLoop::create_reserve_version_of_loop(IdealLoopTree *loop, CountedLoopReserveKit* lk) {
270 Node_List old_new;
271 LoopNode* head = loop->_head->as_Loop();
272 bool counted_loop = head->is_CountedLoop();
273 Node* entry = head->in(LoopNode::EntryControl);
274 _igvn.rehash_node_delayed(entry);
275 IdealLoopTree* outer_loop = loop->_parent;
276
277 ConINode* const_1 = _igvn.intcon(1);
278 set_ctrl(const_1, C->root());
279 IfNode* iff = new IfNode(entry, const_1, PROB_MAX, COUNT_UNKNOWN);
280 register_node(iff, outer_loop, entry, dom_depth(entry));
281 ProjNode* iffast = new IfTrueNode(iff);
282 register_node(iffast, outer_loop, iff, dom_depth(iff));
283 ProjNode* ifslow = new IfFalseNode(iff);
284 register_node(ifslow, outer_loop, iff, dom_depth(iff));
285
286 // Clone the loop body. The clone becomes the fast loop. The
287 // original pre-header will (illegally) have 3 control users
288 // (old & new loops & new if).
289 clone_loop(loop, old_new, dom_depth(head), iff);
290 assert(old_new[head->_idx]->is_Loop(), "" );
291
292 LoopNode* slow_head = old_new[head->_idx]->as_Loop();
293
294 #ifndef PRODUCT
295 if (TraceLoopOpts) {
296 tty->print_cr("PhaseIdealLoop::create_reserve_version_of_loop:");
297 tty->print("\t iff = %d, ", iff->_idx); iff->dump();
298 tty->print("\t iffast = %d, ", iffast->_idx); iffast->dump();
299 tty->print("\t ifslow = %d, ", ifslow->_idx); ifslow->dump();
300 tty->print("\t before replace_input_of: head = %d, ", head->_idx); head->dump();
301 tty->print("\t before replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
302 }
303 #endif
304
305 // Fast (true) control
306 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast);
307 // Slow (false) control
308 _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow);
309
310 recompute_dom_depth();
311
312 lk->set_iff(iff);
313
314 #ifndef PRODUCT
315 if (TraceLoopOpts ) {
316 tty->print("\t after replace_input_of: head = %d, ", head->_idx); head->dump();
317 tty->print("\t after replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
318 }
319 #endif
320
321 return slow_head->as_Loop();
322 }
323
324 CountedLoopReserveKit::CountedLoopReserveKit(PhaseIdealLoop* phase, IdealLoopTree *loop, bool active = true) :
325 _phase(phase),
326 _lpt(loop),
327 _lp(NULL),
328 _iff(NULL),
377 bool loop_not_canonical = true;
378 if (cl->is_post_loop() && (cl->slp_max_unroll() > 0)) {
379 loop_not_canonical = false;
380 }
381 // only reject some loop forms
382 if (loop_not_canonical) {
383 if (TraceLoopOpts) {
384 tty->print_cr("CountedLoopReserveKit::create_reserve: %d not canonical loop", cl->_idx);
385 }
386 return false; // skip normal, pre, and post (conditionally) loops
387 }
388 }
389
390 _lp = _lpt->_head->as_Loop();
391 _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
392
393 if (!_lp_reserved->is_CountedLoop()) {
394 return false;
395 }
396
397 Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
398
399 if (!ifslow_pred->is_IfFalse()) {
400 return false;
401 }
402
403 Node* iff = ifslow_pred->in(0);
404 if (!iff->is_If() || iff != _iff) {
405 return false;
406 }
407
408 if (iff->in(1)->Opcode() != Op_ConI) {
409 return false;
410 }
411
412 return _has_reserved = true;
413 }
|
115 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
116
117 // Find first invariant test that doesn't exit the loop
118 LoopNode *head = loop->_head->as_Loop();
119
120 IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
121 assert(unswitch_iff != NULL, "should be at least one");
122
123 #ifndef PRODUCT
124 if (TraceLoopOpts) {
125 tty->print("Unswitch %d ", head->unswitch_count()+1);
126 loop->dump_head();
127 }
128 #endif
129
130 // Need to revert back to normal loop
131 if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
132 head->as_CountedLoop()->set_normal_loop();
133 }
134
135 ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode(), CloneIncludesStripMined);
136
137 #ifdef ASSERT
138 Node* uniqc = proj_true->unique_ctrl_out();
139 Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
140 Node* predicate = find_predicate(entry);
141 if (predicate != NULL && UseLoopPredicate) {
142 // We may have two predicates, find first.
143 entry = find_predicate(entry->in(0)->in(0));
144 if (entry != NULL) predicate = entry;
145 }
146 if (predicate != NULL) predicate = predicate->in(0);
147 assert(proj_true->is_IfTrue() &&
148 (predicate == NULL && uniqc == head && !head->is_strip_mined() ||
149 predicate == NULL && uniqc == head->in(LoopNode::EntryControl) && head->is_strip_mined() ||
150 predicate != NULL && uniqc == predicate), "by construction");
151 #endif
152 // Increment unswitch count
153 LoopNode* head_clone = old_new[head->_idx]->as_Loop();
154 int nct = head->unswitch_count() + 1;
155 head->set_unswitch_count(nct);
156 head_clone->set_unswitch_count(nct);
157
158 // Add test to new "if" outside of loop
159 IfNode* invar_iff = proj_true->in(0)->as_If();
160 Node* invar_iff_c = invar_iff->in(0);
161 BoolNode* bol = unswitch_iff->in(1)->as_Bool();
162 invar_iff->set_req(1, bol);
163 invar_iff->_prob = unswitch_iff->_prob;
164
165 ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
166
167 // Hoist invariant casts out of each loop to the appropriate
168 // control projection.
169
207 _igvn._worklist.push(n_clone);
208 }
209
210 #ifndef PRODUCT
211 if (TraceLoopUnswitching) {
212 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
213 head->_idx, unswitch_iff->_idx,
214 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
215 }
216 #endif
217
218 C->set_major_progress();
219 }
220
221 //-------------------------create_slow_version_of_loop------------------------
222 // Create a slow version of the loop by cloning the loop
223 // and inserting an if to select fast-slow versions.
224 // Return control projection of the entry to the fast version.
225 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
226 Node_List &old_new,
227 int opcode,
228 CloneLoopMode mode) {
229 LoopNode* head = loop->_head->as_Loop();
230 bool counted_loop = head->is_CountedLoop();
231 Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
232 _igvn.rehash_node_delayed(entry);
233 IdealLoopTree* outer_loop = loop->_parent;
234
235 head->verify_strip_mined(1);
236
237 Node *cont = _igvn.intcon(1);
238 set_ctrl(cont, C->root());
239 Node* opq = new Opaque1Node(C, cont);
240 register_node(opq, outer_loop, entry, dom_depth(entry));
241 Node *bol = new Conv2BNode(opq);
242 register_node(bol, outer_loop, entry, dom_depth(entry));
243 IfNode* iff = (opcode == Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
244 new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
245 register_node(iff, outer_loop, entry, dom_depth(entry));
246 ProjNode* iffast = new IfTrueNode(iff);
247 register_node(iffast, outer_loop, iff, dom_depth(iff));
248 ProjNode* ifslow = new IfFalseNode(iff);
249 register_node(ifslow, outer_loop, iff, dom_depth(iff));
250
251 // Clone the loop body. The clone becomes the fast loop. The
252 // original pre-header will (illegally) have 3 control users
253 // (old & new loops & new if).
254 clone_loop(loop, old_new, dom_depth(head->skip_strip_mined()), mode, iff);
255 assert(old_new[head->_idx]->is_Loop(), "" );
256
257 // Fast (true) control
258 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
259
260 // Slow (false) control
261 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
262
263 Node* l = head->skip_strip_mined();
264 _igvn.replace_input_of(l, LoopNode::EntryControl, iffast_pred);
265 set_idom(l, iffast_pred, dom_depth(l));
266 LoopNode* slow_l = old_new[head->_idx]->as_Loop()->skip_strip_mined();
267 _igvn.replace_input_of(slow_l, LoopNode::EntryControl, ifslow_pred);
268 set_idom(slow_l, ifslow_pred, dom_depth(l));
269
270 recompute_dom_depth();
271
272 return iffast;
273 }
274
275 LoopNode* PhaseIdealLoop::create_reserve_version_of_loop(IdealLoopTree *loop, CountedLoopReserveKit* lk) {
276 Node_List old_new;
277 LoopNode* head = loop->_head->as_Loop();
278 bool counted_loop = head->is_CountedLoop();
279 Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
280 _igvn.rehash_node_delayed(entry);
281 IdealLoopTree* outer_loop = head->is_strip_mined() ? loop->_parent->_parent : loop->_parent;
282
283 ConINode* const_1 = _igvn.intcon(1);
284 set_ctrl(const_1, C->root());
285 IfNode* iff = new IfNode(entry, const_1, PROB_MAX, COUNT_UNKNOWN);
286 register_node(iff, outer_loop, entry, dom_depth(entry));
287 ProjNode* iffast = new IfTrueNode(iff);
288 register_node(iffast, outer_loop, iff, dom_depth(iff));
289 ProjNode* ifslow = new IfFalseNode(iff);
290 register_node(ifslow, outer_loop, iff, dom_depth(iff));
291
292 // Clone the loop body. The clone becomes the fast loop. The
293 // original pre-header will (illegally) have 3 control users
294 // (old & new loops & new if).
295 clone_loop(loop, old_new, dom_depth(head), CloneIncludesStripMined, iff);
296 assert(old_new[head->_idx]->is_Loop(), "" );
297
298 LoopNode* slow_head = old_new[head->_idx]->as_Loop();
299
300 #ifndef PRODUCT
301 if (TraceLoopOpts) {
302 tty->print_cr("PhaseIdealLoop::create_reserve_version_of_loop:");
303 tty->print("\t iff = %d, ", iff->_idx); iff->dump();
304 tty->print("\t iffast = %d, ", iffast->_idx); iffast->dump();
305 tty->print("\t ifslow = %d, ", ifslow->_idx); ifslow->dump();
306 tty->print("\t before replace_input_of: head = %d, ", head->_idx); head->dump();
307 tty->print("\t before replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
308 }
309 #endif
310
311 // Fast (true) control
312 _igvn.replace_input_of(head->skip_strip_mined(), LoopNode::EntryControl, iffast);
313 // Slow (false) control
314 _igvn.replace_input_of(slow_head->skip_strip_mined(), LoopNode::EntryControl, ifslow);
315
316 recompute_dom_depth();
317
318 lk->set_iff(iff);
319
320 #ifndef PRODUCT
321 if (TraceLoopOpts ) {
322 tty->print("\t after replace_input_of: head = %d, ", head->_idx); head->dump();
323 tty->print("\t after replace_input_of: slow_head = %d, ", slow_head->_idx); slow_head->dump();
324 }
325 #endif
326
327 return slow_head->as_Loop();
328 }
329
330 CountedLoopReserveKit::CountedLoopReserveKit(PhaseIdealLoop* phase, IdealLoopTree *loop, bool active = true) :
331 _phase(phase),
332 _lpt(loop),
333 _lp(NULL),
334 _iff(NULL),
383 bool loop_not_canonical = true;
384 if (cl->is_post_loop() && (cl->slp_max_unroll() > 0)) {
385 loop_not_canonical = false;
386 }
387 // only reject some loop forms
388 if (loop_not_canonical) {
389 if (TraceLoopOpts) {
390 tty->print_cr("CountedLoopReserveKit::create_reserve: %d not canonical loop", cl->_idx);
391 }
392 return false; // skip normal, pre, and post (conditionally) loops
393 }
394 }
395
396 _lp = _lpt->_head->as_Loop();
397 _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
398
399 if (!_lp_reserved->is_CountedLoop()) {
400 return false;
401 }
402
403 Node* ifslow_pred = _lp_reserved->skip_strip_mined()->in(LoopNode::EntryControl);
404
405 if (!ifslow_pred->is_IfFalse()) {
406 return false;
407 }
408
409 Node* iff = ifslow_pred->in(0);
410 if (!iff->is_If() || iff != _iff) {
411 return false;
412 }
413
414 if (iff->in(1)->Opcode() != Op_ConI) {
415 return false;
416 }
417
418 return _has_reserved = true;
419 }
|