annotate src/share/vm/opto/subnode.cpp @ 9126:bc26f978b0ce

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