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

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents cc80376deb0c
children 90a66aa50514
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #include "incls/_subnode.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
31 #include "math.h"
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
34 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // If right input is a constant 0, return the left input.
a61af66fc99e Initial load
duke
parents:
diff changeset
36 Node *SubNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 assert(in(1) != this, "Must already have called Value");
a61af66fc99e Initial load
duke
parents:
diff changeset
38 assert(in(2) != this, "Must already have called Value");
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Remove double negation
a61af66fc99e Initial load
duke
parents:
diff changeset
41 const Type *zero = add_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 if( phase->type( in(1) )->higher_equal( zero ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
43 in(2)->Opcode() == Opcode() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
44 phase->type( in(2)->in(1) )->higher_equal( zero ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 return in(2)->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47
212
99bf1609e2a5 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 113
diff changeset
48 // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
0
a61af66fc99e Initial load
duke
parents:
diff changeset
49 if( in(1)->Opcode() == Op_AddI ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 if( phase->eqv(in(1)->in(2),in(2)) )
a61af66fc99e Initial load
duke
parents:
diff changeset
51 return in(1)->in(1);
212
99bf1609e2a5 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 113
diff changeset
52 if (phase->eqv(in(1)->in(1),in(2)))
99bf1609e2a5 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 113
diff changeset
53 return in(1)->in(2);
99bf1609e2a5 6697236: missing Identity for "(X+Y) - X" into Y
never
parents: 113
diff changeset
54
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // trip counter and X is likely to be loop-invariant (that's how O2 Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // are originally used, although the optimizer sometimes jiggers things).
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // This folding through an O2 removes a loop-exit use of a loop-varying
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // value and generally lowers register pressure in and around the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
60 if( in(1)->in(2)->Opcode() == Op_Opaque2 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
61 phase->eqv(in(1)->in(2)->in(1),in(2)) )
a61af66fc99e Initial load
duke
parents:
diff changeset
62 return in(1)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // A subtract node differences it's two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
70 const Type *SubNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 const Node* in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 const Node* in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
74 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Not correct for SubFnode and AddFNode (must check for infinity)
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // Equal? Subtract is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
81 if (phase->eqv_uncast(in1, in2)) return add_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Either input is BOTTOM ==> the result is the local BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return sub(t1,t2); // Local flavor of type subtraction
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //------------------------------Helper function--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static bool ok_to_convert(Node* inc, Node* iv) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Do not collapse (x+c0)-y if "+" is a loop increment, because the
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // "-" is loop invariant and collapsing extends the live-range of "x"
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // to overlap with the "+", forcing another register to be used in
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // This test will be clearer with '&&' (apply DeMorgan's rule)
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // but I like the early cutouts that happen here.
a61af66fc99e Initial load
duke
parents:
diff changeset
101 const PhiNode *phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if( ( !inc->in(1)->is_Phi() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
103 !(phi=inc->in(1)->as_Phi()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
104 phi->is_copy() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
105 !phi->region()->is_CountedLoop() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
106 inc != phi->region()->as_CountedLoop()->incr() )
a61af66fc99e Initial load
duke
parents:
diff changeset
107 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Do not collapse (x+c0)-iv if "iv" is a loop induction variable,
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // because "x" maybe invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 ( !iv->is_loop_iv() )
a61af66fc99e Initial load
duke
parents:
diff changeset
111 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
118 Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
119 Node *in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 Node *in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
121 uint op1 = in1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
122 uint op2 = in2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // Check for dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
126 if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
127 ( op1 == Op_AddI || op1 == Op_SubI ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
128 ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
129 phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
130 assert(false, "dead loop in SubINode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
131 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 const Type *t2 = phase->type( in2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
134 if( t2 == Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Convert "x-c0" into "x+ -c0".
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if( t2->base() == Type::Int ){ // Might be bottom or top...
a61af66fc99e Initial load
duke
parents:
diff changeset
137 const TypeInt *i = t2->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if( i->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return new (phase->C, 3) AddINode(in1, phase->intcon(-i->get_con()));
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Convert "(x+c0) - y" into (x-y) + c0"
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Do not collapse (x+c0)-y if "+" is a loop increment or
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // if "y" is a loop induction variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 if( op1 == Op_AddI && ok_to_convert(in1, in2) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 const Type *tadd = phase->type( in1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if( tadd->singleton() && tadd != Type::TOP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
149 return new (phase->C, 3) AddINode( sub2, in1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // Convert "x - (y+c0)" into "(x-y) - c0"
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Need the same check as in above optimization but reversed.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if (op2 == Op_AddI && ok_to_convert(in2, in1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 Node* in21 = in2->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 Node* in22 = in2->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 const TypeInt* tcon = phase->type(in22)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (tcon != NULL && tcon->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) );
a61af66fc99e Initial load
duke
parents:
diff changeset
162 Node* neg_c0 = phase->intcon(- tcon->get_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return new (phase->C, 3) AddINode(sub2, neg_c0);
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 const Type *t1 = phase->type( in1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if( t1 == Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Check for dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if( ( op2 == Op_AddI || op2 == Op_SubI ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
173 ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
174 phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
175 assert(false, "dead loop in SubINode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
176 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Convert "x - (x+y)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
179 if( op2 == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
180 phase->eqv( in1, in2->in(1) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Convert "(x-y) - x" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
183 if( op1 == Op_SubI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
184 phase->eqv( in1->in(1), in2 ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return new (phase->C, 3) SubINode( phase->intcon(0),in1->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Convert "x - (y+x)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if( op2 == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
188 phase->eqv( in1, in2->in(2) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // Convert "0 - (x-y)" into "y-x"
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if( t1 == TypeInt::ZERO && op2 == Op_SubI )
a61af66fc99e Initial load
duke
parents:
diff changeset
193 return new (phase->C, 3) SubINode( in2->in(2), in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Convert "0 - (x+con)" into "-con-x"
a61af66fc99e Initial load
duke
parents:
diff changeset
196 jint con;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if( t1 == TypeInt::ZERO && op2 == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
198 (con = in2->in(2)->find_int_con(0)) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return new (phase->C, 3) SubINode( phase->intcon(-con), in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Convert "(X+A) - (X+B)" into "A - B"
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) )
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return new (phase->C, 3) SubINode( in1->in(2), in2->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Convert "(A+X) - (B+X)" into "A - B"
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
207 return new (phase->C, 3) SubINode( in1->in(1), in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
208
400
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
209 // Convert "(A+X) - (X+B)" into "A - B"
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
210 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) )
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
211 return new (phase->C, 3) SubINode( in1->in(1), in2->in(2) );
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
212
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
213 // Convert "(X+A) - (B+X)" into "A - B"
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
214 if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) )
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
215 return new (phase->C, 3) SubINode( in1->in(2), in2->in(1) );
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 296
diff changeset
216
0
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // nicer to optimize than subtract.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if( op2 == Op_SubI && in2->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 Node *add1 = phase->transform( new (phase->C, 3) AddINode( in1, in2->in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
221 return new (phase->C, 3) SubINode( add1, in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 //------------------------------sub--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // A subtract node differences it's two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 const Type *SubINode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 const TypeInt *r0 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
231 const TypeInt *r1 = t2->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 int32 lo = r0->_lo - r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 int32 hi = r0->_hi - r1->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // We next check for 32-bit overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // If that happens, we just assume all integers are possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if( (((r0->_lo ^ r1->_hi) >= 0) || // lo ends have same signs OR
a61af66fc99e Initial load
duke
parents:
diff changeset
238 ((r0->_lo ^ lo) >= 0)) && // lo results have same signs AND
a61af66fc99e Initial load
duke
parents:
diff changeset
239 (((r0->_hi ^ r1->_lo) >= 0) || // hi ends have same signs OR
a61af66fc99e Initial load
duke
parents:
diff changeset
240 ((r0->_hi ^ hi) >= 0)) ) // hi results have same signs
a61af66fc99e Initial load
duke
parents:
diff changeset
241 return TypeInt::make(lo,hi,MAX2(r0->_widen,r1->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
242 else // Overflow; assume all integers
a61af66fc99e Initial load
duke
parents:
diff changeset
243 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
247 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
248 Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 Node *in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 Node *in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
251 uint op1 = in1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
252 uint op2 = in2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Check for dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
256 if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
257 ( op1 == Op_AddL || op1 == Op_SubL ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
258 ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
259 phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
260 assert(false, "dead loop in SubLNode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
261 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 if( phase->type( in2 ) == Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 const TypeLong *i = phase->type( in2 )->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Convert "x-c0" into "x+ -c0".
a61af66fc99e Initial load
duke
parents:
diff changeset
266 if( i && // Might be bottom or top...
a61af66fc99e Initial load
duke
parents:
diff changeset
267 i->is_con() )
a61af66fc99e Initial load
duke
parents:
diff changeset
268 return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con()));
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Convert "(x+c0) - y" into (x-y) + c0"
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Do not collapse (x+c0)-y if "+" is a loop increment or
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // if "y" is a loop induction variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if( op1 == Op_AddL && ok_to_convert(in1, in2) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 Node *in11 = in1->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 const Type *tadd = phase->type( in1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if( tadd->singleton() && tadd != Type::TOP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
278 return new (phase->C, 3) AddLNode( sub2, in1->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Convert "x - (y+c0)" into "(x-y) - c0"
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Need the same check as in above optimization but reversed.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 if (op2 == Op_AddL && ok_to_convert(in2, in1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 Node* in21 = in2->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 Node* in22 = in2->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 const TypeLong* tcon = phase->type(in22)->isa_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (tcon != NULL && tcon->is_con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) );
a61af66fc99e Initial load
duke
parents:
diff changeset
290 Node* neg_c0 = phase->longcon(- tcon->get_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
291 return new (phase->C, 3) AddLNode(sub2, neg_c0);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 const Type *t1 = phase->type( in1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
296 if( t1 == Type::TOP ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Check for dead loop
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if( ( op2 == Op_AddL || op2 == Op_SubL ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
301 ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
302 phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
303 assert(false, "dead loop in SubLNode::Ideal");
a61af66fc99e Initial load
duke
parents:
diff changeset
304 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // Convert "x - (x+y)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
307 if( op2 == Op_AddL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
308 phase->eqv( in1, in2->in(1) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
309 return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Convert "x - (y+x)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if( op2 == Op_AddL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
312 phase->eqv( in1, in2->in(2) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
313 return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Convert "0 - (x-y)" into "y-x"
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL )
a61af66fc99e Initial load
duke
parents:
diff changeset
317 return new (phase->C, 3) SubLNode( in2->in(2), in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Convert "(X+A) - (X+B)" into "A - B"
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) )
a61af66fc99e Initial load
duke
parents:
diff changeset
321 return new (phase->C, 3) SubLNode( in1->in(2), in2->in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Convert "(A+X) - (B+X)" into "A - B"
a61af66fc99e Initial load
duke
parents:
diff changeset
324 if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
325 return new (phase->C, 3) SubLNode( in1->in(1), in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Convert "A-(B-C)" into (A+C)-B"
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if( op2 == Op_SubL && in2->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 Node *add1 = phase->transform( new (phase->C, 3) AddLNode( in1, in2->in(2) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return new (phase->C, 3) SubLNode( add1, in2->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 //------------------------------sub--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // A subtract node differences it's two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 const Type *SubLNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
339 const TypeLong *r0 = t1->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
340 const TypeLong *r1 = t2->is_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 jlong lo = r0->_lo - r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 jlong hi = r0->_hi - r1->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // We next check for 32-bit overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // If that happens, we just assume all integers are possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if( (((r0->_lo ^ r1->_hi) >= 0) || // lo ends have same signs OR
a61af66fc99e Initial load
duke
parents:
diff changeset
347 ((r0->_lo ^ lo) >= 0)) && // lo results have same signs AND
a61af66fc99e Initial load
duke
parents:
diff changeset
348 (((r0->_hi ^ r1->_lo) >= 0) || // hi ends have same signs OR
a61af66fc99e Initial load
duke
parents:
diff changeset
349 ((r0->_hi ^ hi) >= 0)) ) // hi results have same signs
a61af66fc99e Initial load
duke
parents:
diff changeset
350 return TypeLong::make(lo,hi,MAX2(r0->_widen,r1->_widen));
a61af66fc99e Initial load
duke
parents:
diff changeset
351 else // Overflow; assume all integers
a61af66fc99e Initial load
duke
parents:
diff changeset
352 return TypeLong::LONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
356 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // A subtract node differences its two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 const Type *SubFPNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 const Node* in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 const Node* in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
362 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
a61af66fc99e Initial load
duke
parents:
diff changeset
363 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // if both operands are infinity of same sign, the result is NaN; do
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // not replace with zero
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if( (t1->is_finite() && t2->is_finite()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if( phase->eqv(in1, in2) ) return add_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // Either input is BOTTOM ==> the result is the local BOTTOM
a61af66fc99e Initial load
duke
parents:
diff changeset
374 const Type *bot = bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if( (t1 == bot) || (t2 == bot) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
376 (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
a61af66fc99e Initial load
duke
parents:
diff changeset
377 return bot;
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 return sub(t1,t2); // Local flavor of type subtraction
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
384 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
385 Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Convert "x-c0" into "x+ -c0".
a61af66fc99e Initial load
duke
parents:
diff changeset
388 if( t2->base() == Type::FloatCon ) { // Might be bottom or top...
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // return new (phase->C, 3) AddFNode(in(1), phase->makecon( TypeF::make(-t2->getf()) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Not associative because of boundary conditions (infinity)
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Convert "x - (x+y)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if( in(2)->is_Add() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
396 phase->eqv(in(1),in(2)->in(1) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
397 return new (phase->C, 3) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 //if( phase->type(in(1)) == TypeF::ZERO )
a61af66fc99e Initial load
duke
parents:
diff changeset
403 //return new (phase->C, 2) NegFNode(in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 //------------------------------sub--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // A subtract node differences its two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 const Type *SubFNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // no folding if one of operands is infinity or NaN, do not do constant folding
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if( g_isfinite(t1->getf()) && g_isfinite(t2->getf()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 return TypeF::make( t1->getf() - t2->getf() );
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415 else if( g_isnan(t1->getf()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 else if( g_isnan(t2->getf()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 return t2;
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 return Type::FLOAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
427 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
428 Node *SubDNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
429 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Convert "x-c0" into "x+ -c0".
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if( t2->base() == Type::DoubleCon ) { // Might be bottom or top...
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // return new (phase->C, 3) AddDNode(in(1), phase->makecon( TypeD::make(-t2->getd()) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // Not associative because of boundary conditions (infinity)
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Convert "x - (x+y)" into "-y"
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if( in(2)->is_Add() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
439 phase->eqv(in(1),in(2)->in(1) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
440 return new (phase->C, 3) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 //if( phase->type(in(1)) == TypeD::ZERO )
a61af66fc99e Initial load
duke
parents:
diff changeset
446 //return new (phase->C, 2) NegDNode(in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 //------------------------------sub--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // A subtract node differences its two inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
453 const Type *SubDNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // no folding if one of operands is infinity or NaN, do not do constant folding
a61af66fc99e Initial load
duke
parents:
diff changeset
455 if( g_isfinite(t1->getd()) && g_isfinite(t2->getd()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 return TypeD::make( t1->getd() - t2->getd() );
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 else if( g_isnan(t1->getd()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 return t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 else if( g_isnan(t2->getd()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 return t2;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
470 //------------------------------Idealize---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // Unlike SubNodes, compare must still flatten return value to the
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // range -1, 0, 1.
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // And optimizations like those for (X + Y) - X fail if overflow happens.
a61af66fc99e Initial load
duke
parents:
diff changeset
474 Node *CmpNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
479 //------------------------------cmp--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Simplify a CmpI (compare 2 integers) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
482 const Type *CmpINode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 const TypeInt *r0 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
484 const TypeInt *r1 = t2->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if( r0->_hi < r1->_lo ) // Range is always low?
a61af66fc99e Initial load
duke
parents:
diff changeset
487 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 else if( r0->_lo > r1->_hi ) // Range is always high?
a61af66fc99e Initial load
duke
parents:
diff changeset
489 return TypeInt::CC_GT;
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 else if( r0->is_con() && r1->is_con() ) { // comparing constants?
a61af66fc99e Initial load
duke
parents:
diff changeset
492 assert(r0->get_con() == r1->get_con(), "must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
493 return TypeInt::CC_EQ; // Equal results.
a61af66fc99e Initial load
duke
parents:
diff changeset
494 } else if( r0->_hi == r1->_lo ) // Range is never high?
a61af66fc99e Initial load
duke
parents:
diff changeset
495 return TypeInt::CC_LE;
a61af66fc99e Initial load
duke
parents:
diff changeset
496 else if( r0->_lo == r1->_hi ) // Range is never low?
a61af66fc99e Initial load
duke
parents:
diff changeset
497 return TypeInt::CC_GE;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 return TypeInt::CC; // else use worst case results
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Simplify a CmpU (compare 2 integers) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
503 const Type *CmpUNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 assert(!t1->isa_ptr(), "obsolete usage of CmpU");
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // comparing two unsigned ints
a61af66fc99e Initial load
duke
parents:
diff changeset
507 const TypeInt *r0 = t1->is_int(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
508 const TypeInt *r1 = t2->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // Current installed version
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // Compare ranges for non-overlap
a61af66fc99e Initial load
duke
parents:
diff changeset
512 juint lo0 = r0->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 juint hi0 = r0->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 juint lo1 = r1->_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 juint hi1 = r1->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // If either one has both negative and positive values,
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // it therefore contains both 0 and -1, and since [0..-1] is the
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // full unsigned range, the type must act as an unsigned bottom.
a61af66fc99e Initial load
duke
parents:
diff changeset
520 bool bot0 = ((jint)(lo0 ^ hi0) < 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 bool bot1 = ((jint)(lo1 ^ hi1) < 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 if (bot0 || bot1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // All unsigned values are LE -1 and GE 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 if (lo0 == 0 && hi0 == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 return TypeInt::CC_LE; // 0 <= bot
a61af66fc99e Initial load
duke
parents:
diff changeset
527 } else if (lo1 == 0 && hi1 == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 return TypeInt::CC_GE; // bot >= 0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // We can use ranges of the form [lo..hi] if signs are the same.
a61af66fc99e Initial load
duke
parents:
diff changeset
532 assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // results are reversed, '-' > '+' for unsigned compare
a61af66fc99e Initial load
duke
parents:
diff changeset
534 if (hi0 < lo1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 return TypeInt::CC_LT; // smaller
a61af66fc99e Initial load
duke
parents:
diff changeset
536 } else if (lo0 > hi1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return TypeInt::CC_GT; // greater
a61af66fc99e Initial load
duke
parents:
diff changeset
538 } else if (hi0 == lo1 && lo0 == hi1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 return TypeInt::CC_EQ; // Equal results
a61af66fc99e Initial load
duke
parents:
diff changeset
540 } else if (lo0 >= hi1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 return TypeInt::CC_GE;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 } else if (hi0 <= lo1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // Check for special case in Hashtable::get. (See below.)
a61af66fc99e Initial load
duke
parents:
diff changeset
544 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
545 in(1)->Opcode() == Op_ModI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
546 in(1)->in(2) == in(2) )
a61af66fc99e Initial load
duke
parents:
diff changeset
547 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 return TypeInt::CC_LE;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Check for special case in Hashtable::get - the hash index is
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // mod'ed to the table size so the following range check is useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Check for: (X Mod Y) CmpU Y, where the mod result and Y both have
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // to be positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // (This is a gross hack, since the sub method never
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // looks at the structure of the node in any other case.)
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
558 in(1)->Opcode() == Op_ModI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
559 in(1)->in(2)->uncast() == in(2)->uncast())
a61af66fc99e Initial load
duke
parents:
diff changeset
560 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return TypeInt::CC; // else use worst case results
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 //------------------------------Idealize---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
565 Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
567 switch (in(1)->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL
a61af66fc99e Initial load
duke
parents:
diff changeset
569 return new (phase->C, 3) CmpLNode(in(1)->in(1),in(1)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
570 case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF
a61af66fc99e Initial load
duke
parents:
diff changeset
571 return new (phase->C, 3) CmpFNode(in(1)->in(1),in(1)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
572 case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD
a61af66fc99e Initial load
duke
parents:
diff changeset
573 return new (phase->C, 3) CmpDNode(in(1)->in(1),in(1)->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
574 //case Op_SubI:
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // If (x - y) cannot overflow, then ((x - y) <?> 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // can be turned into (x <?> y).
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // This is handled (with more general cases) by Ideal_sub_algebra.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580 return NULL; // No change
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Simplify a CmpL (compare 2 longs ) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
587 const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 const TypeLong *r0 = t1->is_long(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
589 const TypeLong *r1 = t2->is_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 if( r0->_hi < r1->_lo ) // Range is always low?
a61af66fc99e Initial load
duke
parents:
diff changeset
592 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
593 else if( r0->_lo > r1->_hi ) // Range is always high?
a61af66fc99e Initial load
duke
parents:
diff changeset
594 return TypeInt::CC_GT;
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 else if( r0->is_con() && r1->is_con() ) { // comparing constants?
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert(r0->get_con() == r1->get_con(), "must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
598 return TypeInt::CC_EQ; // Equal results.
a61af66fc99e Initial load
duke
parents:
diff changeset
599 } else if( r0->_hi == r1->_lo ) // Range is never high?
a61af66fc99e Initial load
duke
parents:
diff changeset
600 return TypeInt::CC_LE;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 else if( r0->_lo == r1->_hi ) // Range is never low?
a61af66fc99e Initial load
duke
parents:
diff changeset
602 return TypeInt::CC_GE;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 return TypeInt::CC; // else use worst case results
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
607 //------------------------------sub--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // Simplify an CmpP (compare 2 pointers) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 const TypePtr *r0 = t1->is_ptr(); // Handy access
a61af66fc99e Initial load
duke
parents:
diff changeset
612 const TypePtr *r1 = t2->is_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // Undefined inputs makes for an undefined result
a61af66fc99e Initial load
duke
parents:
diff changeset
615 if( TypePtr::above_centerline(r0->_ptr) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
616 TypePtr::above_centerline(r1->_ptr) )
a61af66fc99e Initial load
duke
parents:
diff changeset
617 return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 if (r0 == r1 && r0->singleton()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Equal pointer constants (klasses, nulls, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
621 return TypeInt::CC_EQ;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // See if it is 2 unrelated classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 const TypeOopPtr* p0 = r0->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
626 const TypeOopPtr* p1 = r1->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (p0 && p1) {
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
628 Node* in1 = in(1)->uncast();
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
629 Node* in2 = in(2)->uncast();
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
630 AllocateNode* alloc1 = AllocateNode::Ideal_allocation(in1, NULL);
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
631 AllocateNode* alloc2 = AllocateNode::Ideal_allocation(in2, NULL);
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
632 if (MemNode::detect_ptr_independence(in1, alloc1, in2, alloc2, NULL)) {
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
633 return TypeInt::CC_GT; // different pointers
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
634 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
635 ciKlass* klass0 = p0->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
636 bool xklass0 = p0->klass_is_exact();
a61af66fc99e Initial load
duke
parents:
diff changeset
637 ciKlass* klass1 = p1->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
638 bool xklass1 = p1->klass_is_exact();
a61af66fc99e Initial load
duke
parents:
diff changeset
639 int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 if (klass0 && klass1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
641 kps != 1 && // both or neither are klass pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
642 !klass0->is_interface() && // do not trust interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
643 !klass1->is_interface()) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
644 bool unrelated_classes = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // See if neither subclasses the other, or if the class on top
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
646 // is precise. In either of these cases, the compare is known
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
647 // to fail if at least one of the pointers is provably not null.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648 if (klass0->equals(klass1) || // if types are unequal but klasses are
a61af66fc99e Initial load
duke
parents:
diff changeset
649 !klass0->is_java_klass() || // types not part of Java language?
a61af66fc99e Initial load
duke
parents:
diff changeset
650 !klass1->is_java_klass()) { // types not part of Java language?
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Do nothing; we know nothing for imprecise types
a61af66fc99e Initial load
duke
parents:
diff changeset
652 } else if (klass0->is_subtype_of(klass1)) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
653 // If klass1's type is PRECISE, then classes are unrelated.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
654 unrelated_classes = xklass1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
655 } else if (klass1->is_subtype_of(klass0)) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
656 // If klass0's type is PRECISE, then classes are unrelated.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
657 unrelated_classes = xklass0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
658 } else { // Neither subtypes the other
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
659 unrelated_classes = true;
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
660 }
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
661 if (unrelated_classes) {
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
662 // The oops classes are known to be unrelated. If the joined PTRs of
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
663 // two oops is not Null and not Bottom, then we are sure that one
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
664 // of the two oops is non-null, and the comparison will always fail.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
665 TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
666 if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
667 return TypeInt::CC_GT;
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
668 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Known constants can be compared exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // Null can be distinguished from any NotNull pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Unknown inputs makes an unknown result
a61af66fc99e Initial load
duke
parents:
diff changeset
676 if( r0->singleton() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 intptr_t bits0 = r0->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
678 if( r1->singleton() )
a61af66fc99e Initial load
duke
parents:
diff changeset
679 return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 } else if( r1->singleton() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 intptr_t bits1 = r1->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
683 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
a61af66fc99e Initial load
duke
parents:
diff changeset
684 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
685 return TypeInt::CC;
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // Check for the case of comparing an unknown klass loaded from the primary
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // super-type array vs a known klass with no subtypes. This amounts to
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // checking to see an unknown klass subtypes a known klass with no subtypes;
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // this only happens on an exact match. We can shorten this test by 1 load.
a61af66fc99e Initial load
duke
parents:
diff changeset
693 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // Constant pointer on right?
a61af66fc99e Initial load
duke
parents:
diff changeset
695 const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 if (t2 == NULL || !t2->klass_is_exact())
a61af66fc99e Initial load
duke
parents:
diff changeset
697 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Get the constant klass we are comparing to.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 ciKlass* superklass = t2->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // Now check for LoadKlass on left.
a61af66fc99e Initial load
duke
parents:
diff changeset
702 Node* ldk1 = in(1);
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
703 if (ldk1->is_DecodeN()) {
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
704 ldk1 = ldk1->in(1);
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
705 if (ldk1->Opcode() != Op_LoadNKlass )
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
706 return NULL;
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
707 } else if (ldk1->Opcode() != Op_LoadKlass )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
708 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // Take apart the address of the LoadKlass:
a61af66fc99e Initial load
duke
parents:
diff changeset
710 Node* adr1 = ldk1->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 intptr_t con2 = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 Node* ldk2 = AddPNode::Ideal_base_and_offset(adr1, phase, con2);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 if (ldk2 == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
714 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (con2 == oopDesc::klass_offset_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // We are inspecting an object's concrete class.
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // Short-circuit the check if the query is abstract.
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (superklass->is_interface() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
719 superklass->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // Make it come out always false:
a61af66fc99e Initial load
duke
parents:
diff changeset
721 this->set_req(2, phase->makecon(TypePtr::NULL_PTR));
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // Check for a LoadKlass from primary supertype array.
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Any nested loadklass from loadklass+con must be from the p.s. array.
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
728 if (ldk2->is_DecodeN()) {
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
729 // Keep ldk2 as DecodeN since it could be used in CmpP below.
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
730 if (ldk2->in(1)->Opcode() != Op_LoadNKlass )
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
731 return NULL;
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 235
diff changeset
732 } else if (ldk2->Opcode() != Op_LoadKlass)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
733 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // Verify that we understand the situation
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (con2 != (intptr_t) superklass->super_check_offset())
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return NULL; // Might be element-klass loading from array klass
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // If 'superklass' has no subklasses and is not an interface, then we are
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // assured that the only input which will pass the type check is
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // 'superklass' itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
742 //
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // We could be more liberal here, and allow the optimization on interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // which have a single implementor. This would require us to increase the
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // expressiveness of the add_dependency() mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // %%% Do this after we fix TypeOopPtr: Deps are expressive enough now.
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // Object arrays must have their base element have no subtypes
a61af66fc99e Initial load
duke
parents:
diff changeset
749 while (superklass->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 ciType* elem = superklass->as_obj_array_klass()->element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
751 superklass = elem->as_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
753 if (superklass->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 ciInstanceKlass* ik = superklass->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
755 if (ik->has_subklass() || ik->is_interface()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Add a dependency if there is a chance that a subclass will be added later.
a61af66fc99e Initial load
duke
parents:
diff changeset
757 if (!ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 phase->C->dependencies()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // Bypass the dependent load, and compare directly
a61af66fc99e Initial load
duke
parents:
diff changeset
763 this->set_req(1,ldk2);
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 //=============================================================================
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
769 //------------------------------sub--------------------------------------------
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
770 // Simplify an CmpN (compare 2 pointers) node, based on local information.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
771 // If both inputs are constants, compare them.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
772 const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 212
diff changeset
773 const TypePtr *r0 = t1->make_ptr(); // Handy access
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 212
diff changeset
774 const TypePtr *r1 = t2->make_ptr();
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
775
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
776 // Undefined inputs makes for an undefined result
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
777 if( TypePtr::above_centerline(r0->_ptr) ||
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
778 TypePtr::above_centerline(r1->_ptr) )
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
779 return Type::TOP;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
780
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
781 if (r0 == r1 && r0->singleton()) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
782 // Equal pointer constants (klasses, nulls, etc.)
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
783 return TypeInt::CC_EQ;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
784 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
785
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
786 // See if it is 2 unrelated classes.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
787 const TypeOopPtr* p0 = r0->isa_oopptr();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
788 const TypeOopPtr* p1 = r1->isa_oopptr();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
789 if (p0 && p1) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
790 ciKlass* klass0 = p0->klass();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
791 bool xklass0 = p0->klass_is_exact();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
792 ciKlass* klass1 = p1->klass();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
793 bool xklass1 = p1->klass_is_exact();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
794 int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
795 if (klass0 && klass1 &&
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
796 kps != 1 && // both or neither are klass pointers
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
797 !klass0->is_interface() && // do not trust interfaces
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
798 !klass1->is_interface()) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
799 bool unrelated_classes = false;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
800 // See if neither subclasses the other, or if the class on top
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
801 // is precise. In either of these cases, the compare is known
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
802 // to fail if at least one of the pointers is provably not null.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
803 if (klass0->equals(klass1) || // if types are unequal but klasses are
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
804 !klass0->is_java_klass() || // types not part of Java language?
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
805 !klass1->is_java_klass()) { // types not part of Java language?
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
806 // Do nothing; we know nothing for imprecise types
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
807 } else if (klass0->is_subtype_of(klass1)) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
808 // If klass1's type is PRECISE, then classes are unrelated.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
809 unrelated_classes = xklass1;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
810 } else if (klass1->is_subtype_of(klass0)) {
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
811 // If klass0's type is PRECISE, then classes are unrelated.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
812 unrelated_classes = xklass0;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
813 } else { // Neither subtypes the other
296
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
814 unrelated_classes = true;
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
815 }
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
816 if (unrelated_classes) {
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
817 // The oops classes are known to be unrelated. If the joined PTRs of
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
818 // two oops is not Null and not Bottom, then we are sure that one
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
819 // of the two oops is non-null, and the comparison will always fail.
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
820 TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
821 if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
822 return TypeInt::CC_GT;
ce93a51457ae 6730716: nulls from two unrelated classes compare not equal
rasbold
parents: 293
diff changeset
823 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
824 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
825 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
826 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
827
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
828 // Known constants can be compared exactly
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
829 // Null can be distinguished from any NotNull pointers
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
830 // Unknown inputs makes an unknown result
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
831 if( r0->singleton() ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
832 intptr_t bits0 = r0->get_con();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
833 if( r1->singleton() )
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
834 return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
835 return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
836 } else if( r1->singleton() ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
837 intptr_t bits1 = r1->get_con();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
838 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
839 } else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
840 return TypeInt::CC;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
841 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
842
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
843 //------------------------------Ideal------------------------------------------
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
844 Node *CmpNNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
845 return NULL;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
846 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
847
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 33
diff changeset
848 //=============================================================================
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Simplify an CmpF (compare 2 floats ) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
852 const Type *CmpFNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 const Node* in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 const Node* in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
856 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
858 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // Not constants? Don't know squat - even if they are the same
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // value! If they are NaN's they compare to LT instead of EQ.
a61af66fc99e Initial load
duke
parents:
diff changeset
863 const TypeF *tf1 = t1->isa_float_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
864 const TypeF *tf2 = t2->isa_float_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
865 if( !tf1 || !tf2 ) return TypeInt::CC;
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // This implements the Java bytecode fcmpl, so unordered returns -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
868 if( tf1->is_nan() || tf2->is_nan() )
a61af66fc99e Initial load
duke
parents:
diff changeset
869 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871 if( tf1->_f < tf2->_f ) return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 if( tf1->_f > tf2->_f ) return TypeInt::CC_GT;
a61af66fc99e Initial load
duke
parents:
diff changeset
873 assert( tf1->_f == tf2->_f, "do not understand FP behavior" );
a61af66fc99e Initial load
duke
parents:
diff changeset
874 return TypeInt::CC_EQ;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
879 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // Simplify an CmpD (compare 2 doubles ) node, based on local information.
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // If both inputs are constants, compare them.
a61af66fc99e Initial load
duke
parents:
diff changeset
882 const Type *CmpDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 const Node* in1 = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 const Node* in2 = in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Either input is TOP ==> the result is TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
886 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
888 const Type* t2 = (in2 == this) ? Type::TOP : phase->type(in2);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // Not constants? Don't know squat - even if they are the same
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // value! If they are NaN's they compare to LT instead of EQ.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 const TypeD *td1 = t1->isa_double_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
894 const TypeD *td2 = t2->isa_double_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
895 if( !td1 || !td2 ) return TypeInt::CC;
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // This implements the Java bytecode dcmpl, so unordered returns -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
898 if( td1->is_nan() || td2->is_nan() )
a61af66fc99e Initial load
duke
parents:
diff changeset
899 return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 if( td1->_d < td2->_d ) return TypeInt::CC_LT;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if( td1->_d > td2->_d ) return TypeInt::CC_GT;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 assert( td1->_d == td2->_d, "do not understand FP behavior" );
a61af66fc99e Initial load
duke
parents:
diff changeset
904 return TypeInt::CC_EQ;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
908 Node *CmpDNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // Check if we can change this to a CmpF and remove a ConvD2F operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // Change (CMPD (F2D (float)) (ConD value))
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // To (CMPF (float) (ConF value))
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // Valid when 'value' does not lose precision as a float.
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // Benefits: eliminates conversion, does not require 24-bit mode
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // NaNs prevent commuting operands. This transform works regardless of the
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // order of ConD and ConvF2D inputs by preserving the original order.
a61af66fc99e Initial load
duke
parents:
diff changeset
917 int idx_f2d = 1; // ConvF2D on left side?
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if( in(idx_f2d)->Opcode() != Op_ConvF2D )
a61af66fc99e Initial load
duke
parents:
diff changeset
919 idx_f2d = 2; // No, swap to check for reversed args
a61af66fc99e Initial load
duke
parents:
diff changeset
920 int idx_con = 3-idx_f2d; // Check for the constant on other input
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if( ConvertCmpD2CmpF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
923 in(idx_f2d)->Opcode() == Op_ConvF2D &&
a61af66fc99e Initial load
duke
parents:
diff changeset
924 in(idx_con)->Opcode() == Op_ConD ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 double t2_value_as_double = t2->_d;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 float t2_value_as_float = (float)t2_value_as_double;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 if( t2_value_as_double == (double)t2_value_as_float ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Test value can be represented as a float
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // Eliminate the conversion to double and create new comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
931 Node *new_in1 = in(idx_f2d)->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 Node *new_in2 = phase->makecon( TypeF::make(t2_value_as_float) );
a61af66fc99e Initial load
duke
parents:
diff changeset
933 if( idx_f2d != 1 ) { // Must flip args to match original order
a61af66fc99e Initial load
duke
parents:
diff changeset
934 Node *tmp = new_in1;
a61af66fc99e Initial load
duke
parents:
diff changeset
935 new_in1 = new_in2;
a61af66fc99e Initial load
duke
parents:
diff changeset
936 new_in2 = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938 CmpFNode *new_cmp = (Opcode() == Op_CmpD3)
a61af66fc99e Initial load
duke
parents:
diff changeset
939 ? new (phase->C, 3) CmpF3Node( new_in1, new_in2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
940 : new (phase->C, 3) CmpFNode ( new_in1, new_in2 ) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
941 return new_cmp; // Changed to CmpFNode
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // Testing value required the precision of a double
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945 return NULL; // No change
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
950 //------------------------------cc2logical-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Convert a condition code type to a logical type
a61af66fc99e Initial load
duke
parents:
diff changeset
952 const Type *BoolTest::cc2logical( const Type *CC ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 if( CC == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if( CC->base() != Type::Int ) return TypeInt::BOOL; // Bottom or worse
a61af66fc99e Initial load
duke
parents:
diff changeset
955 const TypeInt *ti = CC->is_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if( ti->is_con() ) { // Only 1 kind of condition codes set?
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Match low order 2 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
958 int tmp = ((ti->get_con()&3) == (_test&3)) ? 1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
959 if( _test & 4 ) tmp = 1-tmp; // Optionally complement result
a61af66fc99e Initial load
duke
parents:
diff changeset
960 return TypeInt::make(tmp); // Boolean result
a61af66fc99e Initial load
duke
parents:
diff changeset
961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
962
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if( CC == TypeInt::CC_GE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if( _test == ge ) return TypeInt::ONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 if( _test == lt ) return TypeInt::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967 if( CC == TypeInt::CC_LE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if( _test == le ) return TypeInt::ONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 if( _test == gt ) return TypeInt::ZERO;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 return TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 //------------------------------dump_spec-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // Print special per-node info
a61af66fc99e Initial load
duke
parents:
diff changeset
977 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
978 void BoolTest::dump_on(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
a61af66fc99e Initial load
duke
parents:
diff changeset
980 st->print(msg[_test]);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
985 uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
986 uint BoolNode::size_of() const { return sizeof(BoolNode); }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 //------------------------------operator==-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
989 uint BoolNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 const BoolNode *b = (const BoolNode *)&n; // Cast up
a61af66fc99e Initial load
duke
parents:
diff changeset
991 return (_test._test == b->_test._test);
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 //------------------------------clone_cmp--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // Clone a compare/bool tree
a61af66fc99e Initial load
duke
parents:
diff changeset
996 static Node *clone_cmp( Node *cmp, Node *cmp1, Node *cmp2, PhaseGVN *gvn, BoolTest::mask test ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 Node *ncmp = cmp->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
998 ncmp->set_req(1,cmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
999 ncmp->set_req(2,cmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 ncmp = gvn->transform( ncmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 return new (gvn->C, 2) BoolNode( ncmp, test );
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 //-------------------------------make_predicate--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if (test_value->is_Con()) return test_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 if (test_value->is_Bool()) return test_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if (test_value->is_CMove() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 test_value->in(CMoveNode::Condition)->is_Bool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 BoolNode* bol = test_value->in(CMoveNode::Condition)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 const Type* ftype = phase->type(test_value->in(CMoveNode::IfFalse));
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 const Type* ttype = phase->type(test_value->in(CMoveNode::IfTrue));
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 if (ftype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ttype)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 return bol;
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 } else if (ttype == TypeInt::ZERO && !TypeInt::ZERO->higher_equal(ftype)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 return phase->transform( bol->negate(phase) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // Else fall through. The CMove gets in the way of the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // It should be the case that make_predicate(bol->as_int_value()) == bol.
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 Node* cmp = new (C, 3) CmpINode(test_value, phase->intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 cmp = phase->transform(cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 Node* bol = new (C, 2) BoolNode(cmp, BoolTest::ne);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 return phase->transform(bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 //--------------------------------as_int_value---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 Node* BoolNode::as_int_value(PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // Inverse to make_predicate. The CMove probably boils down to a Conv2B.
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 Node* cmov = CMoveNode::make(phase->C, NULL, this,
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 phase->intcon(0), phase->intcon(1),
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 TypeInt::BOOL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 return phase->transform(cmov);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1036
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 //----------------------------------negate-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 BoolNode* BoolNode::negate(PhaseGVN* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 Compile* C = phase->C;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 return new (C, 2) BoolNode(in(1), _test.negate());
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // This moves the constant to the right. Helps value-numbering.
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 Node *cmp = in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 if( !cmp->is_Sub() ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 int cop = cmp->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 Node *cmp1 = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 Node *cmp2 = cmp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if( !cmp1 ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // Constant on left?
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 Node *con = cmp1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 uint op2 = cmp2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // Move constants to the right of compare's to canonicalize.
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // Do not muck with Opaque1 nodes, as this indicates a loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // guard that cannot change shape.
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if( con->is_Con() && !cmp2->is_Con() && op2 != Op_Opaque1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // Because of NaN's, CmpD and CmpF are not commutative
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 cop != Op_CmpD && cop != Op_CmpF &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // Protect against swapping inputs to a compare when it is used by a
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // counted loop exit, which requires maintaining the loop-limit as in(2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 !is_counted_loop_exit_test() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // Ok, commute the constant to the right of the cmp node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // Clone the Node, getting a new Node of the same class
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 cmp = cmp->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 // Swap inputs to the clone
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 cmp->swap_edges(1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 cmp = phase->transform( cmp );
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 return new (phase->C, 2) BoolNode( cmp, _test.commute() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // The XOR-1 is an idiom used to flip the sense of a bool. We flip the
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // test instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 int cmp1_op = cmp1->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 const TypeInt* cmp2_type = phase->type(cmp2)->isa_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 if (cmp2_type == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 Node* j_xor = cmp1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 if( cmp2_type == TypeInt::ZERO &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 cmp1_op == Op_XorI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 j_xor->in(1) != j_xor && // An xor of itself is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 phase->type( j_xor->in(2) ) == TypeInt::ONE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 (_test._test == BoolTest::eq ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 _test._test == BoolTest::ne) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 Node *ncmp = phase->transform(new (phase->C, 3) CmpINode(j_xor->in(1),cmp2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 return new (phase->C, 2) BoolNode( ncmp, _test.negate() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // This is a standard idiom for branching on a boolean value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 Node *c2b = cmp1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if( cmp2_type == TypeInt::ZERO &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 cmp1_op == Op_Conv2B &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 (_test._test == BoolTest::eq ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 _test._test == BoolTest::ne) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int()
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 ? (Node*)new (phase->C, 3) CmpINode(c2b->in(1),cmp2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 : (Node*)new (phase->C, 3) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 return new (phase->C, 2) BoolNode( ncmp, _test._test );
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // Comparing a SubI against a zero is equal to comparing the SubI
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // arguments directly. This only works for eq and ne comparisons
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // due to possible integer overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 (cop == Op_CmpI) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 (cmp1->Opcode() == Op_SubI) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 ( cmp2_type == TypeInt::ZERO ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(1),cmp1->in(2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 return new (phase->C, 2) BoolNode( ncmp, _test._test );
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // most general case because negating 0x80000000 does nothing. Needed for
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // the CmpF3/SubI/CmpI idiom.
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 if( cop == Op_CmpI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 cmp1->Opcode() == Op_SubI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 cmp2_type == TypeInt::ZERO &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(2),cmp2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 return new (phase->C, 2) BoolNode( ncmp, _test.commute() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // The transformation below is not valid for either signed or unsigned
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // comparisons due to wraparound concerns at MAX_VALUE and MIN_VALUE.
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // This transformation can be resurrected when we are able to
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // make inferences about the range of values being subtracted from
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // (or added to) relative to the wraparound point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // // Remove +/-1's if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // // "X <= Y-1" becomes "X < Y"
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // // "X+1 <= Y" becomes "X < Y"
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // // "X < Y+1" becomes "X <= Y"
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // // "X-1 < Y" becomes "X <= Y"
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // // Do not this to compares off of the counted-loop-end. These guys are
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // // checking the trip counter and they want to use the post-incremented
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // // counter. If they use the PRE-incremented counter, then the counter has
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // // to be incremented in a private block on a loop backedge.
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // if( du && du->cnt(this) && du->out(this)[0]->Opcode() == Op_CountedLoopEnd )
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // // Do not do this in a wash GVN pass during verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // // Gets triggered by too many simple optimizations to be bothered with
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // // re-trying it again and again.
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // if( !phase->allow_progress() ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // // Not valid for unsigned compare because of corner cases in involving zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // // For example, replacing "X-1 <u Y" with "X <=u Y" fails to throw an
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // // exception in case X is 0 (because 0-1 turns into 4billion unsigned but
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // // "0 <=u Y" is always true).
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // if( cmp->Opcode() == Op_CmpU ) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // int cmp2_op = cmp2->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // if( _test._test == BoolTest::le ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // if( cmp1_op == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // phase->type( cmp1->in(2) ) == TypeInt::ONE )
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::lt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // else if( cmp2_op == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // phase->type( cmp2->in(2) ) == TypeInt::MINUS_1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::lt );
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // } else if( _test._test == BoolTest::lt ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // if( cmp1_op == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // phase->type( cmp1->in(2) ) == TypeInt::MINUS_1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::le );
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // else if( cmp2_op == Op_AddI &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // phase->type( cmp2->in(2) ) == TypeInt::ONE )
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::le );
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1175
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // Simplify a Bool (convert condition codes to boolean (1 or 0)) node,
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // based on local information. If the input is constant, do it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 const Type *BoolNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 return _test.cc2logical( phase->type( in(1) ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 //------------------------------dump_spec--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // Dump special per-node info
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 void BoolNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 st->print("[");
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 _test.dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 st->print("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1195
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 //------------------------------is_counted_loop_exit_test--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // Returns true if node is used by a counted loop node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 bool BoolNode::is_counted_loop_exit_test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 Node* use = fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (use->is_CountedLoopEnd()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1207
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 //------------------------------NegNode----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 Node *NegFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if( in(1)->Opcode() == Op_SubF )
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 return new (phase->C, 3) SubFNode( in(1)->in(2), in(1)->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 Node *NegDNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 if( in(1)->Opcode() == Op_SubD )
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 return new (phase->C, 3) SubDNode( in(1)->in(2), in(1)->in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 }
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 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // Compute sqrt
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 const Type *SqrtDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 return TypeD::make( sqrt( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // Compute cos
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 const Type *CosDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 return TypeD::make( SharedRuntime::dcos( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // Compute sin
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 const Type *SinDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 return TypeD::make( SharedRuntime::dsin( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // Compute tan
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 const Type *TanDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 return TypeD::make( SharedRuntime::dtan( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // Compute log
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 const Type *LogDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 return TypeD::make( SharedRuntime::dlog( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // Compute log10
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 const Type *Log10DNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 return TypeD::make( SharedRuntime::dlog10( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 }
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 // Compute exp
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 const Type *ExpDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 double d = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 if( d < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 return TypeD::make( SharedRuntime::dexp( d ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // Compute pow
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 const Type *PowDNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 const Type *t1 = phase->type( in(1) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 if( t1 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 const Type *t2 = phase->type( in(2) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 if( t2 == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 if( t2->base() != Type::DoubleCon ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 double d1 = t1->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 double d2 = t2->getd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 if( d1 < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 if( d2 < 0.0 ) return Type::DOUBLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 return TypeD::make( SharedRuntime::dpow( d1, d2 ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 }