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