annotate src/share/vm/opto/ifnode.cpp @ 452:00b023ae2d78

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