Wed, 09 Dec 2009 16:40:45 -0800
6895383: JCK test throws NPE for method compiled with Escape Analysis
Summary: Add missing checks for MemBar nodes in EA.
Reviewed-by: never
duke@435 | 1 | /* |
xdono@631 | 2 | * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // Portions of code courtesy of Clifford Click |
duke@435 | 26 | |
duke@435 | 27 | //------------------------------SUBNode---------------------------------------- |
duke@435 | 28 | // Class SUBTRACTION functionality. This covers all the usual 'subtract' |
duke@435 | 29 | // behaviors. Subtract-integer, -float, -double, binary xor, compare-integer, |
duke@435 | 30 | // -float, and -double are all inherited from this class. The compare |
duke@435 | 31 | // functions behave like subtract functions, except that all negative answers |
duke@435 | 32 | // are compressed into -1, and all positive answers compressed to 1. |
duke@435 | 33 | class SubNode : public Node { |
duke@435 | 34 | public: |
duke@435 | 35 | SubNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { |
duke@435 | 36 | init_class_id(Class_Sub); |
duke@435 | 37 | } |
duke@435 | 38 | |
duke@435 | 39 | // Handle algebraic identities here. If we have an identity, return the Node |
duke@435 | 40 | // we are equivalent to. We look for "add of zero" as an identity. |
duke@435 | 41 | virtual Node *Identity( PhaseTransform *phase ); |
duke@435 | 42 | |
duke@435 | 43 | // Compute a new Type for this node. Basically we just do the pre-check, |
duke@435 | 44 | // then call the virtual add() to set the type. |
duke@435 | 45 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 46 | |
duke@435 | 47 | // Supplied function returns the subtractend of the inputs. |
duke@435 | 48 | // This also type-checks the inputs for sanity. Guaranteed never to |
duke@435 | 49 | // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. |
duke@435 | 50 | virtual const Type *sub( const Type *, const Type * ) const = 0; |
duke@435 | 51 | |
duke@435 | 52 | // Supplied function to return the additive identity type. |
duke@435 | 53 | // This is returned whenever the subtracts inputs are the same. |
duke@435 | 54 | virtual const Type *add_id() const = 0; |
duke@435 | 55 | |
duke@435 | 56 | }; |
duke@435 | 57 | |
duke@435 | 58 | |
duke@435 | 59 | // NOTE: SubINode should be taken away and replaced by add and negate |
duke@435 | 60 | //------------------------------SubINode--------------------------------------- |
duke@435 | 61 | // Subtract 2 integers |
duke@435 | 62 | class SubINode : public SubNode { |
duke@435 | 63 | public: |
duke@435 | 64 | SubINode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} |
duke@435 | 65 | virtual int Opcode() const; |
duke@435 | 66 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 67 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 68 | const Type *add_id() const { return TypeInt::ZERO; } |
duke@435 | 69 | const Type *bottom_type() const { return TypeInt::INT; } |
duke@435 | 70 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 71 | }; |
duke@435 | 72 | |
duke@435 | 73 | //------------------------------SubLNode--------------------------------------- |
duke@435 | 74 | // Subtract 2 integers |
duke@435 | 75 | class SubLNode : public SubNode { |
duke@435 | 76 | public: |
duke@435 | 77 | SubLNode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} |
duke@435 | 78 | virtual int Opcode() const; |
duke@435 | 79 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 80 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 81 | const Type *add_id() const { return TypeLong::ZERO; } |
duke@435 | 82 | const Type *bottom_type() const { return TypeLong::LONG; } |
duke@435 | 83 | virtual uint ideal_reg() const { return Op_RegL; } |
duke@435 | 84 | }; |
duke@435 | 85 | |
duke@435 | 86 | // NOTE: SubFPNode should be taken away and replaced by add and negate |
duke@435 | 87 | //------------------------------SubFPNode-------------------------------------- |
duke@435 | 88 | // Subtract 2 floats or doubles |
duke@435 | 89 | class SubFPNode : public SubNode { |
duke@435 | 90 | protected: |
duke@435 | 91 | SubFPNode( Node *in1, Node *in2 ) : SubNode(in1,in2) {} |
duke@435 | 92 | public: |
duke@435 | 93 | const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 94 | }; |
duke@435 | 95 | |
duke@435 | 96 | // NOTE: SubFNode should be taken away and replaced by add and negate |
duke@435 | 97 | //------------------------------SubFNode--------------------------------------- |
duke@435 | 98 | // Subtract 2 doubles |
duke@435 | 99 | class SubFNode : public SubFPNode { |
duke@435 | 100 | public: |
duke@435 | 101 | SubFNode( Node *in1, Node *in2 ) : SubFPNode(in1,in2) {} |
duke@435 | 102 | virtual int Opcode() const; |
duke@435 | 103 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 104 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 105 | const Type *add_id() const { return TypeF::ZERO; } |
duke@435 | 106 | const Type *bottom_type() const { return Type::FLOAT; } |
duke@435 | 107 | virtual uint ideal_reg() const { return Op_RegF; } |
duke@435 | 108 | }; |
duke@435 | 109 | |
duke@435 | 110 | // NOTE: SubDNode should be taken away and replaced by add and negate |
duke@435 | 111 | //------------------------------SubDNode--------------------------------------- |
duke@435 | 112 | // Subtract 2 doubles |
duke@435 | 113 | class SubDNode : public SubFPNode { |
duke@435 | 114 | public: |
duke@435 | 115 | SubDNode( Node *in1, Node *in2 ) : SubFPNode(in1,in2) {} |
duke@435 | 116 | virtual int Opcode() const; |
duke@435 | 117 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 118 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 119 | const Type *add_id() const { return TypeD::ZERO; } |
duke@435 | 120 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 121 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 122 | }; |
duke@435 | 123 | |
duke@435 | 124 | //------------------------------CmpNode--------------------------------------- |
duke@435 | 125 | // Compare 2 values, returning condition codes (-1, 0 or 1). |
duke@435 | 126 | class CmpNode : public SubNode { |
duke@435 | 127 | public: |
duke@435 | 128 | CmpNode( Node *in1, Node *in2 ) : SubNode(in1,in2) { |
duke@435 | 129 | init_class_id(Class_Cmp); |
duke@435 | 130 | } |
duke@435 | 131 | virtual Node *Identity( PhaseTransform *phase ); |
duke@435 | 132 | const Type *add_id() const { return TypeInt::ZERO; } |
duke@435 | 133 | const Type *bottom_type() const { return TypeInt::CC; } |
duke@435 | 134 | virtual uint ideal_reg() const { return Op_RegFlags; } |
duke@435 | 135 | }; |
duke@435 | 136 | |
duke@435 | 137 | //------------------------------CmpINode--------------------------------------- |
duke@435 | 138 | // Compare 2 signed values, returning condition codes (-1, 0 or 1). |
duke@435 | 139 | class CmpINode : public CmpNode { |
duke@435 | 140 | public: |
duke@435 | 141 | CmpINode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 142 | virtual int Opcode() const; |
duke@435 | 143 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 144 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 145 | }; |
duke@435 | 146 | |
duke@435 | 147 | //------------------------------CmpUNode--------------------------------------- |
duke@435 | 148 | // Compare 2 unsigned values (integer or pointer), returning condition codes (-1, 0 or 1). |
duke@435 | 149 | class CmpUNode : public CmpNode { |
duke@435 | 150 | public: |
duke@435 | 151 | CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 152 | virtual int Opcode() const; |
duke@435 | 153 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 154 | }; |
duke@435 | 155 | |
duke@435 | 156 | //------------------------------CmpPNode--------------------------------------- |
duke@435 | 157 | // Compare 2 pointer values, returning condition codes (-1, 0 or 1). |
duke@435 | 158 | class CmpPNode : public CmpNode { |
duke@435 | 159 | public: |
duke@435 | 160 | CmpPNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 161 | virtual int Opcode() const; |
duke@435 | 162 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 163 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 164 | }; |
duke@435 | 165 | |
coleenp@548 | 166 | //------------------------------CmpNNode-------------------------------------- |
coleenp@548 | 167 | // Compare 2 narrow oop values, returning condition codes (-1, 0 or 1). |
coleenp@548 | 168 | class CmpNNode : public CmpNode { |
coleenp@548 | 169 | public: |
coleenp@548 | 170 | CmpNNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
coleenp@548 | 171 | virtual int Opcode() const; |
coleenp@548 | 172 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
coleenp@548 | 173 | virtual const Type *sub( const Type *, const Type * ) const; |
coleenp@548 | 174 | }; |
coleenp@548 | 175 | |
duke@435 | 176 | //------------------------------CmpLNode--------------------------------------- |
duke@435 | 177 | // Compare 2 long values, returning condition codes (-1, 0 or 1). |
duke@435 | 178 | class CmpLNode : public CmpNode { |
duke@435 | 179 | public: |
duke@435 | 180 | CmpLNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 181 | virtual int Opcode() const; |
duke@435 | 182 | virtual const Type *sub( const Type *, const Type * ) const; |
duke@435 | 183 | }; |
duke@435 | 184 | |
duke@435 | 185 | //------------------------------CmpL3Node-------------------------------------- |
duke@435 | 186 | // Compare 2 long values, returning integer value (-1, 0 or 1). |
duke@435 | 187 | class CmpL3Node : public CmpLNode { |
duke@435 | 188 | public: |
duke@435 | 189 | CmpL3Node( Node *in1, Node *in2 ) : CmpLNode(in1,in2) { |
duke@435 | 190 | // Since it is not consumed by Bools, it is not really a Cmp. |
duke@435 | 191 | init_class_id(Class_Sub); |
duke@435 | 192 | } |
duke@435 | 193 | virtual int Opcode() const; |
duke@435 | 194 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 195 | }; |
duke@435 | 196 | |
duke@435 | 197 | //------------------------------CmpFNode--------------------------------------- |
duke@435 | 198 | // Compare 2 float values, returning condition codes (-1, 0 or 1). |
duke@435 | 199 | // This implements the Java bytecode fcmpl, so unordered returns -1. |
duke@435 | 200 | // Operands may not commute. |
duke@435 | 201 | class CmpFNode : public CmpNode { |
duke@435 | 202 | public: |
duke@435 | 203 | CmpFNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 204 | virtual int Opcode() const; |
duke@435 | 205 | virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return NULL; } |
duke@435 | 206 | const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 207 | }; |
duke@435 | 208 | |
duke@435 | 209 | //------------------------------CmpF3Node-------------------------------------- |
duke@435 | 210 | // Compare 2 float values, returning integer value (-1, 0 or 1). |
duke@435 | 211 | // This implements the Java bytecode fcmpl, so unordered returns -1. |
duke@435 | 212 | // Operands may not commute. |
duke@435 | 213 | class CmpF3Node : public CmpFNode { |
duke@435 | 214 | public: |
duke@435 | 215 | CmpF3Node( Node *in1, Node *in2 ) : CmpFNode(in1,in2) { |
duke@435 | 216 | // Since it is not consumed by Bools, it is not really a Cmp. |
duke@435 | 217 | init_class_id(Class_Sub); |
duke@435 | 218 | } |
duke@435 | 219 | virtual int Opcode() const; |
duke@435 | 220 | // Since it is not consumed by Bools, it is not really a Cmp. |
duke@435 | 221 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 222 | }; |
duke@435 | 223 | |
duke@435 | 224 | |
duke@435 | 225 | //------------------------------CmpDNode--------------------------------------- |
duke@435 | 226 | // Compare 2 double values, returning condition codes (-1, 0 or 1). |
duke@435 | 227 | // This implements the Java bytecode dcmpl, so unordered returns -1. |
duke@435 | 228 | // Operands may not commute. |
duke@435 | 229 | class CmpDNode : public CmpNode { |
duke@435 | 230 | public: |
duke@435 | 231 | CmpDNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} |
duke@435 | 232 | virtual int Opcode() const; |
duke@435 | 233 | virtual const Type *sub( const Type *, const Type * ) const { ShouldNotReachHere(); return NULL; } |
duke@435 | 234 | const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 235 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 236 | }; |
duke@435 | 237 | |
duke@435 | 238 | //------------------------------CmpD3Node-------------------------------------- |
duke@435 | 239 | // Compare 2 double values, returning integer value (-1, 0 or 1). |
duke@435 | 240 | // This implements the Java bytecode dcmpl, so unordered returns -1. |
duke@435 | 241 | // Operands may not commute. |
duke@435 | 242 | class CmpD3Node : public CmpDNode { |
duke@435 | 243 | public: |
duke@435 | 244 | CmpD3Node( Node *in1, Node *in2 ) : CmpDNode(in1,in2) { |
duke@435 | 245 | // Since it is not consumed by Bools, it is not really a Cmp. |
duke@435 | 246 | init_class_id(Class_Sub); |
duke@435 | 247 | } |
duke@435 | 248 | virtual int Opcode() const; |
duke@435 | 249 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 250 | }; |
duke@435 | 251 | |
duke@435 | 252 | |
duke@435 | 253 | //------------------------------BoolTest--------------------------------------- |
duke@435 | 254 | // Convert condition codes to a boolean test value (0 or -1). |
duke@435 | 255 | // We pick the values as 3 bits; the low order 2 bits we compare against the |
duke@435 | 256 | // condition codes, the high bit flips the sense of the result. |
duke@435 | 257 | struct BoolTest VALUE_OBJ_CLASS_SPEC { |
duke@435 | 258 | enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 }; |
duke@435 | 259 | mask _test; |
duke@435 | 260 | BoolTest( mask btm ) : _test(btm) {} |
duke@435 | 261 | const Type *cc2logical( const Type *CC ) const; |
duke@435 | 262 | // Commute the test. I use a small table lookup. The table is created as |
duke@435 | 263 | // a simple char array where each element is the ASCII version of a 'mask' |
duke@435 | 264 | // enum from above. |
duke@435 | 265 | mask commute( ) const { return mask("038147858"[_test]-'0'); } |
duke@435 | 266 | mask negate( ) const { return mask(_test^4); } |
duke@435 | 267 | bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); } |
duke@435 | 268 | #ifndef PRODUCT |
duke@435 | 269 | void dump_on(outputStream *st) const; |
duke@435 | 270 | #endif |
duke@435 | 271 | }; |
duke@435 | 272 | |
duke@435 | 273 | //------------------------------BoolNode--------------------------------------- |
duke@435 | 274 | // A Node to convert a Condition Codes to a Logical result. |
duke@435 | 275 | class BoolNode : public Node { |
duke@435 | 276 | virtual uint hash() const; |
duke@435 | 277 | virtual uint cmp( const Node &n ) const; |
duke@435 | 278 | virtual uint size_of() const; |
duke@435 | 279 | public: |
duke@435 | 280 | const BoolTest _test; |
duke@435 | 281 | BoolNode( Node *cc, BoolTest::mask t): _test(t), Node(0,cc) { |
duke@435 | 282 | init_class_id(Class_Bool); |
duke@435 | 283 | } |
duke@435 | 284 | // Convert an arbitrary int value to a Bool or other suitable predicate. |
duke@435 | 285 | static Node* make_predicate(Node* test_value, PhaseGVN* phase); |
duke@435 | 286 | // Convert self back to an integer value. |
duke@435 | 287 | Node* as_int_value(PhaseGVN* phase); |
duke@435 | 288 | // Invert sense of self, returning new Bool. |
duke@435 | 289 | BoolNode* negate(PhaseGVN* phase); |
duke@435 | 290 | virtual int Opcode() const; |
duke@435 | 291 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 292 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 293 | virtual const Type *bottom_type() const { return TypeInt::BOOL; } |
duke@435 | 294 | uint match_edge(uint idx) const { return 0; } |
duke@435 | 295 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 296 | |
duke@435 | 297 | bool is_counted_loop_exit_test(); |
duke@435 | 298 | #ifndef PRODUCT |
duke@435 | 299 | virtual void dump_spec(outputStream *st) const; |
duke@435 | 300 | #endif |
duke@435 | 301 | }; |
duke@435 | 302 | |
duke@435 | 303 | //------------------------------AbsNode---------------------------------------- |
duke@435 | 304 | // Abstract class for absolute value. Mostly used to get a handy wrapper |
duke@435 | 305 | // for finding this pattern in the graph. |
duke@435 | 306 | class AbsNode : public Node { |
duke@435 | 307 | public: |
duke@435 | 308 | AbsNode( Node *value ) : Node(0,value) {} |
duke@435 | 309 | }; |
duke@435 | 310 | |
duke@435 | 311 | //------------------------------AbsINode--------------------------------------- |
duke@435 | 312 | // Absolute value an integer. Since a naive graph involves control flow, we |
duke@435 | 313 | // "match" it in the ideal world (so the control flow can be removed). |
duke@435 | 314 | class AbsINode : public AbsNode { |
duke@435 | 315 | public: |
duke@435 | 316 | AbsINode( Node *in1 ) : AbsNode(in1) {} |
duke@435 | 317 | virtual int Opcode() const; |
duke@435 | 318 | const Type *bottom_type() const { return TypeInt::INT; } |
duke@435 | 319 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 320 | }; |
duke@435 | 321 | |
duke@435 | 322 | //------------------------------AbsFNode--------------------------------------- |
duke@435 | 323 | // Absolute value a float, a common float-point idiom with a cheap hardware |
duke@435 | 324 | // implemention on most chips. Since a naive graph involves control flow, we |
duke@435 | 325 | // "match" it in the ideal world (so the control flow can be removed). |
duke@435 | 326 | class AbsFNode : public AbsNode { |
duke@435 | 327 | public: |
duke@435 | 328 | AbsFNode( Node *in1 ) : AbsNode(in1) {} |
duke@435 | 329 | virtual int Opcode() const; |
duke@435 | 330 | const Type *bottom_type() const { return Type::FLOAT; } |
duke@435 | 331 | virtual uint ideal_reg() const { return Op_RegF; } |
duke@435 | 332 | }; |
duke@435 | 333 | |
duke@435 | 334 | //------------------------------AbsDNode--------------------------------------- |
duke@435 | 335 | // Absolute value a double, a common float-point idiom with a cheap hardware |
duke@435 | 336 | // implemention on most chips. Since a naive graph involves control flow, we |
duke@435 | 337 | // "match" it in the ideal world (so the control flow can be removed). |
duke@435 | 338 | class AbsDNode : public AbsNode { |
duke@435 | 339 | public: |
duke@435 | 340 | AbsDNode( Node *in1 ) : AbsNode(in1) {} |
duke@435 | 341 | virtual int Opcode() const; |
duke@435 | 342 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 343 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 344 | }; |
duke@435 | 345 | |
duke@435 | 346 | |
duke@435 | 347 | //------------------------------CmpLTMaskNode---------------------------------- |
duke@435 | 348 | // If p < q, return -1 else return 0. Nice for flow-free idioms. |
duke@435 | 349 | class CmpLTMaskNode : public Node { |
duke@435 | 350 | public: |
duke@435 | 351 | CmpLTMaskNode( Node *p, Node *q ) : Node(0, p, q) {} |
duke@435 | 352 | virtual int Opcode() const; |
duke@435 | 353 | const Type *bottom_type() const { return TypeInt::INT; } |
duke@435 | 354 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 355 | }; |
duke@435 | 356 | |
duke@435 | 357 | |
duke@435 | 358 | //------------------------------NegNode---------------------------------------- |
duke@435 | 359 | class NegNode : public Node { |
duke@435 | 360 | public: |
duke@435 | 361 | NegNode( Node *in1 ) : Node(0,in1) {} |
duke@435 | 362 | }; |
duke@435 | 363 | |
duke@435 | 364 | //------------------------------NegFNode--------------------------------------- |
duke@435 | 365 | // Negate value a float. Negating 0.0 returns -0.0, but subtracting from |
duke@435 | 366 | // zero returns +0.0 (per JVM spec on 'fneg' bytecode). As subtraction |
duke@435 | 367 | // cannot be used to replace negation we have to implement negation as ideal |
duke@435 | 368 | // node; note that negation and addition can replace subtraction. |
duke@435 | 369 | class NegFNode : public NegNode { |
duke@435 | 370 | public: |
duke@435 | 371 | NegFNode( Node *in1 ) : NegNode(in1) {} |
duke@435 | 372 | virtual int Opcode() const; |
duke@435 | 373 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 374 | const Type *bottom_type() const { return Type::FLOAT; } |
duke@435 | 375 | virtual uint ideal_reg() const { return Op_RegF; } |
duke@435 | 376 | }; |
duke@435 | 377 | |
duke@435 | 378 | //------------------------------NegDNode--------------------------------------- |
duke@435 | 379 | // Negate value a double. Negating 0.0 returns -0.0, but subtracting from |
duke@435 | 380 | // zero returns +0.0 (per JVM spec on 'dneg' bytecode). As subtraction |
duke@435 | 381 | // cannot be used to replace negation we have to implement negation as ideal |
duke@435 | 382 | // node; note that negation and addition can replace subtraction. |
duke@435 | 383 | class NegDNode : public NegNode { |
duke@435 | 384 | public: |
duke@435 | 385 | NegDNode( Node *in1 ) : NegNode(in1) {} |
duke@435 | 386 | virtual int Opcode() const; |
duke@435 | 387 | virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
duke@435 | 388 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 389 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 390 | }; |
duke@435 | 391 | |
duke@435 | 392 | //------------------------------CosDNode--------------------------------------- |
duke@435 | 393 | // Cosinus of a double |
duke@435 | 394 | class CosDNode : public Node { |
duke@435 | 395 | public: |
duke@435 | 396 | CosDNode( Node *in1 ) : Node(0, in1) {} |
duke@435 | 397 | virtual int Opcode() const; |
duke@435 | 398 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 399 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 400 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 401 | }; |
duke@435 | 402 | |
duke@435 | 403 | //------------------------------CosDNode--------------------------------------- |
duke@435 | 404 | // Sinus of a double |
duke@435 | 405 | class SinDNode : public Node { |
duke@435 | 406 | public: |
duke@435 | 407 | SinDNode( Node *in1 ) : Node(0, in1) {} |
duke@435 | 408 | virtual int Opcode() const; |
duke@435 | 409 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 410 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 411 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 412 | }; |
duke@435 | 413 | |
duke@435 | 414 | |
duke@435 | 415 | //------------------------------TanDNode--------------------------------------- |
duke@435 | 416 | // tangens of a double |
duke@435 | 417 | class TanDNode : public Node { |
duke@435 | 418 | public: |
duke@435 | 419 | TanDNode(Node *in1 ) : Node(0, in1) {} |
duke@435 | 420 | virtual int Opcode() const; |
duke@435 | 421 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 422 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 423 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 424 | }; |
duke@435 | 425 | |
duke@435 | 426 | |
duke@435 | 427 | //------------------------------AtanDNode-------------------------------------- |
duke@435 | 428 | // arcus tangens of a double |
duke@435 | 429 | class AtanDNode : public Node { |
duke@435 | 430 | public: |
duke@435 | 431 | AtanDNode(Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {} |
duke@435 | 432 | virtual int Opcode() const; |
duke@435 | 433 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 434 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 435 | }; |
duke@435 | 436 | |
duke@435 | 437 | |
duke@435 | 438 | //------------------------------SqrtDNode-------------------------------------- |
duke@435 | 439 | // square root a double |
duke@435 | 440 | class SqrtDNode : public Node { |
duke@435 | 441 | public: |
duke@435 | 442 | SqrtDNode(Node *c, Node *in1 ) : Node(c, in1) {} |
duke@435 | 443 | virtual int Opcode() const; |
duke@435 | 444 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 445 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 446 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 447 | }; |
duke@435 | 448 | |
duke@435 | 449 | //------------------------------ExpDNode--------------------------------------- |
duke@435 | 450 | // Exponentiate a double |
duke@435 | 451 | class ExpDNode : public Node { |
duke@435 | 452 | public: |
duke@435 | 453 | ExpDNode( Node *c, Node *in1 ) : Node(c, in1) {} |
duke@435 | 454 | virtual int Opcode() const; |
duke@435 | 455 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 456 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 457 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 458 | }; |
duke@435 | 459 | |
duke@435 | 460 | //------------------------------LogDNode--------------------------------------- |
duke@435 | 461 | // Log_e of a double |
duke@435 | 462 | class LogDNode : public Node { |
duke@435 | 463 | public: |
duke@435 | 464 | LogDNode( Node *in1 ) : Node(0, in1) {} |
duke@435 | 465 | virtual int Opcode() const; |
duke@435 | 466 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 467 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 468 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 469 | }; |
duke@435 | 470 | |
duke@435 | 471 | //------------------------------Log10DNode--------------------------------------- |
duke@435 | 472 | // Log_10 of a double |
duke@435 | 473 | class Log10DNode : public Node { |
duke@435 | 474 | public: |
duke@435 | 475 | Log10DNode( Node *in1 ) : Node(0, in1) {} |
duke@435 | 476 | virtual int Opcode() const; |
duke@435 | 477 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 478 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 479 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 480 | }; |
duke@435 | 481 | |
duke@435 | 482 | //------------------------------PowDNode--------------------------------------- |
duke@435 | 483 | // Raise a double to a double power |
duke@435 | 484 | class PowDNode : public Node { |
duke@435 | 485 | public: |
duke@435 | 486 | PowDNode(Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {} |
duke@435 | 487 | virtual int Opcode() const; |
duke@435 | 488 | const Type *bottom_type() const { return Type::DOUBLE; } |
duke@435 | 489 | virtual uint ideal_reg() const { return Op_RegD; } |
duke@435 | 490 | virtual const Type *Value( PhaseTransform *phase ) const; |
duke@435 | 491 | }; |
duke@435 | 492 | |
duke@435 | 493 | //-------------------------------ReverseBytesINode-------------------------------- |
duke@435 | 494 | // reverse bytes of an integer |
duke@435 | 495 | class ReverseBytesINode : public Node { |
duke@435 | 496 | public: |
duke@435 | 497 | ReverseBytesINode(Node *c, Node *in1) : Node(c, in1) {} |
duke@435 | 498 | virtual int Opcode() const; |
duke@435 | 499 | const Type *bottom_type() const { return TypeInt::INT; } |
duke@435 | 500 | virtual uint ideal_reg() const { return Op_RegI; } |
duke@435 | 501 | }; |
duke@435 | 502 | |
duke@435 | 503 | //-------------------------------ReverseBytesLNode-------------------------------- |
duke@435 | 504 | // reverse bytes of a long |
duke@435 | 505 | class ReverseBytesLNode : public Node { |
duke@435 | 506 | public: |
duke@435 | 507 | ReverseBytesLNode(Node *c, Node *in1) : Node(c, in1) {} |
duke@435 | 508 | virtual int Opcode() const; |
duke@435 | 509 | const Type *bottom_type() const { return TypeLong::LONG; } |
duke@435 | 510 | virtual uint ideal_reg() const { return Op_RegL; } |
duke@435 | 511 | }; |