Mercurial > hg > truffle
annotate src/share/vm/opto/ifnode.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 |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6804
diff
changeset
|
2 * Copyright (c) 2000, 2012, 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 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
241 Node *region_c = new (igvn->C) RegionNode(req_c + 1); |
0 | 242 Node *phi_c = con1; |
243 uint len = r->req(); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
244 Node *region_x = new (igvn->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. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
275 Node *hook = new (igvn->C) Node(4); |
0 | 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 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
287 Node *b_c = phase->transform(new (igvn->C) BoolNode(cmp_c,b->_test._test)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
288 Node *b_x = phase->transform(new (igvn->C) BoolNode(cmp_x,b->_test._test)); |
0 | 289 // Make the IfNode |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
290 IfNode *iff_c = new (igvn->C) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); |
0 | 291 igvn->set_type_bottom(iff_c); |
292 igvn->_worklist.push(iff_c); | |
293 hook->init_req(2, iff_c); | |
294 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
295 IfNode *iff_x = new (igvn->C) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); |
0 | 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 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
301 Node *iff_c_t = phase->transform(new (igvn->C) IfTrueNode (iff_c)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
302 Node *iff_c_f = phase->transform(new (igvn->C) 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 } |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
309 Node *iff_x_t = phase->transform(new (igvn->C) IfTrueNode (iff_x)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
310 Node *iff_x_f = phase->transform(new (igvn->C) 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 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
319 Node *region_s = new (igvn->C) RegionNode(3); |
0 | 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 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
326 Node *region_f = new (igvn->C) RegionNode(3); |
0 | 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 | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3845
diff
changeset
|
341 igvn->rehash_node_delayed(v); // Have to fixup other Phi users |
0 | 342 uint vop = v->Opcode(); |
343 Node *proj = NULL; | |
344 if( vop == Op_Phi ) { // Remote merge point | |
345 Node *r = v->in(0); | |
346 for (uint i3 = 1; i3 < r->req(); i3++) | |
347 if (r->in(i3) && r->in(i3)->in(0) == iff) { | |
348 proj = r->in(i3); | |
349 break; | |
350 } | |
351 } else if( v->is_ConstraintCast() ) { | |
352 proj = v->in(0); // Controlling projection | |
353 } else { | |
354 assert( 0, "do not know how to handle this guy" ); | |
355 } | |
356 | |
357 Node *proj_path_data, *proj_path_ctrl; | |
358 if( proj->Opcode() == Op_IfTrue ) { | |
359 if( phi_s == NULL ) { | |
360 // Only construct phi_s if needed, otherwise provides | |
361 // interfering use. | |
362 phi_s = PhiNode::make_blank(region_s,phi); | |
363 phi_s->init_req( 1, phi_c ); | |
364 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
|
365 hook->add_req(phi_s); |
0 | 366 phi_s = phase->transform(phi_s); |
367 } | |
368 proj_path_data = phi_s; | |
369 proj_path_ctrl = region_s; | |
370 } else { | |
371 if( phi_f == NULL ) { | |
372 // Only construct phi_f if needed, otherwise provides | |
373 // interfering use. | |
374 phi_f = PhiNode::make_blank(region_f,phi); | |
375 phi_f->init_req( 1, phi_c ); | |
376 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
|
377 hook->add_req(phi_f); |
0 | 378 phi_f = phase->transform(phi_f); |
379 } | |
380 proj_path_data = phi_f; | |
381 proj_path_ctrl = region_f; | |
382 } | |
383 | |
384 // Fixup 'v' for for the split | |
385 if( vop == Op_Phi ) { // Remote merge point | |
386 uint i; | |
387 for( i = 1; i < v->req(); i++ ) | |
388 if( v->in(i) == phi ) | |
389 break; | |
390 v->set_req(i, proj_path_data ); | |
391 } else if( v->is_ConstraintCast() ) { | |
392 v->set_req(0, proj_path_ctrl ); | |
393 v->set_req(1, proj_path_data ); | |
394 } else | |
395 ShouldNotReachHere(); | |
396 } | |
397 | |
398 // Now replace the original iff's True/False with region_s/region_t. | |
399 // This makes the original iff go dead. | |
400 for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) { | |
401 Node* p = iff->last_out(i3); | |
402 assert( p->Opcode() == Op_IfTrue || p->Opcode() == Op_IfFalse, "" ); | |
403 Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f; | |
404 // Replace p with u | |
405 igvn->add_users_to_worklist(p); | |
406 for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { | |
407 Node* x = p->last_out(l); | |
408 igvn->hash_delete(x); | |
409 uint uses_found = 0; | |
410 for( uint j = 0; j < x->req(); j++ ) { | |
411 if( x->in(j) == p ) { | |
412 x->set_req(j, u); | |
413 uses_found++; | |
414 } | |
415 } | |
416 l -= uses_found; // we deleted 1 or more copies of this edge | |
417 } | |
418 igvn->remove_dead_node(p); | |
419 } | |
420 | |
421 // Force the original merge dead | |
422 igvn->hash_delete(r); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
423 // First, remove region's dead users. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
424 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
|
425 Node* u = r->last_out(l); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
426 if( u == r ) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
427 r->set_req(0, NULL); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
428 } else { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
429 assert(u->outcnt() == 0, "only dead users"); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
430 igvn->remove_dead_node(u); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
431 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
432 l -= 1; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
433 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
605
diff
changeset
|
434 igvn->remove_dead_node(r); |
0 | 435 |
436 // Now remove the bogus extra edges used to keep things alive | |
437 igvn->remove_dead_node( hook ); | |
438 | |
439 // Must return either the original node (now dead) or a new node | |
440 // (Do not return a top here, since that would break the uniqueness of top.) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
441 return new (igvn->C) ConINode(TypeInt::ZERO); |
0 | 442 } |
443 | |
444 //------------------------------is_range_check--------------------------------- | |
445 // Return 0 if not a range check. Return 1 if a range check and set index and | |
446 // offset. Return 2 if we had to negate the test. Index is NULL if the check | |
447 // is versus a constant. | |
448 int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) { | |
449 Node* b = in(1); | |
450 if (b == NULL || !b->is_Bool()) return 0; | |
451 BoolNode* bn = b->as_Bool(); | |
452 Node* cmp = bn->in(1); | |
453 if (cmp == NULL) return 0; | |
454 if (cmp->Opcode() != Op_CmpU) return 0; | |
455 | |
456 Node* l = cmp->in(1); | |
457 Node* r = cmp->in(2); | |
458 int flip_test = 1; | |
459 if (bn->_test._test == BoolTest::le) { | |
460 l = cmp->in(2); | |
461 r = cmp->in(1); | |
462 flip_test = 2; | |
463 } else if (bn->_test._test != BoolTest::lt) { | |
464 return 0; | |
465 } | |
466 if (l->is_top()) return 0; // Top input means dead test | |
467 if (r->Opcode() != Op_LoadRange) return 0; | |
468 | |
469 // We have recognized one of these forms: | |
470 // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... | |
471 // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ... | |
472 | |
473 // Make sure it's a real range check by requiring an uncommon trap | |
474 // along the OOB path. Otherwise, it's possible that the user wrote | |
475 // something which optimized to look like a range check but behaves | |
476 // in some other way. | |
477 Node* iftrap = proj_out(flip_test == 2 ? true : false); | |
478 bool found_trap = false; | |
479 if (iftrap != NULL) { | |
480 Node* u = iftrap->unique_ctrl_out(); | |
481 if (u != NULL) { | |
482 // It could be a merge point (Region) for uncommon trap. | |
483 if (u->is_Region()) { | |
484 Node* c = u->unique_ctrl_out(); | |
485 if (c != NULL) { | |
486 iftrap = u; | |
487 u = c; | |
488 } | |
489 } | |
490 if (u->in(0) == iftrap && u->is_CallStaticJava()) { | |
491 int req = u->as_CallStaticJava()->uncommon_trap_request(); | |
492 if (Deoptimization::trap_request_reason(req) == | |
493 Deoptimization::Reason_range_check) { | |
494 found_trap = true; | |
495 } | |
496 } | |
497 } | |
498 } | |
499 if (!found_trap) return 0; // sorry, no cigar | |
500 | |
501 // Look for index+offset form | |
502 Node* ind = l; | |
503 jint off = 0; | |
504 if (l->is_top()) { | |
505 return 0; | |
506 } else if (l->is_Add()) { | |
507 if ((off = l->in(1)->find_int_con(0)) != 0) { | |
508 ind = l->in(2); | |
509 } else if ((off = l->in(2)->find_int_con(0)) != 0) { | |
510 ind = l->in(1); | |
511 } | |
512 } else if ((off = l->find_int_con(-1)) >= 0) { | |
513 // constant offset with no variable index | |
514 ind = NULL; | |
515 } else { | |
516 // variable index with no constant offset (or dead negative index) | |
517 off = 0; | |
518 } | |
519 | |
520 // Return all the values: | |
521 index = ind; | |
522 offset = off; | |
523 range = r; | |
524 return flip_test; | |
525 } | |
526 | |
527 //------------------------------adjust_check----------------------------------- | |
528 // Adjust (widen) a prior range check | |
529 static void adjust_check(Node* proj, Node* range, Node* index, | |
530 int flip, jint off_lo, PhaseIterGVN* igvn) { | |
531 PhaseGVN *gvn = igvn; | |
532 // Break apart the old check | |
533 Node *iff = proj->in(0); | |
534 Node *bol = iff->in(1); | |
535 if( bol->is_top() ) return; // In case a partially dead range check appears | |
536 // bail (or bomb[ASSERT/DEBUG]) if NOT projection-->IfNode-->BoolNode | |
537 DEBUG_ONLY( if( !bol->is_Bool() ) { proj->dump(3); fatal("Expect projection-->IfNode-->BoolNode"); } ) | |
538 if( !bol->is_Bool() ) return; | |
539 | |
540 Node *cmp = bol->in(1); | |
541 // Compute a new check | |
542 Node *new_add = gvn->intcon(off_lo); | |
543 if( index ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
544 new_add = off_lo ? gvn->transform(new (gvn->C) AddINode( index, new_add )) : index; |
0 | 545 } |
546 Node *new_cmp = (flip == 1) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
547 ? new (gvn->C) CmpUNode( new_add, range ) |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
548 : new (gvn->C) CmpUNode( range, new_add ); |
0 | 549 new_cmp = gvn->transform(new_cmp); |
550 // See if no need to adjust the existing check | |
551 if( new_cmp == cmp ) return; | |
552 // Else, adjust existing check | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
553 Node *new_bol = gvn->transform( new (gvn->C) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3845
diff
changeset
|
554 igvn->rehash_node_delayed( iff ); |
0 | 555 iff->set_req_X( 1, new_bol, igvn ); |
556 } | |
557 | |
558 //------------------------------up_one_dom------------------------------------- | |
559 // Walk up the dominator tree one step. Return NULL at root or true | |
560 // complex merges. Skips through small diamonds. | |
561 Node* IfNode::up_one_dom(Node *curr, bool linear_only) { | |
562 Node *dom = curr->in(0); | |
563 if( !dom ) // Found a Region degraded to a copy? | |
564 return curr->nonnull_req(); // Skip thru it | |
565 | |
566 if( curr != dom ) // Normal walk up one step? | |
567 return dom; | |
568 | |
569 // Use linear_only if we are still parsing, since we cannot | |
570 // trust the regions to be fully filled in. | |
571 if (linear_only) | |
572 return NULL; | |
573 | |
1153
bea7a22a6f79
6915110: IfNode::up_one_dom moves beyond RootNode bug in src/share/vm/opto/ifnode.cpp
kvn
parents:
1017
diff
changeset
|
574 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
|
575 return NULL; |
bea7a22a6f79
6915110: IfNode::up_one_dom moves beyond RootNode bug in src/share/vm/opto/ifnode.cpp
kvn
parents:
1017
diff
changeset
|
576 |
0 | 577 // Else hit a Region. Check for a loop header |
578 if( dom->is_Loop() ) | |
579 return dom->in(1); // Skip up thru loops | |
580 | |
581 // Check for small diamonds | |
582 Node *din1, *din2, *din3, *din4; | |
583 if( dom->req() == 3 && // 2-path merge point | |
584 (din1 = dom ->in(1)) && // Left path exists | |
585 (din2 = dom ->in(2)) && // Right path exists | |
586 (din3 = din1->in(0)) && // Left path up one | |
587 (din4 = din2->in(0)) ) { // Right path up one | |
588 if( din3->is_Call() && // Handle a slow-path call on either arm | |
589 (din3 = din3->in(0)) ) | |
590 din3 = din3->in(0); | |
591 if( din4->is_Call() && // Handle a slow-path call on either arm | |
592 (din4 = din4->in(0)) ) | |
593 din4 = din4->in(0); | |
594 if( din3 == din4 && din3->is_If() ) | |
595 return din3; // Skip around diamonds | |
596 } | |
597 | |
598 // Give up the search at true merges | |
599 return NULL; // Dead loop? Or hit root? | |
600 } | |
601 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
602 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
603 //------------------------------filtered_int_type-------------------------------- |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
604 // 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
|
605 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
|
606 assert(if_proj && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
607 (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
|
608 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
|
609 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
|
610 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
|
611 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
|
612 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
|
613 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
|
614 if (cmp->in(1) == val) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
615 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
|
616 if (cmp2_t != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
617 jint lo = cmp2_t->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
618 jint hi = cmp2_t->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
619 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
|
620 switch (msk) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
621 case BoolTest::ne: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
622 // Can't refine type |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
623 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
624 case BoolTest::eq: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
625 return cmp2_t; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
626 case BoolTest::lt: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
627 lo = TypeInt::INT->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
628 if (hi - 1 < hi) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
629 hi = hi - 1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
630 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
631 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
632 case BoolTest::le: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
633 lo = TypeInt::INT->_lo; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
634 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
635 case BoolTest::gt: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
636 if (lo + 1 > lo) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
637 lo = lo + 1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
638 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
639 hi = TypeInt::INT->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
640 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
641 case BoolTest::ge: |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
642 // lo unchanged |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
643 hi = TypeInt::INT->_hi; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
644 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
645 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
646 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
|
647 return rtn_t; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
648 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
649 } |
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 return NULL; |
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 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
656 //------------------------------fold_compares---------------------------- |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
657 // See if a pair of CmpIs can be converted into a CmpU. In some cases |
605 | 658 // 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
|
659 // 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
|
660 // 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
|
661 // 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
|
662 // 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
|
663 // projections. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
664 // |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
665 // If |
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 // / | |
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 // If | |
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 // / \ | |
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 // / Region |
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 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
|
676 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
|
677 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
678 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
|
679 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
|
680 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
|
681 Node* ctrl = in(0); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
682 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
|
683 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
|
684 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
|
685 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
|
686 ctrl->in(0)->is_If() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
687 ctrl->in(0)->outcnt() == 2 && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
688 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
|
689 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
|
690 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
|
691 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
|
692 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
|
693 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
|
694 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
|
695 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
|
696 // 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
|
697 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
|
698 Node* success = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
699 Node* fail = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
700 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
|
701 Node* proj = proj_out(i); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
702 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
|
703 success = proj; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
704 } else if (fail == NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
705 fail = proj; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
706 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
707 success = fail = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
708 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
709 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
710 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
|
711 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
|
712 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
|
713 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
|
714 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
|
715 if (failtype != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
716 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
|
717 if (type2 != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
718 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
|
719 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
720 failtype = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
721 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
722 } |
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 if (failtype != NULL && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
725 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
|
726 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
|
727 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
|
728 // 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
|
729 BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
730 Node* adjusted = phase->transform(new (phase->C) SubINode(n, phase->intcon(failtype->_lo))); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
731 Node* newcmp = phase->transform(new (phase->C) CmpUNode(adjusted, phase->intcon(bound))); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
732 Node* newbool = phase->transform(new (phase->C) BoolNode(newcmp, cond)); |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3845
diff
changeset
|
733 phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
734 phase->hash_delete(this); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
735 set_req(1, newbool); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
736 return this; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
737 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
738 if (failtype->_lo > failtype->_hi) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
739 // 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
|
740 // replace Bool with constant |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
741 phase->hash_delete(this); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
742 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
|
743 return this; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
744 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
745 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
746 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
747 } |
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 return NULL; |
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 |
0 | 753 //------------------------------remove_useless_bool---------------------------- |
754 // Check for people making a useless boolean: things like | |
755 // if( (x < y ? true : false) ) { ... } | |
756 // Replace with if( x < y ) { ... } | |
757 static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) { | |
758 Node *i1 = iff->in(1); | |
759 if( !i1->is_Bool() ) return NULL; | |
760 BoolNode *bol = i1->as_Bool(); | |
761 | |
762 Node *cmp = bol->in(1); | |
763 if( cmp->Opcode() != Op_CmpI ) return NULL; | |
764 | |
765 // Must be comparing against a bool | |
766 const Type *cmp2_t = phase->type( cmp->in(2) ); | |
767 if( cmp2_t != TypeInt::ZERO && | |
768 cmp2_t != TypeInt::ONE ) | |
769 return NULL; | |
770 | |
771 // Find a prior merge point merging the boolean | |
772 i1 = cmp->in(1); | |
773 if( !i1->is_Phi() ) return NULL; | |
774 PhiNode *phi = i1->as_Phi(); | |
775 if( phase->type( phi ) != TypeInt::BOOL ) | |
776 return NULL; | |
777 | |
778 // Check for diamond pattern | |
779 int true_path = phi->is_diamond_phi(); | |
780 if( true_path == 0 ) return NULL; | |
781 | |
250
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
782 // 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
|
783 // 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
|
784 // an illegal cycle. |
6ca61c728c2d
6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents:
17
diff
changeset
|
785 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
|
786 |
0 | 787 // phi->region->if_proj->ifnode->bool->cmp |
788 BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool(); | |
789 | |
790 // Now get the 'sense' of the test correct so we can plug in | |
791 // either iff2->in(1) or its complement. | |
792 int flip = 0; | |
793 if( bol->_test._test == BoolTest::ne ) flip = 1-flip; | |
794 else if( bol->_test._test != BoolTest::eq ) return NULL; | |
795 if( cmp2_t == TypeInt::ZERO ) flip = 1-flip; | |
796 | |
797 const Type *phi1_t = phase->type( phi->in(1) ); | |
798 const Type *phi2_t = phase->type( phi->in(2) ); | |
799 // Check for Phi(0,1) and flip | |
800 if( phi1_t == TypeInt::ZERO ) { | |
801 if( phi2_t != TypeInt::ONE ) return NULL; | |
802 flip = 1-flip; | |
803 } else { | |
804 // Check for Phi(1,0) | |
805 if( phi1_t != TypeInt::ONE ) return NULL; | |
806 if( phi2_t != TypeInt::ZERO ) return NULL; | |
807 } | |
808 if( true_path == 2 ) { | |
809 flip = 1-flip; | |
810 } | |
811 | |
812 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
|
813 assert(new_bol != iff->in(1), "must make progress"); |
0 | 814 iff->set_req(1, new_bol); |
815 // Intervening diamond probably goes dead | |
816 phase->C->set_major_progress(); | |
817 return iff; | |
818 } | |
819 | |
820 static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff); | |
821 | |
822 //------------------------------Ideal------------------------------------------ | |
823 // Return a node which is more "ideal" than the current node. Strip out | |
824 // control copies | |
825 Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
826 if (remove_dead_region(phase, can_reshape)) return this; | |
827 // No Def-Use info? | |
828 if (!can_reshape) return NULL; | |
829 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
830 | |
831 // Don't bother trying to transform a dead if | |
832 if (in(0)->is_top()) return NULL; | |
833 // Don't bother trying to transform an if with a dead test | |
834 if (in(1)->is_top()) return NULL; | |
835 // Another variation of a dead test | |
836 if (in(1)->is_Con()) return NULL; | |
837 // Another variation of a dead if | |
838 if (outcnt() < 2) return NULL; | |
839 | |
840 // Canonicalize the test. | |
841 Node* idt_if = idealize_test(phase, this); | |
842 if (idt_if != NULL) return idt_if; | |
843 | |
844 // Try to split the IF | |
845 Node *s = split_if(this, igvn); | |
846 if (s != NULL) return s; | |
847 | |
848 // Check for people making a useless boolean: things like | |
849 // if( (x < y ? true : false) ) { ... } | |
850 // Replace with if( x < y ) { ... } | |
851 Node *bol2 = remove_useless_bool(this, phase); | |
852 if( bol2 ) return bol2; | |
853 | |
854 // Setup to scan up the CFG looking for a dominating test | |
855 Node *dom = in(0); | |
856 Node *prev_dom = this; | |
857 | |
858 // Check for range-check vs other kinds of tests | |
859 Node *index1, *range1; | |
860 jint offset1; | |
861 int flip1 = is_range_check(range1, index1, offset1); | |
862 if( flip1 ) { | |
863 Node *first_prev_dom = NULL; | |
864 | |
865 // Try to remove extra range checks. All 'up_one_dom' gives up at merges | |
866 // so all checks we inspect post-dominate the top-most check we find. | |
867 // If we are going to fail the current check and we reach the top check | |
605 | 868 // then we are guaranteed to fail, so just start interpreting there. |
0 | 869 // We 'expand' the top 2 range checks to include all post-dominating |
870 // checks. | |
871 | |
872 // The top 2 range checks seen | |
873 Node *prev_chk1 = NULL; | |
874 Node *prev_chk2 = NULL; | |
875 // Low and high offsets seen so far | |
876 jint off_lo = offset1; | |
877 jint off_hi = offset1; | |
878 | |
879 // Scan for the top 2 checks and collect range of offsets | |
880 for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit | |
881 if( dom->Opcode() == Op_If && // Not same opcode? | |
882 prev_dom->in(0) == dom ) { // One path of test does dominate? | |
883 if( dom == this ) return NULL; // dead loop | |
884 // See if this is a range check | |
885 Node *index2, *range2; | |
886 jint offset2; | |
887 int flip2 = dom->as_If()->is_range_check(range2, index2, offset2); | |
888 // See if this is a _matching_ range check, checking against | |
889 // the same array bounds. | |
890 if( flip2 == flip1 && range2 == range1 && index2 == index1 && | |
891 dom->outcnt() == 2 ) { | |
892 // Gather expanded bounds | |
893 off_lo = MIN2(off_lo,offset2); | |
894 off_hi = MAX2(off_hi,offset2); | |
895 // Record top 2 range checks | |
896 prev_chk2 = prev_chk1; | |
897 prev_chk1 = prev_dom; | |
898 // If we match the test exactly, then the top test covers | |
899 // both our lower and upper bounds. | |
900 if( dom->in(1) == in(1) ) | |
901 prev_chk2 = prev_chk1; | |
902 } | |
903 } | |
904 prev_dom = dom; | |
905 dom = up_one_dom( dom ); | |
906 if( !dom ) break; | |
907 } | |
908 | |
909 | |
910 // Attempt to widen the dominating range check to cover some later | |
911 // ones. Since range checks "fail" by uncommon-trapping to the | |
912 // interpreter, widening a check can make us speculative enter the | |
913 // interpreter. If we see range-check deopt's, do not widen! | |
914 if (!phase->C->allow_range_check_smearing()) return NULL; | |
915 | |
916 // Constant indices only need to check the upper bound. | |
917 // Non-constance indices must check both low and high. | |
918 if( index1 ) { | |
919 // Didn't find 2 prior covering checks, so cannot remove anything. | |
920 if( !prev_chk2 ) return NULL; | |
921 // 'Widen' the offsets of the 1st and 2nd covering check | |
922 adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn ); | |
923 // Do not call adjust_check twice on the same projection | |
924 // as the first call may have transformed the BoolNode to a ConI | |
925 if( prev_chk1 != prev_chk2 ) { | |
926 adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn ); | |
927 } | |
928 // Test is now covered by prior checks, dominate it out | |
929 prev_dom = prev_chk2; | |
930 } else { | |
931 // Didn't find prior covering check, so cannot remove anything. | |
932 if( !prev_chk1 ) return NULL; | |
933 // 'Widen' the offset of the 1st and only covering check | |
934 adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn ); | |
935 // Test is now covered by prior checks, dominate it out | |
936 prev_dom = prev_chk1; | |
937 } | |
938 | |
939 | |
940 } else { // Scan for an equivalent test | |
941 | |
942 Node *cmp; | |
943 int dist = 0; // Cutoff limit for search | |
944 int op = Opcode(); | |
945 if( op == Op_If && | |
946 (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) { | |
947 if( cmp->in(2) != NULL && // make sure cmp is not already dead | |
948 cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) { | |
949 dist = 64; // Limit for null-pointer scans | |
950 } else { | |
951 dist = 4; // Do not bother for random pointer tests | |
952 } | |
953 } else { | |
954 dist = 4; // Limit for random junky scans | |
955 } | |
956 | |
957 // Normal equivalent-test check. | |
958 if( !dom ) return NULL; // Dead loop? | |
959 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
960 Node* result = fold_compares(phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
961 if (result != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
962 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
963 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
964 |
0 | 965 // Search up the dominator tree for an If with an identical test |
966 while( dom->Opcode() != op || // Not same opcode? | |
967 dom->in(1) != in(1) || // Not same input 1? | |
968 (req() == 3 && dom->in(2) != in(2)) || // Not same input 2? | |
969 prev_dom->in(0) != dom ) { // One path of test does not dominate? | |
970 if( dist < 0 ) return NULL; | |
971 | |
972 dist--; | |
973 prev_dom = dom; | |
974 dom = up_one_dom( dom ); | |
975 if( !dom ) return NULL; | |
976 } | |
977 | |
978 // Check that we did not follow a loop back to ourselves | |
979 if( this == dom ) | |
980 return NULL; | |
981 | |
982 if( dist > 2 ) // Add to count of NULL checks elided | |
983 explicit_null_checks_elided++; | |
984 | |
985 } // End of Else scan for an equivalent test | |
986 | |
987 // Hit! Remove this IF | |
988 #ifndef PRODUCT | |
989 if( TraceIterativeGVN ) { | |
990 tty->print(" Removing IfNode: "); this->dump(); | |
991 } | |
992 if( VerifyOpto && !phase->allow_progress() ) { | |
993 // Found an equivalent dominating test, | |
994 // we can not guarantee reaching a fix-point for these during iterativeGVN | |
995 // since intervening nodes may not change. | |
996 return NULL; | |
997 } | |
998 #endif | |
999 | |
1000 // Replace dominated IfNode | |
1001 dominated_by( prev_dom, igvn ); | |
1002 | |
1003 // Must return either the original node (now dead) or a new node | |
1004 // (Do not return a top here, since that would break the uniqueness of top.) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
1005 return new (phase->C) ConINode(TypeInt::ZERO); |
0 | 1006 } |
1007 | |
1008 //------------------------------dominated_by----------------------------------- | |
1009 void IfNode::dominated_by( Node *prev_dom, PhaseIterGVN *igvn ) { | |
1010 igvn->hash_delete(this); // Remove self to prevent spurious V-N | |
1011 Node *idom = in(0); | |
1012 // Need opcode to decide which way 'this' test goes | |
1013 int prev_op = prev_dom->Opcode(); | |
1014 Node *top = igvn->C->top(); // Shortcut to top | |
1015 | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1016 // Loop predicates may have depending checks which should not |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1017 // be skipped. For example, range check predicate has two checks |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1018 // for lower and upper bounds. |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1019 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
|
1020 if (PhaseIdealLoop::is_uncommon_trap_proj(unc_proj, Deoptimization::Reason_predicate)) |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1021 prev_dom = idom; |
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1022 |
0 | 1023 // Now walk the current IfNode's projections. |
1024 // Loop ends when 'this' has no more uses. | |
1025 for (DUIterator_Last imin, i = last_outs(imin); i >= imin; --i) { | |
1026 Node *ifp = last_out(i); // Get IfTrue/IfFalse | |
1027 igvn->add_users_to_worklist(ifp); | |
1028 // Check which projection it is and set target. | |
1029 // Data-target is either the dominating projection of the same type | |
1030 // or TOP if the dominating projection is of opposite type. | |
1031 // Data-target will be used as the new control edge for the non-CFG | |
1032 // nodes like Casts and Loads. | |
3840
4e761e7e6e12
7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents:
3348
diff
changeset
|
1033 Node *data_target = (ifp->Opcode() == prev_op) ? prev_dom : top; |
0 | 1034 // 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
|
1035 Node *ctrl_target = (ifp->Opcode() == prev_op) ? idom : top; |
0 | 1036 |
1037 // For each child of an IfTrue/IfFalse projection, reroute. | |
1038 // Loop ends when projection has no more uses. | |
1039 for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) { | |
1040 Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse | |
1041 if( !s->depends_only_on_test() ) { | |
1042 // Find the control input matching this def-use edge. | |
1043 // For Regions it may not be in slot 0. | |
1044 uint l; | |
1045 for( l = 0; s->in(l) != ifp; l++ ) { } | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3845
diff
changeset
|
1046 igvn->replace_input_of(s, l, ctrl_target); |
0 | 1047 } else { // Else, for control producers, |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
3845
diff
changeset
|
1048 igvn->replace_input_of(s, 0, data_target); // Move child to data-target |
0 | 1049 } |
1050 } // End for each child of a projection | |
1051 | |
1052 igvn->remove_dead_node(ifp); | |
1053 } // End for each IfTrue/IfFalse child of If | |
1054 | |
1055 // Kill the IfNode | |
1056 igvn->remove_dead_node(this); | |
1057 } | |
1058 | |
1059 //------------------------------Identity--------------------------------------- | |
1060 // If the test is constant & we match, then we are the input Control | |
1061 Node *IfTrueNode::Identity( PhaseTransform *phase ) { | |
1062 // Can only optimize if cannot go the other way | |
1063 const TypeTuple *t = phase->type(in(0))->is_tuple(); | |
1064 return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE ) | |
1065 ? in(0)->in(0) // IfNode control | |
1066 : this; // no progress | |
1067 } | |
1068 | |
1069 //------------------------------dump_spec-------------------------------------- | |
1070 #ifndef PRODUCT | |
1071 void IfNode::dump_spec(outputStream *st) const { | |
1072 st->print("P=%f, C=%f",_prob,_fcnt); | |
1073 } | |
1074 #endif | |
1075 | |
1076 //------------------------------idealize_test---------------------------------- | |
1077 // Try to canonicalize tests better. Peek at the Cmp/Bool/If sequence and | |
1078 // come up with a canonical sequence. Bools getting 'eq', 'gt' and 'ge' forms | |
1079 // converted to 'ne', 'le' and 'lt' forms. IfTrue/IfFalse get swapped as | |
1080 // needed. | |
1081 static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) { | |
1082 assert(iff->in(0) != NULL, "If must be live"); | |
1083 | |
1084 if (iff->outcnt() != 2) return NULL; // Malformed projections. | |
1085 Node* old_if_f = iff->proj_out(false); | |
1086 Node* old_if_t = iff->proj_out(true); | |
1087 | |
1088 // CountedLoopEnds want the back-control test to be TRUE, irregardless of | |
1089 // whether they are testing a 'gt' or 'lt' condition. The 'gt' condition | |
1090 // happens in count-down loops | |
1091 if (iff->is_CountedLoopEnd()) return NULL; | |
1092 if (!iff->in(1)->is_Bool()) return NULL; // Happens for partially optimized IF tests | |
1093 BoolNode *b = iff->in(1)->as_Bool(); | |
1094 BoolTest bt = b->_test; | |
1095 // Test already in good order? | |
1096 if( bt.is_canonical() ) | |
1097 return NULL; | |
1098 | |
1099 // Flip test to be canonical. Requires flipping the IfFalse/IfTrue and | |
1100 // cloning the IfNode. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
1101 Node* new_b = phase->transform( new (phase->C) BoolNode(b->in(1), bt.negate()) ); |
0 | 1102 if( !new_b->is_Bool() ) return NULL; |
1103 b = new_b->as_Bool(); | |
1104 | |
1105 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
1106 assert( igvn, "Test is not canonical in parser?" ); | |
1107 | |
1108 // The IF node never really changes, but it needs to be cloned | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
1109 iff = new (phase->C) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); |
0 | 1110 |
1111 Node *prior = igvn->hash_find_insert(iff); | |
1112 if( prior ) { | |
1113 igvn->remove_dead_node(iff); | |
1114 iff = (IfNode*)prior; | |
1115 } else { | |
1116 // Cannot call transform on it just yet | |
1117 igvn->set_type_bottom(iff); | |
1118 } | |
1119 igvn->_worklist.push(iff); | |
1120 | |
1121 // Now handle projections. Cloning not required. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
1122 Node* new_if_f = (Node*)(new (phase->C) IfFalseNode( iff )); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6144
diff
changeset
|
1123 Node* new_if_t = (Node*)(new (phase->C) IfTrueNode ( iff )); |
0 | 1124 |
1125 igvn->register_new_node_with_optimizer(new_if_f); | |
1126 igvn->register_new_node_with_optimizer(new_if_t); | |
1127 // 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
|
1128 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
|
1129 igvn->replace_node(old_if_t, new_if_f); |
0 | 1130 |
1131 // Progress | |
1132 return iff; | |
1133 } | |
1134 | |
1135 //------------------------------Identity--------------------------------------- | |
1136 // If the test is constant & we match, then we are the input Control | |
1137 Node *IfFalseNode::Identity( PhaseTransform *phase ) { | |
1138 // Can only optimize if cannot go the other way | |
1139 const TypeTuple *t = phase->type(in(0))->is_tuple(); | |
1140 return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE ) | |
1141 ? in(0)->in(0) // IfNode control | |
1142 : this; // no progress | |
1143 } |