duke@435: /* duke@435: * Copyright 1997-2006 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: // Portions of code courtesy of Clifford Click duke@435: duke@435: class PhaseTransform; duke@435: duke@435: //------------------------------AddNode---------------------------------------- duke@435: // Classic Add functionality. This covers all the usual 'add' behaviors for duke@435: // an algebraic ring. Add-integer, add-float, add-double, and binary-or are duke@435: // all inherited from this class. The various identity values are supplied duke@435: // by virtual functions. duke@435: class AddNode : public Node { duke@435: virtual uint hash() const; duke@435: public: duke@435: AddNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { duke@435: init_class_id(Class_Add); duke@435: } duke@435: duke@435: // Handle algebraic identities here. If we have an identity, return the Node duke@435: // we are equivalent to. We look for "add of zero" as an identity. duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: duke@435: // We also canonicalize the Node, moving constants to the right input, duke@435: // and flatten expressions (so that 1+x+2 becomes x+3). duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: duke@435: // Compute a new Type for this node. Basically we just do the pre-check, duke@435: // then call the virtual add() to set the type. duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: duke@435: // Check if this addition involves the additive identity duke@435: virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; duke@435: duke@435: // Supplied function returns the sum of the inputs. duke@435: // This also type-checks the inputs for sanity. Guaranteed never to duke@435: // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. duke@435: virtual const Type *add_ring( const Type *, const Type * ) const = 0; duke@435: duke@435: // Supplied function to return the additive identity type duke@435: virtual const Type *add_id() const = 0; duke@435: duke@435: }; duke@435: duke@435: //------------------------------AddINode--------------------------------------- duke@435: // Add 2 integers duke@435: class AddINode : public AddNode { duke@435: public: duke@435: AddINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeInt::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } 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_RegI; } duke@435: }; duke@435: duke@435: //------------------------------AddLNode--------------------------------------- duke@435: // Add 2 longs duke@435: class AddLNode : public AddNode { duke@435: public: duke@435: AddLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeLong::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } 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_RegL; } duke@435: }; duke@435: duke@435: //------------------------------AddFNode--------------------------------------- duke@435: // Add 2 floats duke@435: class AddFNode : public AddNode { duke@435: public: duke@435: AddFNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeF::ZERO; } duke@435: virtual const Type *bottom_type() const { return Type::FLOAT; } duke@435: virtual Node *Identity( PhaseTransform *phase ) { return this; } duke@435: virtual uint ideal_reg() const { return Op_RegF; } duke@435: }; duke@435: duke@435: //------------------------------AddDNode--------------------------------------- duke@435: // Add 2 doubles duke@435: class AddDNode : public AddNode { duke@435: public: duke@435: AddDNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeD::ZERO; } duke@435: virtual const Type *bottom_type() const { return Type::DOUBLE; } duke@435: virtual Node *Identity( PhaseTransform *phase ) { return this; } duke@435: virtual uint ideal_reg() const { return Op_RegD; } duke@435: }; duke@435: duke@435: //------------------------------AddPNode--------------------------------------- duke@435: // Add pointer plus integer to get pointer. NOT commutative, really. duke@435: // So not really an AddNode. Lives here, because people associate it with duke@435: // an add. duke@435: class AddPNode : public Node { duke@435: public: duke@435: enum { Control, // When is it safe to do this add? duke@435: Base, // Base oop, for GC purposes duke@435: Address, // Actually address, derived from base duke@435: Offset } ; // Offset added to address duke@435: AddPNode( Node *base, Node *ptr, Node *off ) : Node(0,base,ptr,off) { duke@435: init_class_id(Class_AddP); duke@435: } duke@435: virtual int Opcode() const; duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: virtual const Type *Value( PhaseTransform *phase ) const; duke@435: virtual const Type *bottom_type() const; duke@435: virtual uint ideal_reg() const { return Op_RegP; } duke@435: Node *base_node() { assert( req() > Base, "Missing base"); return in(Base); } duke@435: static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase, duke@435: // second return value: duke@435: intptr_t& offset); never@452: never@452: // Collect the AddP offset values into the elements array, giving up never@452: // if there are more than length. never@452: int unpack_offsets(Node* elements[], int length); never@452: duke@435: // Do not match base-ptr edge duke@435: virtual uint match_edge(uint idx) const; duke@435: static const Type *mach_bottom_type(const MachNode* n); // used by ad_.hpp duke@435: }; duke@435: duke@435: //------------------------------OrINode---------------------------------------- duke@435: // Logically OR 2 integers. Included with the ADD nodes because it inherits duke@435: // all the behavior of addition on a ring. duke@435: class OrINode : public AddNode { duke@435: public: duke@435: OrINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeInt::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------OrLNode---------------------------------------- duke@435: // Logically OR 2 longs. Included with the ADD nodes because it inherits duke@435: // all the behavior of addition on a ring. duke@435: class OrLNode : public AddNode { duke@435: public: duke@435: OrLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeLong::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual Node *Identity( PhaseTransform *phase ); duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------XorINode--------------------------------------- duke@435: // XOR'ing 2 integers duke@435: class XorINode : public AddNode { duke@435: public: duke@435: XorINode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeInt::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------XorINode--------------------------------------- duke@435: // XOR'ing 2 longs duke@435: class XorLNode : public AddNode { duke@435: public: duke@435: XorLNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeLong::ZERO; } duke@435: virtual const Type *bottom_type() const { return TypeLong::LONG; } duke@435: virtual uint ideal_reg() const { return Op_RegL; } duke@435: }; duke@435: duke@435: //------------------------------MaxNode---------------------------------------- duke@435: // Max (or min) of 2 values. Included with the ADD nodes because it inherits duke@435: // all the behavior of addition on a ring. Only new thing is that we allow duke@435: // 2 equal inputs to be equal. duke@435: class MaxNode : public AddNode { duke@435: public: duke@435: MaxNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {} duke@435: virtual int Opcode() const = 0; duke@435: }; duke@435: duke@435: //------------------------------MaxINode--------------------------------------- duke@435: // Maximum of 2 integers. Included with the ADD nodes because it inherits duke@435: // all the behavior of addition on a ring. duke@435: class MaxINode : public MaxNode { duke@435: public: duke@435: MaxINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeInt::make(min_jint); } duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: }; duke@435: duke@435: //------------------------------MinINode--------------------------------------- duke@435: // MINimum of 2 integers. Included with the ADD nodes because it inherits duke@435: // all the behavior of addition on a ring. duke@435: class MinINode : public MaxNode { duke@435: public: duke@435: MinINode( Node *in1, Node *in2 ) : MaxNode(in1,in2) {} duke@435: virtual int Opcode() const; duke@435: virtual const Type *add_ring( const Type *, const Type * ) const; duke@435: virtual const Type *add_id() const { return TypeInt::make(max_jint); } duke@435: virtual const Type *bottom_type() const { return TypeInt::INT; } duke@435: virtual uint ideal_reg() const { return Op_RegI; } duke@435: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); duke@435: };