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