Mercurial > hg > truffle
annotate src/share/vm/opto/loopPredicate.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | b9a9ed0f8eeb |
children | 6f3fd5150b67 |
rev | line source |
---|---|
2445 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6804
diff
changeset
|
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
2445 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #include "precompiled.hpp" | |
26 #include "opto/loopnode.hpp" | |
27 #include "opto/addnode.hpp" | |
28 #include "opto/callnode.hpp" | |
29 #include "opto/connode.hpp" | |
30 #include "opto/loopnode.hpp" | |
31 #include "opto/mulnode.hpp" | |
32 #include "opto/rootnode.hpp" | |
33 #include "opto/subnode.hpp" | |
34 | |
35 /* | |
36 * The general idea of Loop Predication is to insert a predicate on the entry | |
37 * path to a loop, and raise a uncommon trap if the check of the condition fails. | |
38 * The condition checks are promoted from inside the loop body, and thus | |
39 * the checks inside the loop could be eliminated. Currently, loop predication | |
40 * optimization has been applied to remove array range check and loop invariant | |
41 * checks (such as null checks). | |
42 */ | |
43 | |
44 //-------------------------------is_uncommon_trap_proj---------------------------- | |
45 // Return true if proj is the form of "proj->[region->..]call_uct" | |
46 bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) { | |
47 int path_limit = 10; | |
48 assert(proj, "invalid argument"); | |
49 Node* out = proj; | |
50 for (int ct = 0; ct < path_limit; ct++) { | |
51 out = out->unique_ctrl_out(); | |
52 if (out == NULL) | |
53 return false; | |
54 if (out->is_CallStaticJava()) { | |
55 int req = out->as_CallStaticJava()->uncommon_trap_request(); | |
56 if (req != 0) { | |
57 Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); | |
58 if (trap_reason == reason || reason == Deoptimization::Reason_none) { | |
59 return true; | |
60 } | |
61 } | |
62 return false; // don't do further after call | |
63 } | |
64 if (out->Opcode() != Op_Region) | |
65 return false; | |
66 } | |
67 return false; | |
68 } | |
69 | |
70 //-------------------------------is_uncommon_trap_if_pattern------------------------- | |
71 // Return true for "if(test)-> proj -> ... | |
72 // | | |
73 // V | |
74 // other_proj->[region->..]call_uct" | |
75 // | |
76 // "must_reason_predicate" means the uct reason must be Reason_predicate | |
77 bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) { | |
78 Node *in0 = proj->in(0); | |
79 if (!in0->is_If()) return false; | |
80 // Variation of a dead If node. | |
81 if (in0->outcnt() < 2) return false; | |
82 IfNode* iff = in0->as_If(); | |
83 | |
84 // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate | |
85 if (reason != Deoptimization::Reason_none) { | |
86 if (iff->in(1)->Opcode() != Op_Conv2B || | |
87 iff->in(1)->in(1)->Opcode() != Op_Opaque1) { | |
88 return false; | |
89 } | |
90 } | |
91 | |
92 ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj(); | |
93 if (is_uncommon_trap_proj(other_proj, reason)) { | |
94 assert(reason == Deoptimization::Reason_none || | |
95 Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list"); | |
96 return true; | |
97 } | |
98 return false; | |
99 } | |
100 | |
101 //-------------------------------register_control------------------------- | |
102 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) { | |
103 assert(n->is_CFG(), "must be control node"); | |
104 _igvn.register_new_node_with_optimizer(n); | |
105 loop->_body.push(n); | |
106 set_loop(n, loop); | |
107 // When called from beautify_loops() idom is not constructed yet. | |
108 if (_idom != NULL) { | |
109 set_idom(n, pred, dom_depth(pred)); | |
110 } | |
111 } | |
112 | |
113 //------------------------------create_new_if_for_predicate------------------------ | |
114 // create a new if above the uct_if_pattern for the predicate to be promoted. | |
115 // | |
116 // before after | |
117 // ---------- ---------- | |
118 // ctrl ctrl | |
119 // | | | |
120 // | | | |
121 // v v | |
122 // iff new_iff | |
123 // / \ / \ | |
124 // / \ / \ | |
125 // v v v v | |
126 // uncommon_proj cont_proj if_uct if_cont | |
127 // \ | | | | | |
128 // \ | | | | | |
129 // v v v | v | |
130 // rgn loop | iff | |
131 // | | / \ | |
132 // | | / \ | |
133 // v | v v | |
134 // uncommon_trap | uncommon_proj cont_proj | |
135 // \ \ | | | |
136 // \ \ | | | |
137 // v v v v | |
138 // rgn loop | |
139 // | | |
140 // | | |
141 // v | |
142 // uncommon_trap | |
143 // | |
144 // | |
145 // We will create a region to guard the uct call if there is no one there. | |
146 // The true projecttion (if_cont) of the new_iff is returned. | |
147 // This code is also used to clone predicates to clonned loops. | |
148 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, | |
149 Deoptimization::DeoptReason reason) { | |
150 assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); | |
151 IfNode* iff = cont_proj->in(0)->as_If(); | |
152 | |
153 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); | |
154 Node *rgn = uncommon_proj->unique_ctrl_out(); | |
155 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); | |
156 | |
157 uint proj_index = 1; // region's edge corresponding to uncommon_proj | |
158 if (!rgn->is_Region()) { // create a region to guard the call | |
159 assert(rgn->is_Call(), "must be call uct"); | |
160 CallNode* call = rgn->as_Call(); | |
161 IdealLoopTree* loop = get_loop(call); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
162 rgn = new (C) RegionNode(1); |
2445 | 163 rgn->add_req(uncommon_proj); |
164 register_control(rgn, loop, uncommon_proj); | |
165 _igvn.hash_delete(call); | |
166 call->set_req(0, rgn); | |
167 // When called from beautify_loops() idom is not constructed yet. | |
168 if (_idom != NULL) { | |
169 set_idom(call, rgn, dom_depth(rgn)); | |
170 } | |
171 } else { | |
172 // Find region's edge corresponding to uncommon_proj | |
173 for (; proj_index < rgn->req(); proj_index++) | |
174 if (rgn->in(proj_index) == uncommon_proj) break; | |
175 assert(proj_index < rgn->req(), "sanity"); | |
176 } | |
177 | |
178 Node* entry = iff->in(0); | |
179 if (new_entry != NULL) { | |
180 // Clonning the predicate to new location. | |
181 entry = new_entry; | |
182 } | |
183 // Create new_iff | |
184 IdealLoopTree* lp = get_loop(entry); | |
185 IfNode *new_iff = iff->clone()->as_If(); | |
186 new_iff->set_req(0, entry); | |
187 register_control(new_iff, lp, entry); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
188 Node *if_cont = new (C) IfTrueNode(new_iff); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
189 Node *if_uct = new (C) IfFalseNode(new_iff); |
2445 | 190 if (cont_proj->is_IfFalse()) { |
191 // Swap | |
192 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; | |
193 } | |
194 register_control(if_cont, lp, new_iff); | |
195 register_control(if_uct, get_loop(rgn), new_iff); | |
196 | |
197 // if_uct to rgn | |
198 _igvn.hash_delete(rgn); | |
199 rgn->add_req(if_uct); | |
200 // When called from beautify_loops() idom is not constructed yet. | |
201 if (_idom != NULL) { | |
202 Node* ridom = idom(rgn); | |
203 Node* nrdom = dom_lca(ridom, new_iff); | |
204 set_idom(rgn, nrdom, dom_depth(rgn)); | |
205 } | |
206 | |
207 // If rgn has phis add new edges which has the same | |
208 // value as on original uncommon_proj pass. | |
209 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last"); | |
210 bool has_phi = false; | |
211 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) { | |
212 Node* use = rgn->fast_out(i); | |
213 if (use->is_Phi() && use->outcnt() > 0) { | |
214 assert(use->in(0) == rgn, ""); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3850
diff
changeset
|
215 _igvn.rehash_node_delayed(use); |
2445 | 216 use->add_req(use->in(proj_index)); |
217 has_phi = true; | |
218 } | |
219 } | |
220 assert(!has_phi || rgn->req() > 3, "no phis when region is created"); | |
221 | |
222 if (new_entry == NULL) { | |
223 // Attach if_cont to iff | |
224 _igvn.hash_delete(iff); | |
225 iff->set_req(0, if_cont); | |
226 if (_idom != NULL) { | |
227 set_idom(iff, if_cont, dom_depth(iff)); | |
228 } | |
229 } | |
230 return if_cont->as_Proj(); | |
231 } | |
232 | |
233 //------------------------------create_new_if_for_predicate------------------------ | |
234 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization) | |
235 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, | |
236 Deoptimization::DeoptReason reason) { | |
237 assert(new_entry != 0, "only used for clone predicate"); | |
238 assert(PhaseIdealLoop::is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); | |
239 IfNode* iff = cont_proj->in(0)->as_If(); | |
240 | |
241 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); | |
242 Node *rgn = uncommon_proj->unique_ctrl_out(); | |
243 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); | |
244 | |
245 uint proj_index = 1; // region's edge corresponding to uncommon_proj | |
246 if (!rgn->is_Region()) { // create a region to guard the call | |
247 assert(rgn->is_Call(), "must be call uct"); | |
248 CallNode* call = rgn->as_Call(); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
249 rgn = new (C) RegionNode(1); |
2445 | 250 register_new_node_with_optimizer(rgn); |
251 rgn->add_req(uncommon_proj); | |
252 hash_delete(call); | |
253 call->set_req(0, rgn); | |
254 } else { | |
255 // Find region's edge corresponding to uncommon_proj | |
256 for (; proj_index < rgn->req(); proj_index++) | |
257 if (rgn->in(proj_index) == uncommon_proj) break; | |
258 assert(proj_index < rgn->req(), "sanity"); | |
259 } | |
260 | |
261 // Create new_iff in new location. | |
262 IfNode *new_iff = iff->clone()->as_If(); | |
263 new_iff->set_req(0, new_entry); | |
264 | |
265 register_new_node_with_optimizer(new_iff); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
266 Node *if_cont = new (C) IfTrueNode(new_iff); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
267 Node *if_uct = new (C) IfFalseNode(new_iff); |
2445 | 268 if (cont_proj->is_IfFalse()) { |
269 // Swap | |
270 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; | |
271 } | |
272 register_new_node_with_optimizer(if_cont); | |
273 register_new_node_with_optimizer(if_uct); | |
274 | |
275 // if_uct to rgn | |
276 hash_delete(rgn); | |
277 rgn->add_req(if_uct); | |
278 | |
279 // If rgn has phis add corresponding new edges which has the same | |
280 // value as on original uncommon_proj pass. | |
281 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last"); | |
282 bool has_phi = false; | |
283 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) { | |
284 Node* use = rgn->fast_out(i); | |
285 if (use->is_Phi() && use->outcnt() > 0) { | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3850
diff
changeset
|
286 rehash_node_delayed(use); |
2445 | 287 use->add_req(use->in(proj_index)); |
288 has_phi = true; | |
289 } | |
290 } | |
291 assert(!has_phi || rgn->req() > 3, "no phis when region is created"); | |
292 | |
293 return if_cont->as_Proj(); | |
294 } | |
295 | |
296 //--------------------------clone_predicate----------------------- | |
297 ProjNode* PhaseIdealLoop::clone_predicate(ProjNode* predicate_proj, Node* new_entry, | |
298 Deoptimization::DeoptReason reason, | |
299 PhaseIdealLoop* loop_phase, | |
300 PhaseIterGVN* igvn) { | |
301 ProjNode* new_predicate_proj; | |
302 if (loop_phase != NULL) { | |
303 new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason); | |
304 } else { | |
305 new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason); | |
306 } | |
307 IfNode* iff = new_predicate_proj->in(0)->as_If(); | |
308 Node* ctrl = iff->in(0); | |
309 | |
310 // Match original condition since predicate's projections could be swapped. | |
311 assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
312 Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1)); |
2445 | 313 igvn->C->add_predicate_opaq(opq); |
314 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
315 Node* bol = new (igvn->C) Conv2BNode(opq); |
2445 | 316 if (loop_phase != NULL) { |
317 loop_phase->register_new_node(opq, ctrl); | |
318 loop_phase->register_new_node(bol, ctrl); | |
319 } else { | |
320 igvn->register_new_node_with_optimizer(opq); | |
321 igvn->register_new_node_with_optimizer(bol); | |
322 } | |
323 igvn->hash_delete(iff); | |
324 iff->set_req(1, bol); | |
325 return new_predicate_proj; | |
326 } | |
327 | |
328 | |
329 //--------------------------clone_loop_predicates----------------------- | |
330 // Interface from IGVN | |
3345 | 331 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
332 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, clone_limit_check, NULL, this); |
2445 | 333 } |
334 | |
335 // Interface from PhaseIdealLoop | |
3345 | 336 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
337 return clone_loop_predicates(old_entry, new_entry, clone_limit_check, this, &this->_igvn); |
2445 | 338 } |
339 | |
340 // Clone loop predicates to cloned loops (peeled, unswitched, split_if). | |
341 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, | |
3345 | 342 bool clone_limit_check, |
2445 | 343 PhaseIdealLoop* loop_phase, |
344 PhaseIterGVN* igvn) { | |
345 #ifdef ASSERT | |
346 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) { | |
347 if (new_entry != NULL) | |
348 new_entry->dump(); | |
349 assert(false, "not IfTrue, IfFalse, Region or SafePoint"); | |
350 } | |
351 #endif | |
352 // Search original predicates | |
353 Node* entry = old_entry; | |
3345 | 354 ProjNode* limit_check_proj = NULL; |
355 if (LoopLimitCheck) { | |
356 limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | |
357 if (limit_check_proj != NULL) { | |
358 entry = entry->in(0)->in(0); | |
359 } | |
360 } | |
2445 | 361 if (UseLoopPredicate) { |
362 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | |
363 if (predicate_proj != NULL) { // right pattern that can be used by loop predication | |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
364 // clone predicate |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
365 new_entry = clone_predicate(predicate_proj, new_entry, |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
366 Deoptimization::Reason_predicate, |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
367 loop_phase, igvn); |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
368 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate"); |
2445 | 369 if (TraceLoopPredicate) { |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
370 tty->print("Loop Predicate cloned: "); |
2445 | 371 debug_only( new_entry->in(0)->dump(); ) |
372 } | |
373 } | |
374 } | |
3345 | 375 if (limit_check_proj != NULL && clone_limit_check) { |
376 // Clone loop limit check last to insert it before loop. | |
377 // Don't clone a limit check which was already finalized | |
378 // for this counted loop (only one limit check is needed). | |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
379 new_entry = clone_predicate(limit_check_proj, new_entry, |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
380 Deoptimization::Reason_loop_limit_check, |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
381 loop_phase, igvn); |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
382 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check"); |
3345 | 383 if (TraceLoopLimitCheck) { |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
384 tty->print("Loop Limit Check cloned: "); |
3345 | 385 debug_only( new_entry->in(0)->dump(); ) |
386 } | |
387 } | |
2445 | 388 return new_entry; |
389 } | |
390 | |
391 //--------------------------skip_loop_predicates------------------------------ | |
392 // Skip related predicates. | |
393 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) { | |
394 Node* predicate = NULL; | |
3345 | 395 if (LoopLimitCheck) { |
396 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | |
397 if (predicate != NULL) { | |
398 entry = entry->in(0)->in(0); | |
399 } | |
400 } | |
2445 | 401 if (UseLoopPredicate) { |
402 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | |
403 if (predicate != NULL) { // right pattern that can be used by loop predication | |
404 IfNode* iff = entry->in(0)->as_If(); | |
405 ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con); | |
406 Node* rgn = uncommon_proj->unique_ctrl_out(); | |
407 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); | |
408 entry = entry->in(0)->in(0); | |
409 while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) { | |
410 uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con); | |
411 if (uncommon_proj->unique_ctrl_out() != rgn) | |
412 break; | |
413 entry = entry->in(0)->in(0); | |
414 } | |
415 } | |
416 } | |
417 return entry; | |
418 } | |
419 | |
420 //--------------------------find_predicate_insertion_point------------------- | |
421 // Find a good location to insert a predicate | |
422 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) { | |
423 if (start_c == NULL || !start_c->is_Proj()) | |
424 return NULL; | |
425 if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) { | |
426 return start_c->as_Proj(); | |
427 } | |
428 return NULL; | |
429 } | |
430 | |
431 //--------------------------find_predicate------------------------------------ | |
432 // Find a predicate | |
433 Node* PhaseIdealLoop::find_predicate(Node* entry) { | |
434 Node* predicate = NULL; | |
3345 | 435 if (LoopLimitCheck) { |
436 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | |
437 if (predicate != NULL) { // right pattern that can be used by loop predication | |
438 return entry; | |
439 } | |
440 } | |
2445 | 441 if (UseLoopPredicate) { |
442 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | |
443 if (predicate != NULL) { // right pattern that can be used by loop predication | |
444 return entry; | |
445 } | |
446 } | |
447 return NULL; | |
448 } | |
449 | |
450 //------------------------------Invariance----------------------------------- | |
451 // Helper class for loop_predication_impl to compute invariance on the fly and | |
452 // clone invariants. | |
453 class Invariance : public StackObj { | |
454 VectorSet _visited, _invariant; | |
455 Node_Stack _stack; | |
456 VectorSet _clone_visited; | |
457 Node_List _old_new; // map of old to new (clone) | |
458 IdealLoopTree* _lpt; | |
459 PhaseIdealLoop* _phase; | |
460 | |
461 // Helper function to set up the invariance for invariance computation | |
462 // If n is a known invariant, set up directly. Otherwise, look up the | |
463 // the possibility to push n onto the stack for further processing. | |
464 void visit(Node* use, Node* n) { | |
465 if (_lpt->is_invariant(n)) { // known invariant | |
466 _invariant.set(n->_idx); | |
467 } else if (!n->is_CFG()) { | |
468 Node *n_ctrl = _phase->ctrl_or_self(n); | |
469 Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG | |
470 if (_phase->is_dominator(n_ctrl, u_ctrl)) { | |
471 _stack.push(n, n->in(0) == NULL ? 1 : 0); | |
472 } | |
473 } | |
474 } | |
475 | |
476 // Compute invariance for "the_node" and (possibly) all its inputs recursively | |
477 // on the fly | |
478 void compute_invariance(Node* n) { | |
479 assert(_visited.test(n->_idx), "must be"); | |
480 visit(n, n); | |
481 while (_stack.is_nonempty()) { | |
482 Node* n = _stack.node(); | |
483 uint idx = _stack.index(); | |
484 if (idx == n->req()) { // all inputs are processed | |
485 _stack.pop(); | |
486 // n is invariant if it's inputs are all invariant | |
487 bool all_inputs_invariant = true; | |
488 for (uint i = 0; i < n->req(); i++) { | |
489 Node* in = n->in(i); | |
490 if (in == NULL) continue; | |
491 assert(_visited.test(in->_idx), "must have visited input"); | |
492 if (!_invariant.test(in->_idx)) { // bad guy | |
493 all_inputs_invariant = false; | |
494 break; | |
495 } | |
496 } | |
497 if (all_inputs_invariant) { | |
498 _invariant.set(n->_idx); // I am a invariant too | |
499 } | |
500 } else { // process next input | |
501 _stack.set_index(idx + 1); | |
502 Node* m = n->in(idx); | |
503 if (m != NULL && !_visited.test_set(m->_idx)) { | |
504 visit(n, m); | |
505 } | |
506 } | |
507 } | |
508 } | |
509 | |
510 // Helper function to set up _old_new map for clone_nodes. | |
511 // If n is a known invariant, set up directly ("clone" of n == n). | |
512 // Otherwise, push n onto the stack for real cloning. | |
513 void clone_visit(Node* n) { | |
514 assert(_invariant.test(n->_idx), "must be invariant"); | |
515 if (_lpt->is_invariant(n)) { // known invariant | |
516 _old_new.map(n->_idx, n); | |
517 } else { // to be cloned | |
518 assert(!n->is_CFG(), "should not see CFG here"); | |
519 _stack.push(n, n->in(0) == NULL ? 1 : 0); | |
520 } | |
521 } | |
522 | |
523 // Clone "n" and (possibly) all its inputs recursively | |
524 void clone_nodes(Node* n, Node* ctrl) { | |
525 clone_visit(n); | |
526 while (_stack.is_nonempty()) { | |
527 Node* n = _stack.node(); | |
528 uint idx = _stack.index(); | |
529 if (idx == n->req()) { // all inputs processed, clone n! | |
530 _stack.pop(); | |
531 // clone invariant node | |
532 Node* n_cl = n->clone(); | |
533 _old_new.map(n->_idx, n_cl); | |
534 _phase->register_new_node(n_cl, ctrl); | |
535 for (uint i = 0; i < n->req(); i++) { | |
536 Node* in = n_cl->in(i); | |
537 if (in == NULL) continue; | |
538 n_cl->set_req(i, _old_new[in->_idx]); | |
539 } | |
540 } else { // process next input | |
541 _stack.set_index(idx + 1); | |
542 Node* m = n->in(idx); | |
543 if (m != NULL && !_clone_visited.test_set(m->_idx)) { | |
544 clone_visit(m); // visit the input | |
545 } | |
546 } | |
547 } | |
548 } | |
549 | |
550 public: | |
551 Invariance(Arena* area, IdealLoopTree* lpt) : | |
552 _lpt(lpt), _phase(lpt->_phase), | |
553 _visited(area), _invariant(area), _stack(area, 10 /* guess */), | |
554 _clone_visited(area), _old_new(area) | |
555 {} | |
556 | |
557 // Map old to n for invariance computation and clone | |
558 void map_ctrl(Node* old, Node* n) { | |
559 assert(old->is_CFG() && n->is_CFG(), "must be"); | |
560 _old_new.map(old->_idx, n); // "clone" of old is n | |
561 _invariant.set(old->_idx); // old is invariant | |
562 _clone_visited.set(old->_idx); | |
563 } | |
564 | |
565 // Driver function to compute invariance | |
566 bool is_invariant(Node* n) { | |
567 if (!_visited.test_set(n->_idx)) | |
568 compute_invariance(n); | |
569 return (_invariant.test(n->_idx) != 0); | |
570 } | |
571 | |
572 // Driver function to clone invariant | |
573 Node* clone(Node* n, Node* ctrl) { | |
574 assert(ctrl->is_CFG(), "must be"); | |
575 assert(_invariant.test(n->_idx), "must be an invariant"); | |
576 if (!_clone_visited.test(n->_idx)) | |
577 clone_nodes(n, ctrl); | |
578 return _old_new[n->_idx]; | |
579 } | |
580 }; | |
581 | |
582 //------------------------------is_range_check_if ----------------------------------- | |
583 // Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format | |
584 // Note: this function is particularly designed for loop predication. We require load_range | |
585 // and offset to be loop invariant computed on the fly by "invar" | |
586 bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const { | |
587 if (!is_loop_exit(iff)) { | |
588 return false; | |
589 } | |
590 if (!iff->in(1)->is_Bool()) { | |
591 return false; | |
592 } | |
593 const BoolNode *bol = iff->in(1)->as_Bool(); | |
594 if (bol->_test._test != BoolTest::lt) { | |
595 return false; | |
596 } | |
597 if (!bol->in(1)->is_Cmp()) { | |
598 return false; | |
599 } | |
600 const CmpNode *cmp = bol->in(1)->as_Cmp(); | |
601 if (cmp->Opcode() != Op_CmpU) { | |
602 return false; | |
603 } | |
604 Node* range = cmp->in(2); | |
605 if (range->Opcode() != Op_LoadRange) { | |
606 const TypeInt* tint = phase->_igvn.type(range)->isa_int(); | |
3345 | 607 if (tint == NULL || tint->empty() || tint->_lo < 0) { |
2445 | 608 // Allow predication on positive values that aren't LoadRanges. |
609 // This allows optimization of loops where the length of the | |
610 // array is a known value and doesn't need to be loaded back | |
611 // from the array. | |
612 return false; | |
613 } | |
614 } | |
615 if (!invar.is_invariant(range)) { | |
616 return false; | |
617 } | |
618 Node *iv = _head->as_CountedLoop()->phi(); | |
619 int scale = 0; | |
620 Node *offset = NULL; | |
621 if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) { | |
622 return false; | |
623 } | |
624 if (offset && !invar.is_invariant(offset)) { // offset must be invariant | |
625 return false; | |
626 } | |
627 return true; | |
628 } | |
629 | |
630 //------------------------------rc_predicate----------------------------------- | |
631 // Create a range check predicate | |
632 // | |
633 // for (i = init; i < limit; i += stride) { | |
634 // a[scale*i+offset] | |
635 // } | |
636 // | |
637 // Compute max(scale*i + offset) for init <= i < limit and build the predicate | |
638 // as "max(scale*i + offset) u< a.length". | |
639 // | |
640 // There are two cases for max(scale*i + offset): | |
641 // (1) stride*scale > 0 | |
642 // max(scale*i + offset) = scale*(limit-stride) + offset | |
643 // (2) stride*scale < 0 | |
644 // max(scale*i + offset) = scale*init + offset | |
3345 | 645 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl, |
2445 | 646 int scale, Node* offset, |
647 Node* init, Node* limit, Node* stride, | |
648 Node* range, bool upper) { | |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
649 stringStream* predString = NULL; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
650 if (TraceLoopPredicate) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
651 predString = new stringStream(); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
652 predString->print("rc_predicate "); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
653 } |
2445 | 654 |
655 Node* max_idx_expr = init; | |
656 int stride_con = stride->get_int(); | |
657 if ((stride_con > 0) == (scale > 0) == upper) { | |
3345 | 658 if (LoopLimitCheck) { |
659 // With LoopLimitCheck limit is not exact. | |
660 // Calculate exact limit here. | |
661 // Note, counted loop's test is '<' or '>'. | |
662 limit = exact_limit(loop); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
663 max_idx_expr = new (C) SubINode(limit, stride); |
3345 | 664 register_new_node(max_idx_expr, ctrl); |
665 if (TraceLoopPredicate) predString->print("(limit - stride) "); | |
666 } else { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
667 max_idx_expr = new (C) SubINode(limit, stride); |
3345 | 668 register_new_node(max_idx_expr, ctrl); |
669 if (TraceLoopPredicate) predString->print("(limit - stride) "); | |
670 } | |
2445 | 671 } else { |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
672 if (TraceLoopPredicate) predString->print("init "); |
2445 | 673 } |
674 | |
675 if (scale != 1) { | |
676 ConNode* con_scale = _igvn.intcon(scale); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
677 max_idx_expr = new (C) MulINode(max_idx_expr, con_scale); |
2445 | 678 register_new_node(max_idx_expr, ctrl); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
679 if (TraceLoopPredicate) predString->print("* %d ", scale); |
2445 | 680 } |
681 | |
682 if (offset && (!offset->is_Con() || offset->get_int() != 0)){ | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
683 max_idx_expr = new (C) AddINode(max_idx_expr, offset); |
2445 | 684 register_new_node(max_idx_expr, ctrl); |
685 if (TraceLoopPredicate) | |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
686 if (offset->is_Con()) predString->print("+ %d ", offset->get_int()); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
687 else predString->print("+ offset "); |
2445 | 688 } |
689 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
690 CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range); |
2445 | 691 register_new_node(cmp, ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
692 BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt); |
2445 | 693 register_new_node(bol, ctrl); |
694 | |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
695 if (TraceLoopPredicate) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
696 predString->print_cr("<u range"); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
697 tty->print(predString->as_string()); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2445
diff
changeset
|
698 } |
2445 | 699 return bol; |
700 } | |
701 | |
702 //------------------------------ loop_predication_impl-------------------------- | |
703 // Insert loop predicates for null checks and range checks | |
704 bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) { | |
705 if (!UseLoopPredicate) return false; | |
706 | |
707 if (!loop->_head->is_Loop()) { | |
708 // Could be a simple region when irreducible loops are present. | |
709 return false; | |
710 } | |
3345 | 711 LoopNode* head = loop->_head->as_Loop(); |
2445 | 712 |
3345 | 713 if (head->unique_ctrl_out()->Opcode() == Op_NeverBranch) { |
2445 | 714 // do nothing for infinite loops |
715 return false; | |
716 } | |
717 | |
718 CountedLoopNode *cl = NULL; | |
3850
6987871cfb9b
7077439: Possible reference through NULL in loopPredicate.cpp:726
kvn
parents:
3845
diff
changeset
|
719 if (head->is_valid_counted_loop()) { |
3345 | 720 cl = head->as_CountedLoop(); |
2445 | 721 // do nothing for iteration-splitted loops |
722 if (!cl->is_normal_loop()) return false; | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3345
diff
changeset
|
723 // Avoid RCE if Counted loop's test is '!='. |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3345
diff
changeset
|
724 BoolTest::mask bt = cl->loopexit()->test_trip(); |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3345
diff
changeset
|
725 if (bt != BoolTest::lt && bt != BoolTest::gt) |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3345
diff
changeset
|
726 cl = NULL; |
2445 | 727 } |
728 | |
3345 | 729 Node* entry = head->in(LoopNode::EntryControl); |
730 ProjNode *predicate_proj = NULL; | |
731 // Loop limit check predicate should be near the loop. | |
732 if (LoopLimitCheck) { | |
733 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | |
734 if (predicate_proj != NULL) | |
735 entry = predicate_proj->in(0)->in(0); | |
736 } | |
2445 | 737 |
3345 | 738 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); |
2445 | 739 if (!predicate_proj) { |
740 #ifndef PRODUCT | |
741 if (TraceLoopPredicate) { | |
742 tty->print("missing predicate:"); | |
743 loop->dump_head(); | |
3345 | 744 head->dump(1); |
2445 | 745 } |
746 #endif | |
747 return false; | |
748 } | |
749 ConNode* zero = _igvn.intcon(0); | |
750 set_ctrl(zero, C->root()); | |
751 | |
752 ResourceArea *area = Thread::current()->resource_area(); | |
753 Invariance invar(area, loop); | |
754 | |
755 // Create list of if-projs such that a newer proj dominates all older | |
756 // projs in the list, and they all dominate loop->tail() | |
757 Node_List if_proj_list(area); | |
758 Node *current_proj = loop->tail(); //start from tail | |
759 while (current_proj != head) { | |
760 if (loop == get_loop(current_proj) && // still in the loop ? | |
761 current_proj->is_Proj() && // is a projection ? | |
762 current_proj->in(0)->Opcode() == Op_If) { // is a if projection ? | |
763 if_proj_list.push(current_proj); | |
764 } | |
765 current_proj = idom(current_proj); | |
766 } | |
767 | |
768 bool hoisted = false; // true if at least one proj is promoted | |
769 while (if_proj_list.size() > 0) { | |
770 // Following are changed to nonnull when a predicate can be hoisted | |
771 ProjNode* new_predicate_proj = NULL; | |
772 | |
773 ProjNode* proj = if_proj_list.pop()->as_Proj(); | |
774 IfNode* iff = proj->in(0)->as_If(); | |
775 | |
776 if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) { | |
777 if (loop->is_loop_exit(iff)) { | |
778 // stop processing the remaining projs in the list because the execution of them | |
779 // depends on the condition of "iff" (iff->in(1)). | |
780 break; | |
781 } else { | |
782 // Both arms are inside the loop. There are two cases: | |
783 // (1) there is one backward branch. In this case, any remaining proj | |
784 // in the if_proj list post-dominates "iff". So, the condition of "iff" | |
785 // does not determine the execution the remining projs directly, and we | |
786 // can safely continue. | |
787 // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj" | |
788 // does not dominate loop->tail(), so it can not be in the if_proj list. | |
789 continue; | |
790 } | |
791 } | |
792 | |
793 Node* test = iff->in(1); | |
794 if (!test->is_Bool()){ //Conv2B, ... | |
795 continue; | |
796 } | |
797 BoolNode* bol = test->as_Bool(); | |
798 if (invar.is_invariant(bol)) { | |
799 // Invariant test | |
800 new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL, | |
801 Deoptimization::Reason_predicate); | |
802 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0); | |
803 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); | |
804 | |
805 // Negate test if necessary | |
806 bool negated = false; | |
807 if (proj->_con != predicate_proj->_con) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
808 new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); |
2445 | 809 register_new_node(new_predicate_bol, ctrl); |
810 negated = true; | |
811 } | |
812 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If(); | |
813 _igvn.hash_delete(new_predicate_iff); | |
814 new_predicate_iff->set_req(1, new_predicate_bol); | |
815 #ifndef PRODUCT | |
816 if (TraceLoopPredicate) { | |
817 tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx); | |
818 loop->dump_head(); | |
819 } else if (TraceLoopOpts) { | |
820 tty->print("Predicate IC "); | |
821 loop->dump_head(); | |
822 } | |
823 #endif | |
824 } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { | |
825 assert(proj->_con == predicate_proj->_con, "must match"); | |
826 | |
827 // Range check for counted loops | |
828 const Node* cmp = bol->in(1)->as_Cmp(); | |
829 Node* idx = cmp->in(1); | |
830 assert(!invar.is_invariant(idx), "index is variant"); | |
831 Node* rng = cmp->in(2); | |
3345 | 832 assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be"); |
2445 | 833 assert(invar.is_invariant(rng), "range must be invariant"); |
834 int scale = 1; | |
835 Node* offset = zero; | |
836 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); | |
837 assert(ok, "must be index expression"); | |
838 | |
839 Node* init = cl->init_trip(); | |
840 Node* limit = cl->limit(); | |
841 Node* stride = cl->stride(); | |
842 | |
843 // Build if's for the upper and lower bound tests. The | |
844 // lower_bound test will dominate the upper bound test and all | |
845 // cloned or created nodes will use the lower bound test as | |
846 // their declared control. | |
847 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate); | |
848 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate); | |
849 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); | |
850 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); | |
851 | |
852 // Perform cloning to keep Invariance state correct since the | |
853 // late schedule will place invariant things in the loop. | |
854 rng = invar.clone(rng, ctrl); | |
855 if (offset && offset != zero) { | |
856 assert(invar.is_invariant(offset), "offset must be loop invariant"); | |
857 offset = invar.clone(offset, ctrl); | |
858 } | |
859 | |
860 // Test the lower bound | |
3345 | 861 Node* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false); |
2445 | 862 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); |
863 _igvn.hash_delete(lower_bound_iff); | |
864 lower_bound_iff->set_req(1, lower_bound_bol); | |
865 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx); | |
866 | |
867 // Test the upper bound | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3345
diff
changeset
|
868 Node* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true); |
2445 | 869 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); |
870 _igvn.hash_delete(upper_bound_iff); | |
871 upper_bound_iff->set_req(1, upper_bound_bol); | |
872 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx); | |
873 | |
874 // Fall through into rest of the clean up code which will move | |
875 // any dependent nodes onto the upper bound test. | |
876 new_predicate_proj = upper_bound_proj; | |
877 | |
878 #ifndef PRODUCT | |
879 if (TraceLoopOpts && !TraceLoopPredicate) { | |
880 tty->print("Predicate RC "); | |
881 loop->dump_head(); | |
882 } | |
883 #endif | |
884 } else { | |
885 // Loop variant check (for example, range check in non-counted loop) | |
886 // with uncommon trap. | |
887 continue; | |
888 } | |
889 assert(new_predicate_proj != NULL, "sanity"); | |
890 // Success - attach condition (new_predicate_bol) to predicate if | |
891 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate | |
892 | |
893 // Eliminate the old If in the loop body | |
894 dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con ); | |
895 | |
896 hoisted = true; | |
897 C->set_major_progress(); | |
898 } // end while | |
899 | |
900 #ifndef PRODUCT | |
901 // report that the loop predication has been actually performed | |
902 // for this loop | |
903 if (TraceLoopPredicate && hoisted) { | |
904 tty->print("Loop Predication Performed:"); | |
905 loop->dump_head(); | |
906 } | |
907 #endif | |
908 | |
909 return hoisted; | |
910 } | |
911 | |
912 //------------------------------loop_predication-------------------------------- | |
913 // driver routine for loop predication optimization | |
914 bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) { | |
915 bool hoisted = false; | |
916 // Recursively promote predicates | |
917 if (_child) { | |
918 hoisted = _child->loop_predication( phase); | |
919 } | |
920 | |
921 // self | |
922 if (!_irreducible && !tail()->is_top()) { | |
923 hoisted |= phase->loop_predication_impl(this); | |
924 } | |
925 | |
926 if (_next) { //sibling | |
927 hoisted |= _next->loop_predication( phase); | |
928 } | |
929 | |
930 return hoisted; | |
931 } |