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: // Portions of code courtesy of Clifford Click duke@435: duke@435: // Optimization - Graph Style duke@435: duke@435: duke@435: // This class defines a Type lattice. The lattice is used in the constant duke@435: // propagation algorithms, and for some type-checking of the iloc code. duke@435: // Basic types include RSD's (lower bound, upper bound, stride for integers), duke@435: // float & double precision constants, sets of data-labels and code-labels. duke@435: // The complete lattice is described below. Subtypes have no relationship to duke@435: // up or down in the lattice; that is entirely determined by the behavior of duke@435: // the MEET/JOIN functions. duke@435: duke@435: class Dict; duke@435: class Type; duke@435: class TypeD; duke@435: class TypeF; duke@435: class TypeInt; duke@435: class TypeLong; duke@435: class TypeAry; duke@435: class TypeTuple; duke@435: class TypePtr; duke@435: class TypeRawPtr; duke@435: class TypeOopPtr; duke@435: class TypeInstPtr; duke@435: class TypeAryPtr; duke@435: class TypeKlassPtr; duke@435: duke@435: //------------------------------Type------------------------------------------- duke@435: // Basic Type object, represents a set of primitive Values. duke@435: // Types are hash-cons'd into a private class dictionary, so only one of each duke@435: // different kind of Type exists. Types are never modified after creation, so duke@435: // all their interesting fields are constant. duke@435: class Type { duke@435: public: duke@435: enum TYPES { duke@435: Bad=0, // Type check duke@435: Control, // Control of code (not in lattice) duke@435: Top, // Top of the lattice duke@435: Int, // Integer range (lo-hi) duke@435: Long, // Long integer range (lo-hi) duke@435: Half, // Placeholder half of doubleword duke@435: duke@435: Tuple, // Method signature or object layout duke@435: Array, // Array types duke@435: duke@435: AnyPtr, // Any old raw, klass, inst, or array pointer duke@435: RawPtr, // Raw (non-oop) pointers duke@435: OopPtr, // Any and all Java heap entities duke@435: InstPtr, // Instance pointers (non-array objects) duke@435: AryPtr, // Array pointers duke@435: KlassPtr, // Klass pointers duke@435: // (Ptr order matters: See is_ptr, isa_ptr, is_oopptr, isa_oopptr.) duke@435: duke@435: Function, // Function signature duke@435: Abio, // Abstract I/O duke@435: Return_Address, // Subroutine return address duke@435: Memory, // Abstract store duke@435: FloatTop, // No float value duke@435: FloatCon, // Floating point constant duke@435: FloatBot, // Any float value duke@435: DoubleTop, // No double value duke@435: DoubleCon, // Double precision constant duke@435: DoubleBot, // Any double value duke@435: Bottom, // Bottom of lattice duke@435: lastype // Bogus ending type (not in lattice) duke@435: }; duke@435: duke@435: // Signal values for offsets from a base pointer duke@435: enum OFFSET_SIGNALS { duke@435: OffsetTop = -2000000000, // undefined offset duke@435: OffsetBot = -2000000001 // any possible offset duke@435: }; duke@435: duke@435: // Min and max WIDEN values. duke@435: enum WIDEN { duke@435: WidenMin = 0, duke@435: WidenMax = 3 duke@435: }; duke@435: duke@435: private: duke@435: // Dictionary of types shared among compilations. duke@435: static Dict* _shared_type_dict; duke@435: duke@435: static int uhash( const Type *const t ); duke@435: // Structural equality check. Assumes that cmp() has already compared duke@435: // the _base types and thus knows it can cast 't' appropriately. duke@435: virtual bool eq( const Type *t ) const; duke@435: duke@435: // Top-level hash-table of types duke@435: static Dict *type_dict() { duke@435: return Compile::current()->type_dict(); duke@435: } duke@435: duke@435: // DUAL operation: reflect around lattice centerline. Used instead of duke@435: // join to ensure my lattice is symmetric up and down. Dual is computed duke@435: // lazily, on demand, and cached in _dual. duke@435: const Type *_dual; // Cached dual value duke@435: // Table for efficient dualing of base types duke@435: static const TYPES dual_type[lastype]; duke@435: duke@435: protected: duke@435: // Each class of type is also identified by its base. duke@435: const TYPES _base; // Enum of Types type duke@435: duke@435: Type( TYPES t ) : _dual(NULL), _base(t) {} // Simple types duke@435: // ~Type(); // Use fast deallocation duke@435: const Type *hashcons(); // Hash-cons the type duke@435: duke@435: public: duke@435: duke@435: inline void* operator new( size_t x ) { duke@435: Compile* compile = Compile::current(); duke@435: compile->set_type_last_size(x); duke@435: void *temp = compile->type_arena()->Amalloc_D(x); duke@435: compile->set_type_hwm(temp); duke@435: return temp; duke@435: } duke@435: inline void operator delete( void* ptr ) { duke@435: Compile* compile = Compile::current(); duke@435: compile->type_arena()->Afree(ptr,compile->type_last_size()); duke@435: } duke@435: duke@435: // Initialize the type system for a particular compilation. duke@435: static void Initialize(Compile* compile); duke@435: duke@435: // Initialize the types shared by all compilations. duke@435: static void Initialize_shared(Compile* compile); duke@435: duke@435: TYPES base() const { duke@435: assert(_base > Bad && _base < lastype, "sanity"); duke@435: return _base; duke@435: } duke@435: duke@435: // Create a new hash-consd type duke@435: static const Type *make(enum TYPES); duke@435: // Test for equivalence of types duke@435: static int cmp( const Type *const t1, const Type *const t2 ); duke@435: // Test for higher or equal in lattice duke@435: int higher_equal( const Type *t ) const { return !cmp(meet(t),t); } duke@435: duke@435: // MEET operation; lower in lattice. duke@435: const Type *meet( const Type *t ) const; duke@435: // WIDEN: 'widens' for Ints and other range types duke@435: virtual const Type *widen( const Type *old ) const { return this; } duke@435: // NARROW: complement for widen, used by pessimistic phases duke@435: virtual const Type *narrow( const Type *old ) const { return this; } duke@435: duke@435: // DUAL operation: reflect around lattice centerline. Used instead of duke@435: // join to ensure my lattice is symmetric up and down. duke@435: const Type *dual() const { return _dual; } duke@435: duke@435: // Compute meet dependent on base type duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // JOIN operation; higher in lattice. Done by finding the dual of the duke@435: // meet of the dual of the 2 inputs. duke@435: const Type *join( const Type *t ) const { duke@435: return dual()->meet(t->dual())->dual(); } duke@435: duke@435: // Modified version of JOIN adapted to the needs Node::Value. duke@435: // Normalizes all empty values to TOP. Does not kill _widen bits. duke@435: // Currently, it also works around limitations involving interface types. duke@435: virtual const Type *filter( const Type *kills ) const; duke@435: duke@435: // Convenience access duke@435: float getf() const; duke@435: double getd() const; duke@435: duke@435: const TypeInt *is_int() const; duke@435: const TypeInt *isa_int() const; // Returns NULL if not an Int duke@435: const TypeLong *is_long() const; duke@435: const TypeLong *isa_long() const; // Returns NULL if not a Long duke@435: const TypeD *is_double_constant() const; // Asserts it is a DoubleCon duke@435: const TypeD *isa_double_constant() const; // Returns NULL if not a DoubleCon duke@435: const TypeF *is_float_constant() const; // Asserts it is a FloatCon duke@435: const TypeF *isa_float_constant() const; // Returns NULL if not a FloatCon duke@435: const TypeTuple *is_tuple() const; // Collection of fields, NOT a pointer duke@435: const TypeAry *is_ary() const; // Array, NOT array pointer duke@435: const TypePtr *is_ptr() const; // Asserts it is a ptr type duke@435: const TypePtr *isa_ptr() const; // Returns NULL if not ptr type duke@435: const TypeRawPtr *is_rawptr() const; // NOT Java oop duke@435: const TypeOopPtr *isa_oopptr() const; // Returns NULL if not ptr type duke@435: const TypeKlassPtr *isa_klassptr() const; // Returns NULL if not KlassPtr duke@435: const TypeKlassPtr *is_klassptr() const; // assert if not KlassPtr duke@435: const TypeOopPtr *is_oopptr() const; // Java-style GC'd pointer duke@435: const TypeInstPtr *isa_instptr() const; // Returns NULL if not InstPtr duke@435: const TypeInstPtr *is_instptr() const; // Instance duke@435: const TypeAryPtr *isa_aryptr() const; // Returns NULL if not AryPtr duke@435: const TypeAryPtr *is_aryptr() const; // Array oop duke@435: virtual bool is_finite() const; // Has a finite value duke@435: virtual bool is_nan() const; // Is not a number (NaN) duke@435: duke@435: // Special test for register pressure heuristic duke@435: bool is_floatingpoint() const; // True if Float or Double base type duke@435: duke@435: // Do you have memory, directly or through a tuple? duke@435: bool has_memory( ) const; duke@435: duke@435: // Are you a pointer type or not? duke@435: bool isa_oop_ptr() const; duke@435: duke@435: // TRUE if type is a singleton duke@435: virtual bool singleton(void) const; duke@435: duke@435: // TRUE if type is above the lattice centerline, and is therefore vacuous duke@435: virtual bool empty(void) const; duke@435: duke@435: // Return a hash for this type. The hash function is public so ConNode duke@435: // (constants) can hash on their constant, which is represented by a Type. duke@435: virtual int hash() const; duke@435: duke@435: // Map ideal registers (machine types) to ideal types duke@435: static const Type *mreg2type[]; duke@435: duke@435: // Printing, statistics duke@435: static const char * const msg[lastype]; // Printable strings duke@435: #ifndef PRODUCT duke@435: void dump_on(outputStream *st) const; duke@435: void dump() const { duke@435: dump_on(tty); duke@435: } duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: static void dump_stats(); duke@435: static void verify_lastype(); // Check that arrays match type enum duke@435: #endif duke@435: void typerr(const Type *t) const; // Mixing types error duke@435: duke@435: // Create basic type duke@435: static const Type* get_const_basic_type(BasicType type) { duke@435: assert((uint)type <= T_CONFLICT && _const_basic_type[type] != NULL, "bad type"); duke@435: return _const_basic_type[type]; duke@435: } duke@435: duke@435: // Mapping to the array element's basic type. duke@435: BasicType array_element_basic_type() const; duke@435: duke@435: // Create standard type for a ciType: duke@435: static const Type* get_const_type(ciType* type); duke@435: duke@435: // Create standard zero value: duke@435: static const Type* get_zero_type(BasicType type) { duke@435: assert((uint)type <= T_CONFLICT && _zero_type[type] != NULL, "bad type"); duke@435: return _zero_type[type]; duke@435: } duke@435: duke@435: // Report if this is a zero value (not top). duke@435: bool is_zero_type() const { duke@435: BasicType type = basic_type(); duke@435: if (type == T_VOID || type >= T_CONFLICT) duke@435: return false; duke@435: else duke@435: return (this == _zero_type[type]); duke@435: } duke@435: duke@435: // Convenience common pre-built types. duke@435: static const Type *ABIO; duke@435: static const Type *BOTTOM; duke@435: static const Type *CONTROL; duke@435: static const Type *DOUBLE; duke@435: static const Type *FLOAT; duke@435: static const Type *HALF; duke@435: static const Type *MEMORY; duke@435: static const Type *MULTI; duke@435: static const Type *RETURN_ADDRESS; duke@435: static const Type *TOP; duke@435: duke@435: // Mapping from compiler type to VM BasicType duke@435: BasicType basic_type() const { return _basic_type[_base]; } duke@435: duke@435: // Mapping from CI type system to compiler type: duke@435: static const Type* get_typeflow_type(ciType* type); duke@435: duke@435: private: duke@435: // support arrays duke@435: static const BasicType _basic_type[]; duke@435: static const Type* _zero_type[T_CONFLICT+1]; duke@435: static const Type* _const_basic_type[T_CONFLICT+1]; duke@435: }; duke@435: duke@435: //------------------------------TypeF------------------------------------------ duke@435: // Class of Float-Constant Types. duke@435: class TypeF : public Type { duke@435: TypeF( float f ) : Type(FloatCon), _f(f) {}; duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: public: duke@435: const float _f; // Float constant duke@435: duke@435: static const TypeF *make(float f); duke@435: duke@435: virtual bool is_finite() const; // Has a finite value duke@435: virtual bool is_nan() const; // Is not a number (NaN) duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: // Convenience common pre-built types. duke@435: static const TypeF *ZERO; // positive zero only duke@435: static const TypeF *ONE; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeD------------------------------------------ duke@435: // Class of Double-Constant Types. duke@435: class TypeD : public Type { duke@435: TypeD( double d ) : Type(DoubleCon), _d(d) {}; duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: public: duke@435: const double _d; // Double constant duke@435: duke@435: static const TypeD *make(double d); duke@435: duke@435: virtual bool is_finite() const; // Has a finite value duke@435: virtual bool is_nan() const; // Is not a number (NaN) duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: // Convenience common pre-built types. duke@435: static const TypeD *ZERO; // positive zero only duke@435: static const TypeD *ONE; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeInt---------------------------------------- duke@435: // Class of integer ranges, the set of integers between a lower bound and an duke@435: // upper bound, inclusive. duke@435: class TypeInt : public Type { duke@435: TypeInt( jint lo, jint hi, int w ); duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: public: duke@435: const jint _lo, _hi; // Lower bound, upper bound duke@435: const short _widen; // Limit on times we widen this sucker duke@435: duke@435: static const TypeInt *make(jint lo); duke@435: // must always specify w duke@435: static const TypeInt *make(jint lo, jint hi, int w); duke@435: duke@435: // Check for single integer duke@435: int is_con() const { return _lo==_hi; } duke@435: bool is_con(int i) const { return is_con() && _lo == i; } duke@435: jint get_con() const { assert( is_con(), "" ); return _lo; } duke@435: duke@435: virtual bool is_finite() const; // Has a finite value duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: virtual const Type *widen( const Type *t ) const; duke@435: virtual const Type *narrow( const Type *t ) const; duke@435: // Do not kill _widen bits. duke@435: virtual const Type *filter( const Type *kills ) const; duke@435: // Convenience common pre-built types. duke@435: static const TypeInt *MINUS_1; duke@435: static const TypeInt *ZERO; duke@435: static const TypeInt *ONE; duke@435: static const TypeInt *BOOL; duke@435: static const TypeInt *CC; duke@435: static const TypeInt *CC_LT; // [-1] == MINUS_1 duke@435: static const TypeInt *CC_GT; // [1] == ONE duke@435: static const TypeInt *CC_EQ; // [0] == ZERO duke@435: static const TypeInt *CC_LE; // [-1,0] duke@435: static const TypeInt *CC_GE; // [0,1] == BOOL (!) duke@435: static const TypeInt *BYTE; duke@435: static const TypeInt *CHAR; duke@435: static const TypeInt *SHORT; duke@435: static const TypeInt *POS; duke@435: static const TypeInt *POS1; duke@435: static const TypeInt *INT; duke@435: static const TypeInt *SYMINT; // symmetric range [-max_jint..max_jint] duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: duke@435: //------------------------------TypeLong--------------------------------------- duke@435: // Class of long integer ranges, the set of integers between a lower bound and duke@435: // an upper bound, inclusive. duke@435: class TypeLong : public Type { duke@435: TypeLong( jlong lo, jlong hi, int w ); duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: public: duke@435: const jlong _lo, _hi; // Lower bound, upper bound duke@435: const short _widen; // Limit on times we widen this sucker duke@435: duke@435: static const TypeLong *make(jlong lo); duke@435: // must always specify w duke@435: static const TypeLong *make(jlong lo, jlong hi, int w); duke@435: duke@435: // Check for single integer duke@435: int is_con() const { return _lo==_hi; } duke@435: jlong get_con() const { assert( is_con(), "" ); return _lo; } duke@435: duke@435: virtual bool is_finite() const; // Has a finite value duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: virtual const Type *widen( const Type *t ) const; duke@435: virtual const Type *narrow( const Type *t ) const; duke@435: // Do not kill _widen bits. duke@435: virtual const Type *filter( const Type *kills ) const; duke@435: // Convenience common pre-built types. duke@435: static const TypeLong *MINUS_1; duke@435: static const TypeLong *ZERO; duke@435: static const TypeLong *ONE; duke@435: static const TypeLong *POS; duke@435: static const TypeLong *LONG; duke@435: static const TypeLong *INT; // 32-bit subrange [min_jint..max_jint] duke@435: static const TypeLong *UINT; // 32-bit unsigned [0..max_juint] duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint, outputStream *st ) const;// Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeTuple-------------------------------------- duke@435: // Class of Tuple Types, essentially type collections for function signatures duke@435: // and class layouts. It happens to also be a fast cache for the HotSpot duke@435: // signature types. duke@435: class TypeTuple : public Type { duke@435: TypeTuple( uint cnt, const Type **fields ) : Type(Tuple), _cnt(cnt), _fields(fields) { } duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: duke@435: public: duke@435: const uint _cnt; // Count of fields duke@435: const Type ** const _fields; // Array of field types duke@435: duke@435: // Accessors: duke@435: uint cnt() const { return _cnt; } duke@435: const Type* field_at(uint i) const { duke@435: assert(i < _cnt, "oob"); duke@435: return _fields[i]; duke@435: } duke@435: void set_field_at(uint i, const Type* t) { duke@435: assert(i < _cnt, "oob"); duke@435: _fields[i] = t; duke@435: } duke@435: duke@435: static const TypeTuple *make( uint cnt, const Type **fields ); duke@435: static const TypeTuple *make_range(ciSignature *sig); duke@435: static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig); duke@435: duke@435: // Subroutine call type with space allocated for argument types duke@435: static const Type **fields( uint arg_cnt ); duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: // Convenience common pre-built types. duke@435: static const TypeTuple *IFBOTH; duke@435: static const TypeTuple *IFFALSE; duke@435: static const TypeTuple *IFTRUE; duke@435: static const TypeTuple *IFNEITHER; duke@435: static const TypeTuple *LOOPBODY; duke@435: static const TypeTuple *MEMBAR; duke@435: static const TypeTuple *STORECONDITIONAL; duke@435: static const TypeTuple *START_I2C; duke@435: static const TypeTuple *INT_PAIR; duke@435: static const TypeTuple *LONG_PAIR; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeAry---------------------------------------- duke@435: // Class of Array Types duke@435: class TypeAry : public Type { duke@435: TypeAry( const Type *elem, const TypeInt *size) : Type(Array), duke@435: _elem(elem), _size(size) {} duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: duke@435: private: duke@435: const Type *_elem; // Element type of array duke@435: const TypeInt *_size; // Elements in array duke@435: friend class TypeAryPtr; duke@435: duke@435: public: duke@435: static const TypeAry *make( const Type *elem, const TypeInt *size); duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: bool ary_must_be_exact() const; // true if arrays of such are never generic duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypePtr---------------------------------------- duke@435: // Class of machine Pointer Types: raw data, instances or arrays. duke@435: // If the _base enum is AnyPtr, then this refers to all of the above. duke@435: // Otherwise the _base will indicate which subset of pointers is affected, duke@435: // and the class will be inherited from. duke@435: class TypePtr : public Type { duke@435: public: duke@435: enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR }; duke@435: protected: duke@435: TypePtr( TYPES t, PTR ptr, int offset ) : Type(t), _ptr(ptr), _offset(offset) {} duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: static const PTR ptr_meet[lastPTR][lastPTR]; duke@435: static const PTR ptr_dual[lastPTR]; duke@435: static const char * const ptr_msg[lastPTR]; duke@435: duke@435: public: duke@435: const int _offset; // Offset into oop, with TOP & BOT duke@435: const PTR _ptr; // Pointer equivalence class duke@435: duke@435: const int offset() const { return _offset; } duke@435: const PTR ptr() const { return _ptr; } duke@435: duke@435: static const TypePtr *make( TYPES t, PTR ptr, int offset ); duke@435: duke@435: // Return a 'ptr' version of this type duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual intptr_t get_con() const; duke@435: duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: int meet_offset( int offset ) const; duke@435: int dual_offset( ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // meet, dual and join over pointer equivalence sets duke@435: PTR meet_ptr( const PTR in_ptr ) const { return ptr_meet[in_ptr][ptr()]; } duke@435: PTR dual_ptr() const { return ptr_dual[ptr()]; } duke@435: duke@435: // This is textually confusing unless one recalls that duke@435: // join(t) == dual()->meet(t->dual())->dual(). duke@435: PTR join_ptr( const PTR in_ptr ) const { duke@435: return ptr_dual[ ptr_meet[ ptr_dual[in_ptr] ] [ dual_ptr() ] ]; duke@435: } duke@435: duke@435: // Tests for relation to centerline of type lattice: duke@435: static bool above_centerline(PTR ptr) { return (ptr <= AnyNull); } duke@435: static bool below_centerline(PTR ptr) { return (ptr >= NotNull); } duke@435: // Convenience common pre-built types. duke@435: static const TypePtr *NULL_PTR; duke@435: static const TypePtr *NOTNULL; duke@435: static const TypePtr *BOTTOM; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeRawPtr------------------------------------- duke@435: // Class of raw pointers, pointers to things other than Oops. Examples duke@435: // include the stack pointer, top of heap, card-marking area, handles, etc. duke@435: class TypeRawPtr : public TypePtr { duke@435: protected: duke@435: TypeRawPtr( PTR ptr, address bits ) : TypePtr(RawPtr,ptr,0), _bits(bits){} duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: duke@435: const address _bits; // Constant value, if applicable duke@435: duke@435: static const TypeRawPtr *make( PTR ptr ); duke@435: static const TypeRawPtr *make( address bits ); duke@435: duke@435: // Return a 'ptr' version of this type duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual intptr_t get_con() const; duke@435: duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: // Convenience common pre-built types. duke@435: static const TypeRawPtr *BOTTOM; duke@435: static const TypeRawPtr *NOTNULL; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeOopPtr------------------------------------- duke@435: // Some kind of oop (Java pointer), either klass or instance or array. duke@435: class TypeOopPtr : public TypePtr { duke@435: protected: duke@435: TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id ) : TypePtr(t, ptr, offset), _const_oop(o), _klass(k), _klass_is_exact(xk), _instance_id(instance_id) { } duke@435: public: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: enum { duke@435: UNKNOWN_INSTANCE = 0 duke@435: }; duke@435: protected: duke@435: duke@435: int xadd_offset( int offset ) const; duke@435: // Oop is NULL, unless this is a constant oop. duke@435: ciObject* _const_oop; // Constant oop duke@435: // If _klass is NULL, then so is _sig. This is an unloaded klass. duke@435: ciKlass* _klass; // Klass object duke@435: // Does the type exclude subclasses of the klass? (Inexact == polymorphic.) duke@435: bool _klass_is_exact; duke@435: duke@435: int _instance_id; // if not UNKNOWN_INSTANCE, indicates that this is a particular instance duke@435: // of this type which is distinct. This is the the node index of the duke@435: // node creating this instance duke@435: duke@435: static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact); duke@435: duke@435: int dual_instance() const { return -_instance_id; } duke@435: int meet_instance(int uid) const; duke@435: duke@435: public: duke@435: // Creates a type given a klass. Correctly handles multi-dimensional arrays duke@435: // Respects UseUniqueSubclasses. duke@435: // If the klass is final, the resulting type will be exact. duke@435: static const TypeOopPtr* make_from_klass(ciKlass* klass) { duke@435: return make_from_klass_common(klass, true, false); duke@435: } duke@435: // Same as before, but will produce an exact type, even if duke@435: // the klass is not final, as long as it has exactly one implementation. duke@435: static const TypeOopPtr* make_from_klass_unique(ciKlass* klass) { duke@435: return make_from_klass_common(klass, true, true); duke@435: } duke@435: // Same as before, but does not respects UseUniqueSubclasses. duke@435: // Use this only for creating array element types. duke@435: static const TypeOopPtr* make_from_klass_raw(ciKlass* klass) { duke@435: return make_from_klass_common(klass, false, false); duke@435: } duke@435: // Creates a singleton type given an object. duke@435: static const TypeOopPtr* make_from_constant(ciObject* o); duke@435: duke@435: // Make a generic (unclassed) pointer to an oop. duke@435: static const TypeOopPtr* make(PTR ptr, int offset); duke@435: duke@435: ciObject* const_oop() const { return _const_oop; } duke@435: virtual ciKlass* klass() const { return _klass; } duke@435: bool klass_is_exact() const { return _klass_is_exact; } duke@435: bool is_instance() const { return _instance_id != UNKNOWN_INSTANCE; } duke@435: uint instance_id() const { return _instance_id; } kvn@499: bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; } duke@435: duke@435: virtual intptr_t get_con() const; duke@435: duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual const Type *cast_to_exactness(bool klass_is_exact) const; duke@435: duke@435: virtual const TypeOopPtr *cast_to_instance(int instance_id) const; duke@435: duke@435: // corresponding pointer to klass, for a given instance duke@435: const TypeKlassPtr* as_klass_type() const; duke@435: duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // Do not allow interface-vs.-noninterface joins to collapse to top. duke@435: virtual const Type *filter( const Type *kills ) const; duke@435: duke@435: // Convenience common pre-built type. duke@435: static const TypeOopPtr *BOTTOM; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeInstPtr------------------------------------ duke@435: // Class of Java object pointers, pointing either to non-array Java instances duke@435: // or to a klassOop (including array klasses). duke@435: class TypeInstPtr : public TypeOopPtr { duke@435: TypeInstPtr( PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id ); duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: duke@435: ciSymbol* _name; // class name duke@435: duke@435: public: duke@435: ciSymbol* name() const { return _name; } duke@435: duke@435: bool is_loaded() const { return _klass->is_loaded(); } duke@435: duke@435: // Make a pointer to a constant oop. duke@435: static const TypeInstPtr *make(ciObject* o) { duke@435: return make(TypePtr::Constant, o->klass(), true, o, 0); duke@435: } duke@435: duke@435: // Make a pointer to a constant oop with offset. duke@435: static const TypeInstPtr *make(ciObject* o, int offset) { duke@435: return make(TypePtr::Constant, o->klass(), true, o, offset); duke@435: } duke@435: duke@435: // Make a pointer to some value of type klass. duke@435: static const TypeInstPtr *make(PTR ptr, ciKlass* klass) { duke@435: return make(ptr, klass, false, NULL, 0); duke@435: } duke@435: duke@435: // Make a pointer to some non-polymorphic value of exactly type klass. duke@435: static const TypeInstPtr *make_exact(PTR ptr, ciKlass* klass) { duke@435: return make(ptr, klass, true, NULL, 0); duke@435: } duke@435: duke@435: // Make a pointer to some value of type klass with offset. duke@435: static const TypeInstPtr *make(PTR ptr, ciKlass* klass, int offset) { duke@435: return make(ptr, klass, false, NULL, offset); duke@435: } duke@435: duke@435: // Make a pointer to an oop. duke@435: static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = 0 ); duke@435: duke@435: // If this is a java.lang.Class constant, return the type for it or NULL. duke@435: // Pass to Type::get_const_type to turn it to a type, which will usually duke@435: // be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc. duke@435: ciType* java_mirror_type() const; duke@435: duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual const Type *cast_to_exactness(bool klass_is_exact) const; duke@435: duke@435: virtual const TypeOopPtr *cast_to_instance(int instance_id) const; duke@435: duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // Convenience common pre-built types. duke@435: static const TypeInstPtr *NOTNULL; duke@435: static const TypeInstPtr *BOTTOM; duke@435: static const TypeInstPtr *MIRROR; duke@435: static const TypeInstPtr *MARK; duke@435: static const TypeInstPtr *KLASS; duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeAryPtr------------------------------------- duke@435: // Class of Java array pointers duke@435: class TypeAryPtr : public TypeOopPtr { duke@435: TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id ) : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id), _ary(ary) {}; duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: const TypeAry *_ary; // Array we point into duke@435: duke@435: public: duke@435: // Accessors duke@435: ciKlass* klass() const; duke@435: const TypeAry* ary() const { return _ary; } duke@435: const Type* elem() const { return _ary->_elem; } duke@435: const TypeInt* size() const { return _ary->_size; } duke@435: duke@435: static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0); duke@435: // Constant pointer to array duke@435: static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0); duke@435: duke@435: // Convenience duke@435: static const TypeAryPtr *make(ciObject* o); duke@435: duke@435: // Return a 'ptr' version of this type duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual const Type *cast_to_exactness(bool klass_is_exact) const; duke@435: duke@435: virtual const TypeOopPtr *cast_to_instance(int instance_id) const; duke@435: duke@435: virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const; duke@435: duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // Convenience common pre-built types. duke@435: static const TypeAryPtr *RANGE; duke@435: static const TypeAryPtr *OOPS; duke@435: static const TypeAryPtr *BYTES; duke@435: static const TypeAryPtr *SHORTS; duke@435: static const TypeAryPtr *CHARS; duke@435: static const TypeAryPtr *INTS; duke@435: static const TypeAryPtr *LONGS; duke@435: static const TypeAryPtr *FLOATS; duke@435: static const TypeAryPtr *DOUBLES; duke@435: // selects one of the above: duke@435: static const TypeAryPtr *get_array_body_type(BasicType elem) { duke@435: assert((uint)elem <= T_CONFLICT && _array_body_type[elem] != NULL, "bad elem type"); duke@435: return _array_body_type[elem]; duke@435: } duke@435: static const TypeAryPtr *_array_body_type[T_CONFLICT+1]; duke@435: // sharpen the type of an int which is used as an array size duke@435: static const TypeInt* narrow_size_type(const TypeInt* size, BasicType elem); duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeKlassPtr----------------------------------- duke@435: // Class of Java Klass pointers duke@435: class TypeKlassPtr : public TypeOopPtr { duke@435: TypeKlassPtr( PTR ptr, ciKlass* klass, int offset ); duke@435: duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: duke@435: public: duke@435: ciSymbol* name() const { return _klass->name(); } duke@435: duke@435: // ptr to klass 'k' duke@435: static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); } duke@435: // ptr to klass 'k' with offset duke@435: static const TypeKlassPtr *make( ciKlass* k, int offset ) { return make( TypePtr::Constant, k, offset); } duke@435: // ptr to klass 'k' or sub-klass duke@435: static const TypeKlassPtr *make( PTR ptr, ciKlass* k, int offset); duke@435: duke@435: virtual const Type *cast_to_ptr_type(PTR ptr) const; duke@435: duke@435: virtual const Type *cast_to_exactness(bool klass_is_exact) const; duke@435: duke@435: // corresponding pointer to instance, for a given class duke@435: const TypeOopPtr* as_instance_type() const; duke@435: duke@435: virtual const TypePtr *add_offset( int offset ) const; duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: // Convenience common pre-built types. duke@435: static const TypeKlassPtr* OBJECT; // Not-null object klass or below duke@435: static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping duke@435: #endif duke@435: }; duke@435: duke@435: //------------------------------TypeFunc--------------------------------------- duke@435: // Class of Array Types duke@435: class TypeFunc : public Type { duke@435: TypeFunc( const TypeTuple *domain, const TypeTuple *range ) : Type(Function), _domain(domain), _range(range) {} duke@435: virtual bool eq( const Type *t ) const; duke@435: virtual int hash() const; // Type specific hashing duke@435: virtual bool singleton(void) const; // TRUE if type is a singleton duke@435: virtual bool empty(void) const; // TRUE if type is vacuous duke@435: public: duke@435: // Constants are shared among ADLC and VM duke@435: enum { Control = AdlcVMDeps::Control, duke@435: I_O = AdlcVMDeps::I_O, duke@435: Memory = AdlcVMDeps::Memory, duke@435: FramePtr = AdlcVMDeps::FramePtr, duke@435: ReturnAdr = AdlcVMDeps::ReturnAdr, duke@435: Parms = AdlcVMDeps::Parms duke@435: }; duke@435: duke@435: const TypeTuple* const _domain; // Domain of inputs duke@435: const TypeTuple* const _range; // Range of results duke@435: duke@435: // Accessors: duke@435: const TypeTuple* domain() const { return _domain; } duke@435: const TypeTuple* range() const { return _range; } duke@435: duke@435: static const TypeFunc *make(ciMethod* method); duke@435: static const TypeFunc *make(ciSignature signature, const Type* extra); duke@435: static const TypeFunc *make(const TypeTuple* domain, const TypeTuple* range); duke@435: duke@435: virtual const Type *xmeet( const Type *t ) const; duke@435: virtual const Type *xdual() const; // Compute dual right now. duke@435: duke@435: BasicType return_type() const; duke@435: duke@435: #ifndef PRODUCT duke@435: virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping duke@435: void print_flattened() const; // Print a 'flattened' signature duke@435: #endif duke@435: // Convenience common pre-built types. duke@435: }; duke@435: duke@435: //------------------------------accessors-------------------------------------- duke@435: inline float Type::getf() const { duke@435: assert( _base == FloatCon, "Not a FloatCon" ); duke@435: return ((TypeF*)this)->_f; duke@435: } duke@435: duke@435: inline double Type::getd() const { duke@435: assert( _base == DoubleCon, "Not a DoubleCon" ); duke@435: return ((TypeD*)this)->_d; duke@435: } duke@435: duke@435: inline const TypeF *Type::is_float_constant() const { duke@435: assert( _base == FloatCon, "Not a Float" ); duke@435: return (TypeF*)this; duke@435: } duke@435: duke@435: inline const TypeF *Type::isa_float_constant() const { duke@435: return ( _base == FloatCon ? (TypeF*)this : NULL); duke@435: } duke@435: duke@435: inline const TypeD *Type::is_double_constant() const { duke@435: assert( _base == DoubleCon, "Not a Double" ); duke@435: return (TypeD*)this; duke@435: } duke@435: duke@435: inline const TypeD *Type::isa_double_constant() const { duke@435: return ( _base == DoubleCon ? (TypeD*)this : NULL); duke@435: } duke@435: duke@435: inline const TypeInt *Type::is_int() const { duke@435: assert( _base == Int, "Not an Int" ); duke@435: return (TypeInt*)this; duke@435: } duke@435: duke@435: inline const TypeInt *Type::isa_int() const { duke@435: return ( _base == Int ? (TypeInt*)this : NULL); duke@435: } duke@435: duke@435: inline const TypeLong *Type::is_long() const { duke@435: assert( _base == Long, "Not a Long" ); duke@435: return (TypeLong*)this; duke@435: } duke@435: duke@435: inline const TypeLong *Type::isa_long() const { duke@435: return ( _base == Long ? (TypeLong*)this : NULL); duke@435: } duke@435: duke@435: inline const TypeTuple *Type::is_tuple() const { duke@435: assert( _base == Tuple, "Not a Tuple" ); duke@435: return (TypeTuple*)this; duke@435: } duke@435: duke@435: inline const TypeAry *Type::is_ary() const { duke@435: assert( _base == Array , "Not an Array" ); duke@435: return (TypeAry*)this; duke@435: } duke@435: duke@435: inline const TypePtr *Type::is_ptr() const { duke@435: // AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between. duke@435: assert(_base >= AnyPtr && _base <= KlassPtr, "Not a pointer"); duke@435: return (TypePtr*)this; duke@435: } duke@435: duke@435: inline const TypePtr *Type::isa_ptr() const { duke@435: // AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between. duke@435: return (_base >= AnyPtr && _base <= KlassPtr) ? (TypePtr*)this : NULL; duke@435: } duke@435: duke@435: inline const TypeOopPtr *Type::is_oopptr() const { duke@435: // OopPtr is the first and KlassPtr the last, with no non-oops between. duke@435: assert(_base >= OopPtr && _base <= KlassPtr, "Not a Java pointer" ) ; duke@435: return (TypeOopPtr*)this; duke@435: } duke@435: duke@435: inline const TypeOopPtr *Type::isa_oopptr() const { duke@435: // OopPtr is the first and KlassPtr the last, with no non-oops between. duke@435: return (_base >= OopPtr && _base <= KlassPtr) ? (TypeOopPtr*)this : NULL; duke@435: } duke@435: duke@435: inline const TypeRawPtr *Type::is_rawptr() const { duke@435: assert( _base == RawPtr, "Not a raw pointer" ); duke@435: return (TypeRawPtr*)this; duke@435: } duke@435: duke@435: inline const TypeInstPtr *Type::isa_instptr() const { duke@435: return (_base == InstPtr) ? (TypeInstPtr*)this : NULL; duke@435: } duke@435: duke@435: inline const TypeInstPtr *Type::is_instptr() const { duke@435: assert( _base == InstPtr, "Not an object pointer" ); duke@435: return (TypeInstPtr*)this; duke@435: } duke@435: duke@435: inline const TypeAryPtr *Type::isa_aryptr() const { duke@435: return (_base == AryPtr) ? (TypeAryPtr*)this : NULL; duke@435: } duke@435: duke@435: inline const TypeAryPtr *Type::is_aryptr() const { duke@435: assert( _base == AryPtr, "Not an array pointer" ); duke@435: return (TypeAryPtr*)this; duke@435: } duke@435: duke@435: inline const TypeKlassPtr *Type::isa_klassptr() const { duke@435: return (_base == KlassPtr) ? (TypeKlassPtr*)this : NULL; duke@435: } duke@435: duke@435: inline const TypeKlassPtr *Type::is_klassptr() const { duke@435: assert( _base == KlassPtr, "Not a klass pointer" ); duke@435: return (TypeKlassPtr*)this; duke@435: } duke@435: duke@435: inline bool Type::is_floatingpoint() const { duke@435: if( (_base == FloatCon) || (_base == FloatBot) || duke@435: (_base == DoubleCon) || (_base == DoubleBot) ) duke@435: return true; duke@435: return false; duke@435: } duke@435: duke@435: duke@435: // =============================================================== duke@435: // Things that need to be 64-bits in the 64-bit build but duke@435: // 32-bits in the 32-bit build. Done this way to get full duke@435: // optimization AND strong typing. duke@435: #ifdef _LP64 duke@435: duke@435: // For type queries and asserts duke@435: #define is_intptr_t is_long duke@435: #define isa_intptr_t isa_long duke@435: #define find_intptr_t_type find_long_type duke@435: #define find_intptr_t_con find_long_con duke@435: #define TypeX TypeLong duke@435: #define Type_X Type::Long duke@435: #define TypeX_X TypeLong::LONG duke@435: #define TypeX_ZERO TypeLong::ZERO duke@435: // For 'ideal_reg' machine registers duke@435: #define Op_RegX Op_RegL duke@435: // For phase->intcon variants duke@435: #define MakeConX longcon duke@435: #define ConXNode ConLNode duke@435: // For array index arithmetic duke@435: #define MulXNode MulLNode duke@435: #define AndXNode AndLNode duke@435: #define OrXNode OrLNode duke@435: #define CmpXNode CmpLNode duke@435: #define SubXNode SubLNode duke@435: #define LShiftXNode LShiftLNode duke@435: // For object size computation: duke@435: #define AddXNode AddLNode never@452: #define RShiftXNode RShiftLNode duke@435: // For card marks and hashcodes duke@435: #define URShiftXNode URShiftLNode duke@435: // Opcodes duke@435: #define Op_LShiftX Op_LShiftL duke@435: #define Op_AndX Op_AndL duke@435: #define Op_AddX Op_AddL duke@435: #define Op_SubX Op_SubL duke@435: // conversions duke@435: #define ConvI2X(x) ConvI2L(x) duke@435: #define ConvL2X(x) (x) duke@435: #define ConvX2I(x) ConvL2I(x) duke@435: #define ConvX2L(x) (x) duke@435: duke@435: #else duke@435: duke@435: // For type queries and asserts duke@435: #define is_intptr_t is_int duke@435: #define isa_intptr_t isa_int duke@435: #define find_intptr_t_type find_int_type duke@435: #define find_intptr_t_con find_int_con duke@435: #define TypeX TypeInt duke@435: #define Type_X Type::Int duke@435: #define TypeX_X TypeInt::INT duke@435: #define TypeX_ZERO TypeInt::ZERO duke@435: // For 'ideal_reg' machine registers duke@435: #define Op_RegX Op_RegI duke@435: // For phase->intcon variants duke@435: #define MakeConX intcon duke@435: #define ConXNode ConINode duke@435: // For array index arithmetic duke@435: #define MulXNode MulINode duke@435: #define AndXNode AndINode duke@435: #define OrXNode OrINode duke@435: #define CmpXNode CmpINode duke@435: #define SubXNode SubINode duke@435: #define LShiftXNode LShiftINode duke@435: // For object size computation: duke@435: #define AddXNode AddINode never@452: #define RShiftXNode RShiftINode duke@435: // For card marks and hashcodes duke@435: #define URShiftXNode URShiftINode duke@435: // Opcodes duke@435: #define Op_LShiftX Op_LShiftI duke@435: #define Op_AndX Op_AndI duke@435: #define Op_AddX Op_AddI duke@435: #define Op_SubX Op_SubI duke@435: // conversions duke@435: #define ConvI2X(x) (x) duke@435: #define ConvL2X(x) ConvL2I(x) duke@435: #define ConvX2I(x) (x) duke@435: #define ConvX2L(x) ConvI2L(x) duke@435: duke@435: #endif