annotate src/share/vm/opto/ifnode.cpp @ 1994:6cd6d394f280

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