1
|
1 |
/*
|
|
2 |
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation.
|
|
8 |
*
|
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
13 |
* accompanied this code).
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License version
|
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 |
*
|
|
19 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 |
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 |
* have any questions.
|
|
22 |
*
|
|
23 |
*/
|
|
24 |
|
|
25 |
// Portions of code courtesy of Clifford Click
|
|
26 |
|
|
27 |
// Optimization - Graph Style
|
|
28 |
|
|
29 |
#include "incls/_precompiled.incl"
|
|
30 |
#include "incls/_ifnode.cpp.incl"
|
|
31 |
|
|
32 |
|
|
33 |
extern int explicit_null_checks_elided;
|
|
34 |
|
|
35 |
//=============================================================================
|
|
36 |
//------------------------------Value------------------------------------------
|
|
37 |
// Return a tuple for whichever arm of the IF is reachable
|
|
38 |
const Type *IfNode::Value( PhaseTransform *phase ) const {
|
|
39 |
if( !in(0) ) return Type::TOP;
|
|
40 |
if( phase->type(in(0)) == Type::TOP )
|
|
41 |
return Type::TOP;
|
|
42 |
const Type *t = phase->type(in(1));
|
|
43 |
if( t == Type::TOP ) // data is undefined
|
|
44 |
return TypeTuple::IFNEITHER; // unreachable altogether
|
|
45 |
if( t == TypeInt::ZERO ) // zero, or false
|
|
46 |
return TypeTuple::IFFALSE; // only false branch is reachable
|
|
47 |
if( t == TypeInt::ONE ) // 1, or true
|
|
48 |
return TypeTuple::IFTRUE; // only true branch is reachable
|
|
49 |
assert( t == TypeInt::BOOL, "expected boolean type" );
|
|
50 |
|
|
51 |
return TypeTuple::IFBOTH; // No progress
|
|
52 |
}
|
|
53 |
|
|
54 |
const RegMask &IfNode::out_RegMask() const {
|
|
55 |
return RegMask::Empty;
|
|
56 |
}
|
|
57 |
|
|
58 |
//------------------------------split_if---------------------------------------
|
|
59 |
// Look for places where we merge constants, then test on the merged value.
|
|
60 |
// If the IF test will be constant folded on the path with the constant, we
|
|
61 |
// win by splitting the IF to before the merge point.
|
|
62 |
static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
|
|
63 |
// I could be a lot more general here, but I'm trying to squeeze this
|
|
64 |
// in before the Christmas '98 break so I'm gonna be kinda restrictive
|
|
65 |
// on the patterns I accept. CNC
|
|
66 |
|
|
67 |
// Look for a compare of a constant and a merged value
|
|
68 |
Node *i1 = iff->in(1);
|
|
69 |
if( !i1->is_Bool() ) return NULL;
|
|
70 |
BoolNode *b = i1->as_Bool();
|
|
71 |
Node *cmp = b->in(1);
|
|
72 |
if( !cmp->is_Cmp() ) return NULL;
|
|
73 |
i1 = cmp->in(1);
|
|
74 |
if( i1 == NULL || !i1->is_Phi() ) return NULL;
|
|
75 |
PhiNode *phi = i1->as_Phi();
|
|
76 |
if( phi->is_copy() ) return NULL;
|
|
77 |
Node *con2 = cmp->in(2);
|
|
78 |
if( !con2->is_Con() ) return NULL;
|
|
79 |
// See that the merge point contains some constants
|
|
80 |
Node *con1=NULL;
|
|
81 |
uint i4;
|
|
82 |
for( i4 = 1; i4 < phi->req(); i4++ ) {
|
|
83 |
con1 = phi->in(i4);
|
|
84 |
if( !con1 ) return NULL; // Do not optimize partially collaped merges
|
|
85 |
if( con1->is_Con() ) break; // Found a constant
|
|
86 |
// Also allow null-vs-not-null checks
|
|
87 |
const TypePtr *tp = igvn->type(con1)->isa_ptr();
|
|
88 |
if( tp && tp->_ptr == TypePtr::NotNull )
|
|
89 |
break;
|
|
90 |
}
|
|
91 |
if( i4 >= phi->req() ) return NULL; // Found no constants
|
|
92 |
|
|
93 |
igvn->C->set_has_split_ifs(true); // Has chance for split-if
|
|
94 |
|
|
95 |
// Make sure that the compare can be constant folded away
|
|
96 |
Node *cmp2 = cmp->clone();
|
|
97 |
cmp2->set_req(1,con1);
|
|
98 |
cmp2->set_req(2,con2);
|
|
99 |
const Type *t = cmp2->Value(igvn);
|
|
100 |
// This compare is dead, so whack it!
|
|
101 |
igvn->remove_dead_node(cmp2);
|
|
102 |
if( !t->singleton() ) return NULL;
|
|
103 |
|
|
104 |
// No intervening control, like a simple Call
|
|
105 |
Node *r = iff->in(0);
|
|
106 |
if( !r->is_Region() ) return NULL;
|
|
107 |
if( phi->region() != r ) return NULL;
|
|
108 |
// No other users of the cmp/bool
|
|
109 |
if (b->outcnt() != 1 || cmp->outcnt() != 1) {
|
|
110 |
//tty->print_cr("many users of cmp/bool");
|
|
111 |
return NULL;
|
|
112 |
}
|
|
113 |
|
|
114 |
// Make sure we can determine where all the uses of merged values go
|
|
115 |
for (DUIterator_Fast jmax, j = r->fast_outs(jmax); j < jmax; j++) {
|
|
116 |
Node* u = r->fast_out(j);
|
|
117 |
if( u == r ) continue;
|
|
118 |
if( u == iff ) continue;
|
|
119 |
if( u->outcnt() == 0 ) continue; // use is dead & ignorable
|
|
120 |
if( !u->is_Phi() ) {
|
|
121 |
/*
|
|
122 |
if( u->is_Start() ) {
|
|
123 |
tty->print_cr("Region has inlined start use");
|
|
124 |
} else {
|
|
125 |
tty->print_cr("Region has odd use");
|
|
126 |
u->dump(2);
|
|
127 |
}*/
|
|
128 |
return NULL;
|
|
129 |
}
|
|
130 |
if( u != phi ) {
|
|
131 |
// CNC - do not allow any other merged value
|
|
132 |
//tty->print_cr("Merging another value");
|
|
133 |
//u->dump(2);
|
|
134 |
return NULL;
|
|
135 |
}
|
|
136 |
// Make sure we can account for all Phi uses
|
|
137 |
for (DUIterator_Fast kmax, k = u->fast_outs(kmax); k < kmax; k++) {
|
|
138 |
Node* v = u->fast_out(k); // User of the phi
|
|
139 |
// CNC - Allow only really simple patterns.
|
|
140 |
// In particular I disallow AddP of the Phi, a fairly common pattern
|
|
141 |
if( v == cmp ) continue; // The compare is OK
|
|
142 |
if( (v->is_ConstraintCast()) &&
|
|
143 |
v->in(0)->in(0) == iff )
|
|
144 |
continue; // CastPP/II of the IfNode is OK
|
|
145 |
// Disabled following code because I cannot tell if exactly one
|
|
146 |
// path dominates without a real dominator check. CNC 9/9/1999
|
|
147 |
//uint vop = v->Opcode();
|
|
148 |
//if( vop == Op_Phi ) { // Phi from another merge point might be OK
|
|
149 |
// Node *r = v->in(0); // Get controlling point
|
|
150 |
// if( !r ) return NULL; // Degraded to a copy
|
|
151 |
// // Find exactly one path in (either True or False doms, but not IFF)
|
|
152 |
// int cnt = 0;
|
|
153 |
// for( uint i = 1; i < r->req(); i++ )
|
|
154 |
// if( r->in(i) && r->in(i)->in(0) == iff )
|
|
155 |
// cnt++;
|
|
156 |
// if( cnt == 1 ) continue; // Exactly one of True or False guards Phi
|
|
157 |
//}
|
|
158 |
if( !v->is_Call() ) {
|
|
159 |
/*
|
|
160 |
if( v->Opcode() == Op_AddP ) {
|
|
161 |
tty->print_cr("Phi has AddP use");
|
|
162 |
} else if( v->Opcode() == Op_CastPP ) {
|
|
163 |
tty->print_cr("Phi has CastPP use");
|
|
164 |
} else if( v->Opcode() == Op_CastII ) {
|
|
165 |
tty->print_cr("Phi has CastII use");
|
|
166 |
} else {
|
|
167 |
tty->print_cr("Phi has use I cant be bothered with");
|
|
168 |
}
|
|
169 |
*/
|
|
170 |
}
|
|
171 |
return NULL;
|
|
172 |
|
|
173 |
/* CNC - Cut out all the fancy acceptance tests
|
|
174 |
// Can we clone this use when doing the transformation?
|
|
175 |
// If all uses are from Phis at this merge or constants, then YES.
|
|
176 |
if( !v->in(0) && v != cmp ) {
|
|
177 |
tty->print_cr("Phi has free-floating use");
|
|
178 |
v->dump(2);
|
|
179 |
return NULL;
|
|
180 |
}
|
|
181 |
for( uint l = 1; l < v->req(); l++ ) {
|
|
182 |
if( (!v->in(l)->is_Phi() || v->in(l)->in(0) != r) &&
|
|
183 |
!v->in(l)->is_Con() ) {
|
|
184 |
tty->print_cr("Phi has use");
|
|
185 |
v->dump(2);
|
|
186 |
return NULL;
|
|
187 |
} // End of if Phi-use input is neither Phi nor Constant
|
|
188 |
} // End of for all inputs to Phi-use
|
|
189 |
*/
|
|
190 |
} // End of for all uses of Phi
|
|
191 |
} // End of for all uses of Region
|
|
192 |
|
|
193 |
// Only do this if the IF node is in a sane state
|
|
194 |
if (iff->outcnt() != 2)
|
|
195 |
return NULL;
|
|
196 |
|
|
197 |
// Got a hit! Do the Mondo Hack!
|
|
198 |
//
|
|
199 |
//ABC a1c def ghi B 1 e h A C a c d f g i
|
|
200 |
// R - Phi - Phi - Phi Rc - Phi - Phi - Phi Rx - Phi - Phi - Phi
|
|
201 |
// cmp - 2 cmp - 2 cmp - 2
|
|
202 |
// bool bool_c bool_x
|
|
203 |
// if if_c if_x
|
|
204 |
// T F T F T F
|
|
205 |
// ..s.. ..t .. ..s.. ..t.. ..s.. ..t..
|
|
206 |
//
|
|
207 |
// Split the paths coming into the merge point into 2 seperate groups of
|
|
208 |
// merges. On the left will be all the paths feeding constants into the
|
|
209 |
// Cmp's Phi. On the right will be the remaining paths. The Cmp's Phi
|
|
210 |
// will fold up into a constant; this will let the Cmp fold up as well as
|
|
211 |
// all the control flow. Below the original IF we have 2 control
|
|
212 |
// dependent regions, 's' and 't'. Now we will merge the two paths
|
|
213 |
// just prior to 's' and 't' from the two IFs. At least 1 path (and quite
|
|
214 |
// likely 2 or more) will promptly constant fold away.
|
|
215 |
PhaseGVN *phase = igvn;
|
|
216 |
|
|
217 |
// Make a region merging constants and a region merging the rest
|
|
218 |
uint req_c = 0;
|
|
219 |
for (uint ii = 1; ii < r->req(); ii++) {
|
|
220 |
if( phi->in(ii) == con1 ) {
|
|
221 |
req_c++;
|
|
222 |
}
|
|
223 |
}
|
|
224 |
Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1);
|
|
225 |
Node *phi_c = con1;
|
|
226 |
uint len = r->req();
|
|
227 |
Node *region_x = new (igvn->C, len - req_c + 1) RegionNode(len - req_c + 1);
|
|
228 |
Node *phi_x = PhiNode::make_blank(region_x, phi);
|
|
229 |
for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
|
|
230 |
if( phi->in(i) == con1 ) {
|
|
231 |
region_c->init_req( i_c++, r ->in(i) );
|
|
232 |
} else {
|
|
233 |
region_x->init_req( i_x, r ->in(i) );
|
|
234 |
phi_x ->init_req( i_x++, phi->in(i) );
|
|
235 |
}
|
|
236 |
}
|
|
237 |
|
|
238 |
// Register the new RegionNodes but do not transform them. Cannot
|
|
239 |
// transform until the entire Region/Phi conglerate has been hacked
|
|
240 |
// as a single huge transform.
|
|
241 |
igvn->register_new_node_with_optimizer( region_c );
|
|
242 |
igvn->register_new_node_with_optimizer( region_x );
|
|
243 |
phi_x = phase->transform( phi_x );
|
|
244 |
// Prevent the untimely death of phi_x. Currently he has no uses. He is
|
|
245 |
// about to get one. If this only use goes away, then phi_x will look dead.
|
|
246 |
// However, he will be picking up some more uses down below.
|
|
247 |
Node *hook = new (igvn->C, 4) Node(4);
|
|
248 |
hook->init_req(0, phi_x);
|
|
249 |
hook->init_req(1, phi_c);
|
|
250 |
|
|
251 |
// Make the compare
|
|
252 |
Node *cmp_c = phase->makecon(t);
|
|
253 |
Node *cmp_x = cmp->clone();
|
|
254 |
cmp_x->set_req(1,phi_x);
|
|
255 |
cmp_x->set_req(2,con2);
|
|
256 |
cmp_x = phase->transform(cmp_x);
|
|
257 |
// Make the bool
|
|
258 |
Node *b_c = phase->transform(new (igvn->C, 2) BoolNode(cmp_c,b->_test._test));
|
|
259 |
Node *b_x = phase->transform(new (igvn->C, 2) BoolNode(cmp_x,b->_test._test));
|
|
260 |
// Make the IfNode
|
|
261 |
IfNode *iff_c = new (igvn->C, 2) IfNode(region_c,b_c,iff->_prob,iff->_fcnt);
|
|
262 |
igvn->set_type_bottom(iff_c);
|
|
263 |
igvn->_worklist.push(iff_c);
|
|
264 |
hook->init_req(2, iff_c);
|
|
265 |
|
|
266 |
IfNode *iff_x = new (igvn->C, 2) IfNode(region_x,b_x,iff->_prob, iff->_fcnt);
|
|
267 |
igvn->set_type_bottom(iff_x);
|
|
268 |
igvn->_worklist.push(iff_x);
|
|
269 |
hook->init_req(3, iff_x);
|
|
270 |
|
|
271 |
// Make the true/false arms
|
|
272 |
Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c));
|
|
273 |
Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c));
|
|
274 |
Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x));
|
|
275 |
Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x));
|
|
276 |
|
|
277 |
// Merge the TRUE paths
|
|
278 |
Node *region_s = new (igvn->C, 3) RegionNode(3);
|
|
279 |
igvn->_worklist.push(region_s);
|
|
280 |
region_s->init_req(1, iff_c_t);
|
|
281 |
region_s->init_req(2, iff_x_t);
|
|
282 |
igvn->register_new_node_with_optimizer( region_s );
|
|
283 |
|
|
284 |
// Merge the FALSE paths
|
|
285 |
Node *region_f = new (igvn->C, 3) RegionNode(3);
|
|
286 |
igvn->_worklist.push(region_f);
|
|
287 |
region_f->init_req(1, iff_c_f);
|
|
288 |
region_f->init_req(2, iff_x_f);
|
|
289 |
igvn->register_new_node_with_optimizer( region_f );
|
|
290 |
|
|
291 |
igvn->hash_delete(cmp);// Remove soon-to-be-dead node from hash table.
|
|
292 |
cmp->set_req(1,NULL); // Whack the inputs to cmp because it will be dead
|
|
293 |
cmp->set_req(2,NULL);
|
|
294 |
// Check for all uses of the Phi and give them a new home.
|
|
295 |
// The 'cmp' got cloned, but CastPP/IIs need to be moved.
|
|
296 |
Node *phi_s = NULL; // do not construct unless needed
|
|
297 |
Node *phi_f = NULL; // do not construct unless needed
|
|
298 |
for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) {
|
|
299 |
Node* v = phi->last_out(i2);// User of the phi
|
|
300 |
igvn->hash_delete(v); // Have to fixup other Phi users
|
|
301 |
igvn->_worklist.push(v);
|
|
302 |
uint vop = v->Opcode();
|
|
303 |
Node *proj = NULL;
|
|
304 |
if( vop == Op_Phi ) { // Remote merge point
|
|
305 |
Node *r = v->in(0);
|
|
306 |
for (uint i3 = 1; i3 < r->req(); i3++)
|
|
307 |
if (r->in(i3) && r->in(i3)->in(0) == iff) {
|
|
308 |
proj = r->in(i3);
|
|
309 |
break;
|
|
310 |
}
|
|
311 |
} else if( v->is_ConstraintCast() ) {
|
|
312 |
proj = v->in(0); // Controlling projection
|
|
313 |
} else {
|
|
314 |
assert( 0, "do not know how to handle this guy" );
|
|
315 |
}
|
|
316 |
|
|
317 |
Node *proj_path_data, *proj_path_ctrl;
|
|
318 |
if( proj->Opcode() == Op_IfTrue ) {
|
|
319 |
if( phi_s == NULL ) {
|
|
320 |
// Only construct phi_s if needed, otherwise provides
|
|
321 |
// interfering use.
|
|
322 |
phi_s = PhiNode::make_blank(region_s,phi);
|
|
323 |
phi_s->init_req( 1, phi_c );
|
|
324 |
phi_s->init_req( 2, phi_x );
|
|
325 |
phi_s = phase->transform(phi_s);
|
|
326 |
}
|
|
327 |
proj_path_data = phi_s;
|
|
328 |
proj_path_ctrl = region_s;
|
|
329 |
} else {
|
|
330 |
if( phi_f == NULL ) {
|
|
331 |
// Only construct phi_f if needed, otherwise provides
|
|
332 |
// interfering use.
|
|
333 |
phi_f = PhiNode::make_blank(region_f,phi);
|
|
334 |
phi_f->init_req( 1, phi_c );
|
|
335 |
phi_f->init_req( 2, phi_x );
|
|
336 |
phi_f = phase->transform(phi_f);
|
|
337 |
}
|
|
338 |
proj_path_data = phi_f;
|
|
339 |
proj_path_ctrl = region_f;
|
|
340 |
}
|
|
341 |
|
|
342 |
// Fixup 'v' for for the split
|
|
343 |
if( vop == Op_Phi ) { // Remote merge point
|
|
344 |
uint i;
|
|
345 |
for( i = 1; i < v->req(); i++ )
|
|
346 |
if( v->in(i) == phi )
|
|
347 |
break;
|
|
348 |
v->set_req(i, proj_path_data );
|
|
349 |
} else if( v->is_ConstraintCast() ) {
|
|
350 |
v->set_req(0, proj_path_ctrl );
|
|
351 |
v->set_req(1, proj_path_data );
|
|
352 |
} else
|
|
353 |
ShouldNotReachHere();
|
|
354 |
}
|
|
355 |
|
|
356 |
// Now replace the original iff's True/False with region_s/region_t.
|
|
357 |
// This makes the original iff go dead.
|
|
358 |
for (DUIterator_Last i3min, i3 = iff->last_outs(i3min); i3 >= i3min; --i3) {
|
|
359 |
Node* p = iff->last_out(i3);
|
|
360 |
assert( p->Opcode() == Op_IfTrue || p->Opcode() == Op_IfFalse, "" );
|
|
361 |
Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f;
|
|
362 |
// Replace p with u
|
|
363 |
igvn->add_users_to_worklist(p);
|
|
364 |
for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) {
|
|
365 |
Node* x = p->last_out(l);
|
|
366 |
igvn->hash_delete(x);
|
|
367 |
uint uses_found = 0;
|
|
368 |
for( uint j = 0; j < x->req(); j++ ) {
|
|
369 |
if( x->in(j) == p ) {
|
|
370 |
x->set_req(j, u);
|
|
371 |
uses_found++;
|
|
372 |
}
|
|
373 |
}
|
|
374 |
l -= uses_found; // we deleted 1 or more copies of this edge
|
|
375 |
}
|
|
376 |
igvn->remove_dead_node(p);
|
|
377 |
}
|
|
378 |
|
|
379 |
// Force the original merge dead
|
|
380 |
igvn->hash_delete(r);
|
|
381 |
r->set_req_X(0,NULL,igvn);
|
|
382 |
|
|
383 |
// Now remove the bogus extra edges used to keep things alive
|
|
384 |
igvn->remove_dead_node( hook );
|
|
385 |
|
|
386 |
// Must return either the original node (now dead) or a new node
|
|
387 |
// (Do not return a top here, since that would break the uniqueness of top.)
|
|
388 |
return new (igvn->C, 1) ConINode(TypeInt::ZERO);
|
|
389 |
}
|
|
390 |
|
|
391 |
//------------------------------is_range_check---------------------------------
|
|
392 |
// Return 0 if not a range check. Return 1 if a range check and set index and
|
|
393 |
// offset. Return 2 if we had to negate the test. Index is NULL if the check
|
|
394 |
// is versus a constant.
|
|
395 |
int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) {
|
|
396 |
Node* b = in(1);
|
|
397 |
if (b == NULL || !b->is_Bool()) return 0;
|
|
398 |
BoolNode* bn = b->as_Bool();
|
|
399 |
Node* cmp = bn->in(1);
|
|
400 |
if (cmp == NULL) return 0;
|
|
401 |
if (cmp->Opcode() != Op_CmpU) return 0;
|
|
402 |
|
|
403 |
Node* l = cmp->in(1);
|
|
404 |
Node* r = cmp->in(2);
|
|
405 |
int flip_test = 1;
|
|
406 |
if (bn->_test._test == BoolTest::le) {
|
|
407 |
l = cmp->in(2);
|
|
408 |
r = cmp->in(1);
|
|
409 |
flip_test = 2;
|
|
410 |
} else if (bn->_test._test != BoolTest::lt) {
|
|
411 |
return 0;
|
|
412 |
}
|
|
413 |
if (l->is_top()) return 0; // Top input means dead test
|
|
414 |
if (r->Opcode() != Op_LoadRange) return 0;
|
|
415 |
|
|
416 |
// We have recognized one of these forms:
|
|
417 |
// Flip 1: If (Bool[<] CmpU(l, LoadRange)) ...
|
|
418 |
// Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ...
|
|
419 |
|
|
420 |
// Make sure it's a real range check by requiring an uncommon trap
|
|
421 |
// along the OOB path. Otherwise, it's possible that the user wrote
|
|
422 |
// something which optimized to look like a range check but behaves
|
|
423 |
// in some other way.
|
|
424 |
Node* iftrap = proj_out(flip_test == 2 ? true : false);
|
|
425 |
bool found_trap = false;
|
|
426 |
if (iftrap != NULL) {
|
|
427 |
Node* u = iftrap->unique_ctrl_out();
|
|
428 |
if (u != NULL) {
|
|
429 |
// It could be a merge point (Region) for uncommon trap.
|
|
430 |
if (u->is_Region()) {
|
|
431 |
Node* c = u->unique_ctrl_out();
|
|
432 |
if (c != NULL) {
|
|
433 |
iftrap = u;
|
|
434 |
u = c;
|
|
435 |
}
|
|
436 |
}
|
|
437 |
if (u->in(0) == iftrap && u->is_CallStaticJava()) {
|
|
438 |
int req = u->as_CallStaticJava()->uncommon_trap_request();
|
|
439 |
if (Deoptimization::trap_request_reason(req) ==
|
|
440 |
Deoptimization::Reason_range_check) {
|
|
441 |
found_trap = true;
|
|
442 |
}
|
|
443 |
}
|
|
444 |
}
|
|
445 |
}
|
|
446 |
if (!found_trap) return 0; // sorry, no cigar
|
|
447 |
|
|
448 |
// Look for index+offset form
|
|
449 |
Node* ind = l;
|
|
450 |
jint off = 0;
|
|
451 |
if (l->is_top()) {
|
|
452 |
return 0;
|
|
453 |
} else if (l->is_Add()) {
|
|
454 |
if ((off = l->in(1)->find_int_con(0)) != 0) {
|
|
455 |
ind = l->in(2);
|
|
456 |
} else if ((off = l->in(2)->find_int_con(0)) != 0) {
|
|
457 |
ind = l->in(1);
|
|
458 |
}
|
|
459 |
} else if ((off = l->find_int_con(-1)) >= 0) {
|
|
460 |
// constant offset with no variable index
|
|
461 |
ind = NULL;
|
|
462 |
} else {
|
|
463 |
// variable index with no constant offset (or dead negative index)
|
|
464 |
off = 0;
|
|
465 |
}
|
|
466 |
|
|
467 |
// Return all the values:
|
|
468 |
index = ind;
|
|
469 |
offset = off;
|
|
470 |
range = r;
|
|
471 |
return flip_test;
|
|
472 |
}
|
|
473 |
|
|
474 |
//------------------------------adjust_check-----------------------------------
|
|
475 |
// Adjust (widen) a prior range check
|
|
476 |
static void adjust_check(Node* proj, Node* range, Node* index,
|
|
477 |
int flip, jint off_lo, PhaseIterGVN* igvn) {
|
|
478 |
PhaseGVN *gvn = igvn;
|
|
479 |
// Break apart the old check
|
|
480 |
Node *iff = proj->in(0);
|
|
481 |
Node *bol = iff->in(1);
|
|
482 |
if( bol->is_top() ) return; // In case a partially dead range check appears
|
|
483 |
// bail (or bomb[ASSERT/DEBUG]) if NOT projection-->IfNode-->BoolNode
|
|
484 |
DEBUG_ONLY( if( !bol->is_Bool() ) { proj->dump(3); fatal("Expect projection-->IfNode-->BoolNode"); } )
|
|
485 |
if( !bol->is_Bool() ) return;
|
|
486 |
|
|
487 |
Node *cmp = bol->in(1);
|
|
488 |
// Compute a new check
|
|
489 |
Node *new_add = gvn->intcon(off_lo);
|
|
490 |
if( index ) {
|
|
491 |
new_add = off_lo ? gvn->transform(new (gvn->C, 3) AddINode( index, new_add )) : index;
|
|
492 |
}
|
|
493 |
Node *new_cmp = (flip == 1)
|
|
494 |
? new (gvn->C, 3) CmpUNode( new_add, range )
|
|
495 |
: new (gvn->C, 3) CmpUNode( range, new_add );
|
|
496 |
new_cmp = gvn->transform(new_cmp);
|
|
497 |
// See if no need to adjust the existing check
|
|
498 |
if( new_cmp == cmp ) return;
|
|
499 |
// Else, adjust existing check
|
|
500 |
Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) );
|
|
501 |
igvn->hash_delete( iff );
|
|
502 |
iff->set_req_X( 1, new_bol, igvn );
|
|
503 |
}
|
|
504 |
|
|
505 |
//------------------------------up_one_dom-------------------------------------
|
|
506 |
// Walk up the dominator tree one step. Return NULL at root or true
|
|
507 |
// complex merges. Skips through small diamonds.
|
|
508 |
Node* IfNode::up_one_dom(Node *curr, bool linear_only) {
|
|
509 |
Node *dom = curr->in(0);
|
|
510 |
if( !dom ) // Found a Region degraded to a copy?
|
|
511 |
return curr->nonnull_req(); // Skip thru it
|
|
512 |
|
|
513 |
if( curr != dom ) // Normal walk up one step?
|
|
514 |
return dom;
|
|
515 |
|
|
516 |
// Use linear_only if we are still parsing, since we cannot
|
|
517 |
// trust the regions to be fully filled in.
|
|
518 |
if (linear_only)
|
|
519 |
return NULL;
|
|
520 |
|
|
521 |
// Else hit a Region. Check for a loop header
|
|
522 |
if( dom->is_Loop() )
|
|
523 |
return dom->in(1); // Skip up thru loops
|
|
524 |
|
|
525 |
// Check for small diamonds
|
|
526 |
Node *din1, *din2, *din3, *din4;
|
|
527 |
if( dom->req() == 3 && // 2-path merge point
|
|
528 |
(din1 = dom ->in(1)) && // Left path exists
|
|
529 |
(din2 = dom ->in(2)) && // Right path exists
|
|
530 |
(din3 = din1->in(0)) && // Left path up one
|
|
531 |
(din4 = din2->in(0)) ) { // Right path up one
|
|
532 |
if( din3->is_Call() && // Handle a slow-path call on either arm
|
|
533 |
(din3 = din3->in(0)) )
|
|
534 |
din3 = din3->in(0);
|
|
535 |
if( din4->is_Call() && // Handle a slow-path call on either arm
|
|
536 |
(din4 = din4->in(0)) )
|
|
537 |
din4 = din4->in(0);
|
|
538 |
if( din3 == din4 && din3->is_If() )
|
|
539 |
return din3; // Skip around diamonds
|
|
540 |
}
|
|
541 |
|
|
542 |
// Give up the search at true merges
|
|
543 |
return NULL; // Dead loop? Or hit root?
|
|
544 |
}
|
|
545 |
|
|
546 |
//------------------------------remove_useless_bool----------------------------
|
|
547 |
// Check for people making a useless boolean: things like
|
|
548 |
// if( (x < y ? true : false) ) { ... }
|
|
549 |
// Replace with if( x < y ) { ... }
|
|
550 |
static Node *remove_useless_bool(IfNode *iff, PhaseGVN *phase) {
|
|
551 |
Node *i1 = iff->in(1);
|
|
552 |
if( !i1->is_Bool() ) return NULL;
|
|
553 |
BoolNode *bol = i1->as_Bool();
|
|
554 |
|
|
555 |
Node *cmp = bol->in(1);
|
|
556 |
if( cmp->Opcode() != Op_CmpI ) return NULL;
|
|
557 |
|
|
558 |
// Must be comparing against a bool
|
|
559 |
const Type *cmp2_t = phase->type( cmp->in(2) );
|
|
560 |
if( cmp2_t != TypeInt::ZERO &&
|
|
561 |
cmp2_t != TypeInt::ONE )
|
|
562 |
return NULL;
|
|
563 |
|
|
564 |
// Find a prior merge point merging the boolean
|
|
565 |
i1 = cmp->in(1);
|
|
566 |
if( !i1->is_Phi() ) return NULL;
|
|
567 |
PhiNode *phi = i1->as_Phi();
|
|
568 |
if( phase->type( phi ) != TypeInt::BOOL )
|
|
569 |
return NULL;
|
|
570 |
|
|
571 |
// Check for diamond pattern
|
|
572 |
int true_path = phi->is_diamond_phi();
|
|
573 |
if( true_path == 0 ) return NULL;
|
|
574 |
|
|
575 |
// phi->region->if_proj->ifnode->bool->cmp
|
|
576 |
BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
|
|
577 |
|
|
578 |
// Now get the 'sense' of the test correct so we can plug in
|
|
579 |
// either iff2->in(1) or its complement.
|
|
580 |
int flip = 0;
|
|
581 |
if( bol->_test._test == BoolTest::ne ) flip = 1-flip;
|
|
582 |
else if( bol->_test._test != BoolTest::eq ) return NULL;
|
|
583 |
if( cmp2_t == TypeInt::ZERO ) flip = 1-flip;
|
|
584 |
|
|
585 |
const Type *phi1_t = phase->type( phi->in(1) );
|
|
586 |
const Type *phi2_t = phase->type( phi->in(2) );
|
|
587 |
// Check for Phi(0,1) and flip
|
|
588 |
if( phi1_t == TypeInt::ZERO ) {
|
|
589 |
if( phi2_t != TypeInt::ONE ) return NULL;
|
|
590 |
flip = 1-flip;
|
|
591 |
} else {
|
|
592 |
// Check for Phi(1,0)
|
|
593 |
if( phi1_t != TypeInt::ONE ) return NULL;
|
|
594 |
if( phi2_t != TypeInt::ZERO ) return NULL;
|
|
595 |
}
|
|
596 |
if( true_path == 2 ) {
|
|
597 |
flip = 1-flip;
|
|
598 |
}
|
|
599 |
|
|
600 |
Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2);
|
|
601 |
iff->set_req(1, new_bol);
|
|
602 |
// Intervening diamond probably goes dead
|
|
603 |
phase->C->set_major_progress();
|
|
604 |
return iff;
|
|
605 |
}
|
|
606 |
|
|
607 |
static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff);
|
|
608 |
|
|
609 |
//------------------------------Ideal------------------------------------------
|
|
610 |
// Return a node which is more "ideal" than the current node. Strip out
|
|
611 |
// control copies
|
|
612 |
Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|
613 |
if (remove_dead_region(phase, can_reshape)) return this;
|
|
614 |
// No Def-Use info?
|
|
615 |
if (!can_reshape) return NULL;
|
|
616 |
PhaseIterGVN *igvn = phase->is_IterGVN();
|
|
617 |
|
|
618 |
// Don't bother trying to transform a dead if
|
|
619 |
if (in(0)->is_top()) return NULL;
|
|
620 |
// Don't bother trying to transform an if with a dead test
|
|
621 |
if (in(1)->is_top()) return NULL;
|
|
622 |
// Another variation of a dead test
|
|
623 |
if (in(1)->is_Con()) return NULL;
|
|
624 |
// Another variation of a dead if
|
|
625 |
if (outcnt() < 2) return NULL;
|
|
626 |
|
|
627 |
// Canonicalize the test.
|
|
628 |
Node* idt_if = idealize_test(phase, this);
|
|
629 |
if (idt_if != NULL) return idt_if;
|
|
630 |
|
|
631 |
// Try to split the IF
|
|
632 |
Node *s = split_if(this, igvn);
|
|
633 |
if (s != NULL) return s;
|
|
634 |
|
|
635 |
// Check for people making a useless boolean: things like
|
|
636 |
// if( (x < y ? true : false) ) { ... }
|
|
637 |
// Replace with if( x < y ) { ... }
|
|
638 |
Node *bol2 = remove_useless_bool(this, phase);
|
|
639 |
if( bol2 ) return bol2;
|
|
640 |
|
|
641 |
// Setup to scan up the CFG looking for a dominating test
|
|
642 |
Node *dom = in(0);
|
|
643 |
Node *prev_dom = this;
|
|
644 |
|
|
645 |
// Check for range-check vs other kinds of tests
|
|
646 |
Node *index1, *range1;
|
|
647 |
jint offset1;
|
|
648 |
int flip1 = is_range_check(range1, index1, offset1);
|
|
649 |
if( flip1 ) {
|
|
650 |
Node *first_prev_dom = NULL;
|
|
651 |
|
|
652 |
// Try to remove extra range checks. All 'up_one_dom' gives up at merges
|
|
653 |
// so all checks we inspect post-dominate the top-most check we find.
|
|
654 |
// If we are going to fail the current check and we reach the top check
|
|
655 |
// then we are guarenteed to fail, so just start interpreting there.
|
|
656 |
// We 'expand' the top 2 range checks to include all post-dominating
|
|
657 |
// checks.
|
|
658 |
|
|
659 |
// The top 2 range checks seen
|
|
660 |
Node *prev_chk1 = NULL;
|
|
661 |
Node *prev_chk2 = NULL;
|
|
662 |
// Low and high offsets seen so far
|
|
663 |
jint off_lo = offset1;
|
|
664 |
jint off_hi = offset1;
|
|
665 |
|
|
666 |
// Scan for the top 2 checks and collect range of offsets
|
|
667 |
for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit
|
|
668 |
if( dom->Opcode() == Op_If && // Not same opcode?
|
|
669 |
prev_dom->in(0) == dom ) { // One path of test does dominate?
|
|
670 |
if( dom == this ) return NULL; // dead loop
|
|
671 |
// See if this is a range check
|
|
672 |
Node *index2, *range2;
|
|
673 |
jint offset2;
|
|
674 |
int flip2 = dom->as_If()->is_range_check(range2, index2, offset2);
|
|
675 |
// See if this is a _matching_ range check, checking against
|
|
676 |
// the same array bounds.
|
|
677 |
if( flip2 == flip1 && range2 == range1 && index2 == index1 &&
|
|
678 |
dom->outcnt() == 2 ) {
|
|
679 |
// Gather expanded bounds
|
|
680 |
off_lo = MIN2(off_lo,offset2);
|
|
681 |
off_hi = MAX2(off_hi,offset2);
|
|
682 |
// Record top 2 range checks
|
|
683 |
prev_chk2 = prev_chk1;
|
|
684 |
prev_chk1 = prev_dom;
|
|
685 |
// If we match the test exactly, then the top test covers
|
|
686 |
// both our lower and upper bounds.
|
|
687 |
if( dom->in(1) == in(1) )
|
|
688 |
prev_chk2 = prev_chk1;
|
|
689 |
}
|
|
690 |
}
|
|
691 |
prev_dom = dom;
|
|
692 |
dom = up_one_dom( dom );
|
|
693 |
if( !dom ) break;
|
|
694 |
}
|
|
695 |
|
|
696 |
|
|
697 |
// Attempt to widen the dominating range check to cover some later
|
|
698 |
// ones. Since range checks "fail" by uncommon-trapping to the
|
|
699 |
// interpreter, widening a check can make us speculative enter the
|
|
700 |
// interpreter. If we see range-check deopt's, do not widen!
|
|
701 |
if (!phase->C->allow_range_check_smearing()) return NULL;
|
|
702 |
|
|
703 |
// Constant indices only need to check the upper bound.
|
|
704 |
// Non-constance indices must check both low and high.
|
|
705 |
if( index1 ) {
|
|
706 |
// Didn't find 2 prior covering checks, so cannot remove anything.
|
|
707 |
if( !prev_chk2 ) return NULL;
|
|
708 |
// 'Widen' the offsets of the 1st and 2nd covering check
|
|
709 |
adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn );
|
|
710 |
// Do not call adjust_check twice on the same projection
|
|
711 |
// as the first call may have transformed the BoolNode to a ConI
|
|
712 |
if( prev_chk1 != prev_chk2 ) {
|
|
713 |
adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn );
|
|
714 |
}
|
|
715 |
// Test is now covered by prior checks, dominate it out
|
|
716 |
prev_dom = prev_chk2;
|
|
717 |
} else {
|
|
718 |
// Didn't find prior covering check, so cannot remove anything.
|
|
719 |
if( !prev_chk1 ) return NULL;
|
|
720 |
// 'Widen' the offset of the 1st and only covering check
|
|
721 |
adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn );
|
|
722 |
// Test is now covered by prior checks, dominate it out
|
|
723 |
prev_dom = prev_chk1;
|
|
724 |
}
|
|
725 |
|
|
726 |
|
|
727 |
} else { // Scan for an equivalent test
|
|
728 |
|
|
729 |
Node *cmp;
|
|
730 |
int dist = 0; // Cutoff limit for search
|
|
731 |
int op = Opcode();
|
|
732 |
if( op == Op_If &&
|
|
733 |
(cmp=in(1)->in(1))->Opcode() == Op_CmpP ) {
|
|
734 |
if( cmp->in(2) != NULL && // make sure cmp is not already dead
|
|
735 |
cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) {
|
|
736 |
dist = 64; // Limit for null-pointer scans
|
|
737 |
} else {
|
|
738 |
dist = 4; // Do not bother for random pointer tests
|
|
739 |
}
|
|
740 |
} else {
|
|
741 |
dist = 4; // Limit for random junky scans
|
|
742 |
}
|
|
743 |
|
|
744 |
// Normal equivalent-test check.
|
|
745 |
if( !dom ) return NULL; // Dead loop?
|
|
746 |
|
|
747 |
// Search up the dominator tree for an If with an identical test
|
|
748 |
while( dom->Opcode() != op || // Not same opcode?
|
|
749 |
dom->in(1) != in(1) || // Not same input 1?
|
|
750 |
(req() == 3 && dom->in(2) != in(2)) || // Not same input 2?
|
|
751 |
prev_dom->in(0) != dom ) { // One path of test does not dominate?
|
|
752 |
if( dist < 0 ) return NULL;
|
|
753 |
|
|
754 |
dist--;
|
|
755 |
prev_dom = dom;
|
|
756 |
dom = up_one_dom( dom );
|
|
757 |
if( !dom ) return NULL;
|
|
758 |
}
|
|
759 |
|
|
760 |
// Check that we did not follow a loop back to ourselves
|
|
761 |
if( this == dom )
|
|
762 |
return NULL;
|
|
763 |
|
|
764 |
if( dist > 2 ) // Add to count of NULL checks elided
|
|
765 |
explicit_null_checks_elided++;
|
|
766 |
|
|
767 |
} // End of Else scan for an equivalent test
|
|
768 |
|
|
769 |
// Hit! Remove this IF
|
|
770 |
#ifndef PRODUCT
|
|
771 |
if( TraceIterativeGVN ) {
|
|
772 |
tty->print(" Removing IfNode: "); this->dump();
|
|
773 |
}
|
|
774 |
if( VerifyOpto && !phase->allow_progress() ) {
|
|
775 |
// Found an equivalent dominating test,
|
|
776 |
// we can not guarantee reaching a fix-point for these during iterativeGVN
|
|
777 |
// since intervening nodes may not change.
|
|
778 |
return NULL;
|
|
779 |
}
|
|
780 |
#endif
|
|
781 |
|
|
782 |
// Replace dominated IfNode
|
|
783 |
dominated_by( prev_dom, igvn );
|
|
784 |
|
|
785 |
// Must return either the original node (now dead) or a new node
|
|
786 |
// (Do not return a top here, since that would break the uniqueness of top.)
|
|
787 |
return new (phase->C, 1) ConINode(TypeInt::ZERO);
|
|
788 |
}
|
|
789 |
|
|
790 |
//------------------------------dominated_by-----------------------------------
|
|
791 |
void IfNode::dominated_by( Node *prev_dom, PhaseIterGVN *igvn ) {
|
|
792 |
igvn->hash_delete(this); // Remove self to prevent spurious V-N
|
|
793 |
Node *idom = in(0);
|
|
794 |
// Need opcode to decide which way 'this' test goes
|
|
795 |
int prev_op = prev_dom->Opcode();
|
|
796 |
Node *top = igvn->C->top(); // Shortcut to top
|
|
797 |
|
|
798 |
// Now walk the current IfNode's projections.
|
|
799 |
// Loop ends when 'this' has no more uses.
|
|
800 |
for (DUIterator_Last imin, i = last_outs(imin); i >= imin; --i) {
|
|
801 |
Node *ifp = last_out(i); // Get IfTrue/IfFalse
|
|
802 |
igvn->add_users_to_worklist(ifp);
|
|
803 |
// Check which projection it is and set target.
|
|
804 |
// Data-target is either the dominating projection of the same type
|
|
805 |
// or TOP if the dominating projection is of opposite type.
|
|
806 |
// Data-target will be used as the new control edge for the non-CFG
|
|
807 |
// nodes like Casts and Loads.
|
|
808 |
Node *data_target = (ifp->Opcode() == prev_op ) ? prev_dom : top;
|
|
809 |
// Control-target is just the If's immediate dominator or TOP.
|
|
810 |
Node *ctrl_target = (ifp->Opcode() == prev_op ) ? idom : top;
|
|
811 |
|
|
812 |
// For each child of an IfTrue/IfFalse projection, reroute.
|
|
813 |
// Loop ends when projection has no more uses.
|
|
814 |
for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) {
|
|
815 |
Node* s = ifp->last_out(j); // Get child of IfTrue/IfFalse
|
|
816 |
igvn->hash_delete(s); // Yank from hash table before edge hacking
|
|
817 |
if( !s->depends_only_on_test() ) {
|
|
818 |
// Find the control input matching this def-use edge.
|
|
819 |
// For Regions it may not be in slot 0.
|
|
820 |
uint l;
|
|
821 |
for( l = 0; s->in(l) != ifp; l++ ) { }
|
|
822 |
s->set_req(l, ctrl_target);
|
|
823 |
} else { // Else, for control producers,
|
|
824 |
s->set_req(0, data_target); // Move child to data-target
|
|
825 |
}
|
|
826 |
igvn->_worklist.push(s); // Revisit collapsed Phis
|
|
827 |
} // End for each child of a projection
|
|
828 |
|
|
829 |
igvn->remove_dead_node(ifp);
|
|
830 |
} // End for each IfTrue/IfFalse child of If
|
|
831 |
|
|
832 |
// Kill the IfNode
|
|
833 |
igvn->remove_dead_node(this);
|
|
834 |
}
|
|
835 |
|
|
836 |
//------------------------------Identity---------------------------------------
|
|
837 |
// If the test is constant & we match, then we are the input Control
|
|
838 |
Node *IfTrueNode::Identity( PhaseTransform *phase ) {
|
|
839 |
// Can only optimize if cannot go the other way
|
|
840 |
const TypeTuple *t = phase->type(in(0))->is_tuple();
|
|
841 |
return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE )
|
|
842 |
? in(0)->in(0) // IfNode control
|
|
843 |
: this; // no progress
|
|
844 |
}
|
|
845 |
|
|
846 |
//------------------------------dump_spec--------------------------------------
|
|
847 |
#ifndef PRODUCT
|
|
848 |
void IfNode::dump_spec(outputStream *st) const {
|
|
849 |
st->print("P=%f, C=%f",_prob,_fcnt);
|
|
850 |
}
|
|
851 |
#endif
|
|
852 |
|
|
853 |
//------------------------------idealize_test----------------------------------
|
|
854 |
// Try to canonicalize tests better. Peek at the Cmp/Bool/If sequence and
|
|
855 |
// come up with a canonical sequence. Bools getting 'eq', 'gt' and 'ge' forms
|
|
856 |
// converted to 'ne', 'le' and 'lt' forms. IfTrue/IfFalse get swapped as
|
|
857 |
// needed.
|
|
858 |
static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) {
|
|
859 |
assert(iff->in(0) != NULL, "If must be live");
|
|
860 |
|
|
861 |
if (iff->outcnt() != 2) return NULL; // Malformed projections.
|
|
862 |
Node* old_if_f = iff->proj_out(false);
|
|
863 |
Node* old_if_t = iff->proj_out(true);
|
|
864 |
|
|
865 |
// CountedLoopEnds want the back-control test to be TRUE, irregardless of
|
|
866 |
// whether they are testing a 'gt' or 'lt' condition. The 'gt' condition
|
|
867 |
// happens in count-down loops
|
|
868 |
if (iff->is_CountedLoopEnd()) return NULL;
|
|
869 |
if (!iff->in(1)->is_Bool()) return NULL; // Happens for partially optimized IF tests
|
|
870 |
BoolNode *b = iff->in(1)->as_Bool();
|
|
871 |
BoolTest bt = b->_test;
|
|
872 |
// Test already in good order?
|
|
873 |
if( bt.is_canonical() )
|
|
874 |
return NULL;
|
|
875 |
|
|
876 |
// Flip test to be canonical. Requires flipping the IfFalse/IfTrue and
|
|
877 |
// cloning the IfNode.
|
|
878 |
Node* new_b = phase->transform( new (phase->C, 2) BoolNode(b->in(1), bt.negate()) );
|
|
879 |
if( !new_b->is_Bool() ) return NULL;
|
|
880 |
b = new_b->as_Bool();
|
|
881 |
|
|
882 |
PhaseIterGVN *igvn = phase->is_IterGVN();
|
|
883 |
assert( igvn, "Test is not canonical in parser?" );
|
|
884 |
|
|
885 |
// The IF node never really changes, but it needs to be cloned
|
|
886 |
iff = new (phase->C, 2) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt);
|
|
887 |
|
|
888 |
Node *prior = igvn->hash_find_insert(iff);
|
|
889 |
if( prior ) {
|
|
890 |
igvn->remove_dead_node(iff);
|
|
891 |
iff = (IfNode*)prior;
|
|
892 |
} else {
|
|
893 |
// Cannot call transform on it just yet
|
|
894 |
igvn->set_type_bottom(iff);
|
|
895 |
}
|
|
896 |
igvn->_worklist.push(iff);
|
|
897 |
|
|
898 |
// Now handle projections. Cloning not required.
|
|
899 |
Node* new_if_f = (Node*)(new (phase->C, 1) IfFalseNode( iff ));
|
|
900 |
Node* new_if_t = (Node*)(new (phase->C, 1) IfTrueNode ( iff ));
|
|
901 |
|
|
902 |
igvn->register_new_node_with_optimizer(new_if_f);
|
|
903 |
igvn->register_new_node_with_optimizer(new_if_t);
|
|
904 |
igvn->hash_delete(old_if_f);
|
|
905 |
igvn->hash_delete(old_if_t);
|
|
906 |
// Flip test, so flip trailing control
|
|
907 |
igvn->subsume_node(old_if_f, new_if_t);
|
|
908 |
igvn->subsume_node(old_if_t, new_if_f);
|
|
909 |
|
|
910 |
// Progress
|
|
911 |
return iff;
|
|
912 |
}
|
|
913 |
|
|
914 |
//------------------------------Identity---------------------------------------
|
|
915 |
// If the test is constant & we match, then we are the input Control
|
|
916 |
Node *IfFalseNode::Identity( PhaseTransform *phase ) {
|
|
917 |
// Can only optimize if cannot go the other way
|
|
918 |
const TypeTuple *t = phase->type(in(0))->is_tuple();
|
|
919 |
return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE )
|
|
920 |
? in(0)->in(0) // IfNode control
|
|
921 |
: this; // no progress
|
|
922 |
}
|