Mercurial > hg > truffle
annotate src/share/vm/opto/subnode.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | cc32ccaaf47f |
children | 70120f47d403 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6207
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1174
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1174
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:
1174
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileLog.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
28 #include "opto/addnode.hpp" | |
29 #include "opto/callnode.hpp" | |
30 #include "opto/cfgnode.hpp" | |
31 #include "opto/connode.hpp" | |
32 #include "opto/loopnode.hpp" | |
33 #include "opto/matcher.hpp" | |
34 #include "opto/mulnode.hpp" | |
35 #include "opto/opcodes.hpp" | |
36 #include "opto/phaseX.hpp" | |
37 #include "opto/subnode.hpp" | |
38 #include "runtime/sharedRuntime.hpp" | |
39 | |
0 | 40 // Portions of code courtesy of Clifford Click |
41 | |
42 // Optimization - Graph Style | |
43 | |
44 #include "math.h" | |
45 | |
46 //============================================================================= | |
47 //------------------------------Identity--------------------------------------- | |
48 // If right input is a constant 0, return the left input. | |
49 Node *SubNode::Identity( PhaseTransform *phase ) { | |
50 assert(in(1) != this, "Must already have called Value"); | |
51 assert(in(2) != this, "Must already have called Value"); | |
52 | |
53 // Remove double negation | |
54 const Type *zero = add_id(); | |
55 if( phase->type( in(1) )->higher_equal( zero ) && | |
56 in(2)->Opcode() == Opcode() && | |
57 phase->type( in(2)->in(1) )->higher_equal( zero ) ) { | |
58 return in(2)->in(2); | |
59 } | |
60 | |
212 | 61 // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y |
0 | 62 if( in(1)->Opcode() == Op_AddI ) { |
63 if( phase->eqv(in(1)->in(2),in(2)) ) | |
64 return in(1)->in(1); | |
212 | 65 if (phase->eqv(in(1)->in(1),in(2))) |
66 return in(1)->in(2); | |
67 | |
0 | 68 // Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying |
69 // trip counter and X is likely to be loop-invariant (that's how O2 Nodes | |
70 // are originally used, although the optimizer sometimes jiggers things). | |
71 // This folding through an O2 removes a loop-exit use of a loop-varying | |
72 // value and generally lowers register pressure in and around the loop. | |
73 if( in(1)->in(2)->Opcode() == Op_Opaque2 && | |
74 phase->eqv(in(1)->in(2)->in(1),in(2)) ) | |
75 return in(1)->in(1); | |
76 } | |
77 | |
78 return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this; | |
79 } | |
80 | |
81 //------------------------------Value------------------------------------------ | |
82 // A subtract node differences it's two inputs. | |
83 const Type *SubNode::Value( PhaseTransform *phase ) const { | |
84 const Node* in1 = in(1); | |
85 const Node* in2 = in(2); | |
86 // Either input is TOP ==> the result is TOP | |
87 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); | |
88 if( t1 == Type::TOP ) return Type::TOP; | |
89 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2); | |
90 if( t2 == Type::TOP ) return Type::TOP; | |
91 | |
92 // Not correct for SubFnode and AddFNode (must check for infinity) | |
93 // Equal? Subtract is zero | |
4778 | 94 if (in1->eqv_uncast(in2)) return add_id(); |
0 | 95 |
96 // Either input is BOTTOM ==> the result is the local BOTTOM | |
97 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) | |
98 return bottom_type(); | |
99 | |
100 return sub(t1,t2); // Local flavor of type subtraction | |
101 | |
102 } | |
103 | |
104 //============================================================================= | |
105 | |
106 //------------------------------Helper function-------------------------------- | |
107 static bool ok_to_convert(Node* inc, Node* iv) { | |
108 // Do not collapse (x+c0)-y if "+" is a loop increment, because the | |
109 // "-" is loop invariant and collapsing extends the live-range of "x" | |
110 // to overlap with the "+", forcing another register to be used in | |
111 // the loop. | |
112 // This test will be clearer with '&&' (apply DeMorgan's rule) | |
113 // but I like the early cutouts that happen here. | |
114 const PhiNode *phi; | |
115 if( ( !inc->in(1)->is_Phi() || | |
116 !(phi=inc->in(1)->as_Phi()) || | |
117 phi->is_copy() || | |
118 !phi->region()->is_CountedLoop() || | |
119 inc != phi->region()->as_CountedLoop()->incr() ) | |
120 && | |
121 // Do not collapse (x+c0)-iv if "iv" is a loop induction variable, | |
122 // because "x" maybe invariant. | |
123 ( !iv->is_loop_iv() ) | |
124 ) { | |
125 return true; | |
126 } else { | |
127 return false; | |
128 } | |
129 } | |
130 //------------------------------Ideal------------------------------------------ | |
131 Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
132 Node *in1 = in(1); | |
133 Node *in2 = in(2); | |
134 uint op1 = in1->Opcode(); | |
135 uint op2 = in2->Opcode(); | |
136 | |
137 #ifdef ASSERT | |
138 // Check for dead loop | |
139 if( phase->eqv( in1, this ) || phase->eqv( in2, this ) || | |
140 ( op1 == Op_AddI || op1 == Op_SubI ) && | |
141 ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) || | |
142 phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) ) | |
143 assert(false, "dead loop in SubINode::Ideal"); | |
144 #endif | |
145 | |
146 const Type *t2 = phase->type( in2 ); | |
147 if( t2 == Type::TOP ) return NULL; | |
148 // Convert "x-c0" into "x+ -c0". | |
149 if( t2->base() == Type::Int ){ // Might be bottom or top... | |
150 const TypeInt *i = t2->is_int(); | |
151 if( i->is_con() ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
152 return new (phase->C) AddINode(in1, phase->intcon(-i->get_con())); |
0 | 153 } |
154 | |
155 // Convert "(x+c0) - y" into (x-y) + c0" | |
156 // Do not collapse (x+c0)-y if "+" is a loop increment or | |
157 // if "y" is a loop induction variable. | |
158 if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { | |
159 const Type *tadd = phase->type( in1->in(2) ); | |
160 if( tadd->singleton() && tadd != Type::TOP ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
161 Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 )); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
162 return new (phase->C) AddINode( sub2, in1->in(2) ); |
0 | 163 } |
164 } | |
165 | |
166 | |
167 // Convert "x - (y+c0)" into "(x-y) - c0" | |
168 // Need the same check as in above optimization but reversed. | |
169 if (op2 == Op_AddI && ok_to_convert(in2, in1)) { | |
170 Node* in21 = in2->in(1); | |
171 Node* in22 = in2->in(2); | |
172 const TypeInt* tcon = phase->type(in22)->isa_int(); | |
173 if (tcon != NULL && tcon->is_con()) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
174 Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) ); |
0 | 175 Node* neg_c0 = phase->intcon(- tcon->get_con()); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
176 return new (phase->C) AddINode(sub2, neg_c0); |
0 | 177 } |
178 } | |
179 | |
180 const Type *t1 = phase->type( in1 ); | |
181 if( t1 == Type::TOP ) return NULL; | |
182 | |
183 #ifdef ASSERT | |
184 // Check for dead loop | |
185 if( ( op2 == Op_AddI || op2 == Op_SubI ) && | |
186 ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) || | |
187 phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) ) | |
188 assert(false, "dead loop in SubINode::Ideal"); | |
189 #endif | |
190 | |
191 // Convert "x - (x+y)" into "-y" | |
192 if( op2 == Op_AddI && | |
193 phase->eqv( in1, in2->in(1) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
194 return new (phase->C) SubINode( phase->intcon(0),in2->in(2)); |
0 | 195 // Convert "(x-y) - x" into "-y" |
196 if( op1 == Op_SubI && | |
197 phase->eqv( in1->in(1), in2 ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
198 return new (phase->C) SubINode( phase->intcon(0),in1->in(2)); |
0 | 199 // Convert "x - (y+x)" into "-y" |
200 if( op2 == Op_AddI && | |
201 phase->eqv( in1, in2->in(2) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
202 return new (phase->C) SubINode( phase->intcon(0),in2->in(1)); |
0 | 203 |
204 // Convert "0 - (x-y)" into "y-x" | |
205 if( t1 == TypeInt::ZERO && op2 == Op_SubI ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
206 return new (phase->C) SubINode( in2->in(2), in2->in(1) ); |
0 | 207 |
208 // Convert "0 - (x+con)" into "-con-x" | |
209 jint con; | |
210 if( t1 == TypeInt::ZERO && op2 == Op_AddI && | |
211 (con = in2->in(2)->find_int_con(0)) != 0 ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
212 return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) ); |
0 | 213 |
214 // Convert "(X+A) - (X+B)" into "A - B" | |
215 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
216 return new (phase->C) SubINode( in1->in(2), in2->in(2) ); |
0 | 217 |
218 // Convert "(A+X) - (B+X)" into "A - B" | |
219 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
220 return new (phase->C) SubINode( in1->in(1), in2->in(1) ); |
0 | 221 |
400
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
222 // Convert "(A+X) - (X+B)" into "A - B" |
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
223 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) ) |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
224 return new (phase->C) SubINode( in1->in(1), in2->in(2) ); |
400
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
225 |
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
226 // Convert "(X+A) - (B+X)" into "A - B" |
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
227 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) ) |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
228 return new (phase->C) SubINode( in1->in(2), in2->in(1) ); |
400
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
296
diff
changeset
|
229 |
0 | 230 // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally |
231 // nicer to optimize than subtract. | |
232 if( op2 == Op_SubI && in2->outcnt() == 1) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
233 Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
234 return new (phase->C) SubINode( add1, in2->in(1) ); |
0 | 235 } |
236 | |
237 return NULL; | |
238 } | |
239 | |
240 //------------------------------sub-------------------------------------------- | |
241 // A subtract node differences it's two inputs. | |
242 const Type *SubINode::sub( const Type *t1, const Type *t2 ) const { | |
243 const TypeInt *r0 = t1->is_int(); // Handy access | |
244 const TypeInt *r1 = t2->is_int(); | |
245 int32 lo = r0->_lo - r1->_hi; | |
246 int32 hi = r0->_hi - r1->_lo; | |
247 | |
248 // We next check for 32-bit overflow. | |
249 // If that happens, we just assume all integers are possible. | |
250 if( (((r0->_lo ^ r1->_hi) >= 0) || // lo ends have same signs OR | |
251 ((r0->_lo ^ lo) >= 0)) && // lo results have same signs AND | |
252 (((r0->_hi ^ r1->_lo) >= 0) || // hi ends have same signs OR | |
253 ((r0->_hi ^ hi) >= 0)) ) // hi results have same signs | |
254 return TypeInt::make(lo,hi,MAX2(r0->_widen,r1->_widen)); | |
255 else // Overflow; assume all integers | |
256 return TypeInt::INT; | |
257 } | |
258 | |
259 //============================================================================= | |
260 //------------------------------Ideal------------------------------------------ | |
261 Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
262 Node *in1 = in(1); | |
263 Node *in2 = in(2); | |
264 uint op1 = in1->Opcode(); | |
265 uint op2 = in2->Opcode(); | |
266 | |
267 #ifdef ASSERT | |
268 // Check for dead loop | |
269 if( phase->eqv( in1, this ) || phase->eqv( in2, this ) || | |
270 ( op1 == Op_AddL || op1 == Op_SubL ) && | |
271 ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) || | |
272 phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) ) | |
273 assert(false, "dead loop in SubLNode::Ideal"); | |
274 #endif | |
275 | |
276 if( phase->type( in2 ) == Type::TOP ) return NULL; | |
277 const TypeLong *i = phase->type( in2 )->isa_long(); | |
278 // Convert "x-c0" into "x+ -c0". | |
279 if( i && // Might be bottom or top... | |
280 i->is_con() ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
281 return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con())); |
0 | 282 |
283 // Convert "(x+c0) - y" into (x-y) + c0" | |
284 // Do not collapse (x+c0)-y if "+" is a loop increment or | |
285 // if "y" is a loop induction variable. | |
286 if( op1 == Op_AddL && ok_to_convert(in1, in2) ) { | |
287 Node *in11 = in1->in(1); | |
288 const Type *tadd = phase->type( in1->in(2) ); | |
289 if( tadd->singleton() && tadd != Type::TOP ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
290 Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 )); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
291 return new (phase->C) AddLNode( sub2, in1->in(2) ); |
0 | 292 } |
293 } | |
294 | |
295 // Convert "x - (y+c0)" into "(x-y) - c0" | |
296 // Need the same check as in above optimization but reversed. | |
297 if (op2 == Op_AddL && ok_to_convert(in2, in1)) { | |
298 Node* in21 = in2->in(1); | |
299 Node* in22 = in2->in(2); | |
300 const TypeLong* tcon = phase->type(in22)->isa_long(); | |
301 if (tcon != NULL && tcon->is_con()) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
302 Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) ); |
0 | 303 Node* neg_c0 = phase->longcon(- tcon->get_con()); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
304 return new (phase->C) AddLNode(sub2, neg_c0); |
0 | 305 } |
306 } | |
307 | |
308 const Type *t1 = phase->type( in1 ); | |
309 if( t1 == Type::TOP ) return NULL; | |
310 | |
311 #ifdef ASSERT | |
312 // Check for dead loop | |
313 if( ( op2 == Op_AddL || op2 == Op_SubL ) && | |
314 ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) || | |
315 phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) ) | |
316 assert(false, "dead loop in SubLNode::Ideal"); | |
317 #endif | |
318 | |
319 // Convert "x - (x+y)" into "-y" | |
320 if( op2 == Op_AddL && | |
321 phase->eqv( in1, in2->in(1) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
322 return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); |
0 | 323 // Convert "x - (y+x)" into "-y" |
324 if( op2 == Op_AddL && | |
325 phase->eqv( in1, in2->in(2) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
326 return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); |
0 | 327 |
328 // Convert "0 - (x-y)" into "y-x" | |
329 if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
330 return new (phase->C) SubLNode( in2->in(2), in2->in(1) ); |
0 | 331 |
332 // Convert "(X+A) - (X+B)" into "A - B" | |
333 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
334 return new (phase->C) SubLNode( in1->in(2), in2->in(2) ); |
0 | 335 |
336 // Convert "(A+X) - (B+X)" into "A - B" | |
337 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
338 return new (phase->C) SubLNode( in1->in(1), in2->in(1) ); |
0 | 339 |
340 // Convert "A-(B-C)" into (A+C)-B" | |
341 if( op2 == Op_SubL && in2->outcnt() == 1) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
342 Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
343 return new (phase->C) SubLNode( add1, in2->in(1) ); |
0 | 344 } |
345 | |
346 return NULL; | |
347 } | |
348 | |
349 //------------------------------sub-------------------------------------------- | |
350 // A subtract node differences it's two inputs. | |
351 const Type *SubLNode::sub( const Type *t1, const Type *t2 ) const { | |
352 const TypeLong *r0 = t1->is_long(); // Handy access | |
353 const TypeLong *r1 = t2->is_long(); | |
354 jlong lo = r0->_lo - r1->_hi; | |
355 jlong hi = r0->_hi - r1->_lo; | |
356 | |
357 // We next check for 32-bit overflow. | |
358 // If that happens, we just assume all integers are possible. | |
359 if( (((r0->_lo ^ r1->_hi) >= 0) || // lo ends have same signs OR | |
360 ((r0->_lo ^ lo) >= 0)) && // lo results have same signs AND | |
361 (((r0->_hi ^ r1->_lo) >= 0) || // hi ends have same signs OR | |
362 ((r0->_hi ^ hi) >= 0)) ) // hi results have same signs | |
363 return TypeLong::make(lo,hi,MAX2(r0->_widen,r1->_widen)); | |
364 else // Overflow; assume all integers | |
365 return TypeLong::LONG; | |
366 } | |
367 | |
368 //============================================================================= | |
369 //------------------------------Value------------------------------------------ | |
370 // A subtract node differences its two inputs. | |
371 const Type *SubFPNode::Value( PhaseTransform *phase ) const { | |
372 const Node* in1 = in(1); | |
373 const Node* in2 = in(2); | |
374 // Either input is TOP ==> the result is TOP | |
375 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); | |
376 if( t1 == Type::TOP ) return Type::TOP; | |
377 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2); | |
378 if( t2 == Type::TOP ) return Type::TOP; | |
379 | |
380 // if both operands are infinity of same sign, the result is NaN; do | |
381 // not replace with zero | |
382 if( (t1->is_finite() && t2->is_finite()) ) { | |
383 if( phase->eqv(in1, in2) ) return add_id(); | |
384 } | |
385 | |
386 // Either input is BOTTOM ==> the result is the local BOTTOM | |
387 const Type *bot = bottom_type(); | |
388 if( (t1 == bot) || (t2 == bot) || | |
389 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) | |
390 return bot; | |
391 | |
392 return sub(t1,t2); // Local flavor of type subtraction | |
393 } | |
394 | |
395 | |
396 //============================================================================= | |
397 //------------------------------Ideal------------------------------------------ | |
398 Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
399 const Type *t2 = phase->type( in(2) ); | |
400 // Convert "x-c0" into "x+ -c0". | |
401 if( t2->base() == Type::FloatCon ) { // Might be bottom or top... | |
402 // return new (phase->C, 3) AddFNode(in(1), phase->makecon( TypeF::make(-t2->getf()) ) ); | |
403 } | |
404 | |
405 // Not associative because of boundary conditions (infinity) | |
406 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { | |
407 // Convert "x - (x+y)" into "-y" | |
408 if( in(2)->is_Add() && | |
409 phase->eqv(in(1),in(2)->in(1) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
410 return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); |
0 | 411 } |
412 | |
413 // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes | |
414 // 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0. | |
415 //if( phase->type(in(1)) == TypeF::ZERO ) | |
416 //return new (phase->C, 2) NegFNode(in(2)); | |
417 | |
418 return NULL; | |
419 } | |
420 | |
421 //------------------------------sub-------------------------------------------- | |
422 // A subtract node differences its two inputs. | |
423 const Type *SubFNode::sub( const Type *t1, const Type *t2 ) const { | |
424 // no folding if one of operands is infinity or NaN, do not do constant folding | |
425 if( g_isfinite(t1->getf()) && g_isfinite(t2->getf()) ) { | |
426 return TypeF::make( t1->getf() - t2->getf() ); | |
427 } | |
428 else if( g_isnan(t1->getf()) ) { | |
429 return t1; | |
430 } | |
431 else if( g_isnan(t2->getf()) ) { | |
432 return t2; | |
433 } | |
434 else { | |
435 return Type::FLOAT; | |
436 } | |
437 } | |
438 | |
439 //============================================================================= | |
440 //------------------------------Ideal------------------------------------------ | |
441 Node *SubDNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
442 const Type *t2 = phase->type( in(2) ); | |
443 // Convert "x-c0" into "x+ -c0". | |
444 if( t2->base() == Type::DoubleCon ) { // Might be bottom or top... | |
445 // return new (phase->C, 3) AddDNode(in(1), phase->makecon( TypeD::make(-t2->getd()) ) ); | |
446 } | |
447 | |
448 // Not associative because of boundary conditions (infinity) | |
449 if( IdealizedNumerics && !phase->C->method()->is_strict() ) { | |
450 // Convert "x - (x+y)" into "-y" | |
451 if( in(2)->is_Add() && | |
452 phase->eqv(in(1),in(2)->in(1) ) ) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
453 return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); |
0 | 454 } |
455 | |
456 // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes | |
457 // 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0. | |
458 //if( phase->type(in(1)) == TypeD::ZERO ) | |
459 //return new (phase->C, 2) NegDNode(in(2)); | |
460 | |
461 return NULL; | |
462 } | |
463 | |
464 //------------------------------sub-------------------------------------------- | |
465 // A subtract node differences its two inputs. | |
466 const Type *SubDNode::sub( const Type *t1, const Type *t2 ) const { | |
467 // no folding if one of operands is infinity or NaN, do not do constant folding | |
468 if( g_isfinite(t1->getd()) && g_isfinite(t2->getd()) ) { | |
469 return TypeD::make( t1->getd() - t2->getd() ); | |
470 } | |
471 else if( g_isnan(t1->getd()) ) { | |
472 return t1; | |
473 } | |
474 else if( g_isnan(t2->getd()) ) { | |
475 return t2; | |
476 } | |
477 else { | |
478 return Type::DOUBLE; | |
479 } | |
480 } | |
481 | |
482 //============================================================================= | |
483 //------------------------------Idealize--------------------------------------- | |
484 // Unlike SubNodes, compare must still flatten return value to the | |
485 // range -1, 0, 1. | |
486 // And optimizations like those for (X + Y) - X fail if overflow happens. | |
487 Node *CmpNode::Identity( PhaseTransform *phase ) { | |
488 return this; | |
489 } | |
490 | |
491 //============================================================================= | |
492 //------------------------------cmp-------------------------------------------- | |
493 // Simplify a CmpI (compare 2 integers) node, based on local information. | |
494 // If both inputs are constants, compare them. | |
495 const Type *CmpINode::sub( const Type *t1, const Type *t2 ) const { | |
496 const TypeInt *r0 = t1->is_int(); // Handy access | |
497 const TypeInt *r1 = t2->is_int(); | |
498 | |
499 if( r0->_hi < r1->_lo ) // Range is always low? | |
500 return TypeInt::CC_LT; | |
501 else if( r0->_lo > r1->_hi ) // Range is always high? | |
502 return TypeInt::CC_GT; | |
503 | |
504 else if( r0->is_con() && r1->is_con() ) { // comparing constants? | |
505 assert(r0->get_con() == r1->get_con(), "must be equal"); | |
506 return TypeInt::CC_EQ; // Equal results. | |
507 } else if( r0->_hi == r1->_lo ) // Range is never high? | |
508 return TypeInt::CC_LE; | |
509 else if( r0->_lo == r1->_hi ) // Range is never low? | |
510 return TypeInt::CC_GE; | |
511 return TypeInt::CC; // else use worst case results | |
512 } | |
513 | |
514 // Simplify a CmpU (compare 2 integers) node, based on local information. | |
515 // If both inputs are constants, compare them. | |
516 const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const { | |
517 assert(!t1->isa_ptr(), "obsolete usage of CmpU"); | |
518 | |
519 // comparing two unsigned ints | |
520 const TypeInt *r0 = t1->is_int(); // Handy access | |
521 const TypeInt *r1 = t2->is_int(); | |
522 | |
523 // Current installed version | |
524 // Compare ranges for non-overlap | |
525 juint lo0 = r0->_lo; | |
526 juint hi0 = r0->_hi; | |
527 juint lo1 = r1->_lo; | |
528 juint hi1 = r1->_hi; | |
529 | |
530 // If either one has both negative and positive values, | |
531 // it therefore contains both 0 and -1, and since [0..-1] is the | |
532 // full unsigned range, the type must act as an unsigned bottom. | |
533 bool bot0 = ((jint)(lo0 ^ hi0) < 0); | |
534 bool bot1 = ((jint)(lo1 ^ hi1) < 0); | |
535 | |
536 if (bot0 || bot1) { | |
537 // All unsigned values are LE -1 and GE 0. | |
538 if (lo0 == 0 && hi0 == 0) { | |
539 return TypeInt::CC_LE; // 0 <= bot | |
540 } else if (lo1 == 0 && hi1 == 0) { | |
541 return TypeInt::CC_GE; // bot >= 0 | |
542 } | |
543 } else { | |
544 // We can use ranges of the form [lo..hi] if signs are the same. | |
545 assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid"); | |
546 // results are reversed, '-' > '+' for unsigned compare | |
547 if (hi0 < lo1) { | |
548 return TypeInt::CC_LT; // smaller | |
549 } else if (lo0 > hi1) { | |
550 return TypeInt::CC_GT; // greater | |
551 } else if (hi0 == lo1 && lo0 == hi1) { | |
552 return TypeInt::CC_EQ; // Equal results | |
553 } else if (lo0 >= hi1) { | |
554 return TypeInt::CC_GE; | |
555 } else if (hi0 <= lo1) { | |
556 // Check for special case in Hashtable::get. (See below.) | |
6207
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
557 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check()) |
0 | 558 return TypeInt::CC_LT; |
559 return TypeInt::CC_LE; | |
560 } | |
561 } | |
562 // Check for special case in Hashtable::get - the hash index is | |
563 // mod'ed to the table size so the following range check is useless. | |
564 // Check for: (X Mod Y) CmpU Y, where the mod result and Y both have | |
565 // to be positive. | |
566 // (This is a gross hack, since the sub method never | |
567 // looks at the structure of the node in any other case.) | |
6207
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
568 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check()) |
0 | 569 return TypeInt::CC_LT; |
570 return TypeInt::CC; // else use worst case results | |
571 } | |
572 | |
6207
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
573 bool CmpUNode::is_index_range_check() const { |
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
574 // Check for the "(X ModI Y) CmpU Y" shape |
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
575 return (in(1)->Opcode() == Op_ModI && |
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
576 in(1)->in(2)->eqv_uncast(in(2))); |
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
577 } |
ae9241bbce4a
7181658: CTW: assert(t->meet(t0) == t) failed: Not monotonic
kvn
parents:
6131
diff
changeset
|
578 |
0 | 579 //------------------------------Idealize--------------------------------------- |
580 Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) { | |
581 if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) { | |
582 switch (in(1)->Opcode()) { | |
583 case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
584 return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2)); |
0 | 585 case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
586 return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2)); |
0 | 587 case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
588 return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2)); |
0 | 589 //case Op_SubI: |
590 // If (x - y) cannot overflow, then ((x - y) <?> 0) | |
591 // can be turned into (x <?> y). | |
592 // This is handled (with more general cases) by Ideal_sub_algebra. | |
593 } | |
594 } | |
595 return NULL; // No change | |
596 } | |
597 | |
598 | |
599 //============================================================================= | |
600 // Simplify a CmpL (compare 2 longs ) node, based on local information. | |
601 // If both inputs are constants, compare them. | |
602 const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const { | |
603 const TypeLong *r0 = t1->is_long(); // Handy access | |
604 const TypeLong *r1 = t2->is_long(); | |
605 | |
606 if( r0->_hi < r1->_lo ) // Range is always low? | |
607 return TypeInt::CC_LT; | |
608 else if( r0->_lo > r1->_hi ) // Range is always high? | |
609 return TypeInt::CC_GT; | |
610 | |
611 else if( r0->is_con() && r1->is_con() ) { // comparing constants? | |
612 assert(r0->get_con() == r1->get_con(), "must be equal"); | |
613 return TypeInt::CC_EQ; // Equal results. | |
614 } else if( r0->_hi == r1->_lo ) // Range is never high? | |
615 return TypeInt::CC_LE; | |
616 else if( r0->_lo == r1->_hi ) // Range is never low? | |
617 return TypeInt::CC_GE; | |
618 return TypeInt::CC; // else use worst case results | |
619 } | |
620 | |
621 //============================================================================= | |
622 //------------------------------sub-------------------------------------------- | |
623 // Simplify an CmpP (compare 2 pointers) node, based on local information. | |
624 // If both inputs are constants, compare them. | |
625 const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const { | |
626 const TypePtr *r0 = t1->is_ptr(); // Handy access | |
627 const TypePtr *r1 = t2->is_ptr(); | |
628 | |
629 // Undefined inputs makes for an undefined result | |
630 if( TypePtr::above_centerline(r0->_ptr) || | |
631 TypePtr::above_centerline(r1->_ptr) ) | |
632 return Type::TOP; | |
633 | |
634 if (r0 == r1 && r0->singleton()) { | |
635 // Equal pointer constants (klasses, nulls, etc.) | |
636 return TypeInt::CC_EQ; | |
637 } | |
638 | |
639 // See if it is 2 unrelated classes. | |
640 const TypeOopPtr* p0 = r0->isa_oopptr(); | |
641 const TypeOopPtr* p1 = r1->isa_oopptr(); | |
642 if (p0 && p1) { | |
33 | 643 Node* in1 = in(1)->uncast(); |
644 Node* in2 = in(2)->uncast(); | |
645 AllocateNode* alloc1 = AllocateNode::Ideal_allocation(in1, NULL); | |
646 AllocateNode* alloc2 = AllocateNode::Ideal_allocation(in2, NULL); | |
647 if (MemNode::detect_ptr_independence(in1, alloc1, in2, alloc2, NULL)) { | |
648 return TypeInt::CC_GT; // different pointers | |
649 } | |
0 | 650 ciKlass* klass0 = p0->klass(); |
651 bool xklass0 = p0->klass_is_exact(); | |
652 ciKlass* klass1 = p1->klass(); | |
653 bool xklass1 = p1->klass_is_exact(); | |
654 int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0); | |
655 if (klass0 && klass1 && | |
656 kps != 1 && // both or neither are klass pointers | |
668
90a66aa50514
6820510: assertion failure with unloaded class in subnode.cpp
never
parents:
400
diff
changeset
|
657 klass0->is_loaded() && !klass0->is_interface() && // do not trust interfaces |
783
a9e116455022
6832293: JIT compiler got wrong result in type checking with -server
kvn
parents:
668
diff
changeset
|
658 klass1->is_loaded() && !klass1->is_interface() && |
a9e116455022
6832293: JIT compiler got wrong result in type checking with -server
kvn
parents:
668
diff
changeset
|
659 (!klass0->is_obj_array_klass() || |
a9e116455022
6832293: JIT compiler got wrong result in type checking with -server
kvn
parents:
668
diff
changeset
|
660 !klass0->as_obj_array_klass()->base_element_klass()->is_interface()) && |
a9e116455022
6832293: JIT compiler got wrong result in type checking with -server
kvn
parents:
668
diff
changeset
|
661 (!klass1->is_obj_array_klass() || |
a9e116455022
6832293: JIT compiler got wrong result in type checking with -server
kvn
parents:
668
diff
changeset
|
662 !klass1->as_obj_array_klass()->base_element_klass()->is_interface())) { |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
663 bool unrelated_classes = false; |
0 | 664 // See if neither subclasses the other, or if the class on top |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
665 // is precise. In either of these cases, the compare is known |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
666 // to fail if at least one of the pointers is provably not null. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6207
diff
changeset
|
667 if (klass0->equals(klass1)) { // if types are unequal but klasses are equal |
0 | 668 // Do nothing; we know nothing for imprecise types |
669 } else if (klass0->is_subtype_of(klass1)) { | |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
670 // If klass1's type is PRECISE, then classes are unrelated. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
671 unrelated_classes = xklass1; |
0 | 672 } else if (klass1->is_subtype_of(klass0)) { |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
673 // If klass0's type is PRECISE, then classes are unrelated. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
674 unrelated_classes = xklass0; |
0 | 675 } else { // Neither subtypes the other |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
676 unrelated_classes = true; |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
677 } |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
678 if (unrelated_classes) { |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
679 // The oops classes are known to be unrelated. If the joined PTRs of |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
680 // two oops is not Null and not Bottom, then we are sure that one |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
681 // of the two oops is non-null, and the comparison will always fail. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
682 TypePtr::PTR jp = r0->join_ptr(r1->_ptr); |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
683 if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
684 return TypeInt::CC_GT; |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
685 } |
0 | 686 } |
687 } | |
688 } | |
689 | |
690 // Known constants can be compared exactly | |
691 // Null can be distinguished from any NotNull pointers | |
692 // Unknown inputs makes an unknown result | |
693 if( r0->singleton() ) { | |
694 intptr_t bits0 = r0->get_con(); | |
695 if( r1->singleton() ) | |
696 return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT; | |
697 return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC; | |
698 } else if( r1->singleton() ) { | |
699 intptr_t bits1 = r1->get_con(); | |
700 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC; | |
701 } else | |
702 return TypeInt::CC; | |
703 } | |
704 | |
6131
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
705 static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
706 // Return the klass node for |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
707 // LoadP(AddP(foo:Klass, #java_mirror)) |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
708 // or NULL if not matching. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
709 if (n->Opcode() != Op_LoadP) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
710 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
711 const TypeInstPtr* tp = phase->type(n)->isa_instptr(); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
712 if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
713 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
714 Node* adr = n->in(MemNode::Address); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
715 intptr_t off = 0; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
716 Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
717 if (k == NULL) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
718 const TypeKlassPtr* tkp = phase->type(k)->isa_klassptr(); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
719 if (!tkp || off != in_bytes(Klass::java_mirror_offset())) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
720 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
721 // We've found the klass node of a Java mirror load. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
722 return k; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
723 } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
724 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
725 static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
726 // for ConP(Foo.class) return ConP(Foo.klass) |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
727 // otherwise return NULL |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
728 if (!n->is_Con()) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
729 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
730 const TypeInstPtr* tp = phase->type(n)->isa_instptr(); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
731 if (!tp) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
732 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
733 ciType* mirror_type = tp->java_mirror_type(); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
734 // TypeInstPtr::java_mirror_type() returns non-NULL for compile- |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
735 // time Class constants only. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
736 if (!mirror_type) return NULL; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
737 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
738 // x.getClass() == int.class can never be true (for all primitive types) |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
739 // Return a ConP(NULL) node for this case. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
740 if (mirror_type->is_classless()) { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
741 return phase->makecon(TypePtr::NULL_PTR); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
742 } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
743 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
744 // return the ConP(Foo.klass) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6207
diff
changeset
|
745 assert(mirror_type->is_klass(), "mirror_type should represent a Klass*"); |
6131
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
746 return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass())); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
747 } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
748 |
0 | 749 //------------------------------Ideal------------------------------------------ |
6131
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
750 // Normalize comparisons between Java mirror loads to compare the klass instead. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
751 // |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
752 // Also check for the case of comparing an unknown klass loaded from the primary |
0 | 753 // super-type array vs a known klass with no subtypes. This amounts to |
754 // checking to see an unknown klass subtypes a known klass with no subtypes; | |
755 // this only happens on an exact match. We can shorten this test by 1 load. | |
756 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { | |
6131
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
757 // Normalize comparisons between Java mirrors into comparisons of the low- |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
758 // level klass, where a dependent load could be shortened. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
759 // |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
760 // The new pattern has a nice effect of matching the same pattern used in the |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
761 // fast path of instanceof/checkcast/Class.isInstance(), which allows |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
762 // redundant exact type check be optimized away by GVN. |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
763 // For example, in |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
764 // if (x.getClass() == Foo.class) { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
765 // Foo foo = (Foo) x; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
766 // // ... use a ... |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
767 // } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
768 // a CmpPNode could be shared between if_acmpne and checkcast |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
769 { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
770 Node* k1 = isa_java_mirror_load(phase, in(1)); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
771 Node* k2 = isa_java_mirror_load(phase, in(2)); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
772 Node* conk2 = isa_const_java_mirror(phase, in(2)); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
773 |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
774 if (k1 && (k2 || conk2)) { |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
775 Node* lhs = k1; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
776 Node* rhs = (k2 != NULL) ? k2 : conk2; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
777 this->set_req(1, lhs); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
778 this->set_req(2, rhs); |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
779 return this; |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
780 } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
781 } |
8f6ce6f1049b
7170463: C2 should recognize "obj.getClass() == A.class" code pattern
kvn
parents:
6084
diff
changeset
|
782 |
0 | 783 // Constant pointer on right? |
784 const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr(); | |
785 if (t2 == NULL || !t2->klass_is_exact()) | |
786 return NULL; | |
787 // Get the constant klass we are comparing to. | |
788 ciKlass* superklass = t2->klass(); | |
789 | |
790 // Now check for LoadKlass on left. | |
791 Node* ldk1 = in(1); | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
792 if (ldk1->is_DecodeNKlass()) { |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
793 ldk1 = ldk1->in(1); |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
794 if (ldk1->Opcode() != Op_LoadNKlass ) |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
795 return NULL; |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
796 } else if (ldk1->Opcode() != Op_LoadKlass ) |
0 | 797 return NULL; |
798 // Take apart the address of the LoadKlass: | |
799 Node* adr1 = ldk1->in(MemNode::Address); | |
800 intptr_t con2 = 0; | |
801 Node* ldk2 = AddPNode::Ideal_base_and_offset(adr1, phase, con2); | |
802 if (ldk2 == NULL) | |
803 return NULL; | |
804 if (con2 == oopDesc::klass_offset_in_bytes()) { | |
805 // We are inspecting an object's concrete class. | |
806 // Short-circuit the check if the query is abstract. | |
807 if (superklass->is_interface() || | |
808 superklass->is_abstract()) { | |
809 // Make it come out always false: | |
810 this->set_req(2, phase->makecon(TypePtr::NULL_PTR)); | |
811 return this; | |
812 } | |
813 } | |
814 | |
815 // Check for a LoadKlass from primary supertype array. | |
816 // Any nested loadklass from loadklass+con must be from the p.s. array. | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
817 if (ldk2->is_DecodeNKlass()) { |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
818 // Keep ldk2 as DecodeN since it could be used in CmpP below. |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
819 if (ldk2->in(1)->Opcode() != Op_LoadNKlass ) |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
820 return NULL; |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
235
diff
changeset
|
821 } else if (ldk2->Opcode() != Op_LoadKlass) |
0 | 822 return NULL; |
823 | |
824 // Verify that we understand the situation | |
825 if (con2 != (intptr_t) superklass->super_check_offset()) | |
826 return NULL; // Might be element-klass loading from array klass | |
827 | |
828 // If 'superklass' has no subklasses and is not an interface, then we are | |
829 // assured that the only input which will pass the type check is | |
830 // 'superklass' itself. | |
831 // | |
832 // We could be more liberal here, and allow the optimization on interfaces | |
833 // which have a single implementor. This would require us to increase the | |
834 // expressiveness of the add_dependency() mechanism. | |
835 // %%% Do this after we fix TypeOopPtr: Deps are expressive enough now. | |
836 | |
837 // Object arrays must have their base element have no subtypes | |
838 while (superklass->is_obj_array_klass()) { | |
839 ciType* elem = superklass->as_obj_array_klass()->element_type(); | |
840 superklass = elem->as_klass(); | |
841 } | |
842 if (superklass->is_instance_klass()) { | |
843 ciInstanceKlass* ik = superklass->as_instance_klass(); | |
844 if (ik->has_subklass() || ik->is_interface()) return NULL; | |
845 // Add a dependency if there is a chance that a subclass will be added later. | |
846 if (!ik->is_final()) { | |
847 phase->C->dependencies()->assert_leaf_type(ik); | |
848 } | |
849 } | |
850 | |
851 // Bypass the dependent load, and compare directly | |
852 this->set_req(1,ldk2); | |
853 | |
854 return this; | |
855 } | |
856 | |
857 //============================================================================= | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
858 //------------------------------sub-------------------------------------------- |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
859 // Simplify an CmpN (compare 2 pointers) node, based on local information. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
860 // If both inputs are constants, compare them. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
861 const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
212
diff
changeset
|
862 const TypePtr *r0 = t1->make_ptr(); // Handy access |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
212
diff
changeset
|
863 const TypePtr *r1 = t2->make_ptr(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
864 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
865 // Undefined inputs makes for an undefined result |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
866 if( TypePtr::above_centerline(r0->_ptr) || |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
867 TypePtr::above_centerline(r1->_ptr) ) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
868 return Type::TOP; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
869 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
870 if (r0 == r1 && r0->singleton()) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
871 // Equal pointer constants (klasses, nulls, etc.) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
872 return TypeInt::CC_EQ; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
873 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
874 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
875 // See if it is 2 unrelated classes. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
876 const TypeOopPtr* p0 = r0->isa_oopptr(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
877 const TypeOopPtr* p1 = r1->isa_oopptr(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
878 if (p0 && p1) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
879 ciKlass* klass0 = p0->klass(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
880 bool xklass0 = p0->klass_is_exact(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
881 ciKlass* klass1 = p1->klass(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
882 bool xklass1 = p1->klass_is_exact(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
883 int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
884 if (klass0 && klass1 && |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
885 kps != 1 && // both or neither are klass pointers |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
886 !klass0->is_interface() && // do not trust interfaces |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
887 !klass1->is_interface()) { |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
888 bool unrelated_classes = false; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
889 // See if neither subclasses the other, or if the class on top |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
890 // is precise. In either of these cases, the compare is known |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
891 // to fail if at least one of the pointers is provably not null. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6207
diff
changeset
|
892 if (klass0->equals(klass1)) { // if types are unequal but klasses are equal |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
893 // Do nothing; we know nothing for imprecise types |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
894 } else if (klass0->is_subtype_of(klass1)) { |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
895 // If klass1's type is PRECISE, then classes are unrelated. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
896 unrelated_classes = xklass1; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
897 } else if (klass1->is_subtype_of(klass0)) { |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
898 // If klass0's type is PRECISE, then classes are unrelated. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
899 unrelated_classes = xklass0; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
900 } else { // Neither subtypes the other |
296
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
901 unrelated_classes = true; |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
902 } |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
903 if (unrelated_classes) { |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
904 // The oops classes are known to be unrelated. If the joined PTRs of |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
905 // two oops is not Null and not Bottom, then we are sure that one |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
906 // of the two oops is non-null, and the comparison will always fail. |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
907 TypePtr::PTR jp = r0->join_ptr(r1->_ptr); |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
908 if (jp != TypePtr::Null && jp != TypePtr::BotPTR) { |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
909 return TypeInt::CC_GT; |
ce93a51457ae
6730716: nulls from two unrelated classes compare not equal
rasbold
parents:
293
diff
changeset
|
910 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
911 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
912 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
913 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
914 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
915 // Known constants can be compared exactly |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
916 // Null can be distinguished from any NotNull pointers |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
917 // Unknown inputs makes an unknown result |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
918 if( r0->singleton() ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
919 intptr_t bits0 = r0->get_con(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
920 if( r1->singleton() ) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
921 return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
922 return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
923 } else if( r1->singleton() ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
924 intptr_t bits1 = r1->get_con(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
925 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
926 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
927 return TypeInt::CC; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
928 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
929 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
930 //------------------------------Ideal------------------------------------------ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
931 Node *CmpNNode::Ideal( PhaseGVN *phase, bool can_reshape ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
932 return NULL; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
933 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
934 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
33
diff
changeset
|
935 //============================================================================= |
0 | 936 //------------------------------Value------------------------------------------ |
937 // Simplify an CmpF (compare 2 floats ) node, based on local information. | |
938 // If both inputs are constants, compare them. | |
939 const Type *CmpFNode::Value( PhaseTransform *phase ) const { | |
940 const Node* in1 = in(1); | |
941 const Node* in2 = in(2); | |
942 // Either input is TOP ==> the result is TOP | |
943 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); | |
944 if( t1 == Type::TOP ) return Type::TOP; | |
945 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2); | |
946 if( t2 == Type::TOP ) return Type::TOP; | |
947 | |
948 // Not constants? Don't know squat - even if they are the same | |
949 // value! If they are NaN's they compare to LT instead of EQ. | |
950 const TypeF *tf1 = t1->isa_float_constant(); | |
951 const TypeF *tf2 = t2->isa_float_constant(); | |
952 if( !tf1 || !tf2 ) return TypeInt::CC; | |
953 | |
954 // This implements the Java bytecode fcmpl, so unordered returns -1. | |
955 if( tf1->is_nan() || tf2->is_nan() ) | |
956 return TypeInt::CC_LT; | |
957 | |
958 if( tf1->_f < tf2->_f ) return TypeInt::CC_LT; | |
959 if( tf1->_f > tf2->_f ) return TypeInt::CC_GT; | |
960 assert( tf1->_f == tf2->_f, "do not understand FP behavior" ); | |
961 return TypeInt::CC_EQ; | |
962 } | |
963 | |
964 | |
965 //============================================================================= | |
966 //------------------------------Value------------------------------------------ | |
967 // Simplify an CmpD (compare 2 doubles ) node, based on local information. | |
968 // If both inputs are constants, compare them. | |
969 const Type *CmpDNode::Value( PhaseTransform *phase ) const { | |
970 const Node* in1 = in(1); | |
971 const Node* in2 = in(2); | |
972 // Either input is TOP ==> the result is TOP | |
973 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); | |
974 if( t1 == Type::TOP ) return Type::TOP; | |
975 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2); | |
976 if( t2 == Type::TOP ) return Type::TOP; | |
977 | |
978 // Not constants? Don't know squat - even if they are the same | |
979 // value! If they are NaN's they compare to LT instead of EQ. | |
980 const TypeD *td1 = t1->isa_double_constant(); | |
981 const TypeD *td2 = t2->isa_double_constant(); | |
982 if( !td1 || !td2 ) return TypeInt::CC; | |
983 | |
984 // This implements the Java bytecode dcmpl, so unordered returns -1. | |
985 if( td1->is_nan() || td2->is_nan() ) | |
986 return TypeInt::CC_LT; | |
987 | |
988 if( td1->_d < td2->_d ) return TypeInt::CC_LT; | |
989 if( td1->_d > td2->_d ) return TypeInt::CC_GT; | |
990 assert( td1->_d == td2->_d, "do not understand FP behavior" ); | |
991 return TypeInt::CC_EQ; | |
992 } | |
993 | |
994 //------------------------------Ideal------------------------------------------ | |
995 Node *CmpDNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
996 // Check if we can change this to a CmpF and remove a ConvD2F operation. | |
997 // Change (CMPD (F2D (float)) (ConD value)) | |
998 // To (CMPF (float) (ConF value)) | |
999 // Valid when 'value' does not lose precision as a float. | |
1000 // Benefits: eliminates conversion, does not require 24-bit mode | |
1001 | |
1002 // NaNs prevent commuting operands. This transform works regardless of the | |
1003 // order of ConD and ConvF2D inputs by preserving the original order. | |
1004 int idx_f2d = 1; // ConvF2D on left side? | |
1005 if( in(idx_f2d)->Opcode() != Op_ConvF2D ) | |
1006 idx_f2d = 2; // No, swap to check for reversed args | |
1007 int idx_con = 3-idx_f2d; // Check for the constant on other input | |
1008 | |
1009 if( ConvertCmpD2CmpF && | |
1010 in(idx_f2d)->Opcode() == Op_ConvF2D && | |
1011 in(idx_con)->Opcode() == Op_ConD ) { | |
1012 const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant(); | |
1013 double t2_value_as_double = t2->_d; | |
1014 float t2_value_as_float = (float)t2_value_as_double; | |
1015 if( t2_value_as_double == (double)t2_value_as_float ) { | |
1016 // Test value can be represented as a float | |
1017 // Eliminate the conversion to double and create new comparison | |
1018 Node *new_in1 = in(idx_f2d)->in(1); | |
1019 Node *new_in2 = phase->makecon( TypeF::make(t2_value_as_float) ); | |
1020 if( idx_f2d != 1 ) { // Must flip args to match original order | |
1021 Node *tmp = new_in1; | |
1022 new_in1 = new_in2; | |
1023 new_in2 = tmp; | |
1024 } | |
1025 CmpFNode *new_cmp = (Opcode() == Op_CmpD3) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1026 ? new (phase->C) CmpF3Node( new_in1, new_in2 ) |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1027 : new (phase->C) CmpFNode ( new_in1, new_in2 ) ; |
0 | 1028 return new_cmp; // Changed to CmpFNode |
1029 } | |
1030 // Testing value required the precision of a double | |
1031 } | |
1032 return NULL; // No change | |
1033 } | |
1034 | |
1035 | |
1036 //============================================================================= | |
1037 //------------------------------cc2logical------------------------------------- | |
1038 // Convert a condition code type to a logical type | |
1039 const Type *BoolTest::cc2logical( const Type *CC ) const { | |
1040 if( CC == Type::TOP ) return Type::TOP; | |
1041 if( CC->base() != Type::Int ) return TypeInt::BOOL; // Bottom or worse | |
1042 const TypeInt *ti = CC->is_int(); | |
1043 if( ti->is_con() ) { // Only 1 kind of condition codes set? | |
1044 // Match low order 2 bits | |
1045 int tmp = ((ti->get_con()&3) == (_test&3)) ? 1 : 0; | |
1046 if( _test & 4 ) tmp = 1-tmp; // Optionally complement result | |
1047 return TypeInt::make(tmp); // Boolean result | |
1048 } | |
1049 | |
1050 if( CC == TypeInt::CC_GE ) { | |
1051 if( _test == ge ) return TypeInt::ONE; | |
1052 if( _test == lt ) return TypeInt::ZERO; | |
1053 } | |
1054 if( CC == TypeInt::CC_LE ) { | |
1055 if( _test == le ) return TypeInt::ONE; | |
1056 if( _test == gt ) return TypeInt::ZERO; | |
1057 } | |
1058 | |
1059 return TypeInt::BOOL; | |
1060 } | |
1061 | |
1062 //------------------------------dump_spec------------------------------------- | |
1063 // Print special per-node info | |
1064 #ifndef PRODUCT | |
1065 void BoolTest::dump_on(outputStream *st) const { | |
1066 const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"}; | |
1067 st->print(msg[_test]); | |
1068 } | |
1069 #endif | |
1070 | |
1071 //============================================================================= | |
1072 uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); } | |
1073 uint BoolNode::size_of() const { return sizeof(BoolNode); } | |
1074 | |
1075 //------------------------------operator==------------------------------------- | |
1076 uint BoolNode::cmp( const Node &n ) const { | |
1077 const BoolNode *b = (const BoolNode *)&n; // Cast up | |
1078 return (_test._test == b->_test._test); | |
1079 } | |
1080 | |
1081 //-------------------------------make_predicate-------------------------------- | |
1082 Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) { | |
1083 if (test_value->is_Con()) return test_value; | |
1084 if (test_value->is_Bool()) return test_value; | |
1085 Compile* C = phase->C; | |
1086 if (test_value->is_CMove() && | |
1087 test_value->in(CMoveNode::Condition)->is_Bool()) { | |
1088 BoolNode* bol = test_value->in(CMoveNode::Condition)->as_Bool(); | |
1089 const Type* ftype = phase->type(test_value->in(CMoveNode::IfFalse)); | |
1090 const Type* ttype = phase->type(test_value->in(CMoveNode::IfTrue)); | |
1091 if (ftype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ttype)) { | |
1092 return bol; | |
1093 } else if (ttype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ftype)) { | |
1094 return phase->transform( bol->negate(phase) ); | |
1095 } | |
1096 // Else fall through. The CMove gets in the way of the test. | |
1097 // It should be the case that make_predicate(bol->as_int_value()) == bol. | |
1098 } | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1099 Node* cmp = new (C) CmpINode(test_value, phase->intcon(0)); |
0 | 1100 cmp = phase->transform(cmp); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1101 Node* bol = new (C) BoolNode(cmp, BoolTest::ne); |
0 | 1102 return phase->transform(bol); |
1103 } | |
1104 | |
1105 //--------------------------------as_int_value--------------------------------- | |
1106 Node* BoolNode::as_int_value(PhaseGVN* phase) { | |
1107 // Inverse to make_predicate. The CMove probably boils down to a Conv2B. | |
1108 Node* cmov = CMoveNode::make(phase->C, NULL, this, | |
1109 phase->intcon(0), phase->intcon(1), | |
1110 TypeInt::BOOL); | |
1111 return phase->transform(cmov); | |
1112 } | |
1113 | |
1114 //----------------------------------negate------------------------------------- | |
1115 BoolNode* BoolNode::negate(PhaseGVN* phase) { | |
1116 Compile* C = phase->C; | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1117 return new (C) BoolNode(in(1), _test.negate()); |
0 | 1118 } |
1119 | |
1120 | |
1121 //------------------------------Ideal------------------------------------------ | |
1122 Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1123 // Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)". | |
1124 // This moves the constant to the right. Helps value-numbering. | |
1125 Node *cmp = in(1); | |
1126 if( !cmp->is_Sub() ) return NULL; | |
1127 int cop = cmp->Opcode(); | |
1128 if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL; | |
1129 Node *cmp1 = cmp->in(1); | |
1130 Node *cmp2 = cmp->in(2); | |
1131 if( !cmp1 ) return NULL; | |
1132 | |
1133 // Constant on left? | |
1134 Node *con = cmp1; | |
1135 uint op2 = cmp2->Opcode(); | |
1136 // Move constants to the right of compare's to canonicalize. | |
1137 // Do not muck with Opaque1 nodes, as this indicates a loop | |
1138 // guard that cannot change shape. | |
1139 if( con->is_Con() && !cmp2->is_Con() && op2 != Op_Opaque1 && | |
1140 // Because of NaN's, CmpD and CmpF are not commutative | |
1141 cop != Op_CmpD && cop != Op_CmpF && | |
1142 // Protect against swapping inputs to a compare when it is used by a | |
1143 // counted loop exit, which requires maintaining the loop-limit as in(2) | |
1144 !is_counted_loop_exit_test() ) { | |
1145 // Ok, commute the constant to the right of the cmp node. | |
1146 // Clone the Node, getting a new Node of the same class | |
1147 cmp = cmp->clone(); | |
1148 // Swap inputs to the clone | |
1149 cmp->swap_edges(1, 2); | |
1150 cmp = phase->transform( cmp ); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1151 return new (phase->C) BoolNode( cmp, _test.commute() ); |
0 | 1152 } |
1153 | |
1154 // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)". | |
1155 // The XOR-1 is an idiom used to flip the sense of a bool. We flip the | |
1156 // test instead. | |
1157 int cmp1_op = cmp1->Opcode(); | |
1158 const TypeInt* cmp2_type = phase->type(cmp2)->isa_int(); | |
1159 if (cmp2_type == NULL) return NULL; | |
1160 Node* j_xor = cmp1; | |
1161 if( cmp2_type == TypeInt::ZERO && | |
1162 cmp1_op == Op_XorI && | |
1163 j_xor->in(1) != j_xor && // An xor of itself is dead | |
3743 | 1164 phase->type( j_xor->in(1) ) == TypeInt::BOOL && |
0 | 1165 phase->type( j_xor->in(2) ) == TypeInt::ONE && |
1166 (_test._test == BoolTest::eq || | |
1167 _test._test == BoolTest::ne) ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1168 Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1169 return new (phase->C) BoolNode( ncmp, _test.negate() ); |
0 | 1170 } |
1171 | |
1172 // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)". | |
1173 // This is a standard idiom for branching on a boolean value. | |
1174 Node *c2b = cmp1; | |
1175 if( cmp2_type == TypeInt::ZERO && | |
1176 cmp1_op == Op_Conv2B && | |
1177 (_test._test == BoolTest::eq || | |
1178 _test._test == BoolTest::ne) ) { | |
1179 Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int() | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1180 ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2) |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1181 : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) |
0 | 1182 ); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1183 return new (phase->C) BoolNode( ncmp, _test._test ); |
0 | 1184 } |
1185 | |
1186 // Comparing a SubI against a zero is equal to comparing the SubI | |
1187 // arguments directly. This only works for eq and ne comparisons | |
1188 // due to possible integer overflow. | |
1189 if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) && | |
1190 (cop == Op_CmpI) && | |
1191 (cmp1->Opcode() == Op_SubI) && | |
1192 ( cmp2_type == TypeInt::ZERO ) ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1193 Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2))); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1194 return new (phase->C) BoolNode( ncmp, _test._test ); |
0 | 1195 } |
1196 | |
1197 // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the | |
1198 // most general case because negating 0x80000000 does nothing. Needed for | |
1199 // the CmpF3/SubI/CmpI idiom. | |
1200 if( cop == Op_CmpI && | |
1201 cmp1->Opcode() == Op_SubI && | |
1202 cmp2_type == TypeInt::ZERO && | |
1203 phase->type( cmp1->in(1) ) == TypeInt::ZERO && | |
1204 phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1205 Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1206 return new (phase->C) BoolNode( ncmp, _test.commute() ); |
0 | 1207 } |
1208 | |
1209 // The transformation below is not valid for either signed or unsigned | |
1210 // comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE. | |
1211 // This transformation can be resurrected when we are able to | |
1212 // make inferences about the range of values being subtracted from | |
1213 // (or added to) relative to the wraparound point. | |
1214 // | |
1215 // // Remove +/-1's if possible. | |
1216 // // "X <= Y-1" becomes "X < Y" | |
1217 // // "X+1 <= Y" becomes "X < Y" | |
1218 // // "X < Y+1" becomes "X <= Y" | |
1219 // // "X-1 < Y" becomes "X <= Y" | |
1220 // // Do not this to compares off of the counted-loop-end. These guys are | |
1221 // // checking the trip counter and they want to use the post-incremented | |
1222 // // counter. If they use the PRE-incremented counter, then the counter has | |
1223 // // to be incremented in a private block on a loop backedge. | |
1224 // if( du && du->cnt(this) && du->out(this)[0]->Opcode() == Op_CountedLoopEnd ) | |
1225 // return NULL; | |
1226 // #ifndef PRODUCT | |
1227 // // Do not do this in a wash GVN pass during verification. | |
1228 // // Gets triggered by too many simple optimizations to be bothered with | |
1229 // // re-trying it again and again. | |
1230 // if( !phase->allow_progress() ) return NULL; | |
1231 // #endif | |
1232 // // Not valid for unsigned compare because of corner cases in involving zero. | |
1233 // // For example, replacing "X-1 <u Y" with "X <=u Y" fails to throw an | |
1234 // // exception in case X is 0 (because 0-1 turns into 4billion unsigned but | |
1235 // // "0 <=u Y" is always true). | |
1236 // if( cmp->Opcode() == Op_CmpU ) return NULL; | |
1237 // int cmp2_op = cmp2->Opcode(); | |
1238 // if( _test._test == BoolTest::le ) { | |
1239 // if( cmp1_op == Op_AddI && | |
1240 // phase->type( cmp1->in(2) ) == TypeInt::ONE ) | |
1241 // return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::lt ); | |
1242 // else if( cmp2_op == Op_AddI && | |
1243 // phase->type( cmp2->in(2) ) == TypeInt::MINUS_1 ) | |
1244 // return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::lt ); | |
1245 // } else if( _test._test == BoolTest::lt ) { | |
1246 // if( cmp1_op == Op_AddI && | |
1247 // phase->type( cmp1->in(2) ) == TypeInt::MINUS_1 ) | |
1248 // return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::le ); | |
1249 // else if( cmp2_op == Op_AddI && | |
1250 // phase->type( cmp2->in(2) ) == TypeInt::ONE ) | |
1251 // return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::le ); | |
1252 // } | |
1253 | |
1254 return NULL; | |
1255 } | |
1256 | |
1257 //------------------------------Value------------------------------------------ | |
1258 // Simplify a Bool (convert condition codes to boolean (1 or 0)) node, | |
1259 // based on local information. If the input is constant, do it. | |
1260 const Type *BoolNode::Value( PhaseTransform *phase ) const { | |
1261 return _test.cc2logical( phase->type( in(1) ) ); | |
1262 } | |
1263 | |
1264 //------------------------------dump_spec-------------------------------------- | |
1265 // Dump special per-node info | |
1266 #ifndef PRODUCT | |
1267 void BoolNode::dump_spec(outputStream *st) const { | |
1268 st->print("["); | |
1269 _test.dump_on(st); | |
1270 st->print("]"); | |
1271 } | |
1272 #endif | |
1273 | |
1274 //------------------------------is_counted_loop_exit_test-------------------------------------- | |
1275 // Returns true if node is used by a counted loop node. | |
1276 bool BoolNode::is_counted_loop_exit_test() { | |
1277 for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { | |
1278 Node* use = fast_out(i); | |
1279 if (use->is_CountedLoopEnd()) { | |
1280 return true; | |
1281 } | |
1282 } | |
1283 return false; | |
1284 } | |
1285 | |
1286 //============================================================================= | |
1287 //------------------------------Value------------------------------------------ | |
1288 // Compute sqrt | |
1289 const Type *SqrtDNode::Value( PhaseTransform *phase ) const { | |
1290 const Type *t1 = phase->type( in(1) ); | |
1291 if( t1 == Type::TOP ) return Type::TOP; | |
1292 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1293 double d = t1->getd(); | |
1294 if( d < 0.0 ) return Type::DOUBLE; | |
1295 return TypeD::make( sqrt( d ) ); | |
1296 } | |
1297 | |
1298 //============================================================================= | |
1299 //------------------------------Value------------------------------------------ | |
1300 // Compute cos | |
1301 const Type *CosDNode::Value( PhaseTransform *phase ) const { | |
1302 const Type *t1 = phase->type( in(1) ); | |
1303 if( t1 == Type::TOP ) return Type::TOP; | |
1304 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1305 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1306 return TypeD::make( StubRoutines::intrinsic_cos( d ) ); |
0 | 1307 } |
1308 | |
1309 //============================================================================= | |
1310 //------------------------------Value------------------------------------------ | |
1311 // Compute sin | |
1312 const Type *SinDNode::Value( PhaseTransform *phase ) const { | |
1313 const Type *t1 = phase->type( in(1) ); | |
1314 if( t1 == Type::TOP ) return Type::TOP; | |
1315 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1316 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1317 return TypeD::make( StubRoutines::intrinsic_sin( d ) ); |
0 | 1318 } |
1319 | |
1320 //============================================================================= | |
1321 //------------------------------Value------------------------------------------ | |
1322 // Compute tan | |
1323 const Type *TanDNode::Value( PhaseTransform *phase ) const { | |
1324 const Type *t1 = phase->type( in(1) ); | |
1325 if( t1 == Type::TOP ) return Type::TOP; | |
1326 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1327 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1328 return TypeD::make( StubRoutines::intrinsic_tan( d ) ); |
0 | 1329 } |
1330 | |
1331 //============================================================================= | |
1332 //------------------------------Value------------------------------------------ | |
1333 // Compute log | |
1334 const Type *LogDNode::Value( PhaseTransform *phase ) const { | |
1335 const Type *t1 = phase->type( in(1) ); | |
1336 if( t1 == Type::TOP ) return Type::TOP; | |
1337 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1338 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1339 return TypeD::make( StubRoutines::intrinsic_log( d ) ); |
0 | 1340 } |
1341 | |
1342 //============================================================================= | |
1343 //------------------------------Value------------------------------------------ | |
1344 // Compute log10 | |
1345 const Type *Log10DNode::Value( PhaseTransform *phase ) const { | |
1346 const Type *t1 = phase->type( in(1) ); | |
1347 if( t1 == Type::TOP ) return Type::TOP; | |
1348 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1349 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1350 return TypeD::make( StubRoutines::intrinsic_log10( d ) ); |
0 | 1351 } |
1352 | |
1353 //============================================================================= | |
1354 //------------------------------Value------------------------------------------ | |
1355 // Compute exp | |
1356 const Type *ExpDNode::Value( PhaseTransform *phase ) const { | |
1357 const Type *t1 = phase->type( in(1) ); | |
1358 if( t1 == Type::TOP ) return Type::TOP; | |
1359 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1360 double d = t1->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1361 return TypeD::make( StubRoutines::intrinsic_exp( d ) ); |
0 | 1362 } |
1363 | |
1364 | |
1365 //============================================================================= | |
1366 //------------------------------Value------------------------------------------ | |
1367 // Compute pow | |
1368 const Type *PowDNode::Value( PhaseTransform *phase ) const { | |
1369 const Type *t1 = phase->type( in(1) ); | |
1370 if( t1 == Type::TOP ) return Type::TOP; | |
1371 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1372 const Type *t2 = phase->type( in(2) ); | |
1373 if( t2 == Type::TOP ) return Type::TOP; | |
1374 if( t2->base() != Type::DoubleCon ) return Type::DOUBLE; | |
1375 double d1 = t1->getd(); | |
1376 double d2 = t2->getd(); | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
844
diff
changeset
|
1377 return TypeD::make( StubRoutines::intrinsic_pow( d1, d2 ) ); |
0 | 1378 } |