annotate src/share/vm/opto/connode.cpp @ 452:00b023ae2d78

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