annotate src/share/vm/opto/ifnode.cpp @ 9126:bc26f978b0ce

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