aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_OPTO_CONNODE_HPP aoqi@0: #define SHARE_VM_OPTO_CONNODE_HPP aoqi@0: aoqi@0: #include "opto/node.hpp" aoqi@0: #include "opto/opcodes.hpp" aoqi@0: #include "opto/type.hpp" aoqi@0: aoqi@0: class PhaseTransform; aoqi@0: class MachNode; aoqi@0: aoqi@0: //------------------------------ConNode---------------------------------------- aoqi@0: // Simple constants aoqi@0: class ConNode : public TypeNode { aoqi@0: public: aoqi@0: ConNode( const Type *t ) : TypeNode(t->remove_speculative(),1) { aoqi@0: init_req(0, (Node*)Compile::current()->root()); aoqi@0: init_flags(Flag_is_Con); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint hash() const; aoqi@0: virtual const RegMask &out_RegMask() const { return RegMask::Empty; } aoqi@0: virtual const RegMask &in_RegMask(uint) const { return RegMask::Empty; } aoqi@0: aoqi@0: // Polymorphic factory method: aoqi@0: static ConNode* make( Compile* C, const Type *t ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConINode--------------------------------------- aoqi@0: // Simple integer constants aoqi@0: class ConINode : public ConNode { aoqi@0: public: aoqi@0: ConINode( const TypeInt *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: aoqi@0: // Factory method: aoqi@0: static ConINode* make( Compile* C, int con ) { aoqi@0: return new (C) ConINode( TypeInt::make(con) ); aoqi@0: } aoqi@0: aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConPNode--------------------------------------- aoqi@0: // Simple pointer constants aoqi@0: class ConPNode : public ConNode { aoqi@0: public: aoqi@0: ConPNode( const TypePtr *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: aoqi@0: // Factory methods: aoqi@0: static ConPNode* make( Compile *C ,address con ) { aoqi@0: if (con == NULL) aoqi@0: return new (C) ConPNode( TypePtr::NULL_PTR ) ; aoqi@0: else aoqi@0: return new (C) ConPNode( TypeRawPtr::make(con) ); aoqi@0: } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //------------------------------ConNNode-------------------------------------- aoqi@0: // Simple narrow oop constants aoqi@0: class ConNNode : public ConNode { aoqi@0: public: aoqi@0: ConNNode( const TypeNarrowOop *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConNKlassNode--------------------------------- aoqi@0: // Simple narrow klass constants aoqi@0: class ConNKlassNode : public ConNode { aoqi@0: public: aoqi@0: ConNKlassNode( const TypeNarrowKlass *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //------------------------------ConLNode--------------------------------------- aoqi@0: // Simple long constants aoqi@0: class ConLNode : public ConNode { aoqi@0: public: aoqi@0: ConLNode( const TypeLong *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: aoqi@0: // Factory method: aoqi@0: static ConLNode* make( Compile *C ,jlong con ) { aoqi@0: return new (C) ConLNode( TypeLong::make(con) ); aoqi@0: } aoqi@0: aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConFNode--------------------------------------- aoqi@0: // Simple float constants aoqi@0: class ConFNode : public ConNode { aoqi@0: public: aoqi@0: ConFNode( const TypeF *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: aoqi@0: // Factory method: aoqi@0: static ConFNode* make( Compile *C, float con ) { aoqi@0: return new (C) ConFNode( TypeF::make(con) ); aoqi@0: } aoqi@0: aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConDNode--------------------------------------- aoqi@0: // Simple double constants aoqi@0: class ConDNode : public ConNode { aoqi@0: public: aoqi@0: ConDNode( const TypeD *t ) : ConNode(t) {} aoqi@0: virtual int Opcode() const; aoqi@0: aoqi@0: // Factory method: aoqi@0: static ConDNode* make( Compile *C, double con ) { aoqi@0: return new (C) ConDNode( TypeD::make(con) ); aoqi@0: } aoqi@0: aoqi@0: }; aoqi@0: aoqi@0: //------------------------------BinaryNode------------------------------------- aoqi@0: // Place holder for the 2 conditional inputs to a CMove. CMove needs 4 aoqi@0: // inputs: the Bool (for the lt/gt/eq/ne bits), the flags (result of some aoqi@0: // compare), and the 2 values to select between. The Matcher requires a aoqi@0: // binary tree so we break it down like this: aoqi@0: // (CMove (Binary bol cmp) (Binary src1 src2)) aoqi@0: class BinaryNode : public Node { aoqi@0: public: aoqi@0: BinaryNode( Node *n1, Node *n2 ) : Node(0,n1,n2) { } aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const { return 0; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveNode-------------------------------------- aoqi@0: // Conditional move aoqi@0: class CMoveNode : public TypeNode { aoqi@0: public: aoqi@0: enum { Control, // When is it safe to do this cmove? aoqi@0: Condition, // Condition controlling the cmove aoqi@0: IfFalse, // Value if condition is false aoqi@0: IfTrue }; // Value if condition is true aoqi@0: CMoveNode( Node *bol, Node *left, Node *right, const Type *t ) : TypeNode(t,4) aoqi@0: { aoqi@0: init_class_id(Class_CMove); aoqi@0: // all inputs are nullified in Node::Node(int) aoqi@0: // init_req(Control,NULL); aoqi@0: init_req(Condition,bol); aoqi@0: init_req(IfFalse,left); aoqi@0: init_req(IfTrue,right); aoqi@0: } aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: static CMoveNode *make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ); aoqi@0: // Helper function to spot cmove graph shapes aoqi@0: static Node *is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveDNode------------------------------------- aoqi@0: class CMoveDNode : public CMoveNode { aoqi@0: public: aoqi@0: CMoveDNode( Node *bol, Node *left, Node *right, const Type* t) : CMoveNode(bol,left,right,t){} aoqi@0: virtual int Opcode() const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveFNode------------------------------------- aoqi@0: class CMoveFNode : public CMoveNode { aoqi@0: public: aoqi@0: CMoveFNode( Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveINode------------------------------------- aoqi@0: class CMoveINode : public CMoveNode { aoqi@0: public: aoqi@0: CMoveINode( Node *bol, Node *left, Node *right, const TypeInt *ti ) : CMoveNode(bol,left,right,ti){} aoqi@0: virtual int Opcode() const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveLNode------------------------------------- aoqi@0: class CMoveLNode : public CMoveNode { aoqi@0: public: aoqi@0: CMoveLNode(Node *bol, Node *left, Node *right, const TypeLong *tl ) : CMoveNode(bol,left,right,tl){} aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMovePNode------------------------------------- aoqi@0: class CMovePNode : public CMoveNode { aoqi@0: public: aoqi@0: CMovePNode( Node *c, Node *bol, Node *left, Node *right, const TypePtr* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); } aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CMoveNNode------------------------------------- aoqi@0: class CMoveNNode : public CMoveNode { aoqi@0: public: aoqi@0: CMoveNNode( Node *c, Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); } aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConstraintCastNode----------------------------- aoqi@0: // cast to a different range aoqi@0: class ConstraintCastNode: public TypeNode { aoqi@0: public: aoqi@0: ConstraintCastNode (Node *n, const Type *t ): TypeNode(t,2) { aoqi@0: init_class_id(Class_ConstraintCast); aoqi@0: init_req(1, n); aoqi@0: } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const = 0; aoqi@0: virtual Node *Ideal_DU_postCCP( PhaseCCP * ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CastIINode------------------------------------- aoqi@0: // cast integer to integer (different range) aoqi@0: class CastIINode: public ConstraintCastNode { aoqi@0: public: aoqi@0: CastIINode (Node *n, const Type *t ): ConstraintCastNode(n,t) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CastPPNode------------------------------------- aoqi@0: // cast pointer to pointer (different type) aoqi@0: class CastPPNode: public ConstraintCastNode { aoqi@0: public: aoqi@0: CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: virtual Node *Ideal_DU_postCCP( PhaseCCP * ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CheckCastPPNode-------------------------------- aoqi@0: // for _checkcast, cast pointer to pointer (different type), without JOIN, aoqi@0: class CheckCastPPNode: public TypeNode { aoqi@0: public: aoqi@0: CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) { aoqi@0: init_class_id(Class_CheckCastPP); aoqi@0: init_req(0, c); aoqi@0: init_req(1, n); aoqi@0: } aoqi@0: aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: // No longer remove CheckCast after CCP as it gives me a place to hang aoqi@0: // the proper address type - which is required to compute anti-deps. aoqi@0: //virtual Node *Ideal_DU_postCCP( PhaseCCP * ); aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //------------------------------EncodeNarrowPtr-------------------------------- aoqi@0: class EncodeNarrowPtrNode : public TypeNode { aoqi@0: protected: aoqi@0: EncodeNarrowPtrNode(Node* value, const Type* type): aoqi@0: TypeNode(type, 2) { aoqi@0: init_class_id(Class_EncodeNarrowPtr); aoqi@0: init_req(0, NULL); aoqi@0: init_req(1, value); aoqi@0: } aoqi@0: public: aoqi@0: virtual uint ideal_reg() const { return Op_RegN; } aoqi@0: virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------EncodeP-------------------------------- aoqi@0: // Encodes an oop pointers into its compressed form aoqi@0: // Takes an extra argument which is the real heap base as a long which aoqi@0: // may be useful for code generation in the backend. aoqi@0: class EncodePNode : public EncodeNarrowPtrNode { aoqi@0: public: aoqi@0: EncodePNode(Node* value, const Type* type): aoqi@0: EncodeNarrowPtrNode(value, type) { aoqi@0: init_class_id(Class_EncodeP); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------EncodePKlass-------------------------------- aoqi@0: // Encodes a klass pointer into its compressed form aoqi@0: // Takes an extra argument which is the real heap base as a long which aoqi@0: // may be useful for code generation in the backend. aoqi@0: class EncodePKlassNode : public EncodeNarrowPtrNode { aoqi@0: public: aoqi@0: EncodePKlassNode(Node* value, const Type* type): aoqi@0: EncodeNarrowPtrNode(value, type) { aoqi@0: init_class_id(Class_EncodePKlass); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------DecodeNarrowPtr-------------------------------- aoqi@0: class DecodeNarrowPtrNode : public TypeNode { aoqi@0: protected: aoqi@0: DecodeNarrowPtrNode(Node* value, const Type* type): aoqi@0: TypeNode(type, 2) { aoqi@0: init_class_id(Class_DecodeNarrowPtr); aoqi@0: init_req(0, NULL); aoqi@0: init_req(1, value); aoqi@0: } aoqi@0: public: aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------DecodeN-------------------------------- aoqi@0: // Converts a narrow oop into a real oop ptr. aoqi@0: // Takes an extra argument which is the real heap base as a long which aoqi@0: // may be useful for code generation in the backend. aoqi@0: class DecodeNNode : public DecodeNarrowPtrNode { aoqi@0: public: aoqi@0: DecodeNNode(Node* value, const Type* type): aoqi@0: DecodeNarrowPtrNode(value, type) { aoqi@0: init_class_id(Class_DecodeN); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------DecodeNKlass-------------------------------- aoqi@0: // Converts a narrow klass pointer into a real klass ptr. aoqi@0: // Takes an extra argument which is the real heap base as a long which aoqi@0: // may be useful for code generation in the backend. aoqi@0: class DecodeNKlassNode : public DecodeNarrowPtrNode { aoqi@0: public: aoqi@0: DecodeNKlassNode(Node* value, const Type* type): aoqi@0: DecodeNarrowPtrNode(value, type) { aoqi@0: init_class_id(Class_DecodeNKlass); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------Conv2BNode------------------------------------- aoqi@0: // Convert int/pointer to a Boolean. Map zero to zero, all else to 1. aoqi@0: class Conv2BNode : public Node { aoqi@0: public: aoqi@0: Conv2BNode( Node *i ) : Node(0,i) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::BOOL; } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: // The conversions operations are all Alpha sorted. Please keep it that way! aoqi@0: //------------------------------ConvD2FNode------------------------------------ aoqi@0: // Convert double to float aoqi@0: class ConvD2FNode : public Node { aoqi@0: public: aoqi@0: ConvD2FNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::FLOAT; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual uint ideal_reg() const { return Op_RegF; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvD2INode------------------------------------ aoqi@0: // Convert Double to Integer aoqi@0: class ConvD2INode : public Node { aoqi@0: public: aoqi@0: ConvD2INode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvD2LNode------------------------------------ aoqi@0: // Convert Double to Long aoqi@0: class ConvD2LNode : public Node { aoqi@0: public: aoqi@0: ConvD2LNode( Node *dbl ) : Node(0,dbl) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeLong::LONG; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegL; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvF2DNode------------------------------------ aoqi@0: // Convert Float to a Double. aoqi@0: class ConvF2DNode : public Node { aoqi@0: public: aoqi@0: ConvF2DNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::DOUBLE; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual uint ideal_reg() const { return Op_RegD; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvF2INode------------------------------------ aoqi@0: // Convert float to integer aoqi@0: class ConvF2INode : public Node { aoqi@0: public: aoqi@0: ConvF2INode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvF2LNode------------------------------------ aoqi@0: // Convert float to long aoqi@0: class ConvF2LNode : public Node { aoqi@0: public: aoqi@0: ConvF2LNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeLong::LONG; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegL; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvI2DNode------------------------------------ aoqi@0: // Convert Integer to Double aoqi@0: class ConvI2DNode : public Node { aoqi@0: public: aoqi@0: ConvI2DNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::DOUBLE; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual uint ideal_reg() const { return Op_RegD; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvI2FNode------------------------------------ aoqi@0: // Convert Integer to Float aoqi@0: class ConvI2FNode : public Node { aoqi@0: public: aoqi@0: ConvI2FNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::FLOAT; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual uint ideal_reg() const { return Op_RegF; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvI2LNode------------------------------------ aoqi@0: // Convert integer to long aoqi@0: class ConvI2LNode : public TypeNode { aoqi@0: public: aoqi@0: ConvI2LNode(Node *in1, const TypeLong* t = TypeLong::INT) aoqi@0: : TypeNode(t, 2) aoqi@0: { init_req(1, in1); } aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegL; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvL2DNode------------------------------------ aoqi@0: // Convert Long to Double aoqi@0: class ConvL2DNode : public Node { aoqi@0: public: aoqi@0: ConvL2DNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::DOUBLE; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual uint ideal_reg() const { return Op_RegD; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvL2FNode------------------------------------ aoqi@0: // Convert Long to Float aoqi@0: class ConvL2FNode : public Node { aoqi@0: public: aoqi@0: ConvL2FNode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::FLOAT; } aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual uint ideal_reg() const { return Op_RegF; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ConvL2INode------------------------------------ aoqi@0: // Convert long to integer aoqi@0: class ConvL2INode : public Node { aoqi@0: public: aoqi@0: ConvL2INode( Node *in1 ) : Node(0,in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CastX2PNode------------------------------------- aoqi@0: // convert a machine-pointer-sized integer to a raw pointer aoqi@0: class CastX2PNode : public Node { aoqi@0: public: aoqi@0: CastX2PNode( Node *n ) : Node(NULL, n) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------CastP2XNode------------------------------------- aoqi@0: // Used in both 32-bit and 64-bit land. aoqi@0: // Used for card-marks and unsafe pointer math. aoqi@0: class CastP2XNode : public Node { aoqi@0: public: aoqi@0: CastP2XNode( Node *ctrl, Node *n ) : Node(ctrl, n) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual uint ideal_reg() const { return Op_RegX; } aoqi@0: virtual const Type *bottom_type() const { return TypeX_X; } aoqi@0: // Return false to keep node from moving away from an associated card mark. aoqi@0: virtual bool depends_only_on_test() const { return false; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------ThreadLocalNode-------------------------------- aoqi@0: // Ideal Node which returns the base of ThreadLocalStorage. aoqi@0: class ThreadLocalNode : public Node { aoqi@0: public: aoqi@0: ThreadLocalNode( ) : Node((Node*)Compile::current()->root()) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM;} aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------LoadReturnPCNode------------------------------- aoqi@0: class LoadReturnPCNode: public Node { aoqi@0: public: aoqi@0: LoadReturnPCNode(Node *c) : Node(c) { } aoqi@0: virtual int Opcode() const; aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //-----------------------------RoundFloatNode---------------------------------- aoqi@0: class RoundFloatNode: public Node { aoqi@0: public: aoqi@0: RoundFloatNode(Node* c, Node *in1): Node(c, in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::FLOAT; } aoqi@0: virtual uint ideal_reg() const { return Op_RegF; } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //-----------------------------RoundDoubleNode--------------------------------- aoqi@0: class RoundDoubleNode: public Node { aoqi@0: public: aoqi@0: RoundDoubleNode(Node* c, Node *in1): Node(c, in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::DOUBLE; } aoqi@0: virtual uint ideal_reg() const { return Op_RegD; } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: virtual const Type *Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: //------------------------------Opaque1Node------------------------------------ aoqi@0: // A node to prevent unwanted optimizations. Allows constant folding. aoqi@0: // Stops value-numbering, Ideal calls or Identity functions. aoqi@0: class Opaque1Node : public Node { aoqi@0: virtual uint hash() const ; // { return NO_HASH; } aoqi@0: virtual uint cmp( const Node &n ) const; aoqi@0: public: aoqi@0: Opaque1Node( Compile* C, Node *n ) : Node(0,n) { aoqi@0: // Put it on the Macro nodes list to removed during macro nodes expansion. aoqi@0: init_flags(Flag_is_macro); aoqi@0: C->add_macro_node(this); aoqi@0: } aoqi@0: // Special version for the pre-loop to hold the original loop limit aoqi@0: // which is consumed by range check elimination. aoqi@0: Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) { aoqi@0: // Put it on the Macro nodes list to removed during macro nodes expansion. aoqi@0: init_flags(Flag_is_macro); aoqi@0: C->add_macro_node(this); aoqi@0: } aoqi@0: Node* original_loop_limit() { return req()==3 ? in(2) : NULL; } aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: virtual Node *Identity( PhaseTransform *phase ); aoqi@0: }; aoqi@0: aoqi@0: //------------------------------Opaque2Node------------------------------------ aoqi@0: // A node to prevent unwanted optimizations. Allows constant folding. Stops aoqi@0: // value-numbering, most Ideal calls or Identity functions. This Node is aoqi@0: // specifically designed to prevent the pre-increment value of a loop trip aoqi@0: // counter from being live out of the bottom of the loop (hence causing the aoqi@0: // pre- and post-increment values both being live and thus requiring an extra aoqi@0: // temp register and an extra move). If we "accidentally" optimize through aoqi@0: // this kind of a Node, we'll get slightly pessimal, but correct, code. Thus aoqi@0: // it's OK to be slightly sloppy on optimizations here. aoqi@0: class Opaque2Node : public Node { aoqi@0: virtual uint hash() const ; // { return NO_HASH; } aoqi@0: virtual uint cmp( const Node &n ) const; aoqi@0: public: aoqi@0: Opaque2Node( Compile* C, Node *n ) : Node(0,n) { aoqi@0: // Put it on the Macro nodes list to removed during macro nodes expansion. aoqi@0: init_flags(Flag_is_macro); aoqi@0: C->add_macro_node(this); aoqi@0: } aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: }; aoqi@0: aoqi@0: //------------------------------Opaque3Node------------------------------------ aoqi@0: // A node to prevent unwanted optimizations. Will be optimized only during aoqi@0: // macro nodes expansion. aoqi@0: class Opaque3Node : public Opaque2Node { aoqi@0: int _opt; // what optimization it was used for aoqi@0: public: aoqi@0: enum { RTM_OPT }; aoqi@0: Opaque3Node(Compile* C, Node *n, int opt) : Opaque2Node(C, n), _opt(opt) {} aoqi@0: virtual int Opcode() const; aoqi@0: bool rtm_opt() const { return (_opt == RTM_OPT); } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: //----------------------PartialSubtypeCheckNode-------------------------------- aoqi@0: // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass aoqi@0: // array for an instance of the superklass. Set a hidden internal cache on a aoqi@0: // hit (cache is checked with exposed code in gen_subtype_check()). Return aoqi@0: // not zero for a miss or zero for a hit. aoqi@0: class PartialSubtypeCheckNode : public Node { aoqi@0: public: aoqi@0: PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } aoqi@0: virtual uint ideal_reg() const { return Op_RegP; } aoqi@0: }; aoqi@0: aoqi@0: // aoqi@0: class MoveI2FNode : public Node { aoqi@0: public: aoqi@0: MoveI2FNode( Node *value ) : Node(0,value) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::FLOAT; } aoqi@0: virtual uint ideal_reg() const { return Op_RegF; } aoqi@0: virtual const Type* Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: class MoveL2DNode : public Node { aoqi@0: public: aoqi@0: MoveL2DNode( Node *value ) : Node(0,value) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return Type::DOUBLE; } aoqi@0: virtual uint ideal_reg() const { return Op_RegD; } aoqi@0: virtual const Type* Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: class MoveF2INode : public Node { aoqi@0: public: aoqi@0: MoveF2INode( Node *value ) : Node(0,value) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeInt::INT; } aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: virtual const Type* Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: class MoveD2LNode : public Node { aoqi@0: public: aoqi@0: MoveD2LNode( Node *value ) : Node(0,value) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type *bottom_type() const { return TypeLong::LONG; } aoqi@0: virtual uint ideal_reg() const { return Op_RegL; } aoqi@0: virtual const Type* Value( PhaseTransform *phase ) const; aoqi@0: }; aoqi@0: aoqi@0: //---------- CountBitsNode ----------------------------------------------------- aoqi@0: class CountBitsNode : public Node { aoqi@0: public: aoqi@0: CountBitsNode(Node* in1) : Node(0, in1) {} aoqi@0: const Type* bottom_type() const { return TypeInt::INT; } aoqi@0: virtual uint ideal_reg() const { return Op_RegI; } aoqi@0: }; aoqi@0: aoqi@0: //---------- CountLeadingZerosINode -------------------------------------------- aoqi@0: // Count leading zeros (0-bit count starting from MSB) of an integer. aoqi@0: class CountLeadingZerosINode : public CountBitsNode { aoqi@0: public: aoqi@0: CountLeadingZerosINode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type* Value(PhaseTransform* phase) const; aoqi@0: }; aoqi@0: aoqi@0: //---------- CountLeadingZerosLNode -------------------------------------------- aoqi@0: // Count leading zeros (0-bit count starting from MSB) of a long. aoqi@0: class CountLeadingZerosLNode : public CountBitsNode { aoqi@0: public: aoqi@0: CountLeadingZerosLNode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type* Value(PhaseTransform* phase) const; aoqi@0: }; aoqi@0: aoqi@0: //---------- CountTrailingZerosINode ------------------------------------------- aoqi@0: // Count trailing zeros (0-bit count starting from LSB) of an integer. aoqi@0: class CountTrailingZerosINode : public CountBitsNode { aoqi@0: public: aoqi@0: CountTrailingZerosINode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type* Value(PhaseTransform* phase) const; aoqi@0: }; aoqi@0: aoqi@0: //---------- CountTrailingZerosLNode ------------------------------------------- aoqi@0: // Count trailing zeros (0-bit count starting from LSB) of a long. aoqi@0: class CountTrailingZerosLNode : public CountBitsNode { aoqi@0: public: aoqi@0: CountTrailingZerosLNode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: virtual const Type* Value(PhaseTransform* phase) const; aoqi@0: }; aoqi@0: aoqi@0: //---------- PopCountINode ----------------------------------------------------- aoqi@0: // Population count (bit count) of an integer. aoqi@0: class PopCountINode : public CountBitsNode { aoqi@0: public: aoqi@0: PopCountINode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: //---------- PopCountLNode ----------------------------------------------------- aoqi@0: // Population count (bit count) of a long. aoqi@0: class PopCountLNode : public CountBitsNode { aoqi@0: public: aoqi@0: PopCountLNode(Node* in1) : CountBitsNode(in1) {} aoqi@0: virtual int Opcode() const; aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_OPTO_CONNODE_HPP