/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_OPTO_TYPE_HPP
#define SHARE_VM_OPTO_TYPE_HPP
#include "opto/adlcVMDeps.hpp"
#include "runtime/handles.hpp"
// Portions of code courtesy of Clifford Click
// Optimization - Graph Style
// This class defines a Type lattice. The lattice is used in the constant
// propagation algorithms, and for some type-checking of the iloc code.
// Basic types include RSD's (lower bound, upper bound, stride for integers),
// float & double precision constants, sets of data-labels and code-labels.
// The complete lattice is described below. Subtypes have no relationship to
// up or down in the lattice; that is entirely determined by the behavior of
class Dict;
class Type;
class TypeD;
class TypeF;
class TypeInt;
class TypeLong;
class TypeNarrowOop;
class TypeAry;
class TypeTuple;
class TypeVect;
class TypeVectS;
class TypeVectD;
class TypeVectX;
class TypeVectY;
class TypePtr;
class TypeRawPtr;
class TypeOopPtr;
class TypeInstPtr;
class TypeAryPtr;
class TypeKlassPtr;
//------------------------------Type-------------------------------------------
// Basic Type object, represents a set of primitive Values.
// Types are hash-cons'd into a private class dictionary, so only one of each
// different kind of Type exists. Types are never modified after creation, so
// all their interesting fields are constant.
class Type {
friend class VMStructs;
public:
enum TYPES {
// (Ptr order matters: See is_ptr, isa_ptr, is_oopptr, isa_oopptr.)
};
// Signal values for offsets from a base pointer
enum OFFSET_SIGNALS {
};
// Min and max WIDEN values.
enum WIDEN {
WidenMin = 0,
};
private:
// Dictionary of types shared among compilations.
// Structural equality check. Assumes that cmp() has already compared
// the _base types and thus knows it can cast 't' appropriately.
// Top-level hash-table of types
}
// DUAL operation: reflect around lattice centerline. Used instead of
// join to ensure my lattice is symmetric up and down. Dual is computed
// lazily, on demand, and cached in _dual.
// Table for efficient dualing of base types
protected:
// Each class of type is also identified by its base.
// ~Type(); // Use fast deallocation
public:
inline void* operator new( size_t x ) {
return temp;
}
inline void operator delete( void* ptr ) {
}
// Initialize the type system for a particular compilation.
// Initialize the types shared by all compilations.
return _base;
}
// Create a new hash-consd type
// Test for equivalence of types
// Test for higher or equal in lattice
// MEET operation; lower in lattice.
// WIDEN: 'widens' for Ints and other range types
// NARROW: complement for widen, used by pessimistic phases
// DUAL operation: reflect around lattice centerline. Used instead of
// join to ensure my lattice is symmetric up and down.
// Compute meet dependent on base type
// JOIN operation; higher in lattice. Done by finding the dual of the
// meet of the dual of the 2 inputs.
// Modified version of JOIN adapted to the needs Node::Value.
// Normalizes all empty values to TOP. Does not kill _widen bits.
// Currently, it also works around limitations involving interface types.
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
// Returns true if this pointer points at memory which contains a
// compressed oop references.
bool is_ptr_to_narrowoop() const;
// Convenience access
float getf() const;
double getd() const;
virtual bool is_finite() const; // Has a finite value
virtual bool is_nan() const; // Is not a number (NaN)
// Returns this ptr type or the equivalent ptr type for this compressed pointer.
// Returns this oopptr type or the equivalent oopptr type for this compressed pointer.
// Asserts if the underlying type is not an oopptr or narrowoop.
const TypeOopPtr* make_oopptr() const;
// Returns this compressed pointer or the equivalent compressed version
// of this pointer type.
const TypeNarrowOop* make_narrowoop() const;
// Special test for register pressure heuristic
bool is_floatingpoint() const; // True if Float or Double base type
// Do you have memory, directly or through a tuple?
bool has_memory( ) const;
// Are you a pointer type or not?
bool isa_oop_ptr() const;
// TRUE if type is a singleton
virtual bool singleton(void) const;
// TRUE if type is above the lattice centerline, and is therefore vacuous
virtual bool empty(void) const;
// Return a hash for this type. The hash function is public so ConNode
// (constants) can hash on their constant, which is represented by a Type.
virtual int hash() const;
// Map ideal registers (machine types) to ideal types
// Printing, statistics
#ifndef PRODUCT
void dump() const {
}
static void dump_stats();
static void verify_lastype(); // Check that arrays match type enum
#endif
// Create basic type
return _const_basic_type[type];
}
// Mapping to the array element's basic type.
BasicType array_element_basic_type() const;
// Create standard type for a ciType:
// Create standard zero value:
return _zero_type[type];
}
// Report if this is a zero value (not top).
bool is_zero_type() const {
return false;
else
return (this == _zero_type[type]);
}
// Convenience common pre-built types.
// Mapping from compiler type to VM BasicType
// Mapping from CI type system to compiler type:
private:
// support arrays
};
//------------------------------TypeF------------------------------------------
// Class of Float-Constant Types.
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
virtual bool is_finite() const; // Has a finite value
virtual bool is_nan() const; // Is not a number (NaN)
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeD------------------------------------------
// Class of Double-Constant Types.
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
virtual bool is_finite() const; // Has a finite value
virtual bool is_nan() const; // Is not a number (NaN)
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeInt----------------------------------------
// Class of integer ranges, the set of integers between a lower bound and an
// upper bound, inclusive.
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
// must always specify w
// Check for single integer
virtual bool is_finite() const; // Has a finite value
// Do not kill _widen bits.
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeLong---------------------------------------
// Class of long integer ranges, the set of integers between a lower bound and
// an upper bound, inclusive.
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
// must always specify w
// Check for single integer
virtual bool is_finite() const; // Has a finite value
// Do not kill _widen bits.
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeTuple--------------------------------------
// Class of Tuple Types, essentially type collections for function signatures
// and class layouts. It happens to also be a fast cache for the HotSpot
// signature types.
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
// Accessors:
return _fields[i];
}
_fields[i] = t;
}
// Subroutine call type with space allocated for argument types
// Convenience common pre-built types.
static const TypeTuple *STORECONDITIONAL;
#ifndef PRODUCT
#endif
};
//------------------------------TypeAry----------------------------------------
// Class of Array Types
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
private:
friend class TypeAryPtr;
public:
bool ary_must_be_exact() const; // true if arrays of such are never generic
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
#ifndef PRODUCT
#endif
};
//------------------------------TypeVect---------------------------------------
// Class of Vector Types
protected:
public:
uint length_in_bytes() const {
}
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
// Use bottom primitive type.
}
// Used directly by Replicate nodes to construct singleton vector.
#ifndef PRODUCT
#endif
};
friend class TypeVect;
};
friend class TypeVect;
};
friend class TypeVect;
};
friend class TypeVect;
};
//------------------------------TypePtr----------------------------------------
// Class of machine Pointer Types: raw data, instances or arrays.
// If the _base enum is AnyPtr, then this refers to all of the above.
// Otherwise the _base will indicate which subset of pointers is affected,
// and the class will be inherited from.
friend class TypeNarrowOop;
public:
protected:
virtual int hash() const; // Type specific hashing
public:
const int _offset; // Offset into oop, with TOP & BOT
// Return a 'ptr' version of this type
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
int meet_offset( int offset ) const;
int dual_offset( ) const;
// meet, dual and join over pointer equivalence sets
// This is textually confusing unless one recalls that
// join(t) == dual()->meet(t->dual())->dual().
}
// Tests for relation to centerline of type lattice:
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeRawPtr-------------------------------------
// Class of raw pointers, pointers to things other than Oops. Examples
// include the stack pointer, top of heap, card-marking area, handles, etc.
class TypeRawPtr : public TypePtr {
protected:
public:
virtual int hash() const; // Type specific hashing
// Return a 'ptr' version of this type
// Convenience common pre-built types.
static const TypeRawPtr *BOTTOM;
static const TypeRawPtr *NOTNULL;
#ifndef PRODUCT
#endif
};
//------------------------------TypeOopPtr-------------------------------------
// Some kind of oop (Java pointer), either klass or instance or array.
class TypeOopPtr : public TypePtr {
protected:
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
enum {
InstanceBot = 0 // any possible instance
};
protected:
// Oop is NULL, unless this is a constant oop.
// If _klass is NULL, then so is _sig. This is an unloaded klass.
// Does the type exclude subclasses of the klass? (Inexact == polymorphic.)
bool _klass_is_exact;
bool _is_ptr_to_narrowoop;
// If not InstanceTop or InstanceBot, indicates that this is
// a particular instance of this type which is distinct.
// This is the the node index of the allocation node creating this instance.
int _instance_id;
static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
int dual_instance_id() const;
int meet_instance_id(int uid) const;
public:
// Creates a type given a klass. Correctly handles multi-dimensional arrays
// Respects UseUniqueSubclasses.
// If the klass is final, the resulting type will be exact.
return make_from_klass_common(klass, true, false);
}
// Same as before, but will produce an exact type, even if
// the klass is not final, as long as it has exactly one implementation.
return make_from_klass_common(klass, true, true);
}
// Same as before, but does not respects UseUniqueSubclasses.
// Use this only for creating array element types.
return make_from_klass_common(klass, false, false);
}
// Creates a singleton type given an object.
// If the object cannot be rendered as a constant,
// may return a non-singleton type.
// If require_constant, produce a NULL if a singleton is not possible.
// Make a generic (unclassed) pointer to an oop.
bool klass_is_exact() const { return _klass_is_exact; }
// Returns true if this pointer points at memory which contains a
// compressed oop references.
bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
bool is_known_instance() const { return _instance_id > 0; }
int instance_id() const { return _instance_id; }
// corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const;
// Do not allow interface-vs.-noninterface joins to collapse to top.
// Convenience common pre-built type.
static const TypeOopPtr *BOTTOM;
#ifndef PRODUCT
#endif
};
//------------------------------TypeInstPtr------------------------------------
// Class of Java object pointers, pointing either to non-array Java instances
// or to a klassOop (including array klasses).
class TypeInstPtr : public TypeOopPtr {
virtual int hash() const; // Type specific hashing
public:
// Make a pointer to a constant oop.
}
// Make a pointer to a constant oop with offset.
}
// Make a pointer to some value of type klass.
}
// Make a pointer to some non-polymorphic value of exactly type klass.
}
// Make a pointer to some value of type klass with offset.
}
// Make a pointer to an oop.
static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
// If this is a java.lang.Class constant, return the type for it or NULL.
// Pass to Type::get_const_type to turn it to a type, which will usually
// be a TypeInstPtr, but may also be a TypeInt::INT for int.class, etc.
ciType* java_mirror_type() const;
// Convenience common pre-built types.
static const TypeInstPtr *NOTNULL;
static const TypeInstPtr *BOTTOM;
static const TypeInstPtr *MIRROR;
static const TypeInstPtr *MARK;
static const TypeInstPtr *KLASS;
#ifndef PRODUCT
#endif
};
//------------------------------TypeAryPtr-------------------------------------
// Class of Java array pointers
class TypeAryPtr : public TypeOopPtr {
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) {
#ifdef ASSERT
if (k != NULL) {
// Verify that specified klass and TypeAryPtr::klass() follow the same rules.
if (k != ck) {
assert(false, "unexpected TypeAryPtr::_klass");
}
}
#endif
}
virtual int hash() const; // Type specific hashing
public:
// Accessors
static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Constant pointer to array
static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Return a 'ptr' version of this type
virtual bool empty(void) const; // TRUE if type is vacuous
// Convenience common pre-built types.
static const TypeAryPtr *RANGE;
static const TypeAryPtr *OOPS;
static const TypeAryPtr *NARROWOOPS;
static const TypeAryPtr *BYTES;
static const TypeAryPtr *SHORTS;
static const TypeAryPtr *CHARS;
static const TypeAryPtr *INTS;
static const TypeAryPtr *LONGS;
static const TypeAryPtr *FLOATS;
static const TypeAryPtr *DOUBLES;
// selects one of the above:
return _array_body_type[elem];
}
// sharpen the type of an int which is used as an array size
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
#ifndef PRODUCT
#endif
};
//------------------------------TypeKlassPtr-----------------------------------
// Class of Java Klass pointers
class TypeKlassPtr : public TypeOopPtr {
virtual int hash() const; // Type specific hashing
public:
// ptr to klass 'k'
// ptr to klass 'k' with offset
static const TypeKlassPtr *make( ciKlass* k, int offset ) { return make( TypePtr::Constant, k, offset); }
// ptr to klass 'k' or sub-klass
// corresponding pointer to instance, for a given class
const TypeOopPtr* as_instance_type() const;
// Convenience common pre-built types.
#ifndef PRODUCT
#endif
};
//------------------------------TypeNarrowOop----------------------------------
// A compressed reference to some kind of Oop. This type wraps around
// a preexisting TypeOopPtr and forwards most of it's operations to
// the underlying type. It's only real purpose is to track the
// oopness of the compressed oop value when we expose the conversion
// between the normal and the compressed form.
class TypeNarrowOop : public Type {
protected:
}
public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
// Do not allow interface-vs.-noninterface joins to collapse to top.
virtual bool empty(void) const; // TRUE if type is vacuous
}
// returns the equivalent ptr type for this compressed pointer
const TypePtr *get_ptrtype() const {
return _ptrtype;
}
static const TypeNarrowOop *BOTTOM;
static const TypeNarrowOop *NULL_PTR;
#ifndef PRODUCT
#endif
};
//------------------------------TypeFunc---------------------------------------
// Class of Array Types
TypeFunc( const TypeTuple *domain, const TypeTuple *range ) : Type(Function), _domain(domain), _range(range) {}
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
virtual bool empty(void) const; // TRUE if type is vacuous
public:
// Constants are shared among ADLC and VM
};
// Accessors:
BasicType return_type() const;
#ifndef PRODUCT
void print_flattened() const; // Print a 'flattened' signature
#endif
// Convenience common pre-built types.
};
//------------------------------accessors--------------------------------------
inline bool Type::is_ptr_to_narrowoop() const {
#ifdef _LP64
#else
return false;
#endif
}
}
}
return (TypeInt*)this;
}
}
return (TypeLong*)this;
}
}
}
return (TypeF*)this;
}
}
}
return (TypeD*)this;
}
}
return (TypeTuple*)this;
}
return (TypeAry*)this;
}
return (TypeVect*)this;
}
}
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
return (TypePtr*)this;
}
// AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
}
// OopPtr is the first and KlassPtr the last, with no non-oops between.
return (TypeOopPtr*)this;
}
// OopPtr is the first and KlassPtr the last, with no non-oops between.
}
}
return (TypeRawPtr*)this;
}
}
return (TypeInstPtr*)this;
}
}
return (TypeAryPtr*)this;
}
// OopPtr is the first and KlassPtr the last, with no non-oops between.
return (TypeNarrowOop*)this;
}
// OopPtr is the first and KlassPtr the last, with no non-oops between.
}
}
return (TypeKlassPtr*)this;
}
}
}
}
inline bool Type::is_floatingpoint() const {
return true;
return false;
}
// ===============================================================
// Things that need to be 64-bits in the 64-bit build but
// 32-bits in the 32-bit build. Done this way to get full
// optimization AND strong typing.
#ifdef _LP64
// For type queries and asserts
// For 'ideal_reg' machine registers
// For phase->intcon variants
// For array index arithmetic
// For object size computation:
// For card marks and hashcodes
// UseOptoBiasInlining
// Opcodes
// conversions
#define ConvL2X(x) (x)
#define ConvX2L(x) (x)
#else
// For type queries and asserts
#define is_intptr_t is_int
#define isa_intptr_t isa_int
#define find_intptr_t_type find_int_type
#define find_intptr_t_con find_int_con
// For 'ideal_reg' machine registers
// For phase->intcon variants
// For array index arithmetic
#define LShiftXNode LShiftINode
// For object size computation:
#define RShiftXNode RShiftINode
// For card marks and hashcodes
#define URShiftXNode URShiftINode
// UseOptoBiasInlining
// Opcodes
#define Op_LShiftX Op_LShiftI
#define Op_URShiftX Op_URShiftI
// conversions
#define ConvI2X(x) (x)
#define ConvX2I(x) (x)
#endif
#endif // SHARE_VM_OPTO_TYPE_HPP