92 bool IdealLoopTree::policy_unswitching(PhaseIdealLoop* phase) const {
93 if (!LoopUnswitching) {
94 return false;
95 }
96 if (!_head->is_Loop()) {
97 return false;
98 }
99
100 // If nodes are depleted, some transform has miscalculated its needs.
101 assert(!phase->exceeding_node_budget(), "sanity");
102
103 // check for vectorized loops, any unswitching was already applied
104 if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) {
105 return false;
106 }
107
108 LoopNode* head = _head->as_Loop();
109 if (head->unswitch_count() + 1 > head->unswitch_max()) {
110 return false;
111 }
112 if (phase->find_unswitch_candidate(this) == nullptr) {
113 return false;
114 }
115
116 // Too speculative if running low on nodes.
117 return phase->may_require_nodes(est_loop_clone_sz(2));
118 }
119
120 // Find an invariant test in the loop body that does not exit the loop. If multiple tests are found, we pick the first
121 // one in the loop body. Return the "unswitch candidate" If to apply Loop Unswitching on.
122 IfNode* PhaseIdealLoop::find_unswitch_candidate(const IdealLoopTree* loop) const {
123 LoopNode* head = loop->_head->as_Loop();
124 IfNode* unswitch_candidate = nullptr;
125 Node* n = head->in(LoopNode::LoopBackControl);
126 while (n != head) {
127 Node* n_dom = idom(n);
128 if (n->is_Region()) {
129 if (n_dom->is_If()) {
130 IfNode* iff = n_dom->as_If();
131 if (iff->in(1)->is_Bool()) {
132 BoolNode* bol = iff->in(1)->as_Bool();
133 if (bol->in(1)->is_Cmp()) {
134 // If condition is invariant and not a loop exit,
135 // then found reason to unswitch.
136 if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
137 assert(iff->Opcode() == Op_If || iff->is_RangeCheck() || iff->is_BaseCountedLoopEnd(), "valid ifs");
138 unswitch_candidate = iff;
139 }
140 }
141 }
142 }
143 }
144 n = n_dom;
145 }
146 return unswitch_candidate;
147 }
148
149 // This class creates an If node (i.e. loop selector) that selects if the true-path-loop or the false-path-loop should be
150 // executed at runtime. This is done by finding an invariant and non-loop-exiting unswitch candidate If node (guaranteed
151 // to exist at this point) to perform Loop Unswitching on.
152 class UnswitchedLoopSelector : public StackObj {
153 PhaseIdealLoop* const _phase;
154 IdealLoopTree* const _outer_loop;
155 Node* const _original_loop_entry;
156 IfNode* const _unswitch_candidate;
157 IfNode* const _selector;
158 IfTrueNode* const _true_path_loop_proj;
159 IfFalseNode* const _false_path_loop_proj;
160
161 enum PathToLoop { TRUE_PATH, FALSE_PATH };
162
163 public:
164 UnswitchedLoopSelector(IdealLoopTree* loop)
165 : _phase(loop->_phase),
166 _outer_loop(loop->skip_strip_mined()->_parent),
167 _original_loop_entry(loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl)),
168 _unswitch_candidate(find_unswitch_candidate(loop)),
169 _selector(create_selector_if()),
170 _true_path_loop_proj(create_proj_to_loop(TRUE_PATH)->as_IfTrue()),
171 _false_path_loop_proj(create_proj_to_loop(FALSE_PATH)->as_IfFalse()) {
172 }
173 NONCOPYABLE(UnswitchedLoopSelector);
174
175 private:
176 IfNode* find_unswitch_candidate(IdealLoopTree* loop) {
177 IfNode* unswitch_candidate = _phase->find_unswitch_candidate(loop);
178 assert(unswitch_candidate != nullptr, "guaranteed to exist by policy_unswitching");
179 assert(_phase->is_member(loop, unswitch_candidate), "must be inside original loop");
180 return unswitch_candidate;
181 }
182
183 IfNode* create_selector_if() const {
184 const uint dom_depth = _phase->dom_depth(_original_loop_entry);
185 _phase->igvn().rehash_node_delayed(_original_loop_entry);
186 BoolNode* unswitch_candidate_bool = _unswitch_candidate->in(1)->as_Bool();
187 IfNode* selector_if = IfNode::make_with_same_profile(_unswitch_candidate, _original_loop_entry,
188 unswitch_candidate_bool);
189 _phase->register_node(selector_if, _outer_loop, _original_loop_entry, dom_depth);
190 return selector_if;
191 }
192
193 IfProjNode* create_proj_to_loop(const PathToLoop path_to_loop) {
194 const uint dom_depth = _phase->dom_depth(_original_loop_entry);
195 IfProjNode* proj_to_loop;
196 if (path_to_loop == TRUE_PATH) {
197 proj_to_loop = new IfTrueNode(_selector);
198 } else {
199 proj_to_loop = new IfFalseNode(_selector);
200 }
201 _phase->register_node(proj_to_loop, _outer_loop, _selector, dom_depth);
202 return proj_to_loop;
203 }
204
205 public:
206 IfNode* unswitch_candidate() const {
207 return _unswitch_candidate;
208 }
209
210 IfNode* selector() const {
211 return _selector;
212 }
213
214 IfTrueNode* true_path_loop_proj() const {
215 return _true_path_loop_proj;
216 }
217
218 IfFalseNode* false_path_loop_proj() const {
219 return _false_path_loop_proj;
220 }
221 };
222
223 // Class to unswitch the original loop and create Predicates at the new unswitched loop versions. The newly cloned loop
224 // becomes the false-path-loop while original loop becomes the true-path-loop.
225 class OriginalLoop : public StackObj {
226 LoopNode* const _loop_head; // OuterStripMinedLoopNode if loop strip mined, else just the loop head.
227 IdealLoopTree* const _loop;
228 Node_List& _old_new;
229 PhaseIdealLoop* const _phase;
246 Node* old_to_new(const Node* old) const {
247 return _old_new[old->_idx];
248 }
249
250 #ifdef ASSERT
251 void verify_unswitched_loop_versions(LoopNode* true_path_loop_head,
252 const UnswitchedLoopSelector& unswitched_loop_selector) const {
253 verify_unswitched_loop_version(true_path_loop_head, unswitched_loop_selector.true_path_loop_proj());
254 verify_unswitched_loop_version(old_to_new(true_path_loop_head)->as_Loop(),
255 unswitched_loop_selector.false_path_loop_proj());
256 }
257
258 static void verify_unswitched_loop_version(LoopNode* loop_head, IfProjNode* loop_selector_if_proj) {
259 Node* entry = loop_head->skip_strip_mined()->in(LoopNode::EntryControl);
260 const Predicates predicates(entry);
261 // When skipping all predicates, we should end up at 'loop_selector_if_proj'.
262 assert(loop_selector_if_proj == predicates.entry(), "should end up at loop selector If");
263 }
264 #endif // ASSERT
265
266 // Remove the unswitch candidate If nodes in both unswitched loop versions which are now dominated by the loop selector
267 // If node. Keep the true-path-path in the true-path-loop and the false-path-path in the false-path-loop by setting
268 // the bool input accordingly. The unswitch candidate If nodes are folded in the next IGVN round.
269 void remove_unswitch_candidate_from_loops(const UnswitchedLoopSelector& unswitched_loop_selector) {
270 IfNode* unswitching_candidate = unswitched_loop_selector.unswitch_candidate();
271 _phase->igvn().rehash_node_delayed(unswitching_candidate);
272 _phase->dominated_by(unswitched_loop_selector.true_path_loop_proj(), unswitching_candidate);
273
274 IfNode* unswitching_candidate_clone = _old_new[unswitching_candidate->_idx]->as_If();
275 _phase->igvn().rehash_node_delayed(unswitching_candidate_clone);
276 _phase->dominated_by(unswitched_loop_selector.false_path_loop_proj(), unswitching_candidate_clone);
277 }
278
279 public:
280 // Unswitch the original loop on the invariant loop selector by creating a true-path-loop and a false-path-loop.
281 // Remove the unswitch candidate If from both unswitched loop versions which are now covered by the loop selector If.
282 void unswitch(const UnswitchedLoopSelector& unswitched_loop_selector) {
283 _phase->clone_loop(_loop, _old_new, _phase->dom_depth(_loop_head),
284 PhaseIdealLoop::CloneIncludesStripMined, unswitched_loop_selector.selector());
285
286 // At this point, the selector If projections are the corresponding loop entries.
287 // clone_parse_and_assertion_predicates_to_unswitched_loop() could clone additional predicates after the selector
288 // If projections. The loop entries are updated accordingly.
289 IfProjNode* true_path_loop_entry = unswitched_loop_selector.true_path_loop_proj();
290 IfProjNode* false_path_loop_entry = unswitched_loop_selector.false_path_loop_proj();
291 _phase->clone_parse_and_assertion_predicates_to_unswitched_loop(_loop, _old_new,
292 true_path_loop_entry, false_path_loop_entry);
293
294 fix_loop_entries(true_path_loop_entry, false_path_loop_entry);
295
296 DEBUG_ONLY(verify_unswitched_loop_versions(_loop->_head->as_Loop(), unswitched_loop_selector);)
297
298 _phase->recompute_dom_depth();
299 remove_unswitch_candidate_from_loops(unswitched_loop_selector);
300 }
301 };
302
303 // See comments below file header for more information about Loop Unswitching.
304 void PhaseIdealLoop::do_unswitching(IdealLoopTree* loop, Node_List& old_new) {
305 assert(LoopUnswitching, "LoopUnswitching must be enabled");
306
307 LoopNode* original_head = loop->_head->as_Loop();
308 if (has_control_dependencies_from_predicates(original_head)) {
309 NOT_PRODUCT(trace_loop_unswitching_impossible(original_head);)
310 return;
311 }
312
313 NOT_PRODUCT(trace_loop_unswitching_count(loop, original_head);)
314 C->print_method(PHASE_BEFORE_LOOP_UNSWITCHING, 4, original_head);
315
316 revert_to_normal_loop(original_head);
317
318 const UnswitchedLoopSelector unswitched_loop_selector(loop);
319 OriginalLoop original_loop(loop, old_new);
320 original_loop.unswitch(unswitched_loop_selector);
321
322 hoist_invariant_check_casts(loop, old_new, unswitched_loop_selector);
323 add_unswitched_loop_version_bodies_to_igvn(loop, old_new);
324
325 LoopNode* new_head = old_new[original_head->_idx]->as_Loop();
326 increment_unswitch_counts(original_head, new_head);
327
328 NOT_PRODUCT(trace_loop_unswitching_result(unswitched_loop_selector, original_head, new_head);)
329 C->print_method(PHASE_AFTER_LOOP_UNSWITCHING, 4, new_head);
330 C->set_major_progress();
331 }
332
333 bool PhaseIdealLoop::has_control_dependencies_from_predicates(LoopNode* head) {
334 Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
335 const Predicates predicates(entry);
336 if (predicates.has_any()) {
337 assert(entry->is_IfProj(), "sanity - must be ifProj since there is at least one predicate");
338 if (entry->outcnt() > 1) {
339 // Bailout if there are predicates from which there are additional control dependencies (i.e. from loop
340 // entry 'entry') to previously partially peeled statements since this case is not handled and can lead
341 // to a wrong execution. Remove this bailout, once this is fixed.
342 return true;
343 }
344 }
345 return false;
346 }
347
348 #ifndef PRODUCT
349 void PhaseIdealLoop::trace_loop_unswitching_impossible(const LoopNode* original_head) {
350 if (TraceLoopUnswitching) {
351 tty->print_cr("Loop Unswitching \"%d %s\" not possible due to control dependencies",
352 original_head->_idx, original_head->Name());
353 }
354 }
355
356 void PhaseIdealLoop::trace_loop_unswitching_count(IdealLoopTree* loop, LoopNode* original_head) {
357 if (TraceLoopOpts) {
358 tty->print("Unswitch %d ", original_head->unswitch_count() + 1);
359 loop->dump_head();
360 }
361 }
362
363 void PhaseIdealLoop::trace_loop_unswitching_result(const UnswitchedLoopSelector& unswitched_loop_selector,
364 const LoopNode* original_head, const LoopNode* new_head) {
365 if (TraceLoopUnswitching) {
366 IfNode* unswitch_candidate = unswitched_loop_selector.unswitch_candidate();
367 IfNode* loop_selector = unswitched_loop_selector.selector();
368 tty->print_cr("Loop Unswitching:");
369 tty->print_cr("- Unswitch-Candidate-If: %d %s", unswitch_candidate->_idx, unswitch_candidate->Name());
370 tty->print_cr("- Loop-Selector-If: %d %s", loop_selector->_idx, loop_selector->Name());
371 tty->print_cr("- True-Path-Loop (=Orig): %d %s", original_head->_idx, original_head->Name());
372 tty->print_cr("- False-Path-Loop (=Clone): %d %s", new_head->_idx, new_head->Name());
373 }
374 }
375 #endif
376
377 // When unswitching a counted loop, we need to convert it back to a normal loop since it's not a proper pre, main or,
378 // post loop anymore after loop unswitching.
379 void PhaseIdealLoop::revert_to_normal_loop(const LoopNode* loop_head) {
380 CountedLoopNode* cl = loop_head->isa_CountedLoop();
381 if (cl != nullptr && !cl->is_normal_loop()) {
382 cl->set_normal_loop();
383 }
384 }
385
386 // Hoist invariant CheckCastPPNodes out of each unswitched loop version to the appropriate loop selector If projection.
387 void PhaseIdealLoop::hoist_invariant_check_casts(const IdealLoopTree* loop, const Node_List& old_new,
388 const UnswitchedLoopSelector& unswitched_loop_selector) {
389 IfNode* unswitch_candidate = unswitched_loop_selector.unswitch_candidate();
390 IfNode* loop_selector = unswitched_loop_selector.selector();
391 ResourceMark rm;
392 GrowableArray<CheckCastPPNode*> loop_invariant_check_casts;
393 for (DUIterator_Fast imax, i = unswitch_candidate->fast_outs(imax); i < imax; i++) {
394 IfProjNode* proj = unswitch_candidate->fast_out(i)->as_IfProj();
395 // Copy to a worklist for easier manipulation
396 for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
397 CheckCastPPNode* check_cast = proj->fast_out(j)->isa_CheckCastPP();
398 if (check_cast != nullptr && loop->is_invariant(check_cast->in(1))) {
399 loop_invariant_check_casts.push(check_cast);
400 }
401 }
402 IfProjNode* loop_selector_if_proj = loop_selector->proj_out(proj->_con)->as_IfProj();
403 while (loop_invariant_check_casts.length() > 0) {
404 CheckCastPPNode* cast = loop_invariant_check_casts.pop();
405 Node* cast_clone = cast->clone();
406 cast_clone->set_req(0, loop_selector_if_proj);
407 _igvn.replace_input_of(cast, 1, cast_clone);
408 register_new_node(cast_clone, loop_selector_if_proj);
409 // Same for the clone
410 Node* use_clone = old_new[cast->_idx];
411 _igvn.replace_input_of(use_clone, 1, cast_clone);
412 }
413 }
414 }
415
416 // Enable more optimizations possibilities in the next IGVN round.
417 void PhaseIdealLoop::add_unswitched_loop_version_bodies_to_igvn(IdealLoopTree* loop, const Node_List& old_new) {
418 loop->record_for_igvn();
419 for(int i = loop->_body.size() - 1; i >= 0 ; i--) {
420 Node* n = loop->_body[i];
421 Node* n_clone = old_new[n->_idx];
422 _igvn._worklist.push(n_clone);
423 }
424 }
425
426 void PhaseIdealLoop::increment_unswitch_counts(LoopNode* original_head, LoopNode* new_head) {
427 const int unswitch_count = original_head->unswitch_count() + 1;
428 original_head->set_unswitch_count(unswitch_count);
429 new_head->set_unswitch_count(unswitch_count);
430 }
431
|
92 bool IdealLoopTree::policy_unswitching(PhaseIdealLoop* phase) const {
93 if (!LoopUnswitching) {
94 return false;
95 }
96 if (!_head->is_Loop()) {
97 return false;
98 }
99
100 // If nodes are depleted, some transform has miscalculated its needs.
101 assert(!phase->exceeding_node_budget(), "sanity");
102
103 // check for vectorized loops, any unswitching was already applied
104 if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) {
105 return false;
106 }
107
108 LoopNode* head = _head->as_Loop();
109 if (head->unswitch_count() + 1 > head->unswitch_max()) {
110 return false;
111 }
112
113 if (head->is_flat_arrays()) {
114 return false;
115 }
116
117 if (no_unswitch_candidate()) {
118 return false;
119 }
120
121 // Too speculative if running low on nodes.
122 return phase->may_require_nodes(est_loop_clone_sz(2));
123 }
124
125 // Check the absence of any If node that can be used for Loop Unswitching. In that case, no Loop Unswitching can be done.
126 bool IdealLoopTree::no_unswitch_candidate() const {
127 ResourceMark rm;
128 Node_List dont_care;
129 return _phase->find_unswitch_candidates(this, dont_care) == nullptr;
130 }
131
132 // Find an invariant test in the loop body that does not exit the loop. If multiple tests are found, we pick the first
133 // one in the loop body as "unswitch candidate" to apply Loop Unswitching on.
134 // Depending on whether we find such a candidate and if we do, whether it's a flat array check, we do the following:
135 // (1) Candidate is not a flat array check:
136 // Return the unique unswitch candidate.
137 // (2) Candidate is a flat array check:
138 // Collect all remaining non-loop-exiting flat array checks in the loop body in the provided 'flat_array_checks'
139 // list in order to create an unswitched loop version without any flat array checks and a version with checks
140 // (i.e. same as original loop). Return the initially found candidate which could be unique if no further flat array
141 // checks are found.
142 // (3) No candidate is initially found:
143 // As in (2), we collect all non-loop-exiting flat array checks in the loop body in the provided 'flat_array_checks'
144 // list. Pick the first collected flat array check as unswitch candidate, which could be unique, and return it (a).
145 // If there are no flat array checks, we cannot apply Loop Unswitching (b).
146 //
147 // Note that for both (2) and (3a), if there are multiple flat array checks, then the candidate's FlatArrayCheckNode is
148 // later updated in Loop Unswitching to perform a flat array check on all collected flat array checks.
149 IfNode* PhaseIdealLoop::find_unswitch_candidates(const IdealLoopTree* loop, Node_List& flat_array_checks) const {
150 IfNode* unswitch_candidate = find_unswitch_candidate_from_idoms(loop);
151 if (unswitch_candidate != nullptr && !unswitch_candidate->is_flat_array_check(&_igvn)) {
152 // Case (1)
153 return unswitch_candidate;
154 }
155
156 collect_flat_array_checks(loop, flat_array_checks);
157 if (unswitch_candidate != nullptr) {
158 // Case (2)
159 assert(unswitch_candidate->is_flat_array_check(&_igvn), "is a flat array check");
160 return unswitch_candidate;
161 } else if (flat_array_checks.size() > 0) {
162 // Case (3a): Pick first one found as candidate (there could be multiple).
163 return flat_array_checks[0]->as_If();
164 }
165
166 // Case (3b): No suitable unswitch candidate found.
167 return nullptr;
168 }
169
170 // Find an unswitch candidate by following the idom chain from the loop back edge.
171 IfNode* PhaseIdealLoop::find_unswitch_candidate_from_idoms(const IdealLoopTree* loop) const {
172 LoopNode* head = loop->_head->as_Loop();
173 IfNode* unswitch_candidate = nullptr;
174 Node* n = head->in(LoopNode::LoopBackControl);
175 while (n != head) {
176 Node* n_dom = idom(n);
177 if (n->is_Region()) {
178 if (n_dom->is_If()) {
179 IfNode* iff = n_dom->as_If();
180 if (iff->in(1)->is_Bool()) {
181 BoolNode* bol = iff->in(1)->as_Bool();
182 if (bol->in(1)->is_Cmp()) {
183 // If condition is invariant and not a loop exit,
184 // then found reason to unswitch.
185 if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
186 assert(iff->Opcode() == Op_If || iff->is_RangeCheck() || iff->is_BaseCountedLoopEnd(), "valid ifs");
187 unswitch_candidate = iff;
188 }
189 }
190 }
191 }
192 }
193 n = n_dom;
194 }
195 return unswitch_candidate;
196 }
197
198 // Collect all flat array checks in the provided 'flat_array_checks' list.
199 void PhaseIdealLoop::collect_flat_array_checks(const IdealLoopTree* loop, Node_List& flat_array_checks) const {
200 assert(flat_array_checks.size() == 0, "should be empty initially");
201 for (uint i = 0; i < loop->_body.size(); i++) {
202 Node* next = loop->_body.at(i);
203 if (next->is_If() && next->as_If()->is_flat_array_check(&_igvn) && loop->is_invariant(next->in(1)) &&
204 !loop->is_loop_exit(next)) {
205 flat_array_checks.push(next);
206 }
207 }
208 }
209
210 // This class represents an "unswitch candidate" which is an If that can be used to perform Loop Unswitching on. If the
211 // candidate is a flat array check candidate, then we also collect all remaining non-loop-exiting flat array checks.
212 // These are candidates as well. We want to get rid of all these flat array checks in the true-path-loop for the
213 // following reason:
214 //
215 // FlatArrayCheckNodes are used with array accesses to switch between a flat and a non-flat array access. We want
216 // the performance impact on non-flat array accesses to be as small as possible. We therefore create the following
217 // loops in Loop Unswitching:
218 // - True-path-loop: We remove all non-loop-exiting flat array checks to get a loop with only non-flat array accesses
219 // (i.e. a fast path loop).
220 // - False-path-loop: We keep all flat array checks in this loop (i.e. a slow path loop).
221 class UnswitchCandidate : public StackObj {
222 PhaseIdealLoop* const _phase;
223 const Node_List& _old_new;
224 Node* const _original_loop_entry;
225 // If _candidate is a flat array check, this list contains all non-loop-exiting flat array checks in the loop body.
226 Node_List _flat_array_check_candidates;
227 IfNode* const _candidate;
228
229 public:
230 UnswitchCandidate(IdealLoopTree* loop, const Node_List& old_new)
231 : _phase(loop->_phase),
232 _old_new(old_new),
233 _original_loop_entry(loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl)),
234 _flat_array_check_candidates(),
235 _candidate(find_unswitch_candidate(loop)) {}
236 NONCOPYABLE(UnswitchCandidate);
237
238 IfNode* find_unswitch_candidate(IdealLoopTree* loop) {
239 IfNode* unswitch_candidate = _phase->find_unswitch_candidates(loop, _flat_array_check_candidates);
240 assert(unswitch_candidate != nullptr, "guaranteed to exist by policy_unswitching");
241 assert(_phase->is_member(loop, unswitch_candidate), "must be inside original loop");
242 return unswitch_candidate;
243 }
244
245 IfNode* candidate() const {
246 return _candidate;
247 }
248
249 // Is the candidate a flat array check and are there other flat array checks as well?
250 bool has_multiple_flat_array_check_candidates() const {
251 return _flat_array_check_candidates.size() > 1;
252 }
253
254 // Remove all candidates from the true-path-loop which are now dominated by the loop selector
255 // (i.e. 'true_path_loop_proj'). The removed candidates are folded in the next IGVN round.
256 void update_in_true_path_loop(IfTrueNode* true_path_loop_proj) const {
257 remove_from_loop(true_path_loop_proj, _candidate);
258 if (has_multiple_flat_array_check_candidates()) {
259 remove_flat_array_checks(true_path_loop_proj);
260 }
261 }
262
263 // Remove a unique candidate from the false-path-loop which is now dominated by the loop selector
264 // (i.e. 'false_path_loop_proj'). The removed candidate is folded in the next IGVN round. If there are multiple
265 // candidates (i.e. flat array checks), then we leave them in the false-path-loop and only mark the loop such that it
266 // is not unswitched anymore in later loop opts rounds.
267 void update_in_false_path_loop(IfFalseNode* false_path_loop_proj, LoopNode* false_path_loop) const {
268 if (has_multiple_flat_array_check_candidates()) {
269 // Leave the flat array checks in the false-path-loop and prevent it from being unswitched again based on these
270 // checks.
271 false_path_loop->mark_flat_arrays();
272 } else {
273 remove_from_loop(false_path_loop_proj, _old_new[_candidate->_idx]->as_If());
274 }
275 }
276
277 private:
278 void remove_from_loop(IfProjNode* dominating_proj, IfNode* candidate) const {
279 _phase->igvn().rehash_node_delayed(candidate);
280 _phase->dominated_by(dominating_proj, candidate);
281 }
282
283 void remove_flat_array_checks(IfProjNode* dominating_proj) const {
284 for (uint i = 0; i < _flat_array_check_candidates.size(); i++) {
285 IfNode* flat_array_check = _flat_array_check_candidates.at(i)->as_If();
286 _phase->igvn().rehash_node_delayed(flat_array_check);
287 _phase->dominated_by(dominating_proj, flat_array_check);
288 }
289 }
290
291 public:
292 // Merge all flat array checks into a single new BoolNode and return it.
293 BoolNode* merge_flat_array_checks() const {
294 assert(has_multiple_flat_array_check_candidates(), "must have multiple flat array checks to merge");
295 assert(_candidate->in(1)->as_Bool()->_test._test == BoolTest::ne, "IfTrue proj must point to flat array");
296 BoolNode* merged_flat_array_check_bool = create_bool_node();
297 create_flat_array_check_node(merged_flat_array_check_bool);
298 return merged_flat_array_check_bool;
299 }
300
301 private:
302 BoolNode* create_bool_node() const {
303 BoolNode* merged_flat_array_check_bool = _candidate->in(1)->clone()->as_Bool();
304 _phase->register_new_node(merged_flat_array_check_bool, _original_loop_entry);
305 return merged_flat_array_check_bool;
306 }
307
308 void create_flat_array_check_node(BoolNode* merged_flat_array_check_bool) const {
309 FlatArrayCheckNode* cloned_flat_array_check = merged_flat_array_check_bool->in(1)->clone()->as_FlatArrayCheck();
310 _phase->register_new_node(cloned_flat_array_check, _original_loop_entry);
311 merged_flat_array_check_bool->set_req(1, cloned_flat_array_check);
312 set_flat_array_check_inputs(cloned_flat_array_check);
313 }
314
315 // Combine all checks into a single one that fails if one array is flat.
316 void set_flat_array_check_inputs(FlatArrayCheckNode* cloned_flat_array_check) const {
317 assert(cloned_flat_array_check->req() == 3, "unexpected number of inputs for FlatArrayCheck");
318 cloned_flat_array_check->add_req_batch(_phase->C->top(), _flat_array_check_candidates.size() - 1);
319 for (uint i = 0; i < _flat_array_check_candidates.size(); i++) {
320 Node* array = _flat_array_check_candidates.at(i)->in(1)->in(1)->in(FlatArrayCheckNode::ArrayOrKlass);
321 cloned_flat_array_check->set_req(FlatArrayCheckNode::ArrayOrKlass + i, array);
322 }
323 }
324
325 public:
326 #ifndef PRODUCT
327 void trace_flat_array_checks() const {
328 if (has_multiple_flat_array_check_candidates()) {
329 tty->print_cr("- Unswitched and Merged Flat Array Checks:");
330 for (uint i = 0; i < _flat_array_check_candidates.size(); i++) {
331 Node* unswitch_iff = _flat_array_check_candidates.at(i);
332 Node* cloned_unswitch_iff = _old_new[unswitch_iff->_idx];
333 assert(cloned_unswitch_iff != nullptr, "must exist");
334 tty->print_cr(" - %d %s -> %d %s", unswitch_iff->_idx, unswitch_iff->Name(),
335 cloned_unswitch_iff->_idx, cloned_unswitch_iff->Name());
336 }
337 }
338 }
339 #endif // NOT PRODUCT
340 };
341
342 // This class creates an If node (i.e. loop selector) that selects if the true-path-loop or the false-path-loop should be
343 // executed at runtime. This is done by finding an invariant and non-loop-exiting unswitch candidate If node (guaranteed
344 // to exist at this point) to perform Loop Unswitching on.
345 class UnswitchedLoopSelector : public StackObj {
346 PhaseIdealLoop* const _phase;
347 IdealLoopTree* const _outer_loop;
348 Node* const _original_loop_entry;
349 const UnswitchCandidate& _unswitch_candidate;
350 IfNode* const _selector;
351 IfTrueNode* const _true_path_loop_proj;
352 IfFalseNode* const _false_path_loop_proj;
353
354 enum PathToLoop {
355 TRUE_PATH, FALSE_PATH
356 };
357
358 public:
359 UnswitchedLoopSelector(IdealLoopTree* loop, const UnswitchCandidate& unswitch_candidate)
360 : _phase(loop->_phase),
361 _outer_loop(loop->skip_strip_mined()->_parent),
362 _original_loop_entry(loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl)),
363 _unswitch_candidate(unswitch_candidate),
364 _selector(create_selector_if()),
365 _true_path_loop_proj(create_proj_to_loop(TRUE_PATH)->as_IfTrue()),
366 _false_path_loop_proj(create_proj_to_loop(FALSE_PATH)->as_IfFalse()) {
367 }
368 NONCOPYABLE(UnswitchedLoopSelector);
369
370 private:
371 IfNode* create_selector_if() const {
372 const uint dom_depth = _phase->dom_depth(_original_loop_entry);
373 _phase->igvn().rehash_node_delayed(_original_loop_entry);
374 IfNode* unswitch_candidate_if = _unswitch_candidate.candidate();
375 BoolNode* selector_bool;
376 if (_unswitch_candidate.has_multiple_flat_array_check_candidates()) {
377 selector_bool = _unswitch_candidate.merge_flat_array_checks();
378 } else {
379 selector_bool = unswitch_candidate_if->in(1)->as_Bool();
380 }
381 IfNode* selector_if = IfNode::make_with_same_profile(unswitch_candidate_if, _original_loop_entry, selector_bool);
382 _phase->register_node(selector_if, _outer_loop, _original_loop_entry, dom_depth);
383 return selector_if;
384 }
385
386 IfProjNode* create_proj_to_loop(const PathToLoop path_to_loop) {
387 const uint dom_depth = _phase->dom_depth(_original_loop_entry);
388 IfProjNode* proj_to_loop;
389 if (path_to_loop == TRUE_PATH) {
390 proj_to_loop = new IfTrueNode(_selector);
391 } else {
392 proj_to_loop = new IfFalseNode(_selector);
393 }
394 _phase->register_node(proj_to_loop, _outer_loop, _selector, dom_depth);
395 return proj_to_loop;
396 }
397
398 public:
399 IfNode* selector() const {
400 return _selector;
401 }
402
403 IfTrueNode* true_path_loop_proj() const {
404 return _true_path_loop_proj;
405 }
406
407 IfFalseNode* false_path_loop_proj() const {
408 return _false_path_loop_proj;
409 }
410 };
411
412 // Class to unswitch the original loop and create Predicates at the new unswitched loop versions. The newly cloned loop
413 // becomes the false-path-loop while original loop becomes the true-path-loop.
414 class OriginalLoop : public StackObj {
415 LoopNode* const _loop_head; // OuterStripMinedLoopNode if loop strip mined, else just the loop head.
416 IdealLoopTree* const _loop;
417 Node_List& _old_new;
418 PhaseIdealLoop* const _phase;
435 Node* old_to_new(const Node* old) const {
436 return _old_new[old->_idx];
437 }
438
439 #ifdef ASSERT
440 void verify_unswitched_loop_versions(LoopNode* true_path_loop_head,
441 const UnswitchedLoopSelector& unswitched_loop_selector) const {
442 verify_unswitched_loop_version(true_path_loop_head, unswitched_loop_selector.true_path_loop_proj());
443 verify_unswitched_loop_version(old_to_new(true_path_loop_head)->as_Loop(),
444 unswitched_loop_selector.false_path_loop_proj());
445 }
446
447 static void verify_unswitched_loop_version(LoopNode* loop_head, IfProjNode* loop_selector_if_proj) {
448 Node* entry = loop_head->skip_strip_mined()->in(LoopNode::EntryControl);
449 const Predicates predicates(entry);
450 // When skipping all predicates, we should end up at 'loop_selector_if_proj'.
451 assert(loop_selector_if_proj == predicates.entry(), "should end up at loop selector If");
452 }
453 #endif // ASSERT
454
455 public:
456 // Unswitch the original loop on the invariant loop selector by creating a true-path-loop and a false-path-loop.
457 // Remove the unswitch candidate If from both unswitched loop versions which are now covered by the loop selector If.
458 void unswitch(const UnswitchedLoopSelector& unswitched_loop_selector) {
459 _phase->clone_loop(_loop, _old_new, _phase->dom_depth(_loop_head),
460 PhaseIdealLoop::CloneIncludesStripMined, unswitched_loop_selector.selector());
461
462 // At this point, the selector If projections are the corresponding loop entries.
463 // clone_parse_and_assertion_predicates_to_unswitched_loop() could clone additional predicates after the selector
464 // If projections. The loop entries are updated accordingly.
465 IfProjNode* true_path_loop_entry = unswitched_loop_selector.true_path_loop_proj();
466 IfProjNode* false_path_loop_entry = unswitched_loop_selector.false_path_loop_proj();
467 _phase->clone_parse_and_assertion_predicates_to_unswitched_loop(_loop, _old_new,
468 true_path_loop_entry, false_path_loop_entry);
469
470 fix_loop_entries(true_path_loop_entry, false_path_loop_entry);
471 DEBUG_ONLY(verify_unswitched_loop_versions(_loop->_head->as_Loop(), unswitched_loop_selector);)
472 _phase->recompute_dom_depth();
473 }
474 };
475
476 // See comments below file header for more information about Loop Unswitching.
477 void PhaseIdealLoop::do_unswitching(IdealLoopTree* loop, Node_List& old_new) {
478 assert(LoopUnswitching, "LoopUnswitching must be enabled");
479
480 LoopNode* original_head = loop->_head->as_Loop();
481 if (has_control_dependencies_from_predicates(original_head)) {
482 NOT_PRODUCT(trace_loop_unswitching_impossible(original_head);)
483 return;
484 }
485
486 NOT_PRODUCT(trace_loop_unswitching_count(loop, original_head);)
487 C->print_method(PHASE_BEFORE_LOOP_UNSWITCHING, 4, original_head);
488
489 revert_to_normal_loop(original_head);
490
491 const UnswitchCandidate unswitch_candidate(loop, old_new);
492 const UnswitchedLoopSelector unswitched_loop_selector(loop, unswitch_candidate);
493 OriginalLoop original_loop(loop, old_new);
494 original_loop.unswitch(unswitched_loop_selector);
495
496 unswitch_candidate.update_in_true_path_loop(unswitched_loop_selector.true_path_loop_proj());
497 unswitch_candidate.update_in_false_path_loop(unswitched_loop_selector.false_path_loop_proj(),
498 old_new[original_head->_idx]->as_Loop());
499 hoist_invariant_check_casts(loop, old_new, unswitch_candidate, unswitched_loop_selector.selector());
500 add_unswitched_loop_version_bodies_to_igvn(loop, old_new);
501
502 LoopNode* new_head = old_new[original_head->_idx]->as_Loop();
503 increment_unswitch_counts(original_head, new_head);
504
505 NOT_PRODUCT(trace_loop_unswitching_result(unswitched_loop_selector, unswitch_candidate, original_head, new_head);)
506 C->print_method(PHASE_AFTER_LOOP_UNSWITCHING, 4, new_head);
507 C->set_major_progress();
508 }
509
510 bool PhaseIdealLoop::has_control_dependencies_from_predicates(LoopNode* head) {
511 Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl);
512 const Predicates predicates(entry);
513 if (predicates.has_any()) {
514 assert(entry->is_IfProj(), "sanity - must be ifProj since there is at least one predicate");
515 if (entry->outcnt() > 1) {
516 // Bailout if there are predicates from which there are additional control dependencies (i.e. from loop
517 // entry 'entry') to previously partially peeled statements since this case is not handled and can lead
518 // to a wrong execution. Remove this bailout, once this is fixed.
519 return true;
520 }
521 }
522 return false;
523 }
524
525 #ifndef PRODUCT
526 void PhaseIdealLoop::trace_loop_unswitching_impossible(const LoopNode* original_head) {
527 if (TraceLoopUnswitching) {
528 tty->print_cr("Loop Unswitching \"%d %s\" not possible due to control dependencies",
529 original_head->_idx, original_head->Name());
530 }
531 }
532
533 void PhaseIdealLoop::trace_loop_unswitching_count(IdealLoopTree* loop, LoopNode* original_head) {
534 if (TraceLoopOpts) {
535 tty->print("Unswitch %d ", original_head->unswitch_count() + 1);
536 loop->dump_head();
537 }
538 }
539
540 void PhaseIdealLoop::trace_loop_unswitching_result(const UnswitchedLoopSelector& unswitched_loop_selector,
541 const UnswitchCandidate& unswitch_candidate,
542 const LoopNode* original_head, const LoopNode* new_head) {
543 if (TraceLoopUnswitching) {
544 IfNode* unswitch_candidate_if = unswitch_candidate.candidate();
545 IfNode* loop_selector = unswitched_loop_selector.selector();
546 tty->print_cr("Loop Unswitching:");
547 tty->print_cr("- Unswitch-Candidate-If: %d %s", unswitch_candidate_if->_idx, unswitch_candidate_if->Name());
548 tty->print_cr("- Loop-Selector-If: %d %s", loop_selector->_idx, loop_selector->Name());
549 tty->print_cr("- True-Path-Loop (=Orig): %d %s", original_head->_idx, original_head->Name());
550 tty->print_cr("- False-Path-Loop (=Clone): %d %s", new_head->_idx, new_head->Name());
551 unswitch_candidate.trace_flat_array_checks();
552 }
553 }
554 #endif
555
556 // When unswitching a counted loop, we need to convert it back to a normal loop since it's not a proper pre, main or,
557 // post loop anymore after loop unswitching.
558 void PhaseIdealLoop::revert_to_normal_loop(const LoopNode* loop_head) {
559 CountedLoopNode* cl = loop_head->isa_CountedLoop();
560 if (cl != nullptr && !cl->is_normal_loop()) {
561 cl->set_normal_loop();
562 }
563 }
564
565 // Hoist invariant CheckCastPPNodes out of each unswitched loop version to the appropriate loop selector If projection.
566 void PhaseIdealLoop::hoist_invariant_check_casts(const IdealLoopTree* loop, const Node_List& old_new,
567 const UnswitchCandidate& unswitch_candidate,
568 const IfNode* loop_selector) {
569 ResourceMark rm;
570 GrowableArray<CheckCastPPNode*> loop_invariant_check_casts;
571 const IfNode* unswitch_candidate_if = unswitch_candidate.candidate();
572 for (DUIterator_Fast imax, i = unswitch_candidate_if->fast_outs(imax); i < imax; i++) {
573 IfProjNode* proj = unswitch_candidate_if->fast_out(i)->as_IfProj();
574 // Copy to a worklist for easier manipulation
575 for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
576 CheckCastPPNode* check_cast = proj->fast_out(j)->isa_CheckCastPP();
577 if (check_cast != nullptr && loop->is_invariant(check_cast->in(1))) {
578 loop_invariant_check_casts.push(check_cast);
579 }
580 }
581 IfProjNode* loop_selector_if_proj = loop_selector->proj_out(proj->_con)->as_IfProj();
582 while (loop_invariant_check_casts.length() > 0) {
583 CheckCastPPNode* cast = loop_invariant_check_casts.pop();
584 Node* cast_clone = cast->clone();
585 cast_clone->set_req(0, loop_selector_if_proj);
586 _igvn.replace_input_of(cast, 1, cast_clone);
587 register_new_node(cast_clone, loop_selector_if_proj);
588 // Same for the false-path-loop if there are not multiple flat array checks (in that case we leave the
589 // false-path-loop unchanged).
590 if (!unswitch_candidate.has_multiple_flat_array_check_candidates()) {
591 Node* use_clone = old_new[cast->_idx];
592 _igvn.replace_input_of(use_clone, 1, cast_clone);
593 }
594 }
595 }
596 }
597
598 // Enable more optimizations possibilities in the next IGVN round.
599 void PhaseIdealLoop::add_unswitched_loop_version_bodies_to_igvn(IdealLoopTree* loop, const Node_List& old_new) {
600 loop->record_for_igvn();
601 for (int i = loop->_body.size() - 1; i >= 0; i--) {
602 Node* n = loop->_body[i];
603 Node* n_clone = old_new[n->_idx];
604 _igvn._worklist.push(n_clone);
605 }
606 }
607
608 void PhaseIdealLoop::increment_unswitch_counts(LoopNode* original_head, LoopNode* new_head) {
609 const int unswitch_count = original_head->unswitch_count() + 1;
610 original_head->set_unswitch_count(unswitch_count);
611 new_head->set_unswitch_count(unswitch_count);
612 }
|