annotate src/share/vm/opto/mulnode.cpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 897
diff changeset
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. 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 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 897
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 897
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 897
diff changeset
21 * questions.
0
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 // Portions of code courtesy of Clifford Click
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/_mulnode.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 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
32 //------------------------------hash-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // Hash function over MulNodes. Needs to be commutative; i.e., I swap
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // (commute) inputs to MulNodes willy-nilly so the hash function must return
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // the same value in the presence of edge swapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
36 uint MulNode::hash() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 return (uintptr_t)in(1) + (uintptr_t)in(2) + Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
38 }
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // Multiplying a one preserves the other argument
a61af66fc99e Initial load
duke
parents:
diff changeset
42 Node *MulNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 register const Type *one = mul_id(); // The multiplicative identity
a61af66fc99e Initial load
duke
parents:
diff changeset
44 if( phase->type( in(1) )->higher_equal( one ) ) return in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if( phase->type( in(2) )->higher_equal( one ) ) return in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // We also canonicalize the Node, moving constants to the right input,
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // and flatten expressions (so that 1+x+2 becomes x+3).
a61af66fc99e Initial load
duke
parents:
diff changeset
53 Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
55 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
56 Node *progress = NULL; // Progress flag
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // We are OK if right is a constant, or right is a load and
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // left is a non-constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
59 if( !(t2->singleton() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
60 (in(2)->is_Load() && !(t1->singleton() || in(1)->is_Load())) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 if( t1->singleton() || // Left input is a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Otherwise, sort inputs (commutativity) to help value numbering.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 (in(1)->_idx > in(2)->_idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 swap_edges(1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
65 const Type *t = t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 t1 = t2;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 t2 = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 progress = this; // Made progress
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // If the right input is a constant, and the left input is a product of a
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // constant, flatten the expression tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 uint op = Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if( t2->singleton() && // Right input is a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
76 op != Op_MulF && // Float & double cannot reassociate
a61af66fc99e Initial load
duke
parents:
diff changeset
77 op != Op_MulD ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if( t2 == Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 Node *mul1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // Check for dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
82 int op1 = mul1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if( phase->eqv( mul1, this ) || phase->eqv( in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
84 ( op1 == mul_opcode() || op1 == add_opcode() ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
85 ( phase->eqv( mul1->in(1), this ) || phase->eqv( mul1->in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
86 phase->eqv( mul1->in(1), mul1 ) || phase->eqv( mul1->in(2), mul1 ) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
87 assert(false, "dead loop in MulNode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
88 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 if( mul1->Opcode() == mul_opcode() ) { // Left input is a multiply?
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // Mul of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
92 const Type *t12 = phase->type( mul1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if( t12->singleton() && t12 != Type::TOP) { // Left input is an add of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // Compute new constant; check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
95 const Type *tcon01 = mul1->as_Mul()->mul_ring(t2,t12);
a61af66fc99e Initial load
duke
parents:
diff changeset
96 if( tcon01->singleton() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // The Mul of the flattened expression
a61af66fc99e Initial load
duke
parents:
diff changeset
98 set_req(1, mul1->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
99 set_req(2, phase->makecon( tcon01 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
100 t2 = tcon01;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 progress = this; // Made progress
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // If the right input is a constant, and the left input is an add of a
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // constant, flatten the tree: (X+con1)*con0 ==> X*con0 + con1*con0
a61af66fc99e Initial load
duke
parents:
diff changeset
107 const Node *add1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 if( add1->Opcode() == add_opcode() ) { // Left input is an add?
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Add of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
110 const Type *t12 = phase->type( add1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
112 assert( add1->in(1) != add1, "dead loop in MulNode::Ideal" );
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Compute new constant; check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
114 const Type *tcon01 = mul_ring(t2,t12);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if( tcon01->singleton() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Convert (X+con1)*con0 into X*con0
a61af66fc99e Initial load
duke
parents:
diff changeset
118 Node *mul = clone(); // mul = ()*con0
a61af66fc99e Initial load
duke
parents:
diff changeset
119 mul->set_req(1,add1->in(1)); // mul = X*con0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 mul = phase->transform(mul);
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 Node *add2 = add1->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
123 add2->set_req(1, mul); // X*con0 + con0*con1
a61af66fc99e Initial load
duke
parents:
diff changeset
124 add2->set_req(2, phase->makecon(tcon01) );
a61af66fc99e Initial load
duke
parents:
diff changeset
125 progress = add2;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 } // End of is left input an add
a61af66fc99e Initial load
duke
parents:
diff changeset
129 } // End of is right input a Mul
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 return progress;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 //------------------------------Value-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
135 const Type *MulNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
137 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Either input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Not valid for floats or doubles since +0.0 * -0.0 --> +0.0
a61af66fc99e Initial load
duke
parents:
diff changeset
144 int op = Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 if( op == Op_MulI || op == Op_AndI || op == Op_MulL || op == Op_AndL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 const Type *zero = add_id(); // The multiplicative zero
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if( t1->higher_equal( zero ) ) return zero;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if( t2->higher_equal( zero ) ) return zero;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Either input is BOTTOM ==> the result is the local BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
a61af66fc99e Initial load
duke
parents:
diff changeset
153 return bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
154
404
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
155 #if defined(IA32)
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
156 // Can't trust native compilers to properly fold strict double
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
157 // multiplication with round-to-zero on this platform.
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
158 if (op == Op_MulD && phase->C->method()->is_strict()) {
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
159 return TypeD::DOUBLE;
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
160 }
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
161 #endif
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
162
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return mul_ring(t1,t2); // Local flavor of type multiplication
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
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 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Check for power-of-2 multiply, then try the regular MulNode::Ideal
a61af66fc99e Initial load
duke
parents:
diff changeset
170 Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Swap constant to right
a61af66fc99e Initial load
duke
parents:
diff changeset
172 jint con;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 if ((con = in(1)->find_int_con(0)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 swap_edges(1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // Finish rest of method to use info in 'con'
a61af66fc99e Initial load
duke
parents:
diff changeset
176 } else if ((con = in(2)->find_int_con(0)) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Now we have a constant Node on the right and the constant in con
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if( con == 0 ) return NULL; // By zero is handled by Value call
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if( con == 1 ) return NULL; // By one is handled by Identity call
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Check for negative constant; if so negate the final result
a61af66fc99e Initial load
duke
parents:
diff changeset
185 bool sign_flip = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if( con < 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 con = -con;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 sign_flip = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // Get low bit; check for being the only bit
a61af66fc99e Initial load
duke
parents:
diff changeset
192 Node *res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 jint bit1 = con & -con; // Extract low bit
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if( bit1 == con ) { // Found a power of 2?
a61af66fc99e Initial load
duke
parents:
diff changeset
195 res = new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
196 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Check for constant with 2 bits set
a61af66fc99e Initial load
duke
parents:
diff changeset
199 jint bit2 = con-bit1;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 bit2 = bit2 & -bit2; // Extract 2nd bit
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if( bit2 + bit1 == con ) { // Found all bits in con?
a61af66fc99e Initial load
duke
parents:
diff changeset
202 Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
203 Node *n2 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
204 res = new (phase->C, 3) AddINode( n2, n1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 } else if (is_power_of_2(con+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Sleezy: power-of-2 -1. Next time be generic.
a61af66fc99e Initial load
duke
parents:
diff changeset
208 jint temp = (jint) (con + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
210 res = new (phase->C, 3) SubINode( n1, in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
211 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if( sign_flip ) { // Need to negate result?
a61af66fc99e Initial load
duke
parents:
diff changeset
217 res = phase->transform(res);// Transform, before making the zero con
a61af66fc99e Initial load
duke
parents:
diff changeset
218 res = new (phase->C, 3) SubINode(phase->intcon(0),res);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 return res; // Return final result
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Compute the product type of two integer ranges into this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
226 const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 const TypeInt *r0 = t0->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
228 const TypeInt *r1 = t1->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // Fetch endpoints of all ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
231 int32 lo0 = r0->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 double a = (double)lo0;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 int32 hi0 = r0->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 double b = (double)hi0;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 int32 lo1 = r1->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 double c = (double)lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 int32 hi1 = r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 double d = (double)hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // Compute all endpoints & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
241 int32 A = lo0*lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if( (double)A != a*c ) return TypeInt::INT; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
243 int32 B = lo0*hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if( (double)B != a*d ) return TypeInt::INT; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
245 int32 C = hi0*lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 if( (double)C != b*c ) return TypeInt::INT; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
247 int32 D = hi0*hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if( (double)D != b*d ) return TypeInt::INT; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
251 else { lo0 = B; hi0 = A; }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if( C < D ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if( C < lo0 ) lo0 = C;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if( D > hi0 ) hi0 = D;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 if( D < lo0 ) lo0 = D;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if( C > hi0 ) hi0 = C;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 return TypeInt::make(lo0, hi0, MAX2(r0->_widen,r1->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
264 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Check for power-of-2 multiply, then try the regular MulNode::Ideal
a61af66fc99e Initial load
duke
parents:
diff changeset
266 Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Swap constant to right
a61af66fc99e Initial load
duke
parents:
diff changeset
268 jlong con;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if ((con = in(1)->find_long_con(0)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 swap_edges(1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Finish rest of method to use info in 'con'
a61af66fc99e Initial load
duke
parents:
diff changeset
272 } else if ((con = in(2)->find_long_con(0)) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Now we have a constant Node on the right and the constant in con
a61af66fc99e Initial load
duke
parents:
diff changeset
277 if( con == CONST64(0) ) return NULL; // By zero is handled by Value call
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if( con == CONST64(1) ) return NULL; // By one is handled by Identity call
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Check for negative constant; if so negate the final result
a61af66fc99e Initial load
duke
parents:
diff changeset
281 bool sign_flip = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if( con < 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 con = -con;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 sign_flip = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Get low bit; check for being the only bit
a61af66fc99e Initial load
duke
parents:
diff changeset
288 Node *res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 jlong bit1 = con & -con; // Extract low bit
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if( bit1 == con ) { // Found a power of 2?
a61af66fc99e Initial load
duke
parents:
diff changeset
291 res = new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
292 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Check for constant with 2 bits set
a61af66fc99e Initial load
duke
parents:
diff changeset
295 jlong bit2 = con-bit1;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 bit2 = bit2 & -bit2; // Extract 2nd bit
a61af66fc99e Initial load
duke
parents:
diff changeset
297 if( bit2 + bit1 == con ) { // Found all bits in con?
a61af66fc99e Initial load
duke
parents:
diff changeset
298 Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
299 Node *n2 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
300 res = new (phase->C, 3) AddLNode( n2, n1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 } else if (is_power_of_2_long(con+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Sleezy: power-of-2 -1. Next time be generic.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 jlong temp = (jlong) (con + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
306 res = new (phase->C, 3) SubLNode( n1, in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
307 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if( sign_flip ) { // Need to negate result?
a61af66fc99e Initial load
duke
parents:
diff changeset
313 res = phase->transform(res);// Transform, before making the zero con
a61af66fc99e Initial load
duke
parents:
diff changeset
314 res = new (phase->C, 3) SubLNode(phase->longcon(0),res);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 return res; // Return final result
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Compute the product type of two integer ranges into this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
322 const Type *MulLNode::mul_ring(const Type *t0, const Type *t1) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 const TypeLong *r0 = t0->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
324 const TypeLong *r1 = t1->is_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // Fetch endpoints of all ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
327 jlong lo0 = r0->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 double a = (double)lo0;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 jlong hi0 = r0->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 double b = (double)hi0;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 jlong lo1 = r1->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 double c = (double)lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 jlong hi1 = r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 double d = (double)hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Compute all endpoints & check for overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
337 jlong A = lo0*lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 if( (double)A != a*c ) return TypeLong::LONG; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
339 jlong B = lo0*hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
340 if( (double)B != a*d ) return TypeLong::LONG; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
341 jlong C = hi0*lo1;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if( (double)C != b*c ) return TypeLong::LONG; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
343 jlong D = hi0*hi1;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 if( (double)D != b*d ) return TypeLong::LONG; // Overflow?
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
347 else { lo0 = B; hi0 = A; }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if( C < D ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if( C < lo0 ) lo0 = C;
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if( D > hi0 ) hi0 = D;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if( D < lo0 ) lo0 = D;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 if( C > hi0 ) hi0 = C;
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355 return TypeLong::make(lo0, hi0, MAX2(r0->_widen,r1->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
359 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // Compute the product type of two double ranges into this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
361 const Type *MulFNode::mul_ring(const Type *t0, const Type *t1) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if( t0 == Type::FLOAT || t1 == Type::FLOAT ) return Type::FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return TypeF::make( t0->getf() * t1->getf() );
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
367 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // Compute the product type of two double ranges into this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
369 const Type *MulDNode::mul_ring(const Type *t0, const Type *t1) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if( t0 == Type::DOUBLE || t1 == Type::DOUBLE ) return Type::DOUBLE;
404
78c058bc5cdc 6717150: improper constant folding of subnormal strictfp multiplications and divides
rasbold
parents: 196
diff changeset
371 // We must be multiplying 2 double constants.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return TypeD::make( t0->getd() * t1->getd() );
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 //=============================================================================
145
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
376 //------------------------------Value------------------------------------------
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
377 const Type *MulHiLNode::Value( PhaseTransform *phase ) const {
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
378 // Either input is TOP ==> the result is TOP
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
379 const Type *t1 = phase->type( in(1) );
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
380 const Type *t2 = phase->type( in(2) );
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
381 if( t1 == Type::TOP ) return Type::TOP;
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
382 if( t2 == Type::TOP ) return Type::TOP;
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
383
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
384 // Either input is BOTTOM ==> the result is the local BOTTOM
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
385 const Type *bot = bottom_type();
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
386 if( (t1 == bot) || (t2 == bot) ||
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
387 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
388 return bot;
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
389
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
390 // It is not worth trying to constant fold this stuff!
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
391 return TypeLong::LONG;
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
392 }
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
393
f3de1255b035 6603011: RFE: Optimize long division
rasbold
parents: 0
diff changeset
394 //=============================================================================
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // Supplied function returns the product of the inputs IN THE CURRENT RING.
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // For the logical operations the ring's MUL is really a logical AND function.
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // This also type-checks the inputs for sanity. Guaranteed never to
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // be passed a TOP or BOTTOM type, these are filtered out by pre-check.
a61af66fc99e Initial load
duke
parents:
diff changeset
400 const Type *AndINode::mul_ring( const Type *t0, const Type *t1 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 const TypeInt *r0 = t0->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
402 const TypeInt *r1 = t1->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 int widen = MAX2(r0->_widen,r1->_widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // If either input is a constant, might be able to trim cases
a61af66fc99e Initial load
duke
parents:
diff changeset
406 if( !r0->is_con() && !r1->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
407 return TypeInt::INT; // No constants to be had
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Both constants? Return bits
a61af66fc99e Initial load
duke
parents:
diff changeset
410 if( r0->is_con() && r1->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
411 return TypeInt::make( r0->get_con() & r1->get_con() );
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 if( r0->is_con() && r0->get_con() > 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
414 return TypeInt::make(0, r0->get_con(), widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 if( r1->is_con() && r1->get_con() > 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
417 return TypeInt::make(0, r1->get_con(), widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if( r0 == TypeInt::BOOL || r1 == TypeInt::BOOL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 return TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 return TypeInt::INT; // No constants to be had
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // Masking off the high bits of an unsigned load is not required
a61af66fc99e Initial load
duke
parents:
diff changeset
428 Node *AndINode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // x & x => x
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if (phase->eqv(in(1), in(2))) return in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
432
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
433 Node* in1 = in(1);
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
434 uint op = in1->Opcode();
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
435 const TypeInt* t2 = phase->type(in(2))->isa_int();
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
436 if (t2 && t2->is_con()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
437 int con = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // Masking off high bits which are always zero is useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
439 const TypeInt* t1 = phase->type( in(1) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (t1 != NULL && t1->_lo >= 0) {
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
441 jint t1_support = right_n_bits(1 + log2_intptr(t1->_hi));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if ((t1_support & con) == t1_support)
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
443 return in1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // Masking off the high bits of a unsigned-shift-right is not
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // needed either.
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
447 if (op == Op_URShiftI) {
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
448 const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
449 if (t12 && t12->is_con()) { // Shift is by a constant
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
450 int shift = t12->get_con();
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
451 shift &= BitsPerJavaInteger - 1; // semantics of Java shifts
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
452 int mask = max_juint >> shift;
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
453 if ((mask & con) == mask) // If AND is useless, skip it
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
454 return in1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return MulNode::Identity(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
462 Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Special case constant AND mask
a61af66fc99e Initial load
duke
parents:
diff changeset
464 const TypeInt *t2 = phase->type( in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
466 const int mask = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
467 Node *load = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 uint lop = load->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Masking bits off of a Character? Hi bits are already zero.
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 404
diff changeset
471 if( lop == Op_LoadUS &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
472 (mask & 0xFFFF0000) ) // Can we make a smaller mask?
a61af66fc99e Initial load
duke
parents:
diff changeset
473 return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Masking bits off of a Short? Loading a Character does some masking
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
476 if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 404
diff changeset
477 Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
478 load->in(MemNode::Memory),
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
479 load->in(MemNode::Address),
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
480 load->adr_type());
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 404
diff changeset
481 ldus = phase->transform(ldus);
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
482 return new (phase->C, 3) AndINode(ldus, phase->intcon(mask & 0xFFFF));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
485 // Masking sign bits off of a Byte? Do an unsigned byte load plus
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
486 // an and.
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
487 if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
488 Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
489 load->in(MemNode::Memory),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
490 load->in(MemNode::Address),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
491 load->adr_type());
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
492 ldub = phase->transform(ldub);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
493 return new (phase->C, 3) AndINode(ldub, phase->intcon(mask));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Masking off sign bits? Dont make them!
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if( lop == Op_RShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 const TypeInt *t12 = phase->type(load->in(2))->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if( t12 && t12->is_con() ) { // Shift is by a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
500 int shift = t12->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
501 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
502 const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // If the AND'ing of the 2 masks has no bits, then only original shifted
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // bits survive. NO sign-extension bits survive the maskings.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if( (sign_bits_mask & mask) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Use zero-fill shift instead
a61af66fc99e Initial load
duke
parents:
diff changeset
507 Node *zshift = phase->transform(new (phase->C, 3) URShiftINode(load->in(1),load->in(2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return new (phase->C, 3) AndINode( zshift, in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Check for 'negate/and-1', a pattern emitted when someone asks for
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // 'mod 2'. Negate leaves the low order bit unchanged (think: complement
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // plus 1) and the mask is of the low order bit. Skip the negate.
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if( lop == Op_SubI && mask == 1 && load->in(1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
517 phase->type(load->in(1)) == TypeInt::ZERO )
a61af66fc99e Initial load
duke
parents:
diff changeset
518 return new (phase->C, 3) AndINode( load->in(2), in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
524 //------------------------------mul_ring---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // Supplied function returns the product of the inputs IN THE CURRENT RING.
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // For the logical operations the ring's MUL is really a logical AND function.
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // This also type-checks the inputs for sanity. Guaranteed never to
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // be passed a TOP or BOTTOM type, these are filtered out by pre-check.
a61af66fc99e Initial load
duke
parents:
diff changeset
529 const Type *AndLNode::mul_ring( const Type *t0, const Type *t1 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 const TypeLong *r0 = t0->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
531 const TypeLong *r1 = t1->is_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
532 int widen = MAX2(r0->_widen,r1->_widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // If either input is a constant, might be able to trim cases
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if( !r0->is_con() && !r1->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
536 return TypeLong::LONG; // No constants to be had
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // Both constants? Return bits
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if( r0->is_con() && r1->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
540 return TypeLong::make( r0->get_con() & r1->get_con() );
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if( r0->is_con() && r0->get_con() > 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
543 return TypeLong::make(CONST64(0), r0->get_con(), widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if( r1->is_con() && r1->get_con() > 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
546 return TypeLong::make(CONST64(0), r1->get_con(), widen);
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 return TypeLong::LONG; // No constants to be had
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // Masking off the high bits of an unsigned load is not required
a61af66fc99e Initial load
duke
parents:
diff changeset
553 Node *AndLNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // x & x => x
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if (phase->eqv(in(1), in(2))) return in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 Node *usr = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 const TypeLong *t2 = phase->type( in(2) )->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if( t2 && t2->is_con() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 jlong con = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Masking off high bits which are always zero is useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 const TypeLong* t1 = phase->type( in(1) )->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if (t1 != NULL && t1->_lo >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 jlong t1_support = ((jlong)1 << (1 + log2_long(t1->_hi))) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 if ((t1_support & con) == t1_support)
a61af66fc99e Initial load
duke
parents:
diff changeset
567 return usr;
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569 uint lop = usr->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Masking off the high bits of a unsigned-shift-right is not
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // needed either.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if( lop == Op_URShiftL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 const TypeInt *t12 = phase->type( usr->in(2) )->isa_int();
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
574 if( t12 && t12->is_con() ) { // Shift is by a constant
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
575 int shift = t12->get_con();
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
576 shift &= BitsPerJavaLong - 1; // semantics of Java shifts
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
577 jlong mask = max_julong >> shift;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if( (mask&con) == mask ) // If AND is useless, skip it
a61af66fc99e Initial load
duke
parents:
diff changeset
579 return usr;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 return MulNode::Identity(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585
a61af66fc99e Initial load
duke
parents:
diff changeset
586 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
587 Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // Special case constant AND mask
a61af66fc99e Initial load
duke
parents:
diff changeset
589 const TypeLong *t2 = phase->type( in(2) )->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 const jlong mask = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
592
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
593 Node* in1 = in(1);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
594 uint op = in1->Opcode();
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
595
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
596 // Masking sign bits off of an integer? Do an unsigned integer to
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
597 // long load.
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
598 // NOTE: This check must be *before* we try to convert the AndLNode
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
599 // to an AndINode and commute it with ConvI2LNode because
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
600 // 0xFFFFFFFFL masks the whole integer and we get a sign extension,
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
601 // which is wrong.
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
602 if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == CONST64(0x00000000FFFFFFFF)) {
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
603 Node* load = in1->in(1);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
604 return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
605 load->in(MemNode::Memory),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
606 load->in(MemNode::Address),
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
607 load->adr_type());
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
608 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
609
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
610 // Are we masking a long that was converted from an int with a mask
897
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
611 // that fits in 32-bits? Commute them and use an AndINode. Don't
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
612 // convert masks which would cause a sign extension of the integer
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
613 // value. This check includes UI2L masks (0x00000000FFFFFFFF) which
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
614 // would be optimized away later in Identity.
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
615 if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
616 Node* andi = new (phase->C, 3) AndINode(in1->in(1), phase->intcon(mask));
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
617 andi = phase->transform(andi);
52898b0c43e9 6863155: Server compiler generates incorrect code (x86, long, bitshift, bitmask)
twisti
parents: 824
diff changeset
618 return new (phase->C, 2) ConvI2LNode(andi);
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
619 }
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
620
0
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // Masking off sign bits? Dont make them!
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
622 if (op == Op_RShiftL) {
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
623 const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
624 if( t12 && t12->is_con() ) { // Shift is by a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
625 int shift = t12->get_con();
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
626 shift &= BitsPerJavaLong - 1; // semantics of Java shifts
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
627 const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // If the AND'ing of the 2 masks has no bits, then only original shifted
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // bits survive. NO sign-extension bits survive the maskings.
a61af66fc99e Initial load
duke
parents:
diff changeset
630 if( (sign_bits_mask & mask) == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Use zero-fill shift instead
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 559
diff changeset
632 Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2)));
824
18a08a7e16b5 5057225: Remove useless I2L conversions
twisti
parents: 624
diff changeset
633 return new (phase->C, 3) AndLNode(zshift, in(2));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 return MulNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
642 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
643 Node *LShiftINode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int
a61af66fc99e Initial load
duke
parents:
diff changeset
645 return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerInt - 1 ) ) == 0 ) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // If the right input is a constant, and the left input is an add of a
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // constant, flatten the tree: (X+con1)<<con0 ==> X<<con0 + con1<<con0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 Node *LShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 const Type *t = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
653 if( t == Type::TOP ) return NULL; // Right input is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
654 const TypeInt *t2 = t->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
656 const int con = t2->get_con() & ( BitsPerInt - 1 ); // masked shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 if ( con == 0 ) return NULL; // let Identity() handle 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // Left input is an add of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
661 Node *add1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 int add1_op = add1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if( add1_op == Op_AddI ) { // Left input is an add?
a61af66fc99e Initial load
duke
parents:
diff changeset
664 assert( add1 != add1->in(1), "dead loop in LShiftINode::Ideal" );
a61af66fc99e Initial load
duke
parents:
diff changeset
665 const TypeInt *t12 = phase->type(add1->in(2))->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
666 if( t12 && t12->is_con() ){ // Left input is an add of a con?
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Transform is legal, but check for profit. Avoid breaking 'i2s'
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // and 'i2b' patterns which typically fold into 'StoreC/StoreB'.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if( con < 16 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // Compute X << con0
a61af66fc99e Initial load
duke
parents:
diff changeset
671 Node *lsh = phase->transform( new (phase->C, 3) LShiftINode( add1->in(1), in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // Compute X<<con0 + (con1<<con0)
a61af66fc99e Initial load
duke
parents:
diff changeset
673 return new (phase->C, 3) AddINode( lsh, phase->intcon(t12->get_con() << con));
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
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 // Check for "(x>>c0)<<c0" which just masks off low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
680 add1->in(2) == in(2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Convert to "(x & -(1<<c0))"
a61af66fc99e Initial load
duke
parents:
diff changeset
682 return new (phase->C, 3) AndINode(add1->in(1),phase->intcon( -(1<<con)));
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
685 if( add1_op == Op_AndI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
686 Node *add2 = add1->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
687 int add2_op = add2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if( (add2_op == Op_RShiftI || add2_op == Op_URShiftI ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
689 add2->in(2) == in(2) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // Convert to "(x & (Y<<c0))"
a61af66fc99e Initial load
duke
parents:
diff changeset
691 Node *y_sh = phase->transform( new (phase->C, 3) LShiftINode( add1->in(2), in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
692 return new (phase->C, 3) AndINode( add2->in(1), y_sh );
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // Check for ((x & ((1<<(32-c0))-1)) << c0) which ANDs off high bits
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // before shifting them away.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 const jint bits_mask = right_n_bits(BitsPerJavaInteger-con);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 if( add1_op == Op_AndI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
700 phase->type(add1->in(2)) == TypeInt::make( bits_mask ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return new (phase->C, 3) LShiftINode( add1->in(1), in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // A LShiftINode shifts its input2 left by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
708 const Type *LShiftINode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
710 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 if( t1 == TypeInt::ZERO ) return TypeInt::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if( (t1 == TypeInt::INT) || (t2 == TypeInt::INT) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
722 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
a61af66fc99e Initial load
duke
parents:
diff changeset
723 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 const TypeInt *r1 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
726 const TypeInt *r2 = t2->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (!r2->is_con())
a61af66fc99e Initial load
duke
parents:
diff changeset
729 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 uint shift = r2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
732 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // Shift by a multiple of 32 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // If the shift is a constant, shift the bounds of the type,
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // unless this could lead to an overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
738 if (!r1->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 jint lo = r1->_lo, hi = r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 if (((lo << shift) >> shift) == lo &&
a61af66fc99e Initial load
duke
parents:
diff changeset
741 ((hi << shift) >> shift) == hi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // No overflow. The range shifts up cleanly.
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return TypeInt::make((jint)lo << (jint)shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
744 (jint)hi << (jint)shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
745 MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 return TypeInt::make( (jint)r1->get_con() << (jint)shift );
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
754 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
755 Node *LShiftLNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int
a61af66fc99e Initial load
duke
parents:
diff changeset
757 return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759
a61af66fc99e Initial load
duke
parents:
diff changeset
760 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // If the right input is a constant, and the left input is an add of a
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // constant, flatten the tree: (X+con1)<<con0 ==> X<<con0 + con1<<con0
a61af66fc99e Initial load
duke
parents:
diff changeset
763 Node *LShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 const Type *t = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
765 if( t == Type::TOP ) return NULL; // Right input is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
766 const TypeInt *t2 = t->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
768 const int con = t2->get_con() & ( BitsPerLong - 1 ); // masked shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 if ( con == 0 ) return NULL; // let Identity() handle 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Left input is an add of a constant?
a61af66fc99e Initial load
duke
parents:
diff changeset
773 Node *add1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
774 int add1_op = add1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if( add1_op == Op_AddL ) { // Left input is an add?
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // Avoid dead data cycles from dead loops
a61af66fc99e Initial load
duke
parents:
diff changeset
777 assert( add1 != add1->in(1), "dead loop in LShiftLNode::Ideal" );
a61af66fc99e Initial load
duke
parents:
diff changeset
778 const TypeLong *t12 = phase->type(add1->in(2))->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
779 if( t12 && t12->is_con() ){ // Left input is an add of a con?
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // Compute X << con0
a61af66fc99e Initial load
duke
parents:
diff changeset
781 Node *lsh = phase->transform( new (phase->C, 3) LShiftLNode( add1->in(1), in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
782 // Compute X<<con0 + (con1<<con0)
a61af66fc99e Initial load
duke
parents:
diff changeset
783 return new (phase->C, 3) AddLNode( lsh, phase->longcon(t12->get_con() << con));
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // Check for "(x>>c0)<<c0" which just masks off low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
788 if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
789 add1->in(2) == in(2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Convert to "(x & -(1<<c0))"
a61af66fc99e Initial load
duke
parents:
diff changeset
791 return new (phase->C, 3) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<<con)));
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if( add1_op == Op_AndL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 Node *add2 = add1->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 int add2_op = add2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
797 if( (add2_op == Op_RShiftL || add2_op == Op_URShiftL ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
798 add2->in(2) == in(2) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Convert to "(x & (Y<<c0))"
a61af66fc99e Initial load
duke
parents:
diff changeset
800 Node *y_sh = phase->transform( new (phase->C, 3) LShiftLNode( add1->in(2), in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
801 return new (phase->C, 3) AndLNode( add2->in(1), y_sh );
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // before shifting them away.
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
807 const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if( add1_op == Op_AndL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
809 phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
810 return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // A LShiftLNode shifts its input2 left by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
817 const Type *LShiftLNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
819 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
820 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
821 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if( t1 == TypeLong::ZERO ) return TypeLong::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
827 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
830 if( (t1 == TypeLong::LONG) || (t2 == TypeInt::INT) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
831 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
a61af66fc99e Initial load
duke
parents:
diff changeset
832 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 const TypeLong *r1 = t1->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
835 const TypeInt *r2 = t2->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 if (!r2->is_con())
a61af66fc99e Initial load
duke
parents:
diff changeset
838 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840 uint shift = r2->get_con();
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
841 shift &= BitsPerJavaLong - 1; // semantics of Java shifts
0
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // Shift by a multiple of 64 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // If the shift is a constant, shift the bounds of the type,
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // unless this could lead to an overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
847 if (!r1->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 jlong lo = r1->_lo, hi = r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
849 if (((lo << shift) >> shift) == lo &&
a61af66fc99e Initial load
duke
parents:
diff changeset
850 ((hi << shift) >> shift) == hi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // No overflow. The range shifts up cleanly.
a61af66fc99e Initial load
duke
parents:
diff changeset
852 return TypeLong::make((jlong)lo << (jint)shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
853 (jlong)hi << (jint)shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
854 MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858
a61af66fc99e Initial load
duke
parents:
diff changeset
859 return TypeLong::make( (jlong)r1->get_con() << (jint)shift );
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
863 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
864 Node *RShiftINode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 const TypeInt *t2 = phase->type(in(2))->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
866 if( !t2 ) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 if ( t2->is_con() && ( t2->get_con() & ( BitsPerInt - 1 ) ) == 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
868 return in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // Check for useless sign-masking
a61af66fc99e Initial load
duke
parents:
diff changeset
871 if( in(1)->Opcode() == Op_LShiftI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
872 in(1)->req() == 3 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
873 in(1)->in(2) == in(2) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
874 t2->is_con() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
875 uint shift = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
876 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Compute masks for which this shifting doesn't change
a61af66fc99e Initial load
duke
parents:
diff changeset
878 int lo = (-1 << (BitsPerJavaInteger - shift-1)); // FFFF8000
a61af66fc99e Initial load
duke
parents:
diff changeset
879 int hi = ~lo; // 00007FFF
a61af66fc99e Initial load
duke
parents:
diff changeset
880 const TypeInt *t11 = phase->type(in(1)->in(1))->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
881 if( !t11 ) return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Does actual value fit inside of mask?
a61af66fc99e Initial load
duke
parents:
diff changeset
883 if( lo <= t11->_lo && t11->_hi <= hi )
a61af66fc99e Initial load
duke
parents:
diff changeset
884 return in(1)->in(1); // Then shifting is a nop
a61af66fc99e Initial load
duke
parents:
diff changeset
885 }
a61af66fc99e Initial load
duke
parents:
diff changeset
886
a61af66fc99e Initial load
duke
parents:
diff changeset
887 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
891 Node *RShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // Inputs may be TOP if they are dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 const TypeInt *t1 = phase->type( in(1) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if( !t1 ) return NULL; // Left input is an integer
a61af66fc99e Initial load
duke
parents:
diff changeset
895 const TypeInt *t2 = phase->type( in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
896 if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
897 const TypeInt *t3; // type of in(1).in(2)
a61af66fc99e Initial load
duke
parents:
diff changeset
898 int shift = t2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 if ( shift == 0 ) return NULL; // let Identity() handle 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // Check for (x & 0xFF000000) >> 24, whose mask can be made smaller.
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // Such expressions arise normally from shift chains like (byte)(x >> 24).
a61af66fc99e Initial load
duke
parents:
diff changeset
905 const Node *mask = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
906 if( mask->Opcode() == Op_AndI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
907 (t3 = phase->type(mask->in(2))->isa_int()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
908 t3->is_con() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 Node *x = mask->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 jint maskbits = t3->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // Convert to "(x >> shift) & (mask >> shift)"
a61af66fc99e Initial load
duke
parents:
diff changeset
912 Node *shr_nomask = phase->transform( new (phase->C, 3) RShiftINode(mask->in(1), in(2)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
913 return new (phase->C, 3) AndINode(shr_nomask, phase->intcon( maskbits >> shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Check for "(short[i] <<16)>>16" which simply sign-extends
a61af66fc99e Initial load
duke
parents:
diff changeset
917 const Node *shl = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if( shl->Opcode() != Op_LShiftI ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 if( shift == 16 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
921 (t3 = phase->type(shl->in(2))->isa_int()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
922 t3->is_con(16) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 Node *ld = shl->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 if( ld->Opcode() == Op_LoadS ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // Sign extension is just useless here. Return a RShiftI of zero instead
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // returning 'ld' directly. We cannot return an old Node directly as
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // that is the job of 'Identity' calls and Identity calls only work on
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // direct inputs ('ld' is an extra Node removed from 'this'). The
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // combined optimization requires Identity only return direct inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
930 set_req(1, ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
931 set_req(2, phase->intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
932 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 404
diff changeset
934 else if( ld->Opcode() == Op_LoadUS )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // Replace zero-extension-load with sign-extension-load
a61af66fc99e Initial load
duke
parents:
diff changeset
936 return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control),
a61af66fc99e Initial load
duke
parents:
diff changeset
937 ld->in(MemNode::Memory),
a61af66fc99e Initial load
duke
parents:
diff changeset
938 ld->in(MemNode::Address),
a61af66fc99e Initial load
duke
parents:
diff changeset
939 ld->adr_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // Check for "(byte[i] <<24)>>24" which simply sign-extends
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if( shift == 24 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
944 (t3 = phase->type(shl->in(2))->isa_int()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
945 t3->is_con(24) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 Node *ld = shl->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
947 if( ld->Opcode() == Op_LoadB ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // Sign extension is just useless here
a61af66fc99e Initial load
duke
parents:
diff changeset
949 set_req(1, ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 set_req(2, phase->intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
951 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954
a61af66fc99e Initial load
duke
parents:
diff changeset
955 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // A RShiftINode shifts its input2 right by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
960 const Type *RShiftINode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
961 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
962 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if( t1 == TypeInt::ZERO ) return TypeInt::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
970 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
973 if (t1 == Type::BOTTOM || t2 == Type::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
974 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 if (t2 == TypeInt::INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
977 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 const TypeInt *r1 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
980 const TypeInt *r2 = t2->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
981
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // If the shift is a constant, just shift the bounds of the type.
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // For example, if the shift is 31, we just propagate sign bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 if (r2->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 uint shift = r2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
986 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // Shift by a multiple of 32 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // Calculate reasonably aggressive bounds for the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // This is necessary if we are to correctly type things
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // like (x<<24>>24) == ((byte)x).
a61af66fc99e Initial load
duke
parents:
diff changeset
992 jint lo = (jint)r1->_lo >> (jint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 jint hi = (jint)r1->_hi >> (jint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 assert(lo <= hi, "must have valid bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
995 const TypeInt* ti = TypeInt::make(lo, hi, MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
996 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // Make sure we get the sign-capture idiom correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
998 if (shift == BitsPerJavaInteger-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
999 if (r1->_lo >= 0) assert(ti == TypeInt::ZERO, ">>31 of + is 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 if (r1->_hi < 0) assert(ti == TypeInt::MINUS_1, ">>31 of - is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 return ti;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if( !r1->is_con() || !r2->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // Signed shift right
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 return TypeInt::make( r1->get_con() >> (r2->get_con()&31) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 Node *RShiftLNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // A RShiftLNode shifts its input2 right by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 const Type *RShiftLNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 if( t1 == TypeLong::ZERO ) return TypeLong::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 if (t1 == Type::BOTTOM || t2 == Type::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 if (t2 == TypeInt::INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 const TypeLong *r1 = t1->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 const TypeInt *r2 = t2->is_int (); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // If the shift is a constant, just shift the bounds of the type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // For example, if the shift is 63, we just propagate sign bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 if (r2->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 uint shift = r2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 shift &= (2*BitsPerJavaInteger)-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // Shift by a multiple of 64 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // Calculate reasonably aggressive bounds for the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // This is necessary if we are to correctly type things
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // like (x<<24>>24) == ((byte)x).
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 jlong lo = (jlong)r1->_lo >> (jlong)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 jlong hi = (jlong)r1->_hi >> (jlong)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 assert(lo <= hi, "must have valid bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // Make sure we get the sign-capture idiom correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 if (shift == (2*BitsPerJavaInteger)-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>63 of + is 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if (r1->_hi < 0) assert(tl == TypeLong::MINUS_1, ">>63 of - is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 return tl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 return TypeLong::LONG; // Give up
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 Node *URShiftINode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 const TypeInt *ti = phase->type( in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 if ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerInt - 1 ) ) == 0 ) return in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // Check for "((x << LogBytesPerWord) + (wordSize-1)) >> LogBytesPerWord" which is just "x".
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Happens during new-array length computation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // Safe if 'x' is in the range [0..(max_int>>LogBytesPerWord)]
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 Node *add = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if( add->Opcode() == Op_AddI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 const TypeInt *t2 = phase->type(add->in(2))->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 if( t2 && t2->is_con(wordSize - 1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 add->in(1)->Opcode() == Op_LShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // Check that shift_counts are LogBytesPerWord
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 Node *lshift_count = add->in(1)->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 const TypeInt *t_lshift_count = phase->type(lshift_count)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 if( t_lshift_count && t_lshift_count->is_con(LogBytesPerWord) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 t_lshift_count == phase->type(in(2)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 Node *x = add->in(1)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 const TypeInt *t_x = phase->type(x)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 if( t_x != NULL && 0 <= t_x->_lo && t_x->_hi <= (max_jint>>LogBytesPerWord) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1098
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 return (phase->type(in(2))->higher_equal(TypeInt::ZERO)) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 Node *URShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 const TypeInt *t2 = phase->type( in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 const int con = t2->get_con() & 31; // Shift count is always masked
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // We'll be wanting the right-shift amount as a mask of that many bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 const int mask = right_n_bits(BitsPerJavaInteger - con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 int in1_op = in(1)->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // Check for ((x>>>a)>>>b) and replace with (x>>>(a+b)) when a+b < 32
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if( in1_op == Op_URShiftI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 const TypeInt *t12 = phase->type( in(1)->in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 if( t12 && t12->is_con() ) { // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 assert( in(1) != in(1)->in(1), "dead loop in URShiftINode::Ideal" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 const int con2 = t12->get_con() & 31; // Shift count is always masked
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 const int con3 = con+con2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if( con3 < 32 ) // Only merge shifts if total is < 32
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 return new (phase->C, 3) URShiftINode( in(1)->in(1), phase->intcon(con3) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // If Q is "X << z" the rounding is useless. Look for patterns like
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // ((X<<Z) + Y) >>> Z and replace with (X + Y>>>Z) & Z-mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 Node *add = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 if( in1_op == Op_AddI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 Node *lshl = add->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 if( lshl->Opcode() == Op_LShiftI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 phase->type(lshl->in(2)) == t2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 Node *y_z = phase->transform( new (phase->C, 3) URShiftINode(add->in(2),in(2)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 Node *sum = phase->transform( new (phase->C, 3) AddINode( lshl->in(1), y_z ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 return new (phase->C, 3) AndINode( sum, phase->intcon(mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1139
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // This shortens the mask. Also, if we are extracting a high byte and
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // storing it to a buffer, the mask will be removed completely.
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 Node *andi = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 if( in1_op == Op_AndI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 const TypeInt *t3 = phase->type( andi->in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 if( t3 && t3->is_con() ) { // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 jint mask2 = t3->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 Node *newshr = phase->transform( new (phase->C, 3) URShiftINode(andi->in(1), in(2)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 return new (phase->C, 3) AndINode(newshr, phase->intcon(mask2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // The negative values are easier to materialize than positive ones.
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // A typical case from address arithmetic is ((x & ~15) >> 4).
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // It's better to change that to ((x >> 4) & ~0) versus
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // ((x >> 4) & 0x0FFFFFFF). The difference is greatest in LP64.
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // Check for "(X << z ) >>> z" which simply zero-extends
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 Node *shl = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 if( in1_op == Op_LShiftI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 phase->type(shl->in(2)) == t2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 return new (phase->C, 3) AndINode( shl->in(1), phase->intcon(mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1163
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // A URShiftINode shifts its input2 right by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 const Type *URShiftINode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // (This is a near clone of RShiftINode::Value.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 if( t1 == TypeInt::ZERO ) return TypeInt::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 if (t1 == Type::BOTTOM || t2 == Type::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (t2 == TypeInt::INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1188
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 const TypeInt *r1 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 const TypeInt *r2 = t2->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1191
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 if (r2->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 uint shift = r2->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 shift &= BitsPerJavaInteger-1; // semantics of Java shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // Shift by a multiple of 32 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // Calculate reasonably aggressive bounds for the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 jint lo = (juint)r1->_lo >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 jint hi = (juint)r1->_hi >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 if (r1->_hi >= 0 && r1->_lo < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // If the type has both negative and positive values,
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // there are two separate sub-domains to worry about:
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 // The positive half and the negative half.
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 jint neg_lo = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 jint neg_hi = (juint)-1 >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 jint pos_lo = (juint) 0 >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 jint pos_hi = hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 lo = MIN2(neg_lo, pos_lo); // == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 hi = MAX2(neg_hi, pos_hi); // == -1 >>> shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 assert(lo <= hi, "must have valid bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 const TypeInt* ti = TypeInt::make(lo, hi, MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // Make sure we get the sign-capture idiom correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if (shift == BitsPerJavaInteger-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 if (r1->_lo >= 0) assert(ti == TypeInt::ZERO, ">>>31 of + is 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 if (r1->_hi < 0) assert(ti == TypeInt::ONE, ">>>31 of - is +1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 return ti;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // Do not support shifted oops in info for GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // else if( t1->base() == Type::InstPtr ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // const TypeInstPtr *o = t1->is_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // if( t1->singleton() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift );
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // else if( t1->base() == Type::KlassPtr ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // const TypeKlassPtr *o = t1->is_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // if( t1->singleton() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift );
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1240
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 Node *URShiftLNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 const TypeInt *ti = phase->type( in(2) )->isa_int(); // shift count is an int
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 return ( ti && ti->is_con() && ( ti->get_con() & ( BitsPerLong - 1 ) ) == 0 ) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 Node *URShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 const TypeInt *t2 = phase->type( in(2) )->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 const int con = t2->get_con() & ( BitsPerLong - 1 ); // Shift count is always masked
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // note: mask computation below does not work for 0 shift count
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // We'll be wanting the right-shift amount as a mask of that many bits
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
1256 const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // If Q is "X << z" the rounding is useless. Look for patterns like
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // ((X<<Z) + Y) >>> Z and replace with (X + Y>>>Z) & Z-mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 Node *add = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 if( add->Opcode() == Op_AddL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 Node *lshl = add->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 if( lshl->Opcode() == Op_LShiftL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 phase->type(lshl->in(2)) == t2 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 Node *y_z = phase->transform( new (phase->C, 3) URShiftLNode(add->in(2),in(2)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 Node *sum = phase->transform( new (phase->C, 3) AddLNode( lshl->in(1), y_z ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 return new (phase->C, 3) AndLNode( sum, phase->longcon(mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // This shortens the mask. Also, if we are extracting a high byte and
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // storing it to a buffer, the mask will be removed completely.
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 Node *andi = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if( andi->Opcode() == Op_AndL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 const TypeLong *t3 = phase->type( andi->in(2) )->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 if( t3 && t3->is_con() ) { // Right input is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 jlong mask2 = t3->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 Node *newshr = phase->transform( new (phase->C, 3) URShiftLNode(andi->in(1), in(2)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 return new (phase->C, 3) AndLNode(newshr, phase->longcon(mask2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1286
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // Check for "(X << z ) >>> z" which simply zero-extends
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 Node *shl = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 if( shl->Opcode() == Op_LShiftL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 phase->type(shl->in(2)) == t2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 return new (phase->C, 3) AndLNode( shl->in(1), phase->longcon(mask) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // A URShiftINode shifts its input2 right by input1 amount.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 const Type *URShiftLNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // (This is a near clone of RShiftLNode::Value.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // Left input is ZERO ==> the result is ZERO.
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 if( t1 == TypeLong::ZERO ) return TypeLong::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // Shift by zero does nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if( t2 == TypeInt::ZERO ) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // Either input is BOTTOM ==> the result is BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 if (t1 == Type::BOTTOM || t2 == Type::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
1314
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 if (t2 == TypeInt::INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 const TypeLong *r1 = t1->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 const TypeInt *r2 = t2->is_int (); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 if (r2->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 uint shift = r2->get_con();
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
1323 shift &= BitsPerJavaLong - 1; // semantics of Java shifts
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // Shift by a multiple of 64 does nothing:
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 if (shift == 0) return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // Calculate reasonably aggressive bounds for the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 jlong lo = (julong)r1->_lo >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 jlong hi = (julong)r1->_hi >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if (r1->_hi >= 0 && r1->_lo < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // If the type has both negative and positive values,
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // there are two separate sub-domains to worry about:
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // The positive half and the negative half.
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 jlong neg_lo = lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 jlong neg_hi = (julong)-1 >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 jlong pos_lo = (julong) 0 >> (juint)shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 jlong pos_hi = hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 //lo = MIN2(neg_lo, pos_lo); // == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 lo = neg_lo < pos_lo ? neg_lo : pos_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 //hi = MAX2(neg_hi, pos_hi); // == -1 >>> shift;
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 hi = neg_hi > pos_hi ? neg_hi : pos_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 assert(lo <= hi, "must have valid bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // Make sure we get the sign-capture idiom correct.
559
7628781568e1 6795362: 32bit server compiler leads to wrong results on solaris-x86
twisti
parents: 558
diff changeset
1346 if (shift == BitsPerJavaLong - 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>>63 of + is 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 if (r1->_hi < 0) assert(tl == TypeLong::ONE, ">>>63 of - is +1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 return tl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 return TypeLong::LONG; // Give up
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 }