File: | jdk/src/hotspot/share/opto/castnode.cpp |
Warning: | line 210, column 25 Value stored to 't' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
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 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "opto/addnode.hpp" |
27 | #include "opto/callnode.hpp" |
28 | #include "opto/castnode.hpp" |
29 | #include "opto/connode.hpp" |
30 | #include "opto/matcher.hpp" |
31 | #include "opto/phaseX.hpp" |
32 | #include "opto/subnode.hpp" |
33 | #include "opto/type.hpp" |
34 | |
35 | //============================================================================= |
36 | // If input is already higher or equal to cast type, then this is an identity. |
37 | Node* ConstraintCastNode::Identity(PhaseGVN* phase) { |
38 | Node* dom = dominating_cast(phase, phase); |
39 | if (dom != NULL__null) { |
40 | return dom; |
41 | } |
42 | if (_dependency != RegularDependency) { |
43 | return this; |
44 | } |
45 | return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this; |
46 | } |
47 | |
48 | //------------------------------Value------------------------------------------ |
49 | // Take 'join' of input and cast-up type |
50 | const Type* ConstraintCastNode::Value(PhaseGVN* phase) const { |
51 | if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP; |
52 | const Type* ft = phase->type(in(1))->filter_speculative(_type); |
53 | |
54 | #ifdef ASSERT1 |
55 | // Previous versions of this function had some special case logic, |
56 | // which is no longer necessary. Make sure of the required effects. |
57 | switch (Opcode()) { |
58 | case Op_CastII: |
59 | { |
60 | const Type* t1 = phase->type(in(1)); |
61 | if( t1 == Type::TOP ) assert(ft == Type::TOP, "special case #1")do { if (!(ft == Type::TOP)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 61, "assert(" "ft == Type::TOP" ") failed", "special case #1" ); ::breakpoint(); } } while (0); |
62 | const Type* rt = t1->join_speculative(_type); |
63 | if (rt->empty()) assert(ft == Type::TOP, "special case #2")do { if (!(ft == Type::TOP)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 63, "assert(" "ft == Type::TOP" ") failed", "special case #2" ); ::breakpoint(); } } while (0); |
64 | break; |
65 | } |
66 | case Op_CastPP: |
67 | if (phase->type(in(1)) == TypePtr::NULL_PTR && |
68 | _type->isa_ptr() && _type->is_ptr()->_ptr == TypePtr::NotNull) |
69 | assert(ft == Type::TOP, "special case #3")do { if (!(ft == Type::TOP)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 69, "assert(" "ft == Type::TOP" ") failed", "special case #3" ); ::breakpoint(); } } while (0); |
70 | break; |
71 | } |
72 | #endif //ASSERT |
73 | |
74 | return ft; |
75 | } |
76 | |
77 | //------------------------------Ideal------------------------------------------ |
78 | // Return a node which is more "ideal" than the current node. Strip out |
79 | // control copies |
80 | Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
81 | return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL__null; |
82 | } |
83 | |
84 | bool ConstraintCastNode::cmp(const Node &n) const { |
85 | return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency; |
86 | } |
87 | |
88 | uint ConstraintCastNode::size_of() const { |
89 | return sizeof(*this); |
90 | } |
91 | |
92 | Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) { |
93 | switch(opcode) { |
94 | case Op_CastII: { |
95 | Node* cast = new CastIINode(n, t, dependency); |
96 | cast->set_req(0, c); |
97 | return cast; |
98 | } |
99 | case Op_CastLL: { |
100 | Node* cast = new CastLLNode(n, t, dependency); |
101 | cast->set_req(0, c); |
102 | return cast; |
103 | } |
104 | case Op_CastPP: { |
105 | Node* cast = new CastPPNode(n, t, dependency); |
106 | cast->set_req(0, c); |
107 | return cast; |
108 | } |
109 | case Op_CastFF: { |
110 | Node* cast = new CastFFNode(n, t, dependency); |
111 | cast->set_req(0, c); |
112 | return cast; |
113 | } |
114 | case Op_CastDD: { |
115 | Node* cast = new CastDDNode(n, t, dependency); |
116 | cast->set_req(0, c); |
117 | return cast; |
118 | } |
119 | case Op_CastVV: { |
120 | Node* cast = new CastVVNode(n, t, dependency); |
121 | cast->set_req(0, c); |
122 | return cast; |
123 | } |
124 | case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency); |
125 | default: |
126 | fatal("Bad opcode %d", opcode)do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 126, "Bad opcode %d", opcode); ::breakpoint(); } while (0); |
127 | } |
128 | return NULL__null; |
129 | } |
130 | |
131 | Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) { |
132 | switch(bt) { |
133 | case T_INT: { |
134 | return make_cast(Op_CastII, c, n, t, RegularDependency); |
135 | } |
136 | case T_LONG: { |
137 | return make_cast(Op_CastLL, c, n, t, RegularDependency); |
138 | } |
139 | default: |
140 | fatal("Bad basic type %s", type2name(bt))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 140, "Bad basic type %s", type2name(bt)); ::breakpoint(); } while (0); |
141 | } |
142 | return NULL__null; |
143 | } |
144 | |
145 | TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const { |
146 | if (_dependency == UnconditionalDependency) { |
147 | return NULL__null; |
148 | } |
149 | Node* val = in(1); |
150 | Node* ctl = in(0); |
151 | int opc = Opcode(); |
152 | if (ctl == NULL__null) { |
153 | return NULL__null; |
154 | } |
155 | // Range check CastIIs may all end up under a single range check and |
156 | // in that case only the narrower CastII would be kept by the code |
157 | // below which would be incorrect. |
158 | if (is_CastII() && as_CastII()->has_range_check()) { |
159 | return NULL__null; |
160 | } |
161 | if (type()->isa_rawptr() && (gvn->type_or_null(val) == NULL__null || gvn->type(val)->isa_oopptr())) { |
162 | return NULL__null; |
163 | } |
164 | for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { |
165 | Node* u = val->fast_out(i); |
166 | if (u != this && |
167 | u->outcnt() > 0 && |
168 | u->Opcode() == opc && |
169 | u->in(0) != NULL__null && |
170 | u->bottom_type()->higher_equal(type())) { |
171 | if (pt->is_dominator(u->in(0), ctl)) { |
172 | return u->as_Type(); |
173 | } |
174 | if (is_CheckCastPP() && u->in(1)->is_Proj() && u->in(1)->in(0)->is_Allocate() && |
175 | u->in(0)->is_Proj() && u->in(0)->in(0)->is_Initialize() && |
176 | u->in(1)->in(0)->as_Allocate()->initialization() == u->in(0)->in(0)) { |
177 | // CheckCastPP following an allocation always dominates all |
178 | // use of the allocation result |
179 | return u->as_Type(); |
180 | } |
181 | } |
182 | } |
183 | return NULL__null; |
184 | } |
185 | |
186 | #ifndef PRODUCT |
187 | void ConstraintCastNode::dump_spec(outputStream *st) const { |
188 | TypeNode::dump_spec(st); |
189 | if (_dependency != RegularDependency) { |
190 | st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional"); |
191 | } |
192 | } |
193 | #endif |
194 | |
195 | const Type* CastIINode::Value(PhaseGVN* phase) const { |
196 | const Type *res = ConstraintCastNode::Value(phase); |
197 | |
198 | // Try to improve the type of the CastII if we recognize a CmpI/If |
199 | // pattern. |
200 | if (_dependency != RegularDependency) { |
201 | if (in(0) != NULL__null && in(0)->in(0) != NULL__null && in(0)->in(0)->is_If()) { |
202 | assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj")do { if (!(in(0)->is_IfFalse() || in(0)->is_IfTrue())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 202, "assert(" "in(0)->is_IfFalse() || in(0)->is_IfTrue()" ") failed", "should be If proj"); ::breakpoint(); } } while ( 0); |
203 | Node* proj = in(0); |
204 | if (proj->in(0)->in(1)->is_Bool()) { |
205 | Node* b = proj->in(0)->in(1); |
206 | if (b->in(1)->Opcode() == Op_CmpI) { |
207 | Node* cmp = b->in(1); |
208 | if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) { |
209 | const TypeInt* in2_t = phase->type(cmp->in(2))->is_int(); |
210 | const Type* t = TypeInt::INT; |
Value stored to 't' during its initialization is never read | |
211 | BoolTest test = b->as_Bool()->_test; |
212 | if (proj->is_IfFalse()) { |
213 | test = test.negate(); |
214 | } |
215 | BoolTest::mask m = test._test; |
216 | jlong lo_long = min_jint; |
217 | jlong hi_long = max_jint; |
218 | if (m == BoolTest::le || m == BoolTest::lt) { |
219 | hi_long = in2_t->_hi; |
220 | if (m == BoolTest::lt) { |
221 | hi_long -= 1; |
222 | } |
223 | } else if (m == BoolTest::ge || m == BoolTest::gt) { |
224 | lo_long = in2_t->_lo; |
225 | if (m == BoolTest::gt) { |
226 | lo_long += 1; |
227 | } |
228 | } else if (m == BoolTest::eq) { |
229 | lo_long = in2_t->_lo; |
230 | hi_long = in2_t->_hi; |
231 | } else if (m == BoolTest::ne) { |
232 | // can't do any better |
233 | } else { |
234 | stringStream ss; |
235 | test.dump_on(&ss); |
236 | fatal("unexpected comparison %s", ss.as_string())do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 236, "unexpected comparison %s", ss.as_string()); ::breakpoint (); } while (0); |
237 | } |
238 | int lo_int = (int)lo_long; |
239 | int hi_int = (int)hi_long; |
240 | |
241 | if (lo_long != (jlong)lo_int) { |
242 | lo_int = min_jint; |
243 | } |
244 | if (hi_long != (jlong)hi_int) { |
245 | hi_int = max_jint; |
246 | } |
247 | |
248 | t = TypeInt::make(lo_int, hi_int, Type::WidenMax); |
249 | |
250 | res = res->filter_speculative(t); |
251 | |
252 | return res; |
253 | } |
254 | } |
255 | } |
256 | } |
257 | } |
258 | return res; |
259 | } |
260 | |
261 | static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, ConstraintCastNode::DependencyType dependency) { |
262 | Node* n = new CastIINode(parent, type, dependency); |
263 | n->set_req(0, control); |
264 | Node* existing = igvn->hash_find_insert(n); |
265 | if (existing != NULL__null) { |
266 | n->destruct(igvn); |
267 | return existing; |
268 | } |
269 | return igvn->register_new_node_with_optimizer(n); |
270 | } |
271 | |
272 | Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) { |
273 | Node* progress = ConstraintCastNode::Ideal(phase, can_reshape); |
274 | if (progress != NULL__null) { |
275 | return progress; |
276 | } |
277 | |
278 | PhaseIterGVN *igvn = phase->is_IterGVN(); |
279 | const TypeInt* this_type = this->type()->is_int(); |
280 | Node* z = in(1); |
281 | const TypeInteger* rx = NULL__null; |
282 | const TypeInteger* ry = NULL__null; |
283 | // Similar to ConvI2LNode::Ideal() for the same reasons |
284 | if (!_range_check_dependency && Compile::push_thru_add(phase, z, this_type, rx, ry, T_INT)) { |
285 | if (igvn == NULL__null) { |
286 | // Postpone this optimization to iterative GVN, where we can handle deep |
287 | // AddI chains without an exponential number of recursive Ideal() calls. |
288 | phase->record_for_igvn(this); |
289 | return NULL__null; |
290 | } |
291 | int op = z->Opcode(); |
292 | Node* x = z->in(1); |
293 | Node* y = z->in(2); |
294 | |
295 | Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _dependency); |
296 | Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _dependency); |
297 | switch (op) { |
298 | case Op_AddI: return new AddINode(cx, cy); |
299 | case Op_SubI: return new SubINode(cx, cy); |
300 | default: ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here( "/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 300); ::breakpoint(); } while (0); |
301 | } |
302 | } |
303 | |
304 | // Similar to ConvI2LNode::Ideal() for the same reasons |
305 | // Do not narrow the type of range check dependent CastIINodes to |
306 | // avoid corruption of the graph if a CastII is replaced by TOP but |
307 | // the corresponding range check is not removed. |
308 | if (can_reshape && !_range_check_dependency) { |
309 | if (phase->C->post_loop_opts_phase()) { |
310 | const TypeInt* this_type = this->type()->is_int(); |
311 | const TypeInt* in_type = phase->type(in(1))->isa_int(); |
312 | if (in_type != NULL__null && this_type != NULL__null && |
313 | (in_type->_lo != this_type->_lo || |
314 | in_type->_hi != this_type->_hi)) { |
315 | jint lo1 = this_type->_lo; |
316 | jint hi1 = this_type->_hi; |
317 | int w1 = this_type->_widen; |
318 | |
319 | if (lo1 >= 0) { |
320 | // Keep a range assertion of >=0. |
321 | lo1 = 0; hi1 = max_jint; |
322 | } else if (hi1 < 0) { |
323 | // Keep a range assertion of <0. |
324 | lo1 = min_jint; hi1 = -1; |
325 | } else { |
326 | lo1 = min_jint; hi1 = max_jint; |
327 | } |
328 | const TypeInt* wtype = TypeInt::make(MAX2(in_type->_lo, lo1), |
329 | MIN2(in_type->_hi, hi1), |
330 | MAX2((int)in_type->_widen, w1)); |
331 | if (wtype != type()) { |
332 | set_type(wtype); |
333 | return this; |
334 | } |
335 | } |
336 | } else { |
337 | phase->C->record_for_post_loop_opts_igvn(this); |
338 | } |
339 | } |
340 | return NULL__null; |
341 | } |
342 | |
343 | Node* CastIINode::Identity(PhaseGVN* phase) { |
344 | Node* progress = ConstraintCastNode::Identity(phase); |
345 | if (progress != this) { |
346 | return progress; |
347 | } |
348 | if (_range_check_dependency) { |
349 | if (phase->C->post_loop_opts_phase()) { |
350 | return this->in(1); |
351 | } else { |
352 | phase->C->record_for_post_loop_opts_igvn(this); |
353 | } |
354 | } |
355 | return this; |
356 | } |
357 | |
358 | bool CastIINode::cmp(const Node &n) const { |
359 | return ConstraintCastNode::cmp(n) && ((CastIINode&)n)._range_check_dependency == _range_check_dependency; |
360 | } |
361 | |
362 | uint CastIINode::size_of() const { |
363 | return sizeof(*this); |
364 | } |
365 | |
366 | #ifndef PRODUCT |
367 | void CastIINode::dump_spec(outputStream* st) const { |
368 | ConstraintCastNode::dump_spec(st); |
369 | if (_range_check_dependency) { |
370 | st->print(" range check dependency"); |
371 | } |
372 | } |
373 | #endif |
374 | |
375 | //============================================================================= |
376 | //------------------------------Identity--------------------------------------- |
377 | // If input is already higher or equal to cast type, then this is an identity. |
378 | Node* CheckCastPPNode::Identity(PhaseGVN* phase) { |
379 | Node* dom = dominating_cast(phase, phase); |
380 | if (dom != NULL__null) { |
381 | return dom; |
382 | } |
383 | if (_dependency != RegularDependency) { |
384 | return this; |
385 | } |
386 | const Type* t = phase->type(in(1)); |
387 | if (EnableVectorReboxing && in(1)->Opcode() == Op_VectorBox) { |
388 | if (t->higher_equal_speculative(phase->type(this))) { |
389 | return in(1); |
390 | } |
391 | } else if (t == phase->type(this)) { |
392 | // Toned down to rescue meeting at a Phi 3 different oops all implementing |
393 | // the same interface. |
394 | return in(1); |
395 | } |
396 | return this; |
397 | } |
398 | |
399 | //------------------------------Value------------------------------------------ |
400 | // Take 'join' of input and cast-up type, unless working with an Interface |
401 | const Type* CheckCastPPNode::Value(PhaseGVN* phase) const { |
402 | if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP; |
403 | |
404 | const Type *inn = phase->type(in(1)); |
405 | if( inn == Type::TOP ) return Type::TOP; // No information yet |
406 | |
407 | const TypePtr *in_type = inn->isa_ptr(); |
408 | const TypePtr *my_type = _type->isa_ptr(); |
409 | const Type *result = _type; |
410 | if( in_type != NULL__null && my_type != NULL__null ) { |
411 | TypePtr::PTR in_ptr = in_type->ptr(); |
412 | if (in_ptr == TypePtr::Null) { |
413 | result = in_type; |
414 | } else if (in_ptr == TypePtr::Constant) { |
415 | if (my_type->isa_rawptr()) { |
416 | result = my_type; |
417 | } else { |
418 | const TypeOopPtr *jptr = my_type->isa_oopptr(); |
419 | assert(jptr, "")do { if (!(jptr)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/castnode.cpp" , 419, "assert(" "jptr" ") failed", ""); ::breakpoint(); } } while (0); |
420 | result = !in_type->higher_equal(_type) |
421 | ? my_type->cast_to_ptr_type(TypePtr::NotNull) |
422 | : in_type; |
423 | } |
424 | } else { |
425 | result = my_type->cast_to_ptr_type( my_type->join_ptr(in_ptr) ); |
426 | } |
427 | } |
428 | |
429 | // This is the code from TypePtr::xmeet() that prevents us from |
430 | // having 2 ways to represent the same type. We have to replicate it |
431 | // here because we don't go through meet/join. |
432 | if (result->remove_speculative() == result->speculative()) { |
433 | result = result->remove_speculative(); |
434 | } |
435 | |
436 | // Same as above: because we don't go through meet/join, remove the |
437 | // speculative type if we know we won't use it. |
438 | return result->cleanup_speculative(); |
439 | |
440 | // JOIN NOT DONE HERE BECAUSE OF INTERFACE ISSUES. |
441 | // FIX THIS (DO THE JOIN) WHEN UNION TYPES APPEAR! |
442 | |
443 | // |
444 | // Remove this code after overnight run indicates no performance |
445 | // loss from not performing JOIN at CheckCastPPNode |
446 | // |
447 | // const TypeInstPtr *in_oop = in->isa_instptr(); |
448 | // const TypeInstPtr *my_oop = _type->isa_instptr(); |
449 | // // If either input is an 'interface', return destination type |
450 | // assert (in_oop == NULL || in_oop->klass() != NULL, ""); |
451 | // assert (my_oop == NULL || my_oop->klass() != NULL, ""); |
452 | // if( (in_oop && in_oop->klass()->is_interface()) |
453 | // ||(my_oop && my_oop->klass()->is_interface()) ) { |
454 | // TypePtr::PTR in_ptr = in->isa_ptr() ? in->is_ptr()->_ptr : TypePtr::BotPTR; |
455 | // // Preserve cast away nullness for interfaces |
456 | // if( in_ptr == TypePtr::NotNull && my_oop && my_oop->_ptr == TypePtr::BotPTR ) { |
457 | // return my_oop->cast_to_ptr_type(TypePtr::NotNull); |
458 | // } |
459 | // return _type; |
460 | // } |
461 | // |
462 | // // Neither the input nor the destination type is an interface, |
463 | // |
464 | // // history: JOIN used to cause weird corner case bugs |
465 | // // return (in == TypeOopPtr::NULL_PTR) ? in : _type; |
466 | // // JOIN picks up NotNull in common instance-of/check-cast idioms, both oops. |
467 | // // JOIN does not preserve NotNull in other cases, e.g. RawPtr vs InstPtr |
468 | // const Type *join = in->join(_type); |
469 | // // Check if join preserved NotNull'ness for pointers |
470 | // if( join->isa_ptr() && _type->isa_ptr() ) { |
471 | // TypePtr::PTR join_ptr = join->is_ptr()->_ptr; |
472 | // TypePtr::PTR type_ptr = _type->is_ptr()->_ptr; |
473 | // // If there isn't any NotNull'ness to preserve |
474 | // // OR if join preserved NotNull'ness then return it |
475 | // if( type_ptr == TypePtr::BotPTR || type_ptr == TypePtr::Null || |
476 | // join_ptr == TypePtr::NotNull || join_ptr == TypePtr::Constant ) { |
477 | // return join; |
478 | // } |
479 | // // ELSE return same old type as before |
480 | // return _type; |
481 | // } |
482 | // // Not joining two pointers |
483 | // return join; |
484 | } |
485 | |
486 | //============================================================================= |
487 | //------------------------------Value------------------------------------------ |
488 | const Type* CastX2PNode::Value(PhaseGVN* phase) const { |
489 | const Type* t = phase->type(in(1)); |
490 | if (t == Type::TOP) return Type::TOP; |
491 | if (t->base() == Type_XType::Long && t->singleton()) { |
492 | uintptr_t bits = (uintptr_t) t->is_intptr_tis_long()->get_con(); |
493 | if (bits == 0) return TypePtr::NULL_PTR; |
494 | return TypeRawPtr::make((address) bits); |
495 | } |
496 | return CastX2PNode::bottom_type(); |
497 | } |
498 | |
499 | //------------------------------Idealize--------------------------------------- |
500 | static inline bool fits_in_int(const Type* t, bool but_not_min_int = false) { |
501 | if (t == Type::TOP) return false; |
502 | const TypeXTypeLong* tl = t->is_intptr_tis_long(); |
503 | jint lo = min_jint; |
504 | jint hi = max_jint; |
505 | if (but_not_min_int) ++lo; // caller wants to negate the value w/o overflow |
506 | return (tl->_lo >= lo) && (tl->_hi <= hi); |
507 | } |
508 | |
509 | static inline Node* addP_of_X2P(PhaseGVN *phase, |
510 | Node* base, |
511 | Node* dispX, |
512 | bool negate = false) { |
513 | if (negate) { |
514 | dispX = phase->transform(new SubXNodeSubLNode(phase->MakeConXlongcon(0), dispX)); |
515 | } |
516 | return new AddPNode(phase->C->top(), |
517 | phase->transform(new CastX2PNode(base)), |
518 | dispX); |
519 | } |
520 | |
521 | Node *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
522 | // convert CastX2P(AddX(x, y)) to AddP(CastX2P(x), y) if y fits in an int |
523 | int op = in(1)->Opcode(); |
524 | Node* x; |
525 | Node* y; |
526 | switch (op) { |
527 | case Op_SubXOp_SubL: |
528 | x = in(1)->in(1); |
529 | // Avoid ideal transformations ping-pong between this and AddP for raw pointers. |
530 | if (phase->find_intptr_t_confind_long_con(x, -1) == 0) |
531 | break; |
532 | y = in(1)->in(2); |
533 | if (fits_in_int(phase->type(y), true)) { |
534 | return addP_of_X2P(phase, x, y, true); |
535 | } |
536 | break; |
537 | case Op_AddXOp_AddL: |
538 | x = in(1)->in(1); |
539 | y = in(1)->in(2); |
540 | if (fits_in_int(phase->type(y))) { |
541 | return addP_of_X2P(phase, x, y); |
542 | } |
543 | if (fits_in_int(phase->type(x))) { |
544 | return addP_of_X2P(phase, y, x); |
545 | } |
546 | break; |
547 | } |
548 | return NULL__null; |
549 | } |
550 | |
551 | //------------------------------Identity--------------------------------------- |
552 | Node* CastX2PNode::Identity(PhaseGVN* phase) { |
553 | if (in(1)->Opcode() == Op_CastP2X) return in(1)->in(1); |
554 | return this; |
555 | } |
556 | |
557 | //============================================================================= |
558 | //------------------------------Value------------------------------------------ |
559 | const Type* CastP2XNode::Value(PhaseGVN* phase) const { |
560 | const Type* t = phase->type(in(1)); |
561 | if (t == Type::TOP) return Type::TOP; |
562 | if (t->base() == Type::RawPtr && t->singleton()) { |
563 | uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); |
564 | return TypeXTypeLong::make(bits); |
565 | } |
566 | return CastP2XNode::bottom_type(); |
567 | } |
568 | |
569 | Node *CastP2XNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
570 | return (in(0) && remove_dead_region(phase, can_reshape)) ? this : NULL__null; |
571 | } |
572 | |
573 | //------------------------------Identity--------------------------------------- |
574 | Node* CastP2XNode::Identity(PhaseGVN* phase) { |
575 | if (in(1)->Opcode() == Op_CastX2P) return in(1)->in(1); |
576 | return this; |
577 | } |
578 | |
579 | Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) { |
580 | Node* cast= NULL__null; |
581 | if (type->isa_int()) { |
582 | cast = make_cast(Op_CastII, c, in, type, dependency); |
583 | } else if (type->isa_long()) { |
584 | cast = make_cast(Op_CastLL, c, in, type, dependency); |
585 | } else if (type->isa_float()) { |
586 | cast = make_cast(Op_CastFF, c, in, type, dependency); |
587 | } else if (type->isa_double()) { |
588 | cast = make_cast(Op_CastDD, c, in, type, dependency); |
589 | } else if (type->isa_vect()) { |
590 | cast = make_cast(Op_CastVV, c, in, type, dependency); |
591 | } else if (type->isa_ptr()) { |
592 | cast = make_cast(Op_CastPP, c, in, type, dependency); |
593 | } |
594 | return cast; |
595 | } |