Mercurial > hg > graal-compiler
annotate src/share/vm/opto/ifnode.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | c96c3eb1efae |
children | 5e990493719e |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1153
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1153
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1153
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.inline.hpp" | |
27 #include "opto/addnode.hpp" | |
28 #include "opto/cfgnode.hpp" | |
29 #include "opto/connode.hpp" | |
2445 | 30 #include "opto/loopnode.hpp" |
1972 | 31 #include "opto/phaseX.hpp" |
32 #include "opto/runtime.hpp" | |
33 #include "opto/subnode.hpp" | |
34 | |
0 | 35 // Portions of code courtesy of Clifford Click |
36 | |
37 // Optimization - Graph Style | |
38 | |
39 | |
40 extern int explicit_null_checks_elided; | |
41 | |
42 //============================================================================= | |
43 //------------------------------Value------------------------------------------ | |
44 // Return a tuple for whichever arm of the IF is reachable | |
45 const Type *IfNode::Value( PhaseTransform *phase ) const { | |
46 if( !in(0) ) return Type::TOP; | |
47 if( phase->type(in(0)) == Type::TOP ) | |
48 return Type::TOP; | |
49 const Type *t = phase->type(in(1)); | |
50 if( t == Type::TOP ) // data is undefined | |
51 return TypeTuple::IFNEITHER; // unreachable altogether | |
52 if( t == TypeInt::ZERO ) // zero, or false | |
53 return TypeTuple::IFFALSE; // only false branch is reachable | |
54 if( t == TypeInt::ONE ) // 1, or true | |
55 return TypeTuple::IFTRUE; // only true branch is reachable | |
56 assert( t == TypeInt::BOOL, "expected boolean type" ); | |
57 | |
58 return TypeTuple::IFBOTH; // No progress | |
59 } | |
60 | |
61 const RegMask &IfNode::out_RegMask() const { | |
62 return RegMask::Empty; | |
63 } | |
64 | |
65 //------------------------------split_if--------------------------------------- | |
66 // Look for places where we merge constants, then test on the merged value. | |
67 // If the IF test will be constant folded on the path with the constant, we | |
68 // win by splitting the IF to before the merge point. | |
69 static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { | |
70 // I could be a lot more general here, but I'm trying to squeeze this | |
71 // in before the Christmas '98 break so I'm gonna be kinda restrictive | |
72 // on the patterns I accept. CNC | |
73 | |
74 // Look for a compare of a constant and a merged value | |
75 Node *i1 = iff->in(1); | |
76 if( !i1->is_Bool() ) return NULL; | |
77 BoolNode *b = i1->as_Bool(); | |
78 Node *cmp = b->in(1); | |
79 if( !cmp->is_Cmp() ) return NULL; | |
80 i1 = cmp->in(1); | |
81 if( i1 == NULL || !i1->is_Phi() ) return NULL; | |
82 PhiNode *phi = i1->as_Phi(); | |
83 if( phi->is_copy() ) return NULL; | |
84 Node *con2 = cmp->in(2); | |
85 if( !con2->is_Con() ) return NULL; | |
86 // See that the merge point contains some constants | |
87 Node *con1=NULL; | |
88 uint i4; | |
89 for( i4 = 1; i4 < phi->req(); i4++ ) { | |
90 con1 = phi->in(i4); | |
605 | 91 if( !con1 ) return NULL; // Do not optimize partially collapsed merges |
0 | 92 if( con1->is_Con() ) break; // Found a constant |
93 // Also allow null-vs-not-null checks | |
94 const TypePtr *tp = igvn->type(con1)->isa_ptr(); | |
95 if( tp && tp->_ptr == TypePtr::NotNull ) | |
96 break; | |
97 } | |
98 if( i4 >= phi->req() ) return NULL; // Found no constants | |
99 | |
100 igvn->C->set_has_split_ifs(true); // Has chance for split-if | |
101 | |
102 // Make sure that the compare can be constant folded away | |
103 Node *cmp2 = cmp->clone(); | |
104 cmp2->set_req(1,con1); | |
105 cmp2->set_req(2,con2); | |
106 const Type *t = cmp2->Value(igvn); | |
107 // This compare is dead, so whack it! | |
108 igvn->remove_dead_node(cmp2); | |
109 if( !t->singleton() ) return NULL; | |
110 | |
111 // No intervening control, like a simple Call | |
112 Node *r = iff->in(0); | |
113 if( !r->is_Region() ) return NULL; | |
114 if( phi->region() != r ) return NULL; | |
115 // No other users of the cmp/bool | |
116 if (b->outcnt() != 1 || cmp->outcnt() != 1) { | |
117 //tty->print_cr("many users of cmp/bool"); | |
118 return NULL; | |
119 } | |
120 | |
121 // Make sure we can determine where all the uses of merged values go | |
122 for (DUIterator_Fast jmax, j = r->fast_outs(jmax); j < jmax; j++) { | |
123 Node* u = r->fast_out(j); | |
124 if( u == r ) continue; | |
125 if( u == iff ) continue; | |
126 if( u->outcnt() == 0 ) continue; // use is dead & ignorable | |
127 if( !u->is_Phi() ) { | |
128 /* | |
129 if( u->is_Start() ) { | |
130 tty->print_cr("Region has inlined start use"); | |
131 } else { | |
132 tty->print_cr("Region has odd use"); | |
133 u->dump(2); | |
134 }*/ | |
135 return NULL; | |
136 } | |
137 if( u != phi ) { | |
138 // CNC - do not allow any other merged value | |
139 //tty->print_cr("Merging another value"); | |
140 //u->dump(2); | |
141 return NULL; | |
142 } | |
143 // Make sure we can account for all Phi uses | |
144 for (DUIterator_Fast kmax, k = u->fast_outs(kmax); k < kmax; k++) { | |
145 Node* v = u->fast_out(k); // User of the phi | |
146 // CNC - Allow only really simple patterns. | |
147 // In particular I disallow AddP of the Phi, a fairly common pattern | |
148 if( v == cmp ) continue; // The compare is OK | |
149 if( (v->is_ConstraintCast()) && | |
150 v->in(0)->in(0) == iff ) | |
151 continue; // CastPP/II of the IfNode is OK | |
152 // Disabled following code because I cannot tell if exactly one | |
153 // path dominates without a real dominator check. CNC 9/9/1999 | |
154 //uint vop = v->Opcode(); | |
155 //if( vop == Op_Phi ) { // Phi from another merge point might be OK | |
156 // Node *r = v->in(0); // Get controlling point | |
157 // if( !r ) return NULL; // Degraded to a copy | |
158 // // Find exactly one path in (either True or False doms, but not IFF) | |
159 // int cnt = 0; | |
160 // for( uint i = 1; i < r->req(); i++ ) | |
161 // if( r->in(i) && r->in(i)->in(0) == iff ) | |
162 // cnt++; | |
163 // if( cnt == 1 ) continue; // Exactly one of True or False guards Phi | |
164 //} | |
165 if( !v->is_Call() ) { | |
166 /* | |
167 if( v->Opcode() == Op_AddP ) { | |
168 tty->print_cr("Phi has AddP use"); | |
169 } else if( v->Opcode() == Op_CastPP ) { | |
170 tty->print_cr("Phi has CastPP use"); | |
171 } else if( v->Opcode() == Op_CastII ) { | |
172 tty->print_cr("Phi has CastII use"); | |
173 } else { | |
174 tty->print_cr("Phi has use I cant be bothered with"); | |
175 } | |
176 */ | |
177 } | |
178 return NULL; | |
179 | |
180 /* CNC - Cut out all the fancy acceptance tests | |
181 // Can we clone this use when doing the transformation? | |
182 // If all uses are from Phis at this merge or constants, then YES. | |
183 if( !v->in(0) && v != cmp ) { | |
184 tty->print_cr("Phi has free-floating use"); | |
185 v->dump(2); | |
186 return NULL; | |
187 } | |
188 for( uint l = 1; l < v->req(); l++ ) { | |
189 if( (!v->in(l)->is_Phi() || v->in(l)->in(0) != r) && | |
190 !v->in(l)->is_Con() ) { | |
191 tty->print_cr("Phi has use"); | |
192 v->dump(2); | |
193 return NULL; | |
194 } // End of if Phi-use input is neither Phi nor Constant | |
195 } // End of for all inputs to Phi-use | |
196 */ | |
197 } // End of for all uses of Phi | |
198 } // End of for all uses of Region | |
199 | |
200 // Only do this if the IF node is in a sane state | |
201 if (iff->outcnt() != 2) | |
202 return NULL; | |
203 | |
204 // Got a hit! Do the Mondo Hack! | |
205 // | |
206 //ABC a1c def ghi B 1 e h A C a c d f g i | |
207 // R - Phi - Phi - Phi Rc - Phi - Phi - Phi Rx - Phi - Phi - Phi | |
208 // cmp - 2 cmp - 2 cmp - 2 | |
209 // bool bool_c bool_x | |
210 // if if_c if_x | |
211 // T F T F T F | |
212 // ..s.. ..t .. ..s.. ..t.. ..s.. ..t.. | |
213 // | |
605 | 214 // Split the paths coming into the merge point into 2 separate groups of |
0 | 215 // merges. On the left will be all the paths feeding constants into the |
216 // Cmp's Phi. On the right will be the remaining paths. The Cmp's Phi | |
217 // will fold up into a constant; this will let the Cmp fold up as well as | |
218 // all the control flow. Below the original IF we have 2 control | |
219 // dependent regions, 's' and 't'. Now we will merge the two paths | |
220 // just prior to 's' and 't' from the two IFs. At least 1 path (and quite | |
221 // likely 2 or more) will promptly constant fold away. | |
222 PhaseGVN *phase = igvn; | |
223 | |
224 // Make a region merging constants and a region merging the rest | |
225 uint req_c = 0; | |
2445 | 226 Node* predicate_proj = NULL; |
0 | 227 for (uint ii = 1; ii < r->req(); ii++) { |
2445 | 228 if (phi->in(ii) == con1) { |
0 | 229 req_c++; |
230 } | |
2445 | 231 Node* proj = PhaseIdealLoop::find_predicate(r->in(ii)); |
232 if (proj != NULL) { | |
233 assert(predicate_proj == NULL, "only one predicate entry expected"); | |
234 predicate_proj = proj; | |
235 } | |
0 | 236 } |
2445 | 237 Node* predicate_c = NULL; |
238 Node* predicate_x = NULL; | |
3345 | 239 bool counted_loop = r->is_CountedLoop(); |
2445 | 240 |
0 | 241 Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1); |
242 Node *phi_c = con1; | |
243 uint len = r->req(); | |
2445 | 244 Node *region_x = new (igvn->C, len - req_c) RegionNode(len - req_c); |
0 | 245 Node *phi_x = PhiNode::make_blank(region_x, phi); |
246 for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) { | |
2445 | 247 if (phi->in(i) == con1) { |
0 | 248 region_c->init_req( i_c++, r ->in(i) ); |
2445 | 249 if (r->in(i) == predicate_proj) |
250 predicate_c = predicate_proj; | |
0 | 251 } else { |
252 region_x->init_req( i_x, r ->in(i) ); | |
253 phi_x ->init_req( i_x++, phi->in(i) ); | |
2445 | 254 if (r->in(i) == predicate_proj) |
255 predicate_x = predicate_proj; | |
0 | 256 } |
257 } | |
3845
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
258 if (predicate_c != NULL && (req_c > 1)) { |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
259 assert(predicate_x == NULL, "only one predicate entry expected"); |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
260 predicate_c = NULL; // Do not clone predicate below merge point |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
261 } |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
262 if (predicate_x != NULL && ((len - req_c) > 2)) { |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
263 assert(predicate_c == NULL, "only one predicate entry expected"); |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
264 predicate_x = NULL; // Do not clone predicate below merge point |
c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents:
3840
diff
changeset
|
265 } |
0 | 266 |
267 // Register the new RegionNodes but do not transform them. Cannot | |
605 | 268 // transform until the entire Region/Phi conglomerate has been hacked |
0 | 269 // as a single huge transform. |
270 igvn->register_new_node_with_optimizer( region_c ); | |
271 igvn->register_new_node_with_optimizer( region_x ); | |
272 // Prevent the untimely death of phi_x. Currently he has no uses. He is | |
273 // about to get one. If this only use goes away, then phi_x will look dead. | |
274 // However, he will be picking up some more uses down below. | |
275 Node *hook = new (igvn->C, 4) Node(4); | |
276 hook->init_req(0, phi_x); | |
277 hook->init_req(1, phi_c); | |
1013
ce590301ae2a
6889300: assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes")
kvn
parents:
851
diff
changeset
|
278 phi_x = phase->transform( phi_x ); |
0 | 279 |
280 // Make the compare | |
281 Node *cmp_c = phase->makecon(t); | |
282 Node *cmp_x = cmp->clone(); | |
283 cmp_x->set_req(1,phi_x); | |
284 cmp_x->set_req(2,con2); | |
285 cmp_x = phase->transform(cmp_x); | |
286 // Make the bool | |
287 Node *b_c = phase->transform(new (igvn->C, 2) BoolNode(cmp_c,b->_test._test)); | |
288 Node *b_x = phase->transform(new (igvn->C, 2) BoolNode(cmp_x,b->_test._test)); | |
289 // Make the IfNode | |
290 IfNode *iff_c = new (igvn->C, 2) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); | |
291 igvn->set_type_bottom(iff_c); | |
292 igvn->_worklist.push(iff_c); | |
293 hook->init_req(2, iff_c); | |
294 | |
295 IfNode *iff_x = new (igvn->C, 2) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); | |
296 igvn->set_type_bottom(iff_x); | |
297 igvn->_worklist.push(iff_x); | |
298 hook->init_req(3, iff_x); | |
299 | |
300 // Make the true/false arms | |
301 Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c)); | |
302 Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c)); | |
2445 | 303 if (predicate_c != NULL) { |
304 assert(predicate_x == NULL, "only one predicate entry expected"); | |
305 // Clone loop predicates to each path | |
3345 | 306 iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t, !counted_loop); |
307 iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f, !counted_loop); | |
2445 | 308 } |
0 | 309 Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x)); |
310 Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x)); | |
2445 | 311 if (predicate_x != NULL) { |
312 assert(predicate_c == NULL, "only one predicate entry expected"); | |
313 // Clone loop predicates to each path | |
3345 | 314 iff_x_t = igvn->clone_loop_predicates(predicate_x, iff_x_t, !counted_loop); |
315 iff_x_f = igvn->clone_loop_predicates(predicate_x, iff_x_f, !counted_loop); | |
2445 | 316 } |
0 | 317 |
318 // Merge the TRUE paths | |
319 Node *region_s = new (igvn->C, 3) RegionNode(3); | |
320 igvn->_worklist.push(region_s); | |
321 region_s->init_req(1, iff_c_t); | |
322 region_s->init_req(2, iff_x_t); | |
323 igvn->register_new_node_with_optimizer( region_s ); | |
324 | |
325 // Merge the FALSE paths | |
326 Node *region_f = new (igvn->C, 3) RegionNode(3); | |
327 igvn->_worklist.push(region_f); | |
328 region_f->init_req(1, iff_c_f); | |
329 region_f->init_req(2, iff_x_f); | |
330 igvn->register_new_node_with_optimizer( region_f ); | |
331 | |
332 igvn->hash_delete(cmp);// Remove soon-to-be-dead node from hash table. | |
333 cmp->set_req(1,NULL); // Whack the inputs to cmp because it will be dead | |
334 cmp->set_req(2,NULL); | |
335 // Check for all uses of the Phi and give them a new home. | |
336 // The 'cmp' got cloned, but CastPP/IIs need to be moved. | |
337 Node *phi_s = NULL; // do not construct unless needed | |
338 Node *phi_f = NULL; // do not construct unless needed | |
339 for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) { | |
340 Node* v = phi->last_out(i2);// User of the phi | |
341 igvn->hash_delete(v); // Have to fixup other Phi users | |
342 igvn->_worklist.push(v); | |
343 uint vop = v->Opcode(); | |
344 Node *proj = NULL; | |
345 if( vop == Op_Phi ) { // Remote merge point | |
346 Node *r = v->in(0); | |
347 for (uint i3 = 1; i3 < r->req(); i3++) | |
348 if (r->in(i3) && r->in(i3)->in(0) == iff) { | |
349 proj = r->in(i3); | |
350 break; | |
351 } | |
352 } else if( v->is_ConstraintCast() ) { | |
353 proj = v->in(0); // Controlling projection | |
354 } else { | |
355 assert( 0, "do not know how to handle this guy" ); | |
356 } | |
357 | |
358 Node *proj_path_data, *proj_path_ctrl; | |
359 if( proj->Opcode() == Op_IfTrue ) { | |
360 if( phi_s == NULL ) { | |
361 // Only construct phi_s if needed, otherwise provides | |
362 // interfering use. | |
363 phi_s = PhiNode::make_blank(region_s,phi); | |
364 phi_s->init_req( 1, phi_c ); | |
365 phi_s->init_req( 2, phi_x ); | |
1013
ce590301ae2a
6889300: assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes")
kvn
parents:
851
diff
changeset
|
366 hook->add_req(phi_s); |
0 | 367 phi_s = phase->transform(phi_s); |
368 } | |
369 proj_path_data = phi_s; | |
370 proj_path_ctrl = region_s; | |
371 } else { | |
372 if( phi_f == NULL ) { | |
373 // Only construct phi_f if needed, otherwise provides | |
374 // interfering use. | |
375 phi_f = PhiNode::make_blank(region_f,phi); | |
376 phi_f->init_req( 1, phi_c ); | |
377 phi_f->init_req( 2, phi_x ); | |
1013
ce590301ae2a
6889300: assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes")
kvn
parents:
851
diff
changeset
|
378 hook->add_req(phi_f); |
0 | 379 phi_f = phase->transform(phi_f); |
380 } | |
381 proj_path_data = phi_f; | |
382 proj_path_ctrl = region_f; | |
383 } | |
384 | |
385 // Fixup 'v' for for the split | |
386 if( vop == Op_Phi ) { // Remote merge point | |
387 uint i; | |
388 for( i = 1; i < v->req(); i++ ) | |
389 if( v->in(i) == phi ) | |
390 break; | |
391 v->set_req(i, proj_path_data ); | |
392 } else if( v->is_ConstraintCast() ) { | |
393 v->set_req(0, proj_path_ctrl ); | |
394 v->set_req(1, proj_path_data ); | |
395 } else | |
396 ShouldNotReachHere(); | |
397 } | |
398 | |
399 // Now replace the original iff's True/False with region_s/region_t. | |
400 // This makes the original iff go dead. | |
401 for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) { | |
402 Node* p = iff->last_out(i3); | |
403 assert( p->Opcode() == Op_IfTrue || p->Opcode() == Op_IfFalse, "" ); | |
404 Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f; | |
405 // Replace p with u | |
406 igvn->add_users_to_worklist(p); | |
407 for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { | |
408 Node* x = p->last_out(l); | |
409 igvn->hash_delete(x); | |
410 uint uses_found = 0; | |
411 for( uint j = 0; j < x->req(); j++ ) { | |
412 if( x->in(j) == p ) { | |
413 x->set_req(j, u); | |
414 uses_found++; | |
415 } | |
416 } | |
417 l -= uses_found; // we deleted 1 or more copies of this edge | |
418 } | |
419 igvn->remove_dead_node(p); | |
420 } | |
421 | |
422 // Force the original merge dead | |
423 igvn->hash_delete(r); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
424 // First, remove region's dead users. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
425 for (DUIterator_Last lmin, l = r->last_outs(lmin); l >= lmin;) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
426 Node* u = r->last_out(l); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
427 if( u == r ) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
428 r->set_req(0, NULL); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
429 } else { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
430 assert(u->outcnt() == 0, "only dead users"); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
431 igvn->remove_dead_node(u); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
432 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
433 l -= 1; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
434 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
435 igvn->remove_dead_node(r); |
0 | 436 |
437 // Now remove the bogus extra edges used to keep things alive | |
438 igvn->remove_dead_node( hook ); | |
439 | |
440 // Must return either the original node (now dead) or a new node | |
441 // (Do not return a top here, since that would break the uniqueness of top.) | |
442 return new (igvn->C, 1) ConINode(TypeInt::ZERO); | |
443 } | |
444 | |
445 //------------------------------is_range_check--------------------------------- | |
446 // Return 0 if not a range check. Return 1 if a range check and set index and | |
447 // offset. Return 2 if we had to negate the test. Index is NULL if the check | |
448 // is versus a constant. | |
449 int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) { | |
450 Node* b = in(1); | |
451 if (b == NULL || !b->is_Bool()) return 0; | |
452 BoolNode* bn = b->as_Bool(); | |
453 Node* cmp = bn->in(1); | |
454 if (cmp == NULL) return 0; | |
455 if (cmp->Opcode() != Op_CmpU) return 0; | |
456 | |
457 Node* l = cmp->in(1); | |
458 Node* r = cmp->in(2); | |
459 int flip_test = 1; | |
460 if (bn->_test._test == BoolTest::le) { | |
461 l = cmp->in(2); | |
462 r = cmp->in(1); | |
463 flip_test = 2; | |
464 } else if (bn->_test._test != BoolTest::lt) { | |
465 return 0; | |
466 } | |
467 if (l->is_top()) return 0; // Top input means dead test | |
468 if (r->Opcode() != Op_LoadRange) return 0; | |
469 | |
470 // We have recognized one of these forms: | |
471 // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... | |
472 // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ... | |
473 | |
474 // Make sure it's a real range check by requiring an uncommon trap | |
475 // along the OOB path. Otherwise, it's possible that the user wrote | |
476 // something which optimized to look like a range check but behaves | |
477 // in some other way. | |
478 Node* iftrap = proj_out(flip_test == 2 ? true : false); | |
479 bool found_trap = false; | |
480 if (iftrap != NULL) { | |
481 Node* u = iftrap->unique_ctrl_out(); | |
482 if (u != NULL) { | |
483 // It could be a merge point (Region) for uncommon trap. | |
484 if (u->is_Region()) { | |
485 Node* c = u->unique_ctrl_out(); | |
486 if (c != NULL) { | |
487 iftrap = u; | |
488 u = c; | |
489 } | |
490 } | |
491 if (u->in(0) == iftrap && u->is_CallStaticJava()) { | |
492 int req = u->as_CallStaticJava()->uncommon_trap_request(); | |
493 if (Deoptimization::trap_request_reason(req) == | |
494 Deoptimization::Reason_range_check) { | |
495 found_trap = true; | |
496 } | |
497 } | |
498 } | |
499 } | |
500 if (!found_trap) return 0; // sorry, no cigar | |
501 | |
502 // Look for index+offset form | |
503 Node* ind = l; | |
504 jint off = 0; | |
505 if (l->is_top()) { | |
506 return 0; | |
507 } else if (l->is_Add()) { | |
508 if ((off = l->in(1)->find_int_con(0)) != 0) { | |
509 ind = l->in(2); | |
510 } else if ((off = l->in(2)->find_int_con(0)) != 0) { | |
511 ind = l->in(1); | |
512 } | |
513 } else if ((off = l->find_int_con(-1)) >= 0) { | |
514 // constant offset with no variable index | |
515 ind = NULL; | |
516 } else { | |
517 // variable index with no constant offset (or dead negative index) | |
518 off = 0; | |
519 } | |
520 | |
521 // Return all the values: | |
522 index = ind; | |
523 offset = off; | |
524 range = r; | |
525 return flip_test; | |
526 } | |
527 | |
528 //------------------------------adjust_check----------------------------------- | |
529 // Adjust (widen) a prior range check | |
530 static void adjust_check(Node* proj, Node* range, Node* index, | |
531 int flip, jint off_lo, PhaseIterGVN* igvn) { | |
532 PhaseGVN *gvn = igvn; | |
533 // Break apart the old check | |
534 Node *iff = proj->in(0); | |
535 Node *bol = iff->in(1); | |
536 if( bol->is_top() ) return; // In case a partially dead range check appears | |
537 // bail (or bomb[ASSERT/DEBUG]) if NOT projection-->IfNode-->BoolNode | |
538 DEBUG_ONLY( if( !bol->is_Bool() ) { proj->dump(3); fatal("Expect projection-->IfNode-->BoolNode"); } ) | |
539 if( !bol->is_Bool() ) return; | |
540 | |
541 Node *cmp = bol->in(1); | |
542 // Compute a new check | |
543 Node *new_add = gvn->intcon(off_lo); | |
544 if( index ) { | |
545 new_add = off_lo ? gvn->transform(new (gvn->C, 3) AddINode( index, new_add )) : index; | |
546 } | |
547 Node *new_cmp = (flip == 1) | |
548 ? new (gvn->C, 3) CmpUNode( new_add, range ) | |
549 : new (gvn->C, 3) CmpUNode( range, new_add ); | |
550 new_cmp = gvn->transform(new_cmp); | |
551 // See if no need to adjust the existing check | |
552 if( new_cmp == cmp ) return; | |
553 // Else, adjust existing check | |
554 Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); | |
555 igvn->hash_delete( iff ); | |
556 iff->set_req_X( 1, new_bol, igvn ); | |
3348
f879eafd5835
7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents:
3345
diff
changeset
|
557 igvn->_worklist.push( iff ); |
0 | 558 } |
559 | |
560 //------------------------------up_one_dom------------------------------------- | |
561 // Walk up the dominator tree one step. Return NULL at root or true | |
562 // complex merges. Skips through small diamonds. | |
563 Node* IfNode::up_one_dom(Node *curr, bool linear_only) { | |
564 Node *dom = curr->in(0); | |
565 if( !dom ) // Found a Region degraded to a copy? | |
566 return curr->nonnull_req(); // Skip thru it | |
567 | |
568 if( curr != dom ) // Normal walk up one step? | |
569 return dom; | |
570 | |
571 // Use linear_only if we are still parsing, since we cannot | |
572 // trust the regions to be fully filled in. | |
573 if (linear_only) | |
574 return NULL; | |
575 | |
1153
bea7a22a6f79
6915110: IfNode::up_one_dom moves beyond RootNode bug in src/share/vm/opto/ifnode.cpp
kvn
parents:
1017
diff
changeset
|
576 if( dom->is_Root() ) |
bea7a22a6f79
6915110: IfNode::up_one_dom moves beyond RootNode bug in src/share/vm/opto/ifnode.cpp
kvn
parents:
1017
diff
changeset
|
577 return NULL; |
bea7a22a6f79
6915110: IfNode::up_one_dom moves beyond RootNode bug in src/share/vm/opto/ifnode.cpp
kvn
parents:
1017
diff
changeset
|
578 |
0 | 579 // Else hit a Region. Check for a loop header |
580 if( dom->is_Loop() ) | |
581 return dom->in(1); // Skip up thru loops | |
582 | |
583 // Check for small diamonds | |
584 Node *din1, *din2, *din3, *din4; | |
585 if( dom->req() == 3 && // 2-path merge point | |
586 (din1 = dom ->in(1)) && // Left path exists | |
587 (din2 = dom ->in(2)) && // Right path exists | |
588 (din3 = din1->in(0)) && // Left path up one | |
589 (din4 = din2->in(0)) ) { // Right path up one | |
590 if( din3->is_Call() && // Handle a slow-path call on either arm | |
591 (din3 = din3->in(0)) ) | |
592 din3 = din3->in(0); | |
593 if( din4->is_Call() && // Handle a slow-path call on either arm | |
594 (din4 = din4->in(0)) ) | |
595 din4 = din4->in(0); | |
596 if( din3 == din4 && din3->is_If() ) | |
597 return din3; // Skip around diamonds | |
598 } | |
599 | |
600 // Give up the search at true merges | |
601 return NULL; // Dead loop? Or hit root? | |
602 } | |
603 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
604 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
605 //------------------------------filtered_int_type-------------------------------- |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
606 // Return a possibly more restrictive type for val based on condition control flow for an if |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
607 const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
608 assert(if_proj && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
609 (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
610 if (if_proj->in(0) && if_proj->in(0)->is_If()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
611 IfNode* iff = if_proj->in(0)->as_If(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
612 if (iff->in(1) && iff->in(1)->is_Bool()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
613 BoolNode* bol = iff->in(1)->as_Bool(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
614 if (bol->in(1) && bol->in(1)->is_Cmp()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
615 const CmpNode* cmp = bol->in(1)->as_Cmp(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
616 if (cmp->in(1) == val) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
617 const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
618 if (cmp2_t != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
619 jint lo = cmp2_t->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
620 jint hi = cmp2_t->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
621 BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
622 switch (msk) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
623 case BoolTest::ne: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
624 // Can't refine type |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
625 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
626 case BoolTest::eq: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
627 return cmp2_t; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
628 case BoolTest::lt: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
629 lo = TypeInt::INT->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
630 if (hi - 1 < hi) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
631 hi = hi - 1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
632 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
633 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
634 case BoolTest::le: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
635 lo = TypeInt::INT->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
636 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
637 case BoolTest::gt: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
638 if (lo + 1 > lo) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
639 lo = lo + 1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
640 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
641 hi = TypeInt::INT->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
642 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
643 case BoolTest::ge: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
644 // lo unchanged |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
645 hi = TypeInt::INT->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
646 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
647 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
648 const TypeInt* rtn_t = TypeInt::make(lo, hi, cmp2_t->_widen); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
649 return rtn_t; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
650 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
651 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
652 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
653 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
654 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
655 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
656 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
657 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
658 //------------------------------fold_compares---------------------------- |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
659 // See if a pair of CmpIs can be converted into a CmpU. In some cases |
605 | 660 // the direction of this if is determined by the preceding if so it |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
661 // can be eliminate entirely. Given an if testing (CmpI n c) check |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
662 // for an immediately control dependent if that is testing (CmpI n c2) |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
663 // and has one projection leading to this if and the other projection |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
664 // leading to a region that merges one of this ifs control |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
665 // projections. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
666 // |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
667 // If |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
668 // / | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
669 // / | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
670 // / | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
671 // If | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
672 // /\ | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
673 // / \ | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
674 // / \ | |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
675 // / Region |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
676 // |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
677 Node* IfNode::fold_compares(PhaseGVN* phase) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
678 if (!EliminateAutoBox || Opcode() != Op_If) return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
679 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
680 Node* this_cmp = in(1)->in(1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
681 if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
682 this_cmp->in(2)->is_Con() && this_cmp->in(2) != phase->C->top()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
683 Node* ctrl = in(0); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
684 BoolNode* this_bool = in(1)->as_Bool(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
685 Node* n = this_cmp->in(1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
686 int hi = this_cmp->in(2)->get_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
687 if (ctrl != NULL && ctrl->is_Proj() && ctrl->outcnt() == 1 && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
688 ctrl->in(0)->is_If() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
689 ctrl->in(0)->outcnt() == 2 && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
690 ctrl->in(0)->in(1)->is_Bool() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
691 ctrl->in(0)->in(1)->in(1)->Opcode() == Op_CmpI && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
692 ctrl->in(0)->in(1)->in(1)->in(2)->is_Con() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
693 ctrl->in(0)->in(1)->in(1)->in(1) == n) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
694 IfNode* dom_iff = ctrl->in(0)->as_If(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
695 Node* otherproj = dom_iff->proj_out(!ctrl->as_Proj()->_con); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
696 if (otherproj->outcnt() == 1 && otherproj->unique_out()->is_Region() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
697 this_bool->_test._test != BoolTest::ne && this_bool->_test._test != BoolTest::eq) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
698 // Identify which proj goes to the region and which continues on |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
699 RegionNode* region = otherproj->unique_out()->as_Region(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
700 Node* success = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
701 Node* fail = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
702 for (int i = 0; i < 2; i++) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
703 Node* proj = proj_out(i); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
704 if (success == NULL && proj->outcnt() == 1 && proj->unique_out() == region) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
705 success = proj; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
706 } else if (fail == NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
707 fail = proj; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
708 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
709 success = fail = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
710 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
711 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
712 if (success != NULL && fail != NULL && !region->has_phi()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
713 int lo = dom_iff->in(1)->in(1)->in(2)->get_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
714 BoolNode* dom_bool = dom_iff->in(1)->as_Bool(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
715 Node* dom_cmp = dom_bool->in(1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
716 const TypeInt* failtype = filtered_int_type(phase, n, ctrl); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
717 if (failtype != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
718 const TypeInt* type2 = filtered_int_type(phase, n, fail); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
719 if (type2 != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
720 failtype = failtype->join(type2)->is_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
721 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
722 failtype = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
723 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
724 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
725 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
726 if (failtype != NULL && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
727 dom_bool->_test._test != BoolTest::ne && dom_bool->_test._test != BoolTest::eq) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
728 int bound = failtype->_hi - failtype->_lo + 1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
729 if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
730 // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
731 BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
732 Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo))); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
733 Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound))); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
734 Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
735 phase->hash_delete(dom_iff); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
736 dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
737 phase->is_IterGVN()->_worklist.push(dom_iff); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
738 phase->hash_delete(this); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
739 set_req(1, newbool); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
740 return this; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
741 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
742 if (failtype->_lo > failtype->_hi) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
743 // previous if determines the result of this if so |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
744 // replace Bool with constant |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
745 phase->hash_delete(this); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
746 set_req(1, phase->intcon(success->as_Proj()->_con)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
747 return this; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
748 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
749 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
750 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
751 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
752 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
753 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
754 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
755 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
756 |
0 | 757 //------------------------------remove_useless_bool---------------------------- |
758 // Check for people making a useless boolean: things like | |
759 // if( (x < y ? true : false) ) { ... } | |
760 // Replace with if( x < y ) { ... } | |
761 static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { | |
762 Node *i1 = iff->in(1); | |
763 if( !i1->is_Bool() ) return NULL; | |
764 BoolNode *bol = i1->as_Bool(); | |
765 | |
766 Node *cmp = bol->in(1); | |
767 if( cmp->Opcode() != Op_CmpI ) return NULL; | |
768 | |
769 // Must be comparing against a bool | |
770 const Type *cmp2_t = phase->type( cmp->in(2) ); | |
771 if( cmp2_t != TypeInt::ZERO && | |
772 cmp2_t != TypeInt::ONE ) | |
773 return NULL; | |
774 | |
775 // Find a prior merge point merging the boolean | |
776 i1 = cmp->in(1); | |
777 if( !i1->is_Phi() ) return NULL; | |
778 PhiNode *phi = i1->as_Phi(); | |
779 if( phase->type( phi ) != TypeInt::BOOL ) | |
780 return NULL; | |
781 | |
782 // Check for diamond pattern | |
783 int true_path = phi->is_diamond_phi(); | |
784 if( true_path == 0 ) return NULL; | |
785 | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
786 // Make sure that iff and the control of the phi are different. This |
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
787 // should really only happen for dead control flow since it requires |
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
788 // an illegal cycle. |
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
789 if (phi->in(0)->in(1)->in(0) == iff) return NULL; |
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
790 |
0 | 791 // phi->region->if_proj->ifnode->bool->cmp |
792 BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); | |
793 | |
794 // Now get the 'sense' of the test correct so we can plug in | |
795 // either iff2->in(1) or its complement. | |
796 int flip = 0; | |
797 if( bol->_test._test == BoolTest::ne ) flip = 1-flip; | |
798 else if( bol->_test._test != BoolTest::eq ) return NULL; | |
799 if( cmp2_t == TypeInt::ZERO ) flip = 1-flip; | |
800 | |
801 const Type *phi1_t = phase->type( phi->in(1) ); | |
802 const Type *phi2_t = phase->type( phi->in(2) ); | |
803 // Check for Phi(0,1) and flip | |
804 if( phi1_t == TypeInt::ZERO ) { | |
805 if( phi2_t != TypeInt::ONE ) return NULL; | |
806 flip = 1-flip; | |
807 } else { | |
808 // Check for Phi(1,0) | |
809 if( phi1_t != TypeInt::ONE ) return NULL; | |
810 if( phi2_t != TypeInt::ZERO ) return NULL; | |
811 } | |
812 if( true_path == 2 ) { | |
813 flip = 1-flip; | |
814 } | |
815 | |
816 Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2); | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
817 assert(new_bol != iff->in(1), "must make progress"); |
0 | 818 iff->set_req(1, new_bol); |
819 // Intervening diamond probably goes dead | |
820 phase->C->set_major_progress(); | |
821 return iff; | |
822 } | |
823 | |
824 static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff); | |
825 | |
826 //------------------------------Ideal------------------------------------------ | |
827 // Return a node which is more "ideal" than the current node. Strip out | |
828 // control copies | |
829 Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
830 if (remove_dead_region(phase, can_reshape)) return this; | |
831 // No Def-Use info? | |
832 if (!can_reshape) return NULL; | |
833 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
834 | |
835 // Don't bother trying to transform a dead if | |
836 if (in(0)->is_top()) return NULL; | |
837 // Don't bother trying to transform an if with a dead test | |
838 if (in(1)->is_top()) return NULL; | |
839 // Another variation of a dead test | |
840 if (in(1)->is_Con()) return NULL; | |
841 // Another variation of a dead if | |
842 if (outcnt() < 2) return NULL; | |
843 | |
844 // Canonicalize the test. | |
845 Node* idt_if = idealize_test(phase, this); | |
846 if (idt_if != NULL) return idt_if; | |
847 | |
848 // Try to split the IF | |
849 Node *s = split_if(this, igvn); | |
850 if (s != NULL) return s; | |
851 | |
852 // Check for people making a useless boolean: things like | |
853 // if( (x < y ? true : false) ) { ... } | |
854 // Replace with if( x < y ) { ... } | |
855 Node *bol2 = remove_useless_bool(this, phase); | |
856 if( bol2 ) return bol2; | |
857 | |
858 // Setup to scan up the CFG looking for a dominating test | |
859 Node *dom = in(0); | |
860 Node *prev_dom = this; | |
861 | |
862 // Check for range-check vs other kinds of tests | |
863 Node *index1, *range1; | |
864 jint offset1; | |
865 int flip1 = is_range_check(range1, index1, offset1); | |
866 if( flip1 ) { | |
867 Node *first_prev_dom = NULL; | |
868 | |
869 // Try to remove extra range checks. All 'up_one_dom' gives up at merges | |
870 // so all checks we inspect post-dominate the top-most check we find. | |
871 // If we are going to fail the current check and we reach the top check | |
605 | 872 // then we are guaranteed to fail, so just start interpreting there. |
0 | 873 // We 'expand' the top 2 range checks to include all post-dominating |
874 // checks. | |
875 | |
876 // The top 2 range checks seen | |
877 Node *prev_chk1 = NULL; | |
878 Node *prev_chk2 = NULL; | |
879 // Low and high offsets seen so far | |
880 jint off_lo = offset1; | |
881 jint off_hi = offset1; | |
882 | |
883 // Scan for the top 2 checks and collect range of offsets | |
884 for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit | |
885 if( dom->Opcode() == Op_If && // Not same opcode? | |
886 prev_dom->in(0) == dom ) { // One path of test does dominate? | |
887 if( dom == this ) return NULL; // dead loop | |
888 // See if this is a range check | |
889 Node *index2, *range2; | |
890 jint offset2; | |
891 int flip2 = dom->as_If()->is_range_check(range2, index2, offset2); | |
892 // See if this is a _matching_ range check, checking against | |
893 // the same array bounds. | |
894 if( flip2 == flip1 && range2 == range1 && index2 == index1 && | |
895 dom->outcnt() == 2 ) { | |
896 // Gather expanded bounds | |
897 off_lo = MIN2(off_lo,offset2); | |
898 off_hi = MAX2(off_hi,offset2); | |
899 // Record top 2 range checks | |
900 prev_chk2 = prev_chk1; | |
901 prev_chk1 = prev_dom; | |
902 // If we match the test exactly, then the top test covers | |
903 // both our lower and upper bounds. | |
904 if( dom->in(1) == in(1) ) | |
905 prev_chk2 = prev_chk1; | |
906 } | |
907 } | |
908 prev_dom = dom; | |
909 dom = up_one_dom( dom ); | |
910 if( !dom ) break; | |
911 } | |
912 | |
913 | |
914 // Attempt to widen the dominating range check to cover some later | |
915 // ones. Since range checks "fail" by uncommon-trapping to the | |
916 // interpreter, widening a check can make us speculative enter the | |
917 // interpreter. If we see range-check deopt's, do not widen! | |
918 if (!phase->C->allow_range_check_smearing()) return NULL; | |
919 | |
920 // Constant indices only need to check the upper bound. | |
921 // Non-constance indices must check both low and high. | |
922 if( index1 ) { | |
923 // Didn't find 2 prior covering checks, so cannot remove anything. | |
924 if( !prev_chk2 ) return NULL; | |
925 // 'Widen' the offsets of the 1st and 2nd covering check | |
926 adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn ); | |
927 // Do not call adjust_check twice on the same projection | |
928 // as the first call may have transformed the BoolNode to a ConI | |
929 if( prev_chk1 != prev_chk2 ) { | |
930 adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn ); | |
931 } | |
932 // Test is now covered by prior checks, dominate it out | |
933 prev_dom = prev_chk2; | |
934 } else { | |
935 // Didn't find prior covering check, so cannot remove anything. | |
936 if( !prev_chk1 ) return NULL; | |
937 // 'Widen' the offset of the 1st and only covering check | |
938 adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn ); | |
939 // Test is now covered by prior checks, dominate it out | |
940 prev_dom = prev_chk1; | |
941 } | |
942 | |
943 | |
944 } else { // Scan for an equivalent test | |
945 | |
946 Node *cmp; | |
947 int dist = 0; // Cutoff limit for search | |
948 int op = Opcode(); | |
949 if( op == Op_If && | |
950 (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) { | |
951 if( cmp->in(2) != NULL && // make sure cmp is not already dead | |
952 cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { | |
953 dist = 64; // Limit for null-pointer scans | |
954 } else { | |
955 dist = 4; // Do not bother for random pointer tests | |
956 } | |
957 } else { | |
958 dist = 4; // Limit for random junky scans | |
959 } | |
960 | |
961 // Normal equivalent-test check. | |
962 if( !dom ) return NULL; // Dead loop? | |
963 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
964 Node* result = fold_compares(phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
965 if (result != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
966 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
967 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
968 |
0 | 969 // Search up the dominator tree for an If with an identical test |
970 while( dom->Opcode() != op || // Not same opcode? | |
971 dom->in(1) != in(1) || // Not same input 1? | |
972 (req() == 3 && dom->in(2) != in(2)) || // Not same input 2? | |
973 prev_dom->in(0) != dom ) { // One path of test does not dominate? | |
974 if( dist < 0 ) return NULL; | |
975 | |
976 dist--; | |
977 prev_dom = dom; | |
978 dom = up_one_dom( dom ); | |
979 if( !dom ) return NULL; | |
980 } | |
981 | |
982 // Check that we did not follow a loop back to ourselves | |
983 if( this == dom ) | |
984 return NULL; | |
985 | |
986 if( dist > 2 ) // Add to count of NULL checks elided | |
987 explicit_null_checks_elided++; | |
988 | |
989 } // End of Else scan for an equivalent test | |
990 | |
991 // Hit! Remove this IF | |
992 #ifndef PRODUCT | |
993 if( TraceIterativeGVN ) { | |
994 tty->print(" Removing IfNode: "); this->dump(); | |
995 } | |
996 if( VerifyOpto && !phase->allow_progress() ) { | |
997 // Found an equivalent dominating test, | |
998 // we can not guarantee reaching a fix-point for these during iterativeGVN | |
999 // since intervening nodes may not change. | |
1000 return NULL; | |
1001 } | |
1002 #endif | |
1003 | |
1004 // Replace dominated IfNode | |
1005 dominated_by( prev_dom, igvn ); | |
1006 | |
1007 // Must return either the original node (now dead) or a new node | |
1008 // (Do not return a top here, since that would break the uniqueness of top.) | |
1009 return new (phase->C, 1) ConINode(TypeInt::ZERO); | |
1010 } | |
1011 | |
1012 //------------------------------dominated_by----------------------------------- | |
1013 void IfNode::dominated_by( Node *prev_dom, PhaseIterGVN *igvn ) { | |
1014 igvn->hash_delete(this); // Remove self to prevent spurious V-N | |
1015 Node *idom = in(0); | |
1016 // Need opcode to decide which way 'this' test goes | |
1017 int prev_op = prev_dom->Opcode(); | |
1018 Node *top = igvn->C->top(); // Shortcut to top | |
1019 | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1020 // Loop predicates may have depending checks which should not |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1021 // be skipped. For example, range check predicate has two checks |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1022 // for lower and upper bounds. |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1023 ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj(); |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1024 if (PhaseIdealLoop::is_uncommon_trap_proj(unc_proj, Deoptimization::Reason_predicate)) |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1025 prev_dom = idom; |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1026 |
0 | 1027 // Now walk the current IfNode's projections. |
1028 // Loop ends when 'this' has no more uses. | |
1029 for (DUIterator_Last imin, i = last_outs(imin); i >= imin; --i) { | |
1030 Node *ifp = last_out(i); // Get IfTrue/IfFalse | |
1031 igvn->add_users_to_worklist(ifp); | |
1032 // Check which projection it is and set target. | |
1033 // Data-target is either the dominating projection of the same type | |
1034 // or TOP if the dominating projection is of opposite type. | |
1035 // Data-target will be used as the new control edge for the non-CFG | |
1036 // nodes like Casts and Loads. | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1037 Node *data_target = (ifp->Opcode() == prev_op) ? prev_dom : top; |
0 | 1038 // Control-target is just the If's immediate dominator or TOP. |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1039 Node *ctrl_target = (ifp->Opcode() == prev_op) ? idom : top; |
0 | 1040 |
1041 // For each child of an IfTrue/IfFalse projection, reroute. | |
1042 // Loop ends when projection has no more uses. | |
1043 for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) { | |
1044 Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse | |
1045 igvn->hash_delete(s); // Yank from hash table before edge hacking | |
1046 if( !s->depends_only_on_test() ) { | |
1047 // Find the control input matching this def-use edge. | |
1048 // For Regions it may not be in slot 0. | |
1049 uint l; | |
1050 for( l = 0; s->in(l) != ifp; l++ ) { } | |
1051 s->set_req(l, ctrl_target); | |
1052 } else { // Else, for control producers, | |
1053 s->set_req(0, data_target); // Move child to data-target | |
1054 } | |
1055 igvn->_worklist.push(s); // Revisit collapsed Phis | |
1056 } // End for each child of a projection | |
1057 | |
1058 igvn->remove_dead_node(ifp); | |
1059 } // End for each IfTrue/IfFalse child of If | |
1060 | |
1061 // Kill the IfNode | |
1062 igvn->remove_dead_node(this); | |
1063 } | |
1064 | |
1065 //------------------------------Identity--------------------------------------- | |
1066 // If the test is constant & we match, then we are the input Control | |
1067 Node *IfTrueNode::Identity( PhaseTransform *phase ) { | |
1068 // Can only optimize if cannot go the other way | |
1069 const TypeTuple *t = phase->type(in(0))->is_tuple(); | |
1070 return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE ) | |
1071 ? in(0)->in(0) // IfNode control | |
1072 : this; // no progress | |
1073 } | |
1074 | |
1075 //------------------------------dump_spec-------------------------------------- | |
1076 #ifndef PRODUCT | |
1077 void IfNode::dump_spec(outputStream *st) const { | |
1078 st->print("P=%f, C=%f",_prob,_fcnt); | |
1079 } | |
1080 #endif | |
1081 | |
1082 //------------------------------idealize_test---------------------------------- | |
1083 // Try to canonicalize tests better. Peek at the Cmp/Bool/If sequence and | |
1084 // come up with a canonical sequence. Bools getting 'eq', 'gt' and 'ge' forms | |
1085 // converted to 'ne', 'le' and 'lt' forms. IfTrue/IfFalse get swapped as | |
1086 // needed. | |
1087 static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) { | |
1088 assert(iff->in(0) != NULL, "If must be live"); | |
1089 | |
1090 if (iff->outcnt() != 2) return NULL; // Malformed projections. | |
1091 Node* old_if_f = iff->proj_out(false); | |
1092 Node* old_if_t = iff->proj_out(true); | |
1093 | |
1094 // CountedLoopEnds want the back-control test to be TRUE, irregardless of | |
1095 // whether they are testing a 'gt' or 'lt' condition. The 'gt' condition | |
1096 // happens in count-down loops | |
1097 if (iff->is_CountedLoopEnd()) return NULL; | |
1098 if (!iff->in(1)->is_Bool()) return NULL; // Happens for partially optimized IF tests | |
1099 BoolNode *b = iff->in(1)->as_Bool(); | |
1100 BoolTest bt = b->_test; | |
1101 // Test already in good order? | |
1102 if( bt.is_canonical() ) | |
1103 return NULL; | |
1104 | |
1105 // Flip test to be canonical. Requires flipping the IfFalse/IfTrue and | |
1106 // cloning the IfNode. | |
1107 Node* new_b = phase->transform( new (phase->C, 2) BoolNode(b->in(1), bt.negate()) ); | |
1108 if( !new_b->is_Bool() ) return NULL; | |
1109 b = new_b->as_Bool(); | |
1110 | |
1111 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
1112 assert( igvn, "Test is not canonical in parser?" ); | |
1113 | |
1114 // The IF node never really changes, but it needs to be cloned | |
1115 iff = new (phase->C, 2) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); | |
1116 | |
1117 Node *prior = igvn->hash_find_insert(iff); | |
1118 if( prior ) { | |
1119 igvn->remove_dead_node(iff); | |
1120 iff = (IfNode*)prior; | |
1121 } else { | |
1122 // Cannot call transform on it just yet | |
1123 igvn->set_type_bottom(iff); | |
1124 } | |
1125 igvn->_worklist.push(iff); | |
1126 | |
1127 // Now handle projections. Cloning not required. | |
1128 Node* new_if_f = (Node*)(new (phase->C, 1) IfFalseNode( iff )); | |
1129 Node* new_if_t = (Node*)(new (phase->C, 1) IfTrueNode ( iff )); | |
1130 | |
1131 igvn->register_new_node_with_optimizer(new_if_f); | |
1132 igvn->register_new_node_with_optimizer(new_if_t); | |
1133 // Flip test, so flip trailing control | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
1134 igvn->replace_node(old_if_f, new_if_t); |
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
1135 igvn->replace_node(old_if_t, new_if_f); |
0 | 1136 |
1137 // Progress | |
1138 return iff; | |
1139 } | |
1140 | |
1141 //------------------------------Identity--------------------------------------- | |
1142 // If the test is constant & we match, then we are the input Control | |
1143 Node *IfFalseNode::Identity( PhaseTransform *phase ) { | |
1144 // Can only optimize if cannot go the other way | |
1145 const TypeTuple *t = phase->type(in(0))->is_tuple(); | |
1146 return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE ) | |
1147 ? in(0)->in(0) // IfNode control | |
1148 : this; // no progress | |
1149 } |