duke@435: /* duke@435: * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: class PhaseTransform; duke@435: class MachNode; duke@435: duke@435: //------------------------------ConNode---------------------------------------- duke@435: // Simple constants duke@435: class ConNode : public TypeNode { duke@435: public: duke@435: ConNode( const Type *t ) : TypeNode(t,1) { duke@435: init_req(0, (Node*)Compile::current()->root()); duke@435: init_flags(Flag_is_Con); duke@435: } duke@435: virtual int Opcode() const; duke@435: virtual uint hash() const; duke@435: virtual const RegMask &out_RegMask() const { return RegMask::Empty; } duke@435: virtual const RegMask &in_RegMask(uint) const { return RegMask::Empty; } duke@435: duke@435: // Polymorphic factory method: duke@435: static ConNode* make( Compile* C, const Type *t ); duke@435: }; duke@435: duke@435: //------------------------------ConINode--------------------------------------- duke@435: // Simple integer constants duke@435: class ConINode : public ConNode { duke@435: public: duke@435: ConINode( const TypeInt *t ) : ConNode(t) {} duke@435: virtual int Opcode() const; duke@435: duke@435: // Factory method: duke@435: static ConINode* make( Compile* C, int con ) { duke@435: return new (C, 1) ConINode( TypeInt::make(con) ); duke@435: } duke@435: duke@435: }; duke@435: duke@435: //------------------------------ConPNode--------------------------------------- duke@435: // Simple pointer constants duke@435: class ConPNode : public ConNode { duke@435: public: duke@435: ConPNode( const TypePtr *t ) : ConNode(t) {} duke@435: virtual int Opcode() const; duke@435: duke@435: // Factory methods: duke@435: static ConPNode* make( Compile *C ,address con ) { duke@435: if (con == NULL) duke@435: return new (C, 1) ConPNode( TypePtr::NULL_PTR ) ; duke@435: else duke@435: return new (C, 1) ConPNode( TypeRawPtr::make(con) ); duke@435: } duke@435: duke@435: static ConPNode* make( Compile *C, ciObject* con ) { duke@435: return new (C, 1) ConPNode( TypeOopPtr::make_from_constant(con) ); duke@435: } duke@435: duke@435: }; duke@435: duke@435: duke@435: //------------------------------ConLNode--------------------------------------- duke@435: // Simple long constants duke@435: class ConLNode : public ConNode { duke@435: public: duke@435: ConLNode( const TypeLong *t ) : ConNode(t) {} duke@435: virtual int Opcode() const; duke@435: duke@435: // Factory method: duke@435: static ConLNode* make( Compile *C ,jlong con ) { duke@435: return new (C, 1) ConLNode( TypeLong::make(con) ); duke@435: } duke@435: duke@435: }; duke@435: duke@435: //------------------------------ConFNode--------------------------------------- duke@435: // Simple float constants duke@435: class ConFNode : public ConNode { duke@435: public: duke@435: ConFNode( const TypeF *t ) : ConNode(t) {} duke@435: virtual int Opcode() const; duke@435: duke@435: // Factory method: duke@435: static ConFNode* make( Compile *C, float con ) { duke@435: return new (C, 1) ConFNode( TypeF::make(con) ); duke@435: } duke@435: duke@435: }; duke@435: duke@435: //------------------------------ConDNode--------------------------------------- duke@435: // Simple double constants duke@435: class ConDNode : public ConNode { duke@435: public: duke@435: ConDNode( const TypeD *t ) : ConNode(t) {} duke@435: virtual int Opcode() const; duke@435: duke@435: // Factory method: duke@435: static ConDNode* make( Compile *C, double con ) { duke@435: return new (C, 1) ConDNode( TypeD::make(con) ); duke@435: } duke@435: duke@435: }; duke@435: duke@435: //------------------------------BinaryNode------------------------------------- duke@435: // Place holder for the 2 conditional inputs to a CMove. CMove needs 4 duke@435: // inputs: the Bool (for the lt/gt/eq/ne bits), the flags (result of some duke@435: // compare), and the 2 values to select between. The Matcher requires a duke@435: // binary tree so we break it down like this: duke@435: // (CMove (Binary bol cmp) (Binary src1 src2)) duke@435: class BinaryNode : public Node { duke@435: public: duke@435: BinaryNode( Node *n1, Node *n2 ) : Node(0,n1,n2) { } duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const { return 0; } duke@435: }; duke@435: duke@435: //------------------------------CMoveNode-------------------------------------- duke@435: // Conditional move duke@435: class CMoveNode : public TypeNode { duke@435: public: duke@435: enum { Control, // When is it safe to do this cmove? duke@435: Condition, // Condition controlling the cmove duke@435: IfFalse, // Value if condition is false duke@435: IfTrue }; // Value if condition is true duke@435: CMoveNode( Node *bol, Node *left, Node *right, const Type *t ) : TypeNode(t,4) duke@435: { duke@435: init_class_id(Class_CMove); duke@435: // all inputs are nullified in Node::Node(int) duke@435: // init_req(Control,NULL); duke@435: init_req(Condition,bol); duke@435: init_req(IfFalse,left); duke@435: init_req(IfTrue,right); duke@435: } duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: static CMoveNode *make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ); duke@435: // Helper function to spot cmove graph shapes duke@435: static Node *is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ); duke@435: }; duke@435: duke@435: //------------------------------CMoveDNode------------------------------------- duke@435: class CMoveDNode : public CMoveNode { duke@435: public: duke@435: CMoveDNode( Node *bol, Node *left, Node *right, const Type* t) : CMoveNode(bol,left,right,t){} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: }; duke@435: duke@435: //------------------------------CMoveFNode------------------------------------- duke@435: class CMoveFNode : public CMoveNode { duke@435: public: duke@435: CMoveFNode( Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: }; duke@435: duke@435: //------------------------------CMoveINode------------------------------------- duke@435: class CMoveINode : public CMoveNode { duke@435: public: duke@435: CMoveINode( Node *bol, Node *left, Node *right, const TypeInt *ti ) : CMoveNode(bol,left,right,ti){} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: }; duke@435: duke@435: //------------------------------CMoveLNode------------------------------------- duke@435: class CMoveLNode : public CMoveNode { duke@435: public: duke@435: CMoveLNode(Node *bol, Node *left, Node *right, const TypeLong *tl ) : CMoveNode(bol,left,right,tl){} duke@435: virtual int Opcode() const; duke@435: }; duke@435: duke@435: //------------------------------CMovePNode------------------------------------- duke@435: class CMovePNode : public CMoveNode { duke@435: public: duke@435: CMovePNode( Node *c, Node *bol, Node *left, Node *right, const TypePtr* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); } duke@435: virtual int Opcode() const; duke@435: }; duke@435: duke@435: //------------------------------ConstraintCastNode------------------------------------- duke@435: // cast to a different range duke@435: class ConstraintCastNode: public TypeNode { duke@435: public: duke@435: ConstraintCastNode (Node *n, const Type *t ): TypeNode(t,2) { duke@435: init_class_id(Class_ConstraintCast); duke@435: init_req(1, n); duke@435: } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const = 0; duke@435: virtual Node *Ideal_DU_postCCP( PhaseCCP * ); duke@435: }; duke@435: duke@435: //------------------------------CastIINode------------------------------------- duke@435: // cast integer to integer (different range) duke@435: class CastIINode: public ConstraintCastNode { duke@435: public: duke@435: CastIINode (Node *n, const Type *t ): ConstraintCastNode(n,t) {} duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------CastPPNode------------------------------------- duke@435: // cast pointer to pointer (different type) duke@435: class CastPPNode: public ConstraintCastNode { duke@435: public: duke@435: CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) { duke@435: // Only CastPP is safe. CastII can cause optimizer loops. duke@435: init_flags(Flag_is_dead_loop_safe); duke@435: } duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: virtual Node *Ideal_DU_postCCP( PhaseCCP * ); duke@435: }; duke@435: duke@435: //------------------------------CheckCastPPNode-------------------------------- duke@435: // for _checkcast, cast pointer to pointer (different type), without JOIN, duke@435: class CheckCastPPNode: public TypeNode { duke@435: public: duke@435: CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) { duke@435: init_class_id(Class_CheckCastPP); duke@435: init_flags(Flag_is_dead_loop_safe); duke@435: init_req(0, c); duke@435: init_req(1, n); duke@435: } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: // No longer remove CheckCast after CCP as it gives me a place to hang duke@435: // the proper address type - which is required to compute anti-deps. duke@435: //virtual Node *Ideal_DU_postCCP( PhaseCCP * ); duke@435: }; duke@435: duke@435: //------------------------------Conv2BNode------------------------------------- duke@435: // Convert int/pointer to a Boolean. Map zero to zero, all else to 1. duke@435: class Conv2BNode : public Node { duke@435: public: duke@435: Conv2BNode( Node *i ) : Node(0,i) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::BOOL; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: // The conversions operations are all Alpha sorted. Please keep it that way! duke@435: //------------------------------ConvD2FNode------------------------------------ duke@435: // Convert double to float duke@435: class ConvD2FNode : public Node { duke@435: public: duke@435: ConvD2FNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: }; duke@435: duke@435: //------------------------------ConvD2INode------------------------------------ duke@435: // Convert Double to Integer duke@435: class ConvD2INode : public Node { duke@435: public: duke@435: ConvD2INode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------ConvD2LNode------------------------------------ duke@435: // Convert Double to Long duke@435: class ConvD2LNode : public Node { duke@435: public: duke@435: ConvD2LNode( Node *dbl ) : Node(0,dbl) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------ConvF2DNode------------------------------------ duke@435: // Convert Float to a Double. duke@435: class ConvF2DNode : public Node { duke@435: public: duke@435: ConvF2DNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: }; duke@435: duke@435: //------------------------------ConvF2INode------------------------------------ duke@435: // Convert float to integer duke@435: class ConvF2INode : public Node { duke@435: public: duke@435: ConvF2INode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------ConvF2LNode------------------------------------ duke@435: // Convert float to long duke@435: class ConvF2LNode : public Node { duke@435: public: duke@435: ConvF2LNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------ConvI2DNode------------------------------------ duke@435: // Convert Integer to Double duke@435: class ConvI2DNode : public Node { duke@435: public: duke@435: ConvI2DNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: }; duke@435: duke@435: //------------------------------ConvI2FNode------------------------------------ duke@435: // Convert Integer to Float duke@435: class ConvI2FNode : public Node { duke@435: public: duke@435: ConvI2FNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: }; duke@435: duke@435: //------------------------------ConvI2LNode------------------------------------ duke@435: // Convert integer to long duke@435: class ConvI2LNode : public TypeNode { duke@435: public: duke@435: ConvI2LNode(Node *in1, const TypeLong* t = TypeLong::INT) duke@435: : TypeNode(t, 2) duke@435: { init_req(1, in1); } duke@435: virtual int Opcode() const; duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------ConvL2DNode------------------------------------ duke@435: // Convert Long to Double duke@435: class ConvL2DNode : public Node { duke@435: public: duke@435: ConvL2DNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: }; duke@435: duke@435: //------------------------------ConvL2FNode------------------------------------ duke@435: // Convert Long to Float duke@435: class ConvL2FNode : public Node { duke@435: public: duke@435: ConvL2FNode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: }; duke@435: duke@435: //------------------------------ConvL2INode------------------------------------ duke@435: // Convert long to integer duke@435: class ConvL2INode : public Node { duke@435: public: duke@435: ConvL2INode( Node *in1 ) : Node(0,in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------CastX2PNode------------------------------------- duke@435: // convert a machine-pointer-sized integer to a raw pointer duke@435: class CastX2PNode : public Node { duke@435: public: duke@435: CastX2PNode( Node *n ) : Node(NULL, n) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } duke@435: }; duke@435: duke@435: //------------------------------CastP2XNode------------------------------------- duke@435: // Used in both 32-bit and 64-bit land. duke@435: // Used for card-marks and unsafe pointer math. duke@435: class CastP2XNode : public Node { duke@435: public: duke@435: CastP2XNode( Node *ctrl, Node *n ) : Node(ctrl, n) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegX; } duke@435: virtual const Type *bottom_type() const { return TypeX_X; } duke@435: // Return false to keep node from moving away from an associated card mark. duke@435: virtual bool depends_only_on_test() const { return false; } duke@435: }; duke@435: duke@435: //------------------------------MemMoveNode------------------------------------ duke@435: // Memory to memory move. Inserted very late, after allocation. duke@435: class MemMoveNode : public Node { duke@435: public: duke@435: MemMoveNode( Node *dst, Node *src ) : Node(0,dst,src) {} duke@435: virtual int Opcode() const; duke@435: }; duke@435: duke@435: //------------------------------ThreadLocalNode-------------------------------- duke@435: // Ideal Node which returns the base of ThreadLocalStorage. duke@435: class ThreadLocalNode : public Node { duke@435: public: duke@435: ThreadLocalNode( ) : Node((Node*)Compile::current()->root()) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM;} duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: }; duke@435: duke@435: //------------------------------LoadReturnPCNode------------------------------- duke@435: class LoadReturnPCNode: public Node { duke@435: public: duke@435: LoadReturnPCNode(Node *c) : Node(c) { } duke@435: virtual int Opcode() const; duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: }; duke@435: duke@435: duke@435: //-----------------------------RoundFloatNode---------------------------------- duke@435: class RoundFloatNode: public Node { duke@435: public: duke@435: RoundFloatNode(Node* c, Node *in1): Node(c, in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: }; duke@435: duke@435: duke@435: //-----------------------------RoundDoubleNode--------------------------------- duke@435: class RoundDoubleNode: public Node { duke@435: public: duke@435: RoundDoubleNode(Node* c, Node *in1): Node(c, in1) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: }; duke@435: duke@435: //------------------------------Opaque1Node------------------------------------ duke@435: // A node to prevent unwanted optimizations. Allows constant folding. duke@435: // Stops value-numbering, Ideal calls or Identity functions. duke@435: class Opaque1Node : public Node { duke@435: virtual uint hash() const ; // { return NO_HASH; } duke@435: virtual uint cmp( const Node &n ) const; duke@435: public: duke@435: Opaque1Node( Node *n ) : Node(0,n) {} duke@435: // Special version for the pre-loop to hold the original loop limit duke@435: // which is consumed by range check elimination. duke@435: Opaque1Node( Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {} duke@435: Node* original_loop_limit() { return req()==3 ? in(2) : NULL; } duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: }; duke@435: duke@435: //------------------------------Opaque2Node------------------------------------ duke@435: // A node to prevent unwanted optimizations. Allows constant folding. Stops duke@435: // value-numbering, most Ideal calls or Identity functions. This Node is duke@435: // specifically designed to prevent the pre-increment value of a loop trip duke@435: // counter from being live out of the bottom of the loop (hence causing the duke@435: // pre- and post-increment values both being live and thus requiring an extra duke@435: // temp register and an extra move). If we "accidentally" optimize through duke@435: // this kind of a Node, we'll get slightly pessimal, but correct, code. Thus duke@435: // it's OK to be slightly sloppy on optimizations here. duke@435: class Opaque2Node : public Node { duke@435: virtual uint hash() const ; // { return NO_HASH; } duke@435: virtual uint cmp( const Node &n ) const; duke@435: public: duke@435: Opaque2Node( Node *n ) : Node(0,n) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: }; duke@435: duke@435: //----------------------PartialSubtypeCheckNode-------------------------------- duke@435: // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass duke@435: // array for an instance of the superklass. Set a hidden internal cache on a duke@435: // hit (cache is checked with exposed code in gen_subtype_check()). Return duke@435: // not zero for a miss or zero for a hit. duke@435: class PartialSubtypeCheckNode : public Node { duke@435: public: duke@435: PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: }; duke@435: duke@435: // duke@435: class MoveI2FNode : public Node { duke@435: public: duke@435: MoveI2FNode( Node *value ) : Node(0,value) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: virtual const Type* Value( PhaseTransform *phase ) const; duke@435: }; duke@435: duke@435: class MoveL2DNode : public Node { duke@435: public: duke@435: MoveL2DNode( Node *value ) : Node(0,value) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: virtual const Type* Value( PhaseTransform *phase ) const; duke@435: }; duke@435: duke@435: class MoveF2INode : public Node { duke@435: public: duke@435: MoveF2INode( Node *value ) : Node(0,value) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: virtual const Type* Value( PhaseTransform *phase ) const; duke@435: }; duke@435: duke@435: class MoveD2LNode : public Node { duke@435: public: duke@435: MoveD2LNode( Node *value ) : Node(0,value) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: virtual const Type* Value( PhaseTransform *phase ) const; duke@435: };