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