Mercurial > hg > truffle
annotate src/share/vm/opto/connode.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 | 7944aba7ba41 |
rev | line source |
---|---|
0 | 1 /* |
5901 | 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:
995
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
995
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:
995
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.inline.hpp" | |
27 #include "opto/addnode.hpp" | |
28 #include "opto/compile.hpp" | |
29 #include "opto/connode.hpp" | |
30 #include "opto/machnode.hpp" | |
31 #include "opto/matcher.hpp" | |
32 #include "opto/memnode.hpp" | |
33 #include "opto/phaseX.hpp" | |
34 #include "opto/subnode.hpp" | |
35 #include "runtime/sharedRuntime.hpp" | |
0 | 36 |
1972 | 37 // Optimization - Graph Style |
0 | 38 |
39 //============================================================================= | |
40 //------------------------------hash------------------------------------------- | |
41 uint ConNode::hash() const { | |
42 return (uintptr_t)in(TypeFunc::Control) + _type->hash(); | |
43 } | |
44 | |
45 //------------------------------make------------------------------------------- | |
46 ConNode *ConNode::make( Compile* C, const Type *t ) { | |
47 switch( t->basic_type() ) { | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
48 case T_INT: return new (C) ConINode( t->is_int() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
49 case T_LONG: return new (C) ConLNode( t->is_long() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
50 case T_FLOAT: return new (C) ConFNode( t->is_float_constant() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
51 case T_DOUBLE: return new (C) ConDNode( t->is_double_constant() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
52 case T_VOID: return new (C) ConNode ( Type::TOP ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
53 case T_OBJECT: return new (C) ConPNode( t->is_ptr() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
54 case T_ARRAY: return new (C) ConPNode( t->is_aryptr() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
55 case T_ADDRESS: return new (C) ConPNode( t->is_ptr() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
56 case T_NARROWOOP: return new (C) ConNNode( t->is_narrowoop() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
57 case T_NARROWKLASS: return new (C) ConNKlassNode( t->is_narrowklass() ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
58 case T_METADATA: return new (C) ConPNode( t->is_ptr() ); |
0 | 59 // Expected cases: TypePtr::NULL_PTR, any is_rawptr() |
60 // Also seen: AnyPtr(TopPTR *+top); from command line: | |
61 // r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660 | |
62 // %%%% Stop using TypePtr::NULL_PTR to represent nulls: use either TypeRawPtr::NULL_PTR | |
63 // or else TypeOopPtr::NULL_PTR. Then set Type::_basic_type[AnyPtr] = T_ILLEGAL | |
64 } | |
65 ShouldNotReachHere(); | |
66 return NULL; | |
67 } | |
68 | |
69 //============================================================================= | |
70 /* | |
71 The major change is for CMoveP and StrComp. They have related but slightly | |
72 different problems. They both take in TWO oops which are both null-checked | |
73 independently before the using Node. After CCP removes the CastPP's they need | |
74 to pick up the guarding test edge - in this case TWO control edges. I tried | |
75 various solutions, all have problems: | |
76 | |
77 (1) Do nothing. This leads to a bug where we hoist a Load from a CMoveP or a | |
78 StrComp above a guarding null check. I've seen both cases in normal -Xcomp | |
79 testing. | |
80 | |
81 (2) Plug the control edge from 1 of the 2 oops in. Apparent problem here is | |
82 to figure out which test post-dominates. The real problem is that it doesn't | |
83 matter which one you pick. After you pick up, the dominating-test elider in | |
84 IGVN can remove the test and allow you to hoist up to the dominating test on | |
605 | 85 the chosen oop bypassing the test on the not-chosen oop. Seen in testing. |
0 | 86 Oops. |
87 | |
88 (3) Leave the CastPP's in. This makes the graph more accurate in some sense; | |
89 we get to keep around the knowledge that an oop is not-null after some test. | |
90 Alas, the CastPP's interfere with GVN (some values are the regular oop, some | |
91 are the CastPP of the oop, all merge at Phi's which cannot collapse, etc). | |
92 This cost us 10% on SpecJVM, even when I removed some of the more trivial | |
93 cases in the optimizer. Removing more useless Phi's started allowing Loads to | |
94 illegally float above null checks. I gave up on this approach. | |
95 | |
96 (4) Add BOTH control edges to both tests. Alas, too much code knows that | |
97 control edges are in slot-zero ONLY. Many quick asserts fail; no way to do | |
98 this one. Note that I really want to allow the CMoveP to float and add both | |
99 control edges to the dependent Load op - meaning I can select early but I | |
100 cannot Load until I pass both tests. | |
101 | |
102 (5) Do not hoist CMoveP and StrComp. To this end I added the v-call | |
103 depends_only_on_test(). No obvious performance loss on Spec, but we are | |
104 clearly conservative on CMoveP (also so on StrComp but that's unlikely to | |
105 matter ever). | |
106 | |
107 */ | |
108 | |
109 | |
110 //------------------------------Ideal------------------------------------------ | |
111 // Return a node which is more "ideal" than the current node. | |
112 // Move constants to the right. | |
113 Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
114 if( in(0) && remove_dead_region(phase, can_reshape) ) return this; | |
305 | 115 // Don't bother trying to transform a dead node |
116 if( in(0) && in(0)->is_top() ) return NULL; | |
0 | 117 assert( !phase->eqv(in(Condition), this) && |
118 !phase->eqv(in(IfFalse), this) && | |
119 !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); | |
120 if( phase->type(in(Condition)) == Type::TOP ) | |
121 return NULL; // return NULL when Condition is dead | |
122 | |
123 if( in(IfFalse)->is_Con() && !in(IfTrue)->is_Con() ) { | |
124 if( in(Condition)->is_Bool() ) { | |
125 BoolNode* b = in(Condition)->as_Bool(); | |
126 BoolNode* b2 = b->negate(phase); | |
127 return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); | |
128 } | |
129 } | |
130 return NULL; | |
131 } | |
132 | |
133 //------------------------------is_cmove_id------------------------------------ | |
134 // Helper function to check for CMOVE identity. Shared with PhiNode::Identity | |
135 Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ) { | |
136 // Check for Cmp'ing and CMove'ing same values | |
137 if( (phase->eqv(cmp->in(1),f) && | |
138 phase->eqv(cmp->in(2),t)) || | |
139 // Swapped Cmp is OK | |
140 (phase->eqv(cmp->in(2),f) && | |
141 phase->eqv(cmp->in(1),t)) ) { | |
755
36ee9b69616e
6833879: Assigning positive zero is ignored when old value is negative zero
cfang
parents:
642
diff
changeset
|
142 // Give up this identity check for floating points because it may choose incorrect |
36ee9b69616e
6833879: Assigning positive zero is ignored when old value is negative zero
cfang
parents:
642
diff
changeset
|
143 // value around 0.0 and -0.0 |
36ee9b69616e
6833879: Assigning positive zero is ignored when old value is negative zero
cfang
parents:
642
diff
changeset
|
144 if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD ) |
36ee9b69616e
6833879: Assigning positive zero is ignored when old value is negative zero
cfang
parents:
642
diff
changeset
|
145 return NULL; |
0 | 146 // Check for "(t==f)?t:f;" and replace with "f" |
147 if( b->_test._test == BoolTest::eq ) | |
148 return f; | |
149 // Allow the inverted case as well | |
150 // Check for "(t!=f)?t:f;" and replace with "t" | |
151 if( b->_test._test == BoolTest::ne ) | |
152 return t; | |
153 } | |
154 return NULL; | |
155 } | |
156 | |
157 //------------------------------Identity--------------------------------------- | |
158 // Conditional-move is an identity if both inputs are the same, or the test | |
159 // true or false. | |
160 Node *CMoveNode::Identity( PhaseTransform *phase ) { | |
161 if( phase->eqv(in(IfFalse),in(IfTrue)) ) // C-moving identical inputs? | |
162 return in(IfFalse); // Then it doesn't matter | |
163 if( phase->type(in(Condition)) == TypeInt::ZERO ) | |
164 return in(IfFalse); // Always pick left(false) input | |
165 if( phase->type(in(Condition)) == TypeInt::ONE ) | |
166 return in(IfTrue); // Always pick right(true) input | |
167 | |
168 // Check for CMove'ing a constant after comparing against the constant. | |
169 // Happens all the time now, since if we compare equality vs a constant in | |
170 // the parser, we "know" the variable is constant on one path and we force | |
171 // it. Thus code like "if( x==0 ) {/*EMPTY*/}" ends up inserting a | |
172 // conditional move: "x = (x==0)?0:x;". Yucko. This fix is slightly more | |
173 // general in that we don't need constants. | |
174 if( in(Condition)->is_Bool() ) { | |
175 BoolNode *b = in(Condition)->as_Bool(); | |
176 Node *cmp = b->in(1); | |
177 if( cmp->is_Cmp() ) { | |
178 Node *id = is_cmove_id( phase, cmp, in(IfTrue), in(IfFalse), b ); | |
179 if( id ) return id; | |
180 } | |
181 } | |
182 | |
183 return this; | |
184 } | |
185 | |
186 //------------------------------Value------------------------------------------ | |
187 // Result is the meet of inputs | |
188 const Type *CMoveNode::Value( PhaseTransform *phase ) const { | |
189 if( phase->type(in(Condition)) == Type::TOP ) | |
190 return Type::TOP; | |
191 return phase->type(in(IfFalse))->meet(phase->type(in(IfTrue))); | |
192 } | |
193 | |
194 //------------------------------make------------------------------------------- | |
195 // Make a correctly-flavored CMove. Since _type is directly determined | |
196 // from the inputs we do not need to specify it here. | |
197 CMoveNode *CMoveNode::make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ) { | |
198 switch( t->basic_type() ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
199 case T_INT: return new (C) CMoveINode( bol, left, right, t->is_int() ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
200 case T_FLOAT: return new (C) CMoveFNode( bol, left, right, t ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
201 case T_DOUBLE: return new (C) CMoveDNode( bol, left, right, t ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
202 case T_LONG: return new (C) CMoveLNode( bol, left, right, t->is_long() ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
203 case T_OBJECT: return new (C) CMovePNode( c, bol, left, right, t->is_oopptr() ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
204 case T_ADDRESS: return new (C) CMovePNode( c, bol, left, right, t->is_ptr() ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
205 case T_NARROWOOP: return new (C) CMoveNNode( c, bol, left, right, t ); |
0 | 206 default: |
207 ShouldNotReachHere(); | |
208 return NULL; | |
209 } | |
210 } | |
211 | |
212 //============================================================================= | |
213 //------------------------------Ideal------------------------------------------ | |
214 // Return a node which is more "ideal" than the current node. | |
215 // Check for conversions to boolean | |
216 Node *CMoveINode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
217 // Try generic ideal's first | |
218 Node *x = CMoveNode::Ideal(phase, can_reshape); | |
219 if( x ) return x; | |
220 | |
221 // If zero is on the left (false-case, no-move-case) it must mean another | |
222 // constant is on the right (otherwise the shared CMove::Ideal code would | |
223 // have moved the constant to the right). This situation is bad for Intel | |
224 // and a don't-care for Sparc. It's bad for Intel because the zero has to | |
225 // be manifested in a register with a XOR which kills flags, which are live | |
226 // on input to the CMoveI, leading to a situation which causes excessive | |
227 // spilling on Intel. For Sparc, if the zero in on the left the Sparc will | |
228 // zero a register via G0 and conditionally-move the other constant. If the | |
229 // zero is on the right, the Sparc will load the first constant with a | |
230 // 13-bit set-lo and conditionally move G0. See bug 4677505. | |
231 if( phase->type(in(IfFalse)) == TypeInt::ZERO && !(phase->type(in(IfTrue)) == TypeInt::ZERO) ) { | |
232 if( in(Condition)->is_Bool() ) { | |
233 BoolNode* b = in(Condition)->as_Bool(); | |
234 BoolNode* b2 = b->negate(phase); | |
235 return make( phase->C, in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type ); | |
236 } | |
237 } | |
238 | |
239 // Now check for booleans | |
240 int flip = 0; | |
241 | |
242 // Check for picking from zero/one | |
243 if( phase->type(in(IfFalse)) == TypeInt::ZERO && phase->type(in(IfTrue)) == TypeInt::ONE ) { | |
244 flip = 1 - flip; | |
245 } else if( phase->type(in(IfFalse)) == TypeInt::ONE && phase->type(in(IfTrue)) == TypeInt::ZERO ) { | |
246 } else return NULL; | |
247 | |
248 // Check for eq/ne test | |
249 if( !in(1)->is_Bool() ) return NULL; | |
250 BoolNode *bol = in(1)->as_Bool(); | |
251 if( bol->_test._test == BoolTest::eq ) { | |
252 } else if( bol->_test._test == BoolTest::ne ) { | |
253 flip = 1-flip; | |
254 } else return NULL; | |
255 | |
256 // Check for vs 0 or 1 | |
257 if( !bol->in(1)->is_Cmp() ) return NULL; | |
258 const CmpNode *cmp = bol->in(1)->as_Cmp(); | |
259 if( phase->type(cmp->in(2)) == TypeInt::ZERO ) { | |
260 } else if( phase->type(cmp->in(2)) == TypeInt::ONE ) { | |
261 // Allow cmp-vs-1 if the other input is bounded by 0-1 | |
262 if( phase->type(cmp->in(1)) != TypeInt::BOOL ) | |
263 return NULL; | |
264 flip = 1 - flip; | |
265 } else return NULL; | |
266 | |
267 // Convert to a bool (flipped) | |
268 // Build int->bool conversion | |
269 #ifndef PRODUCT | |
270 if( PrintOpto ) tty->print_cr("CMOV to I2B"); | |
271 #endif | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
272 Node *n = new (phase->C) Conv2BNode( cmp->in(1) ); |
0 | 273 if( flip ) |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
274 n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); |
0 | 275 |
276 return n; | |
277 } | |
278 | |
279 //============================================================================= | |
280 //------------------------------Ideal------------------------------------------ | |
281 // Return a node which is more "ideal" than the current node. | |
282 // Check for absolute value | |
283 Node *CMoveFNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
284 // Try generic ideal's first | |
285 Node *x = CMoveNode::Ideal(phase, can_reshape); | |
286 if( x ) return x; | |
287 | |
288 int cmp_zero_idx = 0; // Index of compare input where to look for zero | |
289 int phi_x_idx = 0; // Index of phi input where to find naked x | |
290 | |
291 // Find the Bool | |
292 if( !in(1)->is_Bool() ) return NULL; | |
293 BoolNode *bol = in(1)->as_Bool(); | |
294 // Check bool sense | |
295 switch( bol->_test._test ) { | |
296 case BoolTest::lt: cmp_zero_idx = 1; phi_x_idx = IfTrue; break; | |
297 case BoolTest::le: cmp_zero_idx = 2; phi_x_idx = IfFalse; break; | |
298 case BoolTest::gt: cmp_zero_idx = 2; phi_x_idx = IfTrue; break; | |
299 case BoolTest::ge: cmp_zero_idx = 1; phi_x_idx = IfFalse; break; | |
300 default: return NULL; break; | |
301 } | |
302 | |
303 // Find zero input of CmpF; the other input is being abs'd | |
304 Node *cmpf = bol->in(1); | |
305 if( cmpf->Opcode() != Op_CmpF ) return NULL; | |
306 Node *X = NULL; | |
307 bool flip = false; | |
308 if( phase->type(cmpf->in(cmp_zero_idx)) == TypeF::ZERO ) { | |
309 X = cmpf->in(3 - cmp_zero_idx); | |
310 } else if (phase->type(cmpf->in(3 - cmp_zero_idx)) == TypeF::ZERO) { | |
311 // The test is inverted, we should invert the result... | |
312 X = cmpf->in(cmp_zero_idx); | |
313 flip = true; | |
314 } else { | |
315 return NULL; | |
316 } | |
317 | |
318 // If X is found on the appropriate phi input, find the subtract on the other | |
319 if( X != in(phi_x_idx) ) return NULL; | |
320 int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue; | |
321 Node *sub = in(phi_sub_idx); | |
322 | |
323 // Allow only SubF(0,X) and fail out for all others; NegF is not OK | |
324 if( sub->Opcode() != Op_SubF || | |
325 sub->in(2) != X || | |
326 phase->type(sub->in(1)) != TypeF::ZERO ) return NULL; | |
327 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
328 Node *abs = new (phase->C) AbsFNode( X ); |
0 | 329 if( flip ) |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
330 abs = new (phase->C) SubFNode(sub->in(1), phase->transform(abs)); |
0 | 331 |
332 return abs; | |
333 } | |
334 | |
335 //============================================================================= | |
336 //------------------------------Ideal------------------------------------------ | |
337 // Return a node which is more "ideal" than the current node. | |
338 // Check for absolute value | |
339 Node *CMoveDNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
340 // Try generic ideal's first | |
341 Node *x = CMoveNode::Ideal(phase, can_reshape); | |
342 if( x ) return x; | |
343 | |
344 int cmp_zero_idx = 0; // Index of compare input where to look for zero | |
345 int phi_x_idx = 0; // Index of phi input where to find naked x | |
346 | |
347 // Find the Bool | |
348 if( !in(1)->is_Bool() ) return NULL; | |
349 BoolNode *bol = in(1)->as_Bool(); | |
350 // Check bool sense | |
351 switch( bol->_test._test ) { | |
352 case BoolTest::lt: cmp_zero_idx = 1; phi_x_idx = IfTrue; break; | |
353 case BoolTest::le: cmp_zero_idx = 2; phi_x_idx = IfFalse; break; | |
354 case BoolTest::gt: cmp_zero_idx = 2; phi_x_idx = IfTrue; break; | |
355 case BoolTest::ge: cmp_zero_idx = 1; phi_x_idx = IfFalse; break; | |
356 default: return NULL; break; | |
357 } | |
358 | |
359 // Find zero input of CmpD; the other input is being abs'd | |
360 Node *cmpd = bol->in(1); | |
361 if( cmpd->Opcode() != Op_CmpD ) return NULL; | |
362 Node *X = NULL; | |
363 bool flip = false; | |
364 if( phase->type(cmpd->in(cmp_zero_idx)) == TypeD::ZERO ) { | |
365 X = cmpd->in(3 - cmp_zero_idx); | |
366 } else if (phase->type(cmpd->in(3 - cmp_zero_idx)) == TypeD::ZERO) { | |
367 // The test is inverted, we should invert the result... | |
368 X = cmpd->in(cmp_zero_idx); | |
369 flip = true; | |
370 } else { | |
371 return NULL; | |
372 } | |
373 | |
374 // If X is found on the appropriate phi input, find the subtract on the other | |
375 if( X != in(phi_x_idx) ) return NULL; | |
376 int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue; | |
377 Node *sub = in(phi_sub_idx); | |
378 | |
379 // Allow only SubD(0,X) and fail out for all others; NegD is not OK | |
380 if( sub->Opcode() != Op_SubD || | |
381 sub->in(2) != X || | |
382 phase->type(sub->in(1)) != TypeD::ZERO ) return NULL; | |
383 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
384 Node *abs = new (phase->C) AbsDNode( X ); |
0 | 385 if( flip ) |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
386 abs = new (phase->C) SubDNode(sub->in(1), phase->transform(abs)); |
0 | 387 |
388 return abs; | |
389 } | |
390 | |
391 | |
392 //============================================================================= | |
393 // If input is already higher or equal to cast type, then this is an identity. | |
394 Node *ConstraintCastNode::Identity( PhaseTransform *phase ) { | |
395 return phase->type(in(1))->higher_equal(_type) ? in(1) : this; | |
396 } | |
397 | |
398 //------------------------------Value------------------------------------------ | |
399 // Take 'join' of input and cast-up type | |
400 const Type *ConstraintCastNode::Value( PhaseTransform *phase ) const { | |
401 if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP; | |
402 const Type* ft = phase->type(in(1))->filter(_type); | |
403 | |
404 #ifdef ASSERT | |
405 // Previous versions of this function had some special case logic, | |
406 // which is no longer necessary. Make sure of the required effects. | |
407 switch (Opcode()) { | |
408 case Op_CastII: | |
409 { | |
410 const Type* t1 = phase->type(in(1)); | |
411 if( t1 == Type::TOP ) assert(ft == Type::TOP, "special case #1"); | |
412 const Type* rt = t1->join(_type); | |
413 if (rt->empty()) assert(ft == Type::TOP, "special case #2"); | |
414 break; | |
415 } | |
416 case Op_CastPP: | |
417 if (phase->type(in(1)) == TypePtr::NULL_PTR && | |
418 _type->isa_ptr() && _type->is_ptr()->_ptr == TypePtr::NotNull) | |
419 assert(ft == Type::TOP, "special case #3"); | |
420 break; | |
421 } | |
422 #endif //ASSERT | |
423 | |
424 return ft; | |
425 } | |
426 | |
427 //------------------------------Ideal------------------------------------------ | |
428 // Return a node which is more "ideal" than the current node. Strip out | |
429 // control copies | |
430 Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
431 return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; | |
432 } | |
433 | |
434 //------------------------------Ideal_DU_postCCP------------------------------- | |
435 // Throw away cast after constant propagation | |
436 Node *ConstraintCastNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { | |
437 const Type *t = ccp->type(in(1)); | |
438 ccp->hash_delete(this); | |
439 set_type(t); // Turn into ID function | |
440 ccp->hash_insert(this); | |
441 return this; | |
442 } | |
443 | |
444 | |
445 //============================================================================= | |
446 | |
447 //------------------------------Ideal_DU_postCCP------------------------------- | |
448 // If not converting int->oop, throw away cast after constant propagation | |
449 Node *CastPPNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { | |
450 const Type *t = ccp->type(in(1)); | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
451 if (!t->isa_oop_ptr() || ((in(1)->is_DecodeN()) && Matcher::gen_narrow_oop_implicit_null_checks())) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
305
diff
changeset
|
452 return NULL; // do not transform raw pointers or narrow oops |
0 | 453 } |
454 return ConstraintCastNode::Ideal_DU_postCCP(ccp); | |
455 } | |
456 | |
457 | |
458 | |
459 //============================================================================= | |
460 //------------------------------Identity--------------------------------------- | |
461 // If input is already higher or equal to cast type, then this is an identity. | |
462 Node *CheckCastPPNode::Identity( PhaseTransform *phase ) { | |
463 // Toned down to rescue meeting at a Phi 3 different oops all implementing | |
464 // the same interface. CompileTheWorld starting at 502, kd12rc1.zip. | |
465 return (phase->type(in(1)) == phase->type(this)) ? in(1) : this; | |
466 } | |
467 | |
468 //------------------------------Value------------------------------------------ | |
469 // Take 'join' of input and cast-up type, unless working with an Interface | |
470 const Type *CheckCastPPNode::Value( PhaseTransform *phase ) const { | |
471 if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP; | |
472 | |
473 const Type *inn = phase->type(in(1)); | |
474 if( inn == Type::TOP ) return Type::TOP; // No information yet | |
475 | |
476 const TypePtr *in_type = inn->isa_ptr(); | |
477 const TypePtr *my_type = _type->isa_ptr(); | |
478 const Type *result = _type; | |
479 if( in_type != NULL && my_type != NULL ) { | |
480 TypePtr::PTR in_ptr = in_type->ptr(); | |
481 if( in_ptr == TypePtr::Null ) { | |
482 result = in_type; | |
483 } else if( in_ptr == TypePtr::Constant ) { | |
484 // Casting a constant oop to an interface? | |
485 // (i.e., a String to a Comparable?) | |
486 // Then return the interface. | |
487 const TypeOopPtr *jptr = my_type->isa_oopptr(); | |
488 assert( jptr, "" ); | |
489 result = (jptr->klass()->is_interface() || !in_type->higher_equal(_type)) | |
490 ? my_type->cast_to_ptr_type( TypePtr::NotNull ) | |
491 : in_type; | |
492 } else { | |
493 result = my_type->cast_to_ptr_type( my_type->join_ptr(in_ptr) ); | |
494 } | |
495 } | |
496 return result; | |
497 | |
498 // JOIN NOT DONE HERE BECAUSE OF INTERFACE ISSUES. | |
499 // FIX THIS (DO THE JOIN) WHEN UNION TYPES APPEAR! | |
500 | |
501 // | |
502 // Remove this code after overnight run indicates no performance | |
503 // loss from not performing JOIN at CheckCastPPNode | |
504 // | |
505 // const TypeInstPtr *in_oop = in->isa_instptr(); | |
506 // const TypeInstPtr *my_oop = _type->isa_instptr(); | |
507 // // If either input is an 'interface', return destination type | |
508 // assert (in_oop == NULL || in_oop->klass() != NULL, ""); | |
509 // assert (my_oop == NULL || my_oop->klass() != NULL, ""); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5901
diff
changeset
|
510 // if( (in_oop && in_oop->klass()->is_interface()) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
5901
diff
changeset
|
511 // ||(my_oop && my_oop->klass()->is_interface()) ) { |
0 | 512 // TypePtr::PTR in_ptr = in->isa_ptr() ? in->is_ptr()->_ptr : TypePtr::BotPTR; |
513 // // Preserve cast away nullness for interfaces | |
514 // if( in_ptr == TypePtr::NotNull && my_oop && my_oop->_ptr == TypePtr::BotPTR ) { | |
515 // return my_oop->cast_to_ptr_type(TypePtr::NotNull); | |
516 // } | |
517 // return _type; | |
518 // } | |
519 // | |
520 // // Neither the input nor the destination type is an interface, | |
521 // | |
522 // // history: JOIN used to cause weird corner case bugs | |
523 // // return (in == TypeOopPtr::NULL_PTR) ? in : _type; | |
524 // // JOIN picks up NotNull in common instance-of/check-cast idioms, both oops. | |
525 // // JOIN does not preserve NotNull in other cases, e.g. RawPtr vs InstPtr | |
526 // const Type *join = in->join(_type); | |
527 // // Check if join preserved NotNull'ness for pointers | |
528 // if( join->isa_ptr() && _type->isa_ptr() ) { | |
529 // TypePtr::PTR join_ptr = join->is_ptr()->_ptr; | |
530 // TypePtr::PTR type_ptr = _type->is_ptr()->_ptr; | |
531 // // If there isn't any NotNull'ness to preserve | |
532 // // OR if join preserved NotNull'ness then return it | |
533 // if( type_ptr == TypePtr::BotPTR || type_ptr == TypePtr::Null || | |
534 // join_ptr == TypePtr::NotNull || join_ptr == TypePtr::Constant ) { | |
535 // return join; | |
536 // } | |
537 // // ELSE return same old type as before | |
538 // return _type; | |
539 // } | |
540 // // Not joining two pointers | |
541 // return join; | |
542 } | |
543 | |
544 //------------------------------Ideal------------------------------------------ | |
545 // Return a node which is more "ideal" than the current node. Strip out | |
546 // control copies | |
547 Node *CheckCastPPNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
548 return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; | |
549 } | |
550 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
551 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
552 Node* DecodeNNode::Identity(PhaseTransform* phase) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
553 const Type *t = phase->type( in(1) ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
554 if( t == Type::TOP ) return in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
555 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
556 if (in(1)->is_EncodeP()) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
557 // (DecodeN (EncodeP p)) -> p |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
558 return in(1)->in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
559 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
560 return this; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
561 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
562 |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
563 const Type *DecodeNNode::Value( PhaseTransform *phase ) const { |
216
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
564 const Type *t = phase->type( in(1) ); |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
565 if (t == Type::TOP) return Type::TOP; |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
566 if (t == TypeNarrowOop::NULL_PTR) return TypePtr::NULL_PTR; |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
567 |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
568 assert(t->isa_narrowoop(), "only narrowoop here"); |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
569 return t->make_ptr(); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
570 } |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
571 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
572 Node* EncodePNode::Identity(PhaseTransform* phase) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
573 const Type *t = phase->type( in(1) ); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
574 if( t == Type::TOP ) return in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
575 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
576 if (in(1)->is_DecodeN()) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
577 // (EncodeP (DecodeN p)) -> p |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
578 return in(1)->in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
579 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
580 return this; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
581 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
582 |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
583 const Type *EncodePNode::Value( PhaseTransform *phase ) const { |
216
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
584 const Type *t = phase->type( in(1) ); |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
585 if (t == Type::TOP) return Type::TOP; |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
586 if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR; |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
168
diff
changeset
|
587 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
588 assert(t->isa_oop_ptr(), "only oopptr here"); |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
589 return t->make_narrowoop(); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
590 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
591 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
592 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
593 Node *EncodeNarrowPtrNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { |
163 | 594 return MemNode::Ideal_common_DU_postCCP(ccp, this, in(1)); |
595 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
36
diff
changeset
|
596 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
597 Node* DecodeNKlassNode::Identity(PhaseTransform* phase) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
598 const Type *t = phase->type( in(1) ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
599 if( t == Type::TOP ) return in(1); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
600 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
601 if (in(1)->is_EncodePKlass()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
602 // (DecodeNKlass (EncodePKlass p)) -> p |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
603 return in(1)->in(1); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
604 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
605 return this; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
606 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
607 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
608 const Type *DecodeNKlassNode::Value( PhaseTransform *phase ) const { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
609 const Type *t = phase->type( in(1) ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
610 if (t == Type::TOP) return Type::TOP; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
611 assert(t != TypeNarrowKlass::NULL_PTR, "null klass?"); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
612 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
613 assert(t->isa_narrowklass(), "only narrow klass ptr here"); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
614 return t->make_ptr(); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
615 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
616 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
617 Node* EncodePKlassNode::Identity(PhaseTransform* phase) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
618 const Type *t = phase->type( in(1) ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
619 if( t == Type::TOP ) return in(1); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
620 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
621 if (in(1)->is_DecodeNKlass()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
622 // (EncodePKlass (DecodeNKlass p)) -> p |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
623 return in(1)->in(1); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
624 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
625 return this; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
626 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
627 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
628 const Type *EncodePKlassNode::Value( PhaseTransform *phase ) const { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
629 const Type *t = phase->type( in(1) ); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
630 if (t == Type::TOP) return Type::TOP; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
631 assert (t != TypePtr::NULL_PTR, "null klass?"); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
632 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
633 assert(UseCompressedKlassPointers && t->isa_klassptr(), "only klass ptr here"); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
634 return t->make_narrowklass(); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
635 } |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
636 |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
637 |
0 | 638 //============================================================================= |
639 //------------------------------Identity--------------------------------------- | |
640 Node *Conv2BNode::Identity( PhaseTransform *phase ) { | |
641 const Type *t = phase->type( in(1) ); | |
642 if( t == Type::TOP ) return in(1); | |
643 if( t == TypeInt::ZERO ) return in(1); | |
644 if( t == TypeInt::ONE ) return in(1); | |
645 if( t == TypeInt::BOOL ) return in(1); | |
646 return this; | |
647 } | |
648 | |
649 //------------------------------Value------------------------------------------ | |
650 const Type *Conv2BNode::Value( PhaseTransform *phase ) const { | |
651 const Type *t = phase->type( in(1) ); | |
652 if( t == Type::TOP ) return Type::TOP; | |
653 if( t == TypeInt::ZERO ) return TypeInt::ZERO; | |
654 if( t == TypePtr::NULL_PTR ) return TypeInt::ZERO; | |
655 const TypePtr *tp = t->isa_ptr(); | |
656 if( tp != NULL ) { | |
657 if( tp->ptr() == TypePtr::AnyNull ) return Type::TOP; | |
658 if( tp->ptr() == TypePtr::Constant) return TypeInt::ONE; | |
659 if (tp->ptr() == TypePtr::NotNull) return TypeInt::ONE; | |
660 return TypeInt::BOOL; | |
661 } | |
662 if (t->base() != Type::Int) return TypeInt::BOOL; | |
663 const TypeInt *ti = t->is_int(); | |
664 if( ti->_hi < 0 || ti->_lo > 0 ) return TypeInt::ONE; | |
665 return TypeInt::BOOL; | |
666 } | |
667 | |
668 | |
669 // The conversions operations are all Alpha sorted. Please keep it that way! | |
670 //============================================================================= | |
671 //------------------------------Value------------------------------------------ | |
672 const Type *ConvD2FNode::Value( PhaseTransform *phase ) const { | |
673 const Type *t = phase->type( in(1) ); | |
674 if( t == Type::TOP ) return Type::TOP; | |
675 if( t == Type::DOUBLE ) return Type::FLOAT; | |
676 const TypeD *td = t->is_double_constant(); | |
677 return TypeF::make( (float)td->getd() ); | |
678 } | |
679 | |
680 //------------------------------Identity--------------------------------------- | |
681 // Float's can be converted to doubles with no loss of bits. Hence | |
682 // converting a float to a double and back to a float is a NOP. | |
683 Node *ConvD2FNode::Identity(PhaseTransform *phase) { | |
684 return (in(1)->Opcode() == Op_ConvF2D) ? in(1)->in(1) : this; | |
685 } | |
686 | |
687 //============================================================================= | |
688 //------------------------------Value------------------------------------------ | |
689 const Type *ConvD2INode::Value( PhaseTransform *phase ) const { | |
690 const Type *t = phase->type( in(1) ); | |
691 if( t == Type::TOP ) return Type::TOP; | |
692 if( t == Type::DOUBLE ) return TypeInt::INT; | |
693 const TypeD *td = t->is_double_constant(); | |
694 return TypeInt::make( SharedRuntime::d2i( td->getd() ) ); | |
695 } | |
696 | |
697 //------------------------------Ideal------------------------------------------ | |
698 // If converting to an int type, skip any rounding nodes | |
699 Node *ConvD2INode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
700 if( in(1)->Opcode() == Op_RoundDouble ) | |
701 set_req(1,in(1)->in(1)); | |
702 return NULL; | |
703 } | |
704 | |
705 //------------------------------Identity--------------------------------------- | |
706 // Int's can be converted to doubles with no loss of bits. Hence | |
707 // converting an integer to a double and back to an integer is a NOP. | |
708 Node *ConvD2INode::Identity(PhaseTransform *phase) { | |
709 return (in(1)->Opcode() == Op_ConvI2D) ? in(1)->in(1) : this; | |
710 } | |
711 | |
712 //============================================================================= | |
713 //------------------------------Value------------------------------------------ | |
714 const Type *ConvD2LNode::Value( PhaseTransform *phase ) const { | |
715 const Type *t = phase->type( in(1) ); | |
716 if( t == Type::TOP ) return Type::TOP; | |
717 if( t == Type::DOUBLE ) return TypeLong::LONG; | |
718 const TypeD *td = t->is_double_constant(); | |
719 return TypeLong::make( SharedRuntime::d2l( td->getd() ) ); | |
720 } | |
721 | |
722 //------------------------------Identity--------------------------------------- | |
723 Node *ConvD2LNode::Identity(PhaseTransform *phase) { | |
724 // Remove ConvD2L->ConvL2D->ConvD2L sequences. | |
725 if( in(1) ->Opcode() == Op_ConvL2D && | |
726 in(1)->in(1)->Opcode() == Op_ConvD2L ) | |
727 return in(1)->in(1); | |
728 return this; | |
729 } | |
730 | |
731 //------------------------------Ideal------------------------------------------ | |
732 // If converting to an int type, skip any rounding nodes | |
733 Node *ConvD2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
734 if( in(1)->Opcode() == Op_RoundDouble ) | |
735 set_req(1,in(1)->in(1)); | |
736 return NULL; | |
737 } | |
738 | |
739 //============================================================================= | |
740 //------------------------------Value------------------------------------------ | |
741 const Type *ConvF2DNode::Value( PhaseTransform *phase ) const { | |
742 const Type *t = phase->type( in(1) ); | |
743 if( t == Type::TOP ) return Type::TOP; | |
744 if( t == Type::FLOAT ) return Type::DOUBLE; | |
745 const TypeF *tf = t->is_float_constant(); | |
746 return TypeD::make( (double)tf->getf() ); | |
747 } | |
748 | |
749 //============================================================================= | |
750 //------------------------------Value------------------------------------------ | |
751 const Type *ConvF2INode::Value( PhaseTransform *phase ) const { | |
752 const Type *t = phase->type( in(1) ); | |
753 if( t == Type::TOP ) return Type::TOP; | |
754 if( t == Type::FLOAT ) return TypeInt::INT; | |
755 const TypeF *tf = t->is_float_constant(); | |
756 return TypeInt::make( SharedRuntime::f2i( tf->getf() ) ); | |
757 } | |
758 | |
759 //------------------------------Identity--------------------------------------- | |
760 Node *ConvF2INode::Identity(PhaseTransform *phase) { | |
761 // Remove ConvF2I->ConvI2F->ConvF2I sequences. | |
762 if( in(1) ->Opcode() == Op_ConvI2F && | |
763 in(1)->in(1)->Opcode() == Op_ConvF2I ) | |
764 return in(1)->in(1); | |
765 return this; | |
766 } | |
767 | |
768 //------------------------------Ideal------------------------------------------ | |
769 // If converting to an int type, skip any rounding nodes | |
770 Node *ConvF2INode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
771 if( in(1)->Opcode() == Op_RoundFloat ) | |
772 set_req(1,in(1)->in(1)); | |
773 return NULL; | |
774 } | |
775 | |
776 //============================================================================= | |
777 //------------------------------Value------------------------------------------ | |
778 const Type *ConvF2LNode::Value( PhaseTransform *phase ) const { | |
779 const Type *t = phase->type( in(1) ); | |
780 if( t == Type::TOP ) return Type::TOP; | |
781 if( t == Type::FLOAT ) return TypeLong::LONG; | |
782 const TypeF *tf = t->is_float_constant(); | |
783 return TypeLong::make( SharedRuntime::f2l( tf->getf() ) ); | |
784 } | |
785 | |
786 //------------------------------Identity--------------------------------------- | |
787 Node *ConvF2LNode::Identity(PhaseTransform *phase) { | |
788 // Remove ConvF2L->ConvL2F->ConvF2L sequences. | |
789 if( in(1) ->Opcode() == Op_ConvL2F && | |
790 in(1)->in(1)->Opcode() == Op_ConvF2L ) | |
791 return in(1)->in(1); | |
792 return this; | |
793 } | |
794 | |
795 //------------------------------Ideal------------------------------------------ | |
796 // If converting to an int type, skip any rounding nodes | |
797 Node *ConvF2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
798 if( in(1)->Opcode() == Op_RoundFloat ) | |
799 set_req(1,in(1)->in(1)); | |
800 return NULL; | |
801 } | |
802 | |
803 //============================================================================= | |
804 //------------------------------Value------------------------------------------ | |
805 const Type *ConvI2DNode::Value( PhaseTransform *phase ) const { | |
806 const Type *t = phase->type( in(1) ); | |
807 if( t == Type::TOP ) return Type::TOP; | |
808 const TypeInt *ti = t->is_int(); | |
809 if( ti->is_con() ) return TypeD::make( (double)ti->get_con() ); | |
810 return bottom_type(); | |
811 } | |
812 | |
813 //============================================================================= | |
814 //------------------------------Value------------------------------------------ | |
815 const Type *ConvI2FNode::Value( PhaseTransform *phase ) const { | |
816 const Type *t = phase->type( in(1) ); | |
817 if( t == Type::TOP ) return Type::TOP; | |
818 const TypeInt *ti = t->is_int(); | |
819 if( ti->is_con() ) return TypeF::make( (float)ti->get_con() ); | |
820 return bottom_type(); | |
821 } | |
822 | |
823 //------------------------------Identity--------------------------------------- | |
824 Node *ConvI2FNode::Identity(PhaseTransform *phase) { | |
825 // Remove ConvI2F->ConvF2I->ConvI2F sequences. | |
826 if( in(1) ->Opcode() == Op_ConvF2I && | |
827 in(1)->in(1)->Opcode() == Op_ConvI2F ) | |
828 return in(1)->in(1); | |
829 return this; | |
830 } | |
831 | |
832 //============================================================================= | |
833 //------------------------------Value------------------------------------------ | |
834 const Type *ConvI2LNode::Value( PhaseTransform *phase ) const { | |
835 const Type *t = phase->type( in(1) ); | |
836 if( t == Type::TOP ) return Type::TOP; | |
837 const TypeInt *ti = t->is_int(); | |
838 const Type* tl = TypeLong::make(ti->_lo, ti->_hi, ti->_widen); | |
839 // Join my declared type against my incoming type. | |
840 tl = tl->filter(_type); | |
841 return tl; | |
842 } | |
843 | |
844 #ifdef _LP64 | |
845 static inline bool long_ranges_overlap(jlong lo1, jlong hi1, | |
846 jlong lo2, jlong hi2) { | |
847 // Two ranges overlap iff one range's low point falls in the other range. | |
848 return (lo2 <= lo1 && lo1 <= hi2) || (lo1 <= lo2 && lo2 <= hi1); | |
849 } | |
850 #endif | |
851 | |
852 //------------------------------Ideal------------------------------------------ | |
853 Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
854 const TypeLong* this_type = this->type()->is_long(); | |
855 Node* this_changed = NULL; | |
856 | |
857 // If _major_progress, then more loop optimizations follow. Do NOT | |
858 // remove this node's type assertion until no more loop ops can happen. | |
859 // The progress bit is set in the major loop optimizations THEN comes the | |
860 // call to IterGVN and any chance of hitting this code. Cf. Opaque1Node. | |
861 if (can_reshape && !phase->C->major_progress()) { | |
862 const TypeInt* in_type = phase->type(in(1))->isa_int(); | |
863 if (in_type != NULL && this_type != NULL && | |
864 (in_type->_lo != this_type->_lo || | |
865 in_type->_hi != this_type->_hi)) { | |
866 // Although this WORSENS the type, it increases GVN opportunities, | |
867 // because I2L nodes with the same input will common up, regardless | |
868 // of slightly differing type assertions. Such slight differences | |
869 // arise routinely as a result of loop unrolling, so this is a | |
870 // post-unrolling graph cleanup. Choose a type which depends only | |
871 // on my input. (Exception: Keep a range assertion of >=0 or <0.) | |
872 jlong lo1 = this_type->_lo; | |
873 jlong hi1 = this_type->_hi; | |
874 int w1 = this_type->_widen; | |
875 if (lo1 != (jint)lo1 || | |
876 hi1 != (jint)hi1 || | |
877 lo1 > hi1) { | |
878 // Overflow leads to wraparound, wraparound leads to range saturation. | |
879 lo1 = min_jint; hi1 = max_jint; | |
880 } else if (lo1 >= 0) { | |
881 // Keep a range assertion of >=0. | |
882 lo1 = 0; hi1 = max_jint; | |
883 } else if (hi1 < 0) { | |
884 // Keep a range assertion of <0. | |
885 lo1 = min_jint; hi1 = -1; | |
886 } else { | |
887 lo1 = min_jint; hi1 = max_jint; | |
888 } | |
889 const TypeLong* wtype = TypeLong::make(MAX2((jlong)in_type->_lo, lo1), | |
890 MIN2((jlong)in_type->_hi, hi1), | |
891 MAX2((int)in_type->_widen, w1)); | |
892 if (wtype != type()) { | |
893 set_type(wtype); | |
894 // Note: this_type still has old type value, for the logic below. | |
895 this_changed = this; | |
896 } | |
897 } | |
898 } | |
899 | |
900 #ifdef _LP64 | |
901 // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) , | |
902 // but only if x and y have subranges that cannot cause 32-bit overflow, | |
903 // under the assumption that x+y is in my own subrange this->type(). | |
904 | |
905 // This assumption is based on a constraint (i.e., type assertion) | |
906 // established in Parse::array_addressing or perhaps elsewhere. | |
907 // This constraint has been adjoined to the "natural" type of | |
908 // the incoming argument in(0). We know (because of runtime | |
909 // checks) - that the result value I2L(x+y) is in the joined range. | |
910 // Hence we can restrict the incoming terms (x, y) to values such | |
911 // that their sum also lands in that range. | |
912 | |
913 // This optimization is useful only on 64-bit systems, where we hope | |
914 // the addition will end up subsumed in an addressing mode. | |
915 // It is necessary to do this when optimizing an unrolled array | |
916 // copy loop such as x[i++] = y[i++]. | |
917 | |
918 // On 32-bit systems, it's better to perform as much 32-bit math as | |
919 // possible before the I2L conversion, because 32-bit math is cheaper. | |
920 // There's no common reason to "leak" a constant offset through the I2L. | |
921 // Addressing arithmetic will not absorb it as part of a 64-bit AddL. | |
922 | |
923 Node* z = in(1); | |
924 int op = z->Opcode(); | |
925 if (op == Op_AddI || op == Op_SubI) { | |
926 Node* x = z->in(1); | |
927 Node* y = z->in(2); | |
928 assert (x != z && y != z, "dead loop in ConvI2LNode::Ideal"); | |
929 if (phase->type(x) == Type::TOP) return this_changed; | |
930 if (phase->type(y) == Type::TOP) return this_changed; | |
931 const TypeInt* tx = phase->type(x)->is_int(); | |
932 const TypeInt* ty = phase->type(y)->is_int(); | |
933 const TypeLong* tz = this_type; | |
934 jlong xlo = tx->_lo; | |
935 jlong xhi = tx->_hi; | |
936 jlong ylo = ty->_lo; | |
937 jlong yhi = ty->_hi; | |
938 jlong zlo = tz->_lo; | |
939 jlong zhi = tz->_hi; | |
940 jlong vbit = CONST64(1) << BitsPerInt; | |
941 int widen = MAX2(tx->_widen, ty->_widen); | |
942 if (op == Op_SubI) { | |
943 jlong ylo0 = ylo; | |
944 ylo = -yhi; | |
945 yhi = -ylo0; | |
946 } | |
947 // See if x+y can cause positive overflow into z+2**32 | |
948 if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo+vbit, zhi+vbit)) { | |
949 return this_changed; | |
950 } | |
951 // See if x+y can cause negative overflow into z-2**32 | |
952 if (long_ranges_overlap(xlo+ylo, xhi+yhi, zlo-vbit, zhi-vbit)) { | |
953 return this_changed; | |
954 } | |
955 // Now it's always safe to assume x+y does not overflow. | |
956 // This is true even if some pairs x,y might cause overflow, as long | |
957 // as that overflow value cannot fall into [zlo,zhi]. | |
958 | |
959 // Confident that the arithmetic is "as if infinite precision", | |
960 // we can now use z's range to put constraints on those of x and y. | |
961 // The "natural" range of x [xlo,xhi] can perhaps be narrowed to a | |
962 // more "restricted" range by intersecting [xlo,xhi] with the | |
963 // range obtained by subtracting y's range from the asserted range | |
964 // of the I2L conversion. Here's the interval arithmetic algebra: | |
965 // x == z-y == [zlo,zhi]-[ylo,yhi] == [zlo,zhi]+[-yhi,-ylo] | |
966 // => x in [zlo-yhi, zhi-ylo] | |
967 // => x in [zlo-yhi, zhi-ylo] INTERSECT [xlo,xhi] | |
968 // => x in [xlo MAX zlo-yhi, xhi MIN zhi-ylo] | |
969 jlong rxlo = MAX2(xlo, zlo - yhi); | |
970 jlong rxhi = MIN2(xhi, zhi - ylo); | |
971 // And similarly, x changing place with y: | |
972 jlong rylo = MAX2(ylo, zlo - xhi); | |
973 jlong ryhi = MIN2(yhi, zhi - xlo); | |
974 if (rxlo > rxhi || rylo > ryhi) { | |
975 return this_changed; // x or y is dying; don't mess w/ it | |
976 } | |
977 if (op == Op_SubI) { | |
978 jlong rylo0 = rylo; | |
979 rylo = -ryhi; | |
980 ryhi = -rylo0; | |
981 } | |
982 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
983 Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
984 Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); |
0 | 985 switch (op) { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
986 case Op_AddI: return new (phase->C) AddLNode(cx, cy); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
987 case Op_SubI: return new (phase->C) SubLNode(cx, cy); |
0 | 988 default: ShouldNotReachHere(); |
989 } | |
990 } | |
991 #endif //_LP64 | |
992 | |
993 return this_changed; | |
994 } | |
995 | |
996 //============================================================================= | |
997 //------------------------------Value------------------------------------------ | |
998 const Type *ConvL2DNode::Value( PhaseTransform *phase ) const { | |
999 const Type *t = phase->type( in(1) ); | |
1000 if( t == Type::TOP ) return Type::TOP; | |
1001 const TypeLong *tl = t->is_long(); | |
1002 if( tl->is_con() ) return TypeD::make( (double)tl->get_con() ); | |
1003 return bottom_type(); | |
1004 } | |
1005 | |
1006 //============================================================================= | |
1007 //------------------------------Value------------------------------------------ | |
1008 const Type *ConvL2FNode::Value( PhaseTransform *phase ) const { | |
1009 const Type *t = phase->type( in(1) ); | |
1010 if( t == Type::TOP ) return Type::TOP; | |
1011 const TypeLong *tl = t->is_long(); | |
1012 if( tl->is_con() ) return TypeF::make( (float)tl->get_con() ); | |
1013 return bottom_type(); | |
1014 } | |
1015 | |
1016 //============================================================================= | |
1017 //----------------------------Identity----------------------------------------- | |
1018 Node *ConvL2INode::Identity( PhaseTransform *phase ) { | |
1019 // Convert L2I(I2L(x)) => x | |
1020 if (in(1)->Opcode() == Op_ConvI2L) return in(1)->in(1); | |
1021 return this; | |
1022 } | |
1023 | |
1024 //------------------------------Value------------------------------------------ | |
1025 const Type *ConvL2INode::Value( PhaseTransform *phase ) const { | |
1026 const Type *t = phase->type( in(1) ); | |
1027 if( t == Type::TOP ) return Type::TOP; | |
1028 const TypeLong *tl = t->is_long(); | |
1029 if (tl->is_con()) | |
1030 // Easy case. | |
1031 return TypeInt::make((jint)tl->get_con()); | |
1032 return bottom_type(); | |
1033 } | |
1034 | |
1035 //------------------------------Ideal------------------------------------------ | |
1036 // Return a node which is more "ideal" than the current node. | |
1037 // Blow off prior masking to int | |
1038 Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1039 Node *andl = in(1); | |
1040 uint andl_op = andl->Opcode(); | |
1041 if( andl_op == Op_AndL ) { | |
1042 // Blow off prior masking to int | |
1043 if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) { | |
1044 set_req(1,andl->in(1)); | |
1045 return this; | |
1046 } | |
1047 } | |
1048 | |
1049 // Swap with a prior add: convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) | |
1050 // This replaces an 'AddL' with an 'AddI'. | |
1051 if( andl_op == Op_AddL ) { | |
1052 // Don't do this for nodes which have more than one user since | |
1053 // we'll end up computing the long add anyway. | |
1054 if (andl->outcnt() > 1) return NULL; | |
1055 | |
1056 Node* x = andl->in(1); | |
1057 Node* y = andl->in(2); | |
1058 assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); | |
1059 if (phase->type(x) == Type::TOP) return NULL; | |
1060 if (phase->type(y) == Type::TOP) return NULL; | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1061 Node *add1 = phase->transform(new (phase->C) ConvL2INode(x)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1062 Node *add2 = phase->transform(new (phase->C) ConvL2INode(y)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1063 return new (phase->C) AddINode(add1,add2); |
0 | 1064 } |
1065 | |
36 | 1066 // Disable optimization: LoadL->ConvL2I ==> LoadI. |
1067 // It causes problems (sizes of Load and Store nodes do not match) | |
1068 // in objects initialization code and Escape Analysis. | |
0 | 1069 return NULL; |
1070 } | |
1071 | |
1072 //============================================================================= | |
1073 //------------------------------Value------------------------------------------ | |
1074 const Type *CastX2PNode::Value( PhaseTransform *phase ) const { | |
1075 const Type* t = phase->type(in(1)); | |
5901 | 1076 if (t == Type::TOP) return Type::TOP; |
0 | 1077 if (t->base() == Type_X && t->singleton()) { |
1078 uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con(); | |
1079 if (bits == 0) return TypePtr::NULL_PTR; | |
1080 return TypeRawPtr::make((address) bits); | |
1081 } | |
1082 return CastX2PNode::bottom_type(); | |
1083 } | |
1084 | |
1085 //------------------------------Idealize--------------------------------------- | |
1086 static inline bool fits_in_int(const Type* t, bool but_not_min_int = false) { | |
1087 if (t == Type::TOP) return false; | |
1088 const TypeX* tl = t->is_intptr_t(); | |
1089 jint lo = min_jint; | |
1090 jint hi = max_jint; | |
1091 if (but_not_min_int) ++lo; // caller wants to negate the value w/o overflow | |
1092 return (tl->_lo >= lo) && (tl->_hi <= hi); | |
1093 } | |
1094 | |
1095 static inline Node* addP_of_X2P(PhaseGVN *phase, | |
1096 Node* base, | |
1097 Node* dispX, | |
1098 bool negate = false) { | |
1099 if (negate) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1100 dispX = new (phase->C) SubXNode(phase->MakeConX(0), phase->transform(dispX)); |
0 | 1101 } |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1102 return new (phase->C) AddPNode(phase->C->top(), |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1103 phase->transform(new (phase->C) CastX2PNode(base)), |
0 | 1104 phase->transform(dispX)); |
1105 } | |
1106 | |
1107 Node *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1108 // convert CastX2P(AddX(x, y)) to AddP(CastX2P(x), y) if y fits in an int | |
1109 int op = in(1)->Opcode(); | |
1110 Node* x; | |
1111 Node* y; | |
1112 switch (op) { | |
1113 case Op_SubX: | |
1114 x = in(1)->in(1); | |
995
ddd6f1182ae3
6883468: C2 compiler enters infinite loop in PhaseIterGVN::transform
kvn
parents:
844
diff
changeset
|
1115 // Avoid ideal transformations ping-pong between this and AddP for raw pointers. |
ddd6f1182ae3
6883468: C2 compiler enters infinite loop in PhaseIterGVN::transform
kvn
parents:
844
diff
changeset
|
1116 if (phase->find_intptr_t_con(x, -1) == 0) |
ddd6f1182ae3
6883468: C2 compiler enters infinite loop in PhaseIterGVN::transform
kvn
parents:
844
diff
changeset
|
1117 break; |
0 | 1118 y = in(1)->in(2); |
1119 if (fits_in_int(phase->type(y), true)) { | |
1120 return addP_of_X2P(phase, x, y, true); | |
1121 } | |
1122 break; | |
1123 case Op_AddX: | |
1124 x = in(1)->in(1); | |
1125 y = in(1)->in(2); | |
1126 if (fits_in_int(phase->type(y))) { | |
1127 return addP_of_X2P(phase, x, y); | |
1128 } | |
1129 if (fits_in_int(phase->type(x))) { | |
1130 return addP_of_X2P(phase, y, x); | |
1131 } | |
1132 break; | |
1133 } | |
1134 return NULL; | |
1135 } | |
1136 | |
1137 //------------------------------Identity--------------------------------------- | |
1138 Node *CastX2PNode::Identity( PhaseTransform *phase ) { | |
1139 if (in(1)->Opcode() == Op_CastP2X) return in(1)->in(1); | |
1140 return this; | |
1141 } | |
1142 | |
1143 //============================================================================= | |
1144 //------------------------------Value------------------------------------------ | |
1145 const Type *CastP2XNode::Value( PhaseTransform *phase ) const { | |
1146 const Type* t = phase->type(in(1)); | |
5901 | 1147 if (t == Type::TOP) return Type::TOP; |
0 | 1148 if (t->base() == Type::RawPtr && t->singleton()) { |
1149 uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); | |
1150 return TypeX::make(bits); | |
1151 } | |
1152 return CastP2XNode::bottom_type(); | |
1153 } | |
1154 | |
1155 Node *CastP2XNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1156 return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL; | |
1157 } | |
1158 | |
1159 //------------------------------Identity--------------------------------------- | |
1160 Node *CastP2XNode::Identity( PhaseTransform *phase ) { | |
1161 if (in(1)->Opcode() == Op_CastX2P) return in(1)->in(1); | |
1162 return this; | |
1163 } | |
1164 | |
1165 | |
1166 //============================================================================= | |
1167 //------------------------------Identity--------------------------------------- | |
1168 // Remove redundant roundings | |
1169 Node *RoundFloatNode::Identity( PhaseTransform *phase ) { | |
1170 assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); | |
1171 // Do not round constants | |
1172 if (phase->type(in(1))->base() == Type::FloatCon) return in(1); | |
1173 int op = in(1)->Opcode(); | |
1174 // Redundant rounding | |
1175 if( op == Op_RoundFloat ) return in(1); | |
1176 // Already rounded | |
1177 if( op == Op_Parm ) return in(1); | |
1178 if( op == Op_LoadF ) return in(1); | |
1179 return this; | |
1180 } | |
1181 | |
1182 //------------------------------Value------------------------------------------ | |
1183 const Type *RoundFloatNode::Value( PhaseTransform *phase ) const { | |
1184 return phase->type( in(1) ); | |
1185 } | |
1186 | |
1187 //============================================================================= | |
1188 //------------------------------Identity--------------------------------------- | |
1189 // Remove redundant roundings. Incoming arguments are already rounded. | |
1190 Node *RoundDoubleNode::Identity( PhaseTransform *phase ) { | |
1191 assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); | |
1192 // Do not round constants | |
1193 if (phase->type(in(1))->base() == Type::DoubleCon) return in(1); | |
1194 int op = in(1)->Opcode(); | |
1195 // Redundant rounding | |
1196 if( op == Op_RoundDouble ) return in(1); | |
1197 // Already rounded | |
1198 if( op == Op_Parm ) return in(1); | |
1199 if( op == Op_LoadD ) return in(1); | |
1200 if( op == Op_ConvF2D ) return in(1); | |
1201 if( op == Op_ConvI2D ) return in(1); | |
1202 return this; | |
1203 } | |
1204 | |
1205 //------------------------------Value------------------------------------------ | |
1206 const Type *RoundDoubleNode::Value( PhaseTransform *phase ) const { | |
1207 return phase->type( in(1) ); | |
1208 } | |
1209 | |
1210 | |
1211 //============================================================================= | |
1212 // Do not allow value-numbering | |
1213 uint Opaque1Node::hash() const { return NO_HASH; } | |
1214 uint Opaque1Node::cmp( const Node &n ) const { | |
1215 return (&n == this); // Always fail except on self | |
1216 } | |
1217 | |
1218 //------------------------------Identity--------------------------------------- | |
1219 // If _major_progress, then more loop optimizations follow. Do NOT remove | |
1220 // the opaque Node until no more loop ops can happen. Note the timing of | |
1221 // _major_progress; it's set in the major loop optimizations THEN comes the | |
1222 // call to IterGVN and any chance of hitting this code. Hence there's no | |
1223 // phase-ordering problem with stripping Opaque1 in IGVN followed by some | |
1224 // more loop optimizations that require it. | |
1225 Node *Opaque1Node::Identity( PhaseTransform *phase ) { | |
1226 return phase->C->major_progress() ? this : in(1); | |
1227 } | |
1228 | |
1229 //============================================================================= | |
1230 // A node to prevent unwanted optimizations. Allows constant folding. Stops | |
1231 // value-numbering, most Ideal calls or Identity functions. This Node is | |
1232 // specifically designed to prevent the pre-increment value of a loop trip | |
1233 // counter from being live out of the bottom of the loop (hence causing the | |
1234 // pre- and post-increment values both being live and thus requiring an extra | |
1235 // temp register and an extra move). If we "accidentally" optimize through | |
1236 // this kind of a Node, we'll get slightly pessimal, but correct, code. Thus | |
1237 // it's OK to be slightly sloppy on optimizations here. | |
1238 | |
1239 // Do not allow value-numbering | |
1240 uint Opaque2Node::hash() const { return NO_HASH; } | |
1241 uint Opaque2Node::cmp( const Node &n ) const { | |
1242 return (&n == this); // Always fail except on self | |
1243 } | |
1244 | |
1245 | |
1246 //------------------------------Value------------------------------------------ | |
1247 const Type *MoveL2DNode::Value( PhaseTransform *phase ) const { | |
1248 const Type *t = phase->type( in(1) ); | |
1249 if( t == Type::TOP ) return Type::TOP; | |
1250 const TypeLong *tl = t->is_long(); | |
1251 if( !tl->is_con() ) return bottom_type(); | |
1252 JavaValue v; | |
1253 v.set_jlong(tl->get_con()); | |
1254 return TypeD::make( v.get_jdouble() ); | |
1255 } | |
1256 | |
1257 //------------------------------Value------------------------------------------ | |
1258 const Type *MoveI2FNode::Value( PhaseTransform *phase ) const { | |
1259 const Type *t = phase->type( in(1) ); | |
1260 if( t == Type::TOP ) return Type::TOP; | |
1261 const TypeInt *ti = t->is_int(); | |
1262 if( !ti->is_con() ) return bottom_type(); | |
1263 JavaValue v; | |
1264 v.set_jint(ti->get_con()); | |
1265 return TypeF::make( v.get_jfloat() ); | |
1266 } | |
1267 | |
1268 //------------------------------Value------------------------------------------ | |
1269 const Type *MoveF2INode::Value( PhaseTransform *phase ) const { | |
1270 const Type *t = phase->type( in(1) ); | |
1271 if( t == Type::TOP ) return Type::TOP; | |
1272 if( t == Type::FLOAT ) return TypeInt::INT; | |
1273 const TypeF *tf = t->is_float_constant(); | |
1274 JavaValue v; | |
1275 v.set_jfloat(tf->getf()); | |
1276 return TypeInt::make( v.get_jint() ); | |
1277 } | |
1278 | |
1279 //------------------------------Value------------------------------------------ | |
1280 const Type *MoveD2LNode::Value( PhaseTransform *phase ) const { | |
1281 const Type *t = phase->type( in(1) ); | |
1282 if( t == Type::TOP ) return Type::TOP; | |
1283 if( t == Type::DOUBLE ) return TypeLong::LONG; | |
1284 const TypeD *td = t->is_double_constant(); | |
1285 JavaValue v; | |
1286 v.set_jdouble(td->getd()); | |
1287 return TypeLong::make( v.get_jlong() ); | |
1288 } | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1289 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1290 //------------------------------Value------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1291 const Type* CountLeadingZerosINode::Value(PhaseTransform* phase) const { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1292 const Type* t = phase->type(in(1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1293 if (t == Type::TOP) return Type::TOP; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1294 const TypeInt* ti = t->isa_int(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1295 if (ti && ti->is_con()) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1296 jint i = ti->get_con(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1297 // HD, Figure 5-6 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1298 if (i == 0) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1299 return TypeInt::make(BitsPerInt); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1300 int n = 1; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1301 unsigned int x = i; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1302 if (x >> 16 == 0) { n += 16; x <<= 16; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1303 if (x >> 24 == 0) { n += 8; x <<= 8; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1304 if (x >> 28 == 0) { n += 4; x <<= 4; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1305 if (x >> 30 == 0) { n += 2; x <<= 2; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1306 n -= x >> 31; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1307 return TypeInt::make(n); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1308 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1309 return TypeInt::INT; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1310 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1311 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1312 //------------------------------Value------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1313 const Type* CountLeadingZerosLNode::Value(PhaseTransform* phase) const { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1314 const Type* t = phase->type(in(1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1315 if (t == Type::TOP) return Type::TOP; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1316 const TypeLong* tl = t->isa_long(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1317 if (tl && tl->is_con()) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1318 jlong l = tl->get_con(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1319 // HD, Figure 5-6 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1320 if (l == 0) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1321 return TypeInt::make(BitsPerLong); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1322 int n = 1; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1323 unsigned int x = (((julong) l) >> 32); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1324 if (x == 0) { n += 32; x = (int) l; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1325 if (x >> 16 == 0) { n += 16; x <<= 16; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1326 if (x >> 24 == 0) { n += 8; x <<= 8; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1327 if (x >> 28 == 0) { n += 4; x <<= 4; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1328 if (x >> 30 == 0) { n += 2; x <<= 2; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1329 n -= x >> 31; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1330 return TypeInt::make(n); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1331 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1332 return TypeInt::INT; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1333 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1334 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1335 //------------------------------Value------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1336 const Type* CountTrailingZerosINode::Value(PhaseTransform* phase) const { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1337 const Type* t = phase->type(in(1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1338 if (t == Type::TOP) return Type::TOP; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1339 const TypeInt* ti = t->isa_int(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1340 if (ti && ti->is_con()) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1341 jint i = ti->get_con(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1342 // HD, Figure 5-14 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1343 int y; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1344 if (i == 0) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1345 return TypeInt::make(BitsPerInt); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1346 int n = 31; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1347 y = i << 16; if (y != 0) { n = n - 16; i = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1348 y = i << 8; if (y != 0) { n = n - 8; i = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1349 y = i << 4; if (y != 0) { n = n - 4; i = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1350 y = i << 2; if (y != 0) { n = n - 2; i = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1351 y = i << 1; if (y != 0) { n = n - 1; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1352 return TypeInt::make(n); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1353 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1354 return TypeInt::INT; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1355 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1356 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1357 //------------------------------Value------------------------------------------ |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1358 const Type* CountTrailingZerosLNode::Value(PhaseTransform* phase) const { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1359 const Type* t = phase->type(in(1)); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1360 if (t == Type::TOP) return Type::TOP; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1361 const TypeLong* tl = t->isa_long(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1362 if (tl && tl->is_con()) { |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1363 jlong l = tl->get_con(); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1364 // HD, Figure 5-14 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1365 int x, y; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1366 if (l == 0) |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1367 return TypeInt::make(BitsPerLong); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1368 int n = 63; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1369 y = (int) l; if (y != 0) { n = n - 32; x = y; } else x = (((julong) l) >> 32); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1370 y = x << 16; if (y != 0) { n = n - 16; x = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1371 y = x << 8; if (y != 0) { n = n - 8; x = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1372 y = x << 4; if (y != 0) { n = n - 4; x = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1373 y = x << 2; if (y != 0) { n = n - 2; x = y; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1374 y = x << 1; if (y != 0) { n = n - 1; } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1375 return TypeInt::make(n); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1376 } |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1377 return TypeInt::INT; |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
755
diff
changeset
|
1378 } |