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