annotate src/share/vm/opto/ifnode.cpp @ 4710:41406797186b

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