For PR1064:

Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.

This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
   bits in an integer. The Type classes SubclassData field is used to
   store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
   64-bit integers. These are replaced with just IntegerType which is not
   a primitive any more.
3. Adjust the rest of LLVM to account for this change.

Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types.  Future increments
will rectify this situation.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2007-01-12 07:05:14 +00:00
parent ed30989895
commit a54b7cbd45
41 changed files with 4035 additions and 3394 deletions

View File

@ -29,6 +29,7 @@ class ArrayValType;
class StructValType;
class PointerValType;
class PackedValType;
class IntegerValType;
class DerivedType : public Type {
friend class Type;
@ -71,6 +72,40 @@ public:
}
};
/// Class to represent integer types. Note that this class is also used to
/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
/// Int64Ty.
/// @brief Integer representation type
class IntegerType : public DerivedType {
protected:
IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) {
setSubclassData(NumBits);
}
friend class TypeMap<IntegerValType, IntegerType>;
public:
/// This enum is just used to hold constants we need for IntegerType.
enum {
MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified
MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
///< Note that bit width is stored in the Type classes SubclassData field
///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
};
/// This static method is the primary way of constructing an IntegerType.
/// If an IntegerType with the same NumBits value was previously instantiated,
/// that instance will be returned. Otherwise a new one will be created. Only
/// one instance with a given NumBits value is ever created.
/// @brief Get or create an IntegerType instance.
static const IntegerType* get(unsigned NumBits);
/// @brief Get the number of bits in this IntegerType
unsigned getBitWidth() const { return getSubclassData(); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const IntegerType *T) { return true; }
static inline bool classof(const Type *T) { return T->isIntegral(); }
};
/// FunctionType - Class to represent function types
///

View File

@ -57,6 +57,11 @@ class LLVMType<ValueType vt, string typeval> {
string TypeVal = typeval;
}
class LLVMIntegerType<ValueType VT, int width>
: LLVMType<VT, "Type::IntegerTyID"> {
int Width = width;
}
class LLVMPackedType<ValueType VT, int numelts, LLVMType elty>
: LLVMType<VT, "Type::PackedTyID">{
int NumElts = numelts;
@ -64,25 +69,24 @@ class LLVMPackedType<ValueType VT, int numelts, LLVMType elty>
}
def llvm_void_ty : LLVMType<isVoid, "Type::VoidTyID">;
def llvm_i1_ty : LLVMType<i1 , "Type::Int1TyID">;
def llvm_i8_ty : LLVMType<i8 , "Type::Int8TyID">;
def llvm_i16_ty : LLVMType<i16, "Type::Int16TyID">;
def llvm_i32_ty : LLVMType<i32, "Type::Int32TyID">;
def llvm_i64_ty : LLVMType<i64, "Type::Int64TyID">;
def llvm_bool_ty : LLVMIntegerType<i1, 1>;
def llvm_i8_ty : LLVMIntegerType<i8 , 8>;
def llvm_i16_ty : LLVMIntegerType<i16, 16>;
def llvm_i32_ty : LLVMIntegerType<i32, 32>;
def llvm_i64_ty : LLVMIntegerType<i64, 64>;
def llvm_float_ty : LLVMType<f32, "Type::FloatTyID">;
def llvm_double_ty : LLVMType<f64, "Type::DoubleTyID">;
def llvm_ptr_ty : LLVMType<iPTR, "Type::PointerTyID">; // sbyte*
def llvm_ptrptr_ty : LLVMType<iPTR, "Type::PointerTyID">; // sbyte**
def llvm_ptr_ty : LLVMType<iPTR, "Type::PointerTyID">; // i8*
def llvm_ptrptr_ty : LLVMType<iPTR, "Type::PointerTyID">; // i8**
def llvm_descriptor_ty : LLVMType<iPTR, "Type::PointerTyID">; // global*
def llvm_v16i8_ty : LLVMPackedType<v16i8,16, llvm_i8_ty>; // 16 x sbyte
def llvm_v8i16_ty : LLVMPackedType<v8i16, 8, llvm_i16_ty>; // 8 x short
def llvm_v2i64_ty : LLVMPackedType<v2i64, 2, llvm_i64_ty>; // 2 x long
def llvm_v2i32_ty : LLVMPackedType<v2i32, 2, llvm_i32_ty>; // 2 x int
def llvm_v4i32_ty : LLVMPackedType<v4i32, 4, llvm_i32_ty>; // 4 x int
def llvm_v4f32_ty : LLVMPackedType<v4f32, 4, llvm_float_ty>; // 4 x float
def llvm_v2f64_ty : LLVMPackedType<v2f64, 2, llvm_double_ty>; // 2 x double
def llvm_v16i8_ty : LLVMPackedType<v16i8,16, llvm_i8_ty>; // 16 x i8
def llvm_v8i16_ty : LLVMPackedType<v8i16, 8, llvm_i16_ty>; // 8 x i16
def llvm_v2i64_ty : LLVMPackedType<v2i64, 2, llvm_i64_ty>; // 2 x i64
def llvm_v2i32_ty : LLVMPackedType<v2i32, 2, llvm_i32_ty>; // 2 x i32
def llvm_v4i32_ty : LLVMPackedType<v4i32, 4, llvm_i32_ty>; // 4 x i32
def llvm_v4f32_ty : LLVMPackedType<v4f32, 4, llvm_float_ty>; // 4 x float
def llvm_v2f64_ty : LLVMPackedType<v2f64, 2, llvm_double_ty>;// 2 x double
//===----------------------------------------------------------------------===//
// Intrinsic Definitions.

View File

@ -22,7 +22,7 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
#include "llvm/Type.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include <map>
@ -429,11 +429,16 @@ public:
switch (Ty->getTypeID()) {
default: assert(0 && "Unknown type!");
case Type::VoidTyID: return MVT::isVoid;
case Type::Int1TyID: return MVT::i1;
case Type::Int8TyID: return MVT::i8;
case Type::Int16TyID: return MVT::i16;
case Type::Int32TyID: return MVT::i32;
case Type::Int64TyID: return MVT::i64;
case Type::IntegerTyID:
switch (cast<IntegerType>(Ty)->getBitWidth()) {
default: assert(0 && "Invalid width for value type");
case 1: return MVT::i1;
case 8: return MVT::i8;
case 16: return MVT::i16;
case 32: return MVT::i32;
case 64: return MVT::i64;
}
break;
case Type::FloatTyID: return MVT::f32;
case Type::DoubleTyID: return MVT::f64;
case Type::PointerTyID: return PointerTy;

View File

@ -71,32 +71,31 @@ public:
///
enum TypeID {
// PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
VoidTyID = 0 , Int1TyID, // 0, 1: Basics...
Int8TyID, // 2 : 8 bit type...
Int16TyID, // 3 : 16 bit type...
Int32TyID, // 4 : 32 bit type...
Int64TyID, // 5 : 64 bit type...
FloatTyID, DoubleTyID, // 6, 7: Floating point types...
LabelTyID, // 8 : Labels...
VoidTyID = 0, ///< 0: type with no size
FloatTyID, ///< 1: 32 bit floating point type
DoubleTyID, ///< 2: 64 bit floating point type
LabelTyID, ///< 3: Labels
// Derived types... see DerivedTypes.h file...
// Make sure FirstDerivedTyID stays up to date!!!
FunctionTyID , StructTyID, // Functions... Structs...
ArrayTyID , PointerTyID, // Array... pointer...
OpaqueTyID, // Opaque type instances...
PackedTyID, // SIMD 'packed' format...
BC_ONLY_PackedStructTyID, // packed struct, for BC rep only
//...
IntegerTyID, ///< 4: Arbitrary bit width integers
FunctionTyID, ///< 5: Functions
StructTyID, ///< 6: Structures
PackedStructTyID,///< 7: Packed Structure. This is for bytecode only
ArrayTyID, ///< 8: Arrays
PointerTyID, ///< 9: Pointers
OpaqueTyID, ///< 10: Opaque: type with unknown structure
PackedTyID, ///< 11: SIMD 'packed' format, or other vector type
NumTypeIDs, // Must remain as last defined ID
LastPrimitiveTyID = LabelTyID,
FirstDerivedTyID = FunctionTyID
FirstDerivedTyID = IntegerTyID
};
private:
TypeID ID : 8; // The current base type of this type.
bool Abstract : 1; // True if type contains an OpaqueType
bool SubclassData : 1; //Space for subclasses to store a flag
unsigned SubclassData : 23; //Space for subclasses to store data
/// RefCount - This counts the number of PATypeHolders that are pointing to
/// this type. When this number falls to zero, if the type is abstract and
@ -108,7 +107,8 @@ private:
const Type *getForwardedTypeInternal() const;
protected:
Type(const char *Name, TypeID id);
Type(TypeID id) : ID(id), Abstract(false), RefCount(0), ForwardType(0) {}
Type(TypeID id) : ID(id), Abstract(false), SubclassData(0), RefCount(0),
ForwardType(0) {}
virtual ~Type() {
assert(AbstractTypeUsers.empty());
}
@ -119,8 +119,8 @@ protected:
unsigned getRefCount() const { return RefCount; }
bool getSubclassData() const { return SubclassData; }
void setSubclassData(bool b) { SubclassData = b; }
unsigned getSubclassData() const { return SubclassData; }
void setSubclassData(unsigned val) { SubclassData = val; }
/// ForwardType - This field is used to implement the union find scheme for
/// abstract types. When types are refined to other types, this field is set
@ -162,12 +162,12 @@ public:
/// isInteger - Equivalent to isSigned() || isUnsigned()
///
bool isInteger() const { return ID >= Int8TyID && ID <= Int64TyID; }
bool isInteger() const { return ID == IntegerTyID && this != Int1Ty; }
/// isIntegral - Returns true if this is an integral type, which is either
/// Int1Ty or one of the Integer types.
///
bool isIntegral() const { return isInteger() || this == Int1Ty; }
bool isIntegral() const { return ID == IntegerTyID; }
/// isFloatingPoint - Return true if this is one of the two floating point
/// types
@ -200,7 +200,7 @@ public:
///
inline bool isFirstClassType() const {
return (ID != VoidTyID && ID <= LastPrimitiveTyID) ||
ID == PointerTyID || ID == PackedTyID;
ID == IntegerTyID || ID == PointerTyID || ID == PackedTyID;
}
/// isSized - Return true if it makes sense to take the size of this type. To
@ -209,11 +209,13 @@ public:
///
bool isSized() const {
// If it's a primitive, it is always sized.
if (ID >= Int1TyID && ID <= DoubleTyID || ID == PointerTyID)
if (ID == IntegerTyID || (ID >= FloatTyID && ID <= DoubleTyID) ||
ID == PointerTyID)
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
if (ID != StructTyID && ID != ArrayTyID && ID != PackedTyID)
if (ID != StructTyID && ID != ArrayTyID && ID != PackedTyID &&
ID != PackedStructTyID)
return false;
// If it is something that can have a size and it's concrete, it definitely
// has a size, otherwise we have to try harder to decide.
@ -224,7 +226,6 @@ public:
/// type. These are fixed by LLVM and are not target dependent. This will
/// return zero if the type does not have a size or is not a primitive type.
///
unsigned getPrimitiveSize() const;
unsigned getPrimitiveSizeInBits() const;
/// getIntegralTypeMask - Return a bitmask with ones set for all of the bits
@ -248,7 +249,7 @@ public:
/// will be promoted to if passed through a variable argument
/// function.
const Type *getVAArgsPromotedType() const {
if (ID == Int1TyID || ID == Int8TyID || ID == Int16TyID)
if (ID == IntegerTyID && getSubclassData() < 32)
return Type::Int32Ty;
else if (ID == FloatTyID)
return Type::DoubleTy;
@ -288,12 +289,8 @@ public:
//===--------------------------------------------------------------------===//
// These are the builtin types that are always available...
//
static Type *VoidTy , *Int1Ty;
static Type *Int8Ty , *Int16Ty,
*Int32Ty, *Int64Ty;
static Type *FloatTy, *DoubleTy;
static Type* LabelTy;
static const Type *VoidTy, *LabelTy, *FloatTy, *DoubleTy;
static const Type *Int1Ty, *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Type *T) { return true; }

File diff suppressed because it is too large Load Diff

View File

@ -165,6 +165,8 @@ StringConstant \"[^\"]*\"
EPInteger %[0-9]+
ENInteger %-[0-9]+
IntegerType i[0-9]*
/* E[PN]Integer: match positive and negative literal integer values */
PInteger [0-9]+
@ -235,15 +237,18 @@ x86_fastcallcc { return X86_FASTCALLCC_TOK; }
void { RET_TY(Type::VoidTy, VOID); }
bool { RET_TY(Type::Int1Ty, BOOL); }
i8 { RET_TY(Type::Int8Ty, INT8); }
i16 { RET_TY(Type::Int16Ty, INT16); }
i32 { RET_TY(Type::Int32Ty, INT32); }
i64 { RET_TY(Type::Int64Ty, INT64); }
float { RET_TY(Type::FloatTy, FLOAT); }
double { RET_TY(Type::DoubleTy,DOUBLE);}
label { RET_TY(Type::LabelTy, LABEL); }
type { return TYPE; }
opaque { return OPAQUE; }
{IntegerType} { uint64_t NumBits = atoull(yytext+1);
if (NumBits < IntegerType::MIN_INT_BITS ||
NumBits > IntegerType::MAX_INT_BITS)
GenerateError("Bitwidth for integer type out of range!");
const Type* Ty = IntegerType::get(NumBits);
RET_TY(Ty, INTTYPE);
}
add { RET_TOK(BinaryOpVal, Add, ADD); }
sub { RET_TOK(BinaryOpVal, Sub, SUB); }

View File

@ -165,6 +165,8 @@ StringConstant \"[^\"]*\"
EPInteger %[0-9]+
ENInteger %-[0-9]+
IntegerType i[0-9]*
/* E[PN]Integer: match positive and negative literal integer values */
PInteger [0-9]+
@ -235,15 +237,18 @@ x86_fastcallcc { return X86_FASTCALLCC_TOK; }
void { RET_TY(Type::VoidTy, VOID); }
bool { RET_TY(Type::Int1Ty, BOOL); }
i8 { RET_TY(Type::Int8Ty, INT8); }
i16 { RET_TY(Type::Int16Ty, INT16); }
i32 { RET_TY(Type::Int32Ty, INT32); }
i64 { RET_TY(Type::Int64Ty, INT64); }
float { RET_TY(Type::FloatTy, FLOAT); }
double { RET_TY(Type::DoubleTy,DOUBLE);}
label { RET_TY(Type::LabelTy, LABEL); }
type { return TYPE; }
opaque { return OPAQUE; }
{IntegerType} { uint64_t NumBits = atoull(yytext+1);
if (NumBits < IntegerType::MIN_INT_BITS ||
NumBits > IntegerType::MAX_INT_BITS)
GenerateError("Bitwidth for integer type out of range!");
const Type* Ty = IntegerType::get(NumBits);
RET_TY(Ty, INTTYPE);
}
add { RET_TOK(BinaryOpVal, Add, ADD); }
sub { RET_TOK(BinaryOpVal, Sub, SUB); }

File diff suppressed because it is too large Load Diff

View File

@ -36,132 +36,129 @@
FPVAL = 262,
VOID = 263,
BOOL = 264,
INT8 = 265,
INT16 = 266,
INT32 = 267,
INT64 = 268,
FLOAT = 269,
DOUBLE = 270,
LABEL = 271,
TYPE = 272,
VAR_ID = 273,
LABELSTR = 274,
STRINGCONSTANT = 275,
IMPLEMENTATION = 276,
ZEROINITIALIZER = 277,
TRUETOK = 278,
FALSETOK = 279,
BEGINTOK = 280,
ENDTOK = 281,
DECLARE = 282,
DEFINE = 283,
GLOBAL = 284,
CONSTANT = 285,
SECTION = 286,
VOLATILE = 287,
TO = 288,
DOTDOTDOT = 289,
NULL_TOK = 290,
UNDEF = 291,
INTERNAL = 292,
LINKONCE = 293,
WEAK = 294,
APPENDING = 295,
DLLIMPORT = 296,
DLLEXPORT = 297,
EXTERN_WEAK = 298,
OPAQUE = 299,
NOT = 300,
EXTERNAL = 301,
TARGET = 302,
TRIPLE = 303,
ENDIAN = 304,
POINTERSIZE = 305,
LITTLE = 306,
BIG = 307,
ALIGN = 308,
DEPLIBS = 309,
CALL = 310,
TAIL = 311,
ASM_TOK = 312,
MODULE = 313,
SIDEEFFECT = 314,
CC_TOK = 315,
CCC_TOK = 316,
CSRETCC_TOK = 317,
FASTCC_TOK = 318,
COLDCC_TOK = 319,
X86_STDCALLCC_TOK = 320,
X86_FASTCALLCC_TOK = 321,
DATALAYOUT = 322,
RET = 323,
BR = 324,
SWITCH = 325,
INVOKE = 326,
UNWIND = 327,
UNREACHABLE = 328,
ADD = 329,
SUB = 330,
MUL = 331,
UDIV = 332,
SDIV = 333,
FDIV = 334,
UREM = 335,
SREM = 336,
FREM = 337,
AND = 338,
OR = 339,
XOR = 340,
ICMP = 341,
FCMP = 342,
EQ = 343,
NE = 344,
SLT = 345,
SGT = 346,
SLE = 347,
SGE = 348,
ULT = 349,
UGT = 350,
ULE = 351,
UGE = 352,
OEQ = 353,
ONE = 354,
OLT = 355,
OGT = 356,
OLE = 357,
OGE = 358,
ORD = 359,
UNO = 360,
UEQ = 361,
UNE = 362,
MALLOC = 363,
ALLOCA = 364,
FREE = 365,
LOAD = 366,
STORE = 367,
GETELEMENTPTR = 368,
TRUNC = 369,
ZEXT = 370,
SEXT = 371,
FPTRUNC = 372,
FPEXT = 373,
BITCAST = 374,
UITOFP = 375,
SITOFP = 376,
FPTOUI = 377,
FPTOSI = 378,
INTTOPTR = 379,
PTRTOINT = 380,
PHI_TOK = 381,
SELECT = 382,
SHL = 383,
LSHR = 384,
ASHR = 385,
VAARG = 386,
EXTRACTELEMENT = 387,
INSERTELEMENT = 388,
SHUFFLEVECTOR = 389,
NORETURN = 390
INTTYPE = 265,
FLOAT = 266,
DOUBLE = 267,
LABEL = 268,
TYPE = 269,
VAR_ID = 270,
LABELSTR = 271,
STRINGCONSTANT = 272,
IMPLEMENTATION = 273,
ZEROINITIALIZER = 274,
TRUETOK = 275,
FALSETOK = 276,
BEGINTOK = 277,
ENDTOK = 278,
DECLARE = 279,
DEFINE = 280,
GLOBAL = 281,
CONSTANT = 282,
SECTION = 283,
VOLATILE = 284,
TO = 285,
DOTDOTDOT = 286,
NULL_TOK = 287,
UNDEF = 288,
INTERNAL = 289,
LINKONCE = 290,
WEAK = 291,
APPENDING = 292,
DLLIMPORT = 293,
DLLEXPORT = 294,
EXTERN_WEAK = 295,
OPAQUE = 296,
NOT = 297,
EXTERNAL = 298,
TARGET = 299,
TRIPLE = 300,
ENDIAN = 301,
POINTERSIZE = 302,
LITTLE = 303,
BIG = 304,
ALIGN = 305,
DEPLIBS = 306,
CALL = 307,
TAIL = 308,
ASM_TOK = 309,
MODULE = 310,
SIDEEFFECT = 311,
CC_TOK = 312,
CCC_TOK = 313,
CSRETCC_TOK = 314,
FASTCC_TOK = 315,
COLDCC_TOK = 316,
X86_STDCALLCC_TOK = 317,
X86_FASTCALLCC_TOK = 318,
DATALAYOUT = 319,
RET = 320,
BR = 321,
SWITCH = 322,
INVOKE = 323,
UNWIND = 324,
UNREACHABLE = 325,
ADD = 326,
SUB = 327,
MUL = 328,
UDIV = 329,
SDIV = 330,
FDIV = 331,
UREM = 332,
SREM = 333,
FREM = 334,
AND = 335,
OR = 336,
XOR = 337,
ICMP = 338,
FCMP = 339,
EQ = 340,
NE = 341,
SLT = 342,
SGT = 343,
SLE = 344,
SGE = 345,
ULT = 346,
UGT = 347,
ULE = 348,
UGE = 349,
OEQ = 350,
ONE = 351,
OLT = 352,
OGT = 353,
OLE = 354,
OGE = 355,
ORD = 356,
UNO = 357,
UEQ = 358,
UNE = 359,
MALLOC = 360,
ALLOCA = 361,
FREE = 362,
LOAD = 363,
STORE = 364,
GETELEMENTPTR = 365,
TRUNC = 366,
ZEXT = 367,
SEXT = 368,
FPTRUNC = 369,
FPEXT = 370,
BITCAST = 371,
UITOFP = 372,
SITOFP = 373,
FPTOUI = 374,
FPTOSI = 375,
INTTOPTR = 376,
PTRTOINT = 377,
PHI_TOK = 378,
SELECT = 379,
SHL = 380,
LSHR = 381,
ASHR = 382,
VAARG = 383,
EXTRACTELEMENT = 384,
INSERTELEMENT = 385,
SHUFFLEVECTOR = 386,
NORETURN = 387
};
#endif
/* Tokens. */
@ -172,138 +169,135 @@
#define FPVAL 262
#define VOID 263
#define BOOL 264
#define INT8 265
#define INT16 266
#define INT32 267
#define INT64 268
#define FLOAT 269
#define DOUBLE 270
#define LABEL 271
#define TYPE 272
#define VAR_ID 273
#define LABELSTR 274
#define STRINGCONSTANT 275
#define IMPLEMENTATION 276
#define ZEROINITIALIZER 277
#define TRUETOK 278
#define FALSETOK 279
#define BEGINTOK 280
#define ENDTOK 281
#define DECLARE 282
#define DEFINE 283
#define GLOBAL 284
#define CONSTANT 285
#define SECTION 286
#define VOLATILE 287
#define TO 288
#define DOTDOTDOT 289
#define NULL_TOK 290
#define UNDEF 291
#define INTERNAL 292
#define LINKONCE 293
#define WEAK 294
#define APPENDING 295
#define DLLIMPORT 296
#define DLLEXPORT 297
#define EXTERN_WEAK 298
#define OPAQUE 299
#define NOT 300
#define EXTERNAL 301
#define TARGET 302
#define TRIPLE 303
#define ENDIAN 304
#define POINTERSIZE 305
#define LITTLE 306
#define BIG 307
#define ALIGN 308
#define DEPLIBS 309
#define CALL 310
#define TAIL 311
#define ASM_TOK 312
#define MODULE 313
#define SIDEEFFECT 314
#define CC_TOK 315
#define CCC_TOK 316
#define CSRETCC_TOK 317
#define FASTCC_TOK 318
#define COLDCC_TOK 319
#define X86_STDCALLCC_TOK 320
#define X86_FASTCALLCC_TOK 321
#define DATALAYOUT 322
#define RET 323
#define BR 324
#define SWITCH 325
#define INVOKE 326
#define UNWIND 327
#define UNREACHABLE 328
#define ADD 329
#define SUB 330
#define MUL 331
#define UDIV 332
#define SDIV 333
#define FDIV 334
#define UREM 335
#define SREM 336
#define FREM 337
#define AND 338
#define OR 339
#define XOR 340
#define ICMP 341
#define FCMP 342
#define EQ 343
#define NE 344
#define SLT 345
#define SGT 346
#define SLE 347
#define SGE 348
#define ULT 349
#define UGT 350
#define ULE 351
#define UGE 352
#define OEQ 353
#define ONE 354
#define OLT 355
#define OGT 356
#define OLE 357
#define OGE 358
#define ORD 359
#define UNO 360
#define UEQ 361
#define UNE 362
#define MALLOC 363
#define ALLOCA 364
#define FREE 365
#define LOAD 366
#define STORE 367
#define GETELEMENTPTR 368
#define TRUNC 369
#define ZEXT 370
#define SEXT 371
#define FPTRUNC 372
#define FPEXT 373
#define BITCAST 374
#define UITOFP 375
#define SITOFP 376
#define FPTOUI 377
#define FPTOSI 378
#define INTTOPTR 379
#define PTRTOINT 380
#define PHI_TOK 381
#define SELECT 382
#define SHL 383
#define LSHR 384
#define ASHR 385
#define VAARG 386
#define EXTRACTELEMENT 387
#define INSERTELEMENT 388
#define SHUFFLEVECTOR 389
#define NORETURN 390
#define INTTYPE 265
#define FLOAT 266
#define DOUBLE 267
#define LABEL 268
#define TYPE 269
#define VAR_ID 270
#define LABELSTR 271
#define STRINGCONSTANT 272
#define IMPLEMENTATION 273
#define ZEROINITIALIZER 274
#define TRUETOK 275
#define FALSETOK 276
#define BEGINTOK 277
#define ENDTOK 278
#define DECLARE 279
#define DEFINE 280
#define GLOBAL 281
#define CONSTANT 282
#define SECTION 283
#define VOLATILE 284
#define TO 285
#define DOTDOTDOT 286
#define NULL_TOK 287
#define UNDEF 288
#define INTERNAL 289
#define LINKONCE 290
#define WEAK 291
#define APPENDING 292
#define DLLIMPORT 293
#define DLLEXPORT 294
#define EXTERN_WEAK 295
#define OPAQUE 296
#define NOT 297
#define EXTERNAL 298
#define TARGET 299
#define TRIPLE 300
#define ENDIAN 301
#define POINTERSIZE 302
#define LITTLE 303
#define BIG 304
#define ALIGN 305
#define DEPLIBS 306
#define CALL 307
#define TAIL 308
#define ASM_TOK 309
#define MODULE 310
#define SIDEEFFECT 311
#define CC_TOK 312
#define CCC_TOK 313
#define CSRETCC_TOK 314
#define FASTCC_TOK 315
#define COLDCC_TOK 316
#define X86_STDCALLCC_TOK 317
#define X86_FASTCALLCC_TOK 318
#define DATALAYOUT 319
#define RET 320
#define BR 321
#define SWITCH 322
#define INVOKE 323
#define UNWIND 324
#define UNREACHABLE 325
#define ADD 326
#define SUB 327
#define MUL 328
#define UDIV 329
#define SDIV 330
#define FDIV 331
#define UREM 332
#define SREM 333
#define FREM 334
#define AND 335
#define OR 336
#define XOR 337
#define ICMP 338
#define FCMP 339
#define EQ 340
#define NE 341
#define SLT 342
#define SGT 343
#define SLE 344
#define SGE 345
#define ULT 346
#define UGT 347
#define ULE 348
#define UGE 349
#define OEQ 350
#define ONE 351
#define OLT 352
#define OGT 353
#define OLE 354
#define OGE 355
#define ORD 356
#define UNO 357
#define UEQ 358
#define UNE 359
#define MALLOC 360
#define ALLOCA 361
#define FREE 362
#define LOAD 363
#define STORE 364
#define GETELEMENTPTR 365
#define TRUNC 366
#define ZEXT 367
#define SEXT 368
#define FPTRUNC 369
#define FPEXT 370
#define BITCAST 371
#define UITOFP 372
#define SITOFP 373
#define FPTOUI 374
#define FPTOSI 375
#define INTTOPTR 376
#define PTRTOINT 377
#define PHI_TOK 378
#define SELECT 379
#define SHL 380
#define LSHR 381
#define ASHR 382
#define VAARG 383
#define EXTRACTELEMENT 384
#define INSERTELEMENT 385
#define SHUFFLEVECTOR 386
#define NORETURN 387
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 876 "/proj/llvm/llvm-4/lib/AsmParser/llvmAsmParser.y"
#line 876 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y"
typedef union YYSTYPE {
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
@ -350,7 +344,7 @@ typedef union YYSTYPE {
llvm::FCmpInst::Predicate FPredicate;
} YYSTYPE;
/* Line 1447 of yacc.c. */
#line 354 "llvmAsmParser.tab.h"
#line 348 "llvmAsmParser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1

View File

@ -961,7 +961,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
// Built in types...
%type <TypeVal> Types ResultTypes
%type <PrimType> IntType FPType PrimType // Classifications
%token <PrimType> VOID BOOL INT8 INT16 INT32 INT64
%token <PrimType> VOID BOOL INTTYPE
%token <PrimType> FLOAT DOUBLE LABEL
%token TYPE
@ -1054,7 +1054,7 @@ FPredicates
// These are some types that allow classification if we only want a particular
// thing... for example, only a signed, unsigned, or integral type.
IntType : INT64 | INT32 | INT16 | INT8;
IntType : INTTYPE;
FPType : FLOAT | DOUBLE;
// OptAssign - Value producing statements have an optional assignment component
@ -1181,7 +1181,7 @@ GlobalVarAttribute : SectionString {
// Derived types are added later...
//
PrimType : BOOL | INT8 | INT16 | INT32 | INT64 | FLOAT | DOUBLE | LABEL ;
PrimType : BOOL | INTTYPE | FLOAT | DOUBLE | LABEL ;
Types
: OPAQUE {
@ -1257,8 +1257,8 @@ Types
const llvm::Type* ElemTy = $4->get();
if ((unsigned)$2 != $2)
GEN_ERROR("Unsigned result not equal to signed result");
if (!ElemTy->isPrimitiveType())
GEN_ERROR("Elemental type of a PackedType must be primitive");
if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger())
GEN_ERROR("Element type of a PackedType must be primitive");
if (!isPowerOf2_32($2))
GEN_ERROR("Vector length should be a power of 2!");
$$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2)));
@ -2780,7 +2780,7 @@ MemoryInst : MALLOC Types OptCAlign {
delete $2;
CHECK_FOR_ERROR
}
| MALLOC Types ',' INT32 ValueRef OptCAlign {
| MALLOC Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
Value* tmpVal = getVal($4, $5);
@ -2795,7 +2795,7 @@ MemoryInst : MALLOC Types OptCAlign {
delete $2;
CHECK_FOR_ERROR
}
| ALLOCA Types ',' INT32 ValueRef OptCAlign {
| ALLOCA Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
Value* tmpVal = getVal($4, $5);

View File

@ -961,7 +961,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
// Built in types...
%type <TypeVal> Types ResultTypes
%type <PrimType> IntType FPType PrimType // Classifications
%token <PrimType> VOID BOOL INT8 INT16 INT32 INT64
%token <PrimType> VOID BOOL INTTYPE
%token <PrimType> FLOAT DOUBLE LABEL
%token TYPE
@ -1054,7 +1054,7 @@ FPredicates
// These are some types that allow classification if we only want a particular
// thing... for example, only a signed, unsigned, or integral type.
IntType : INT64 | INT32 | INT16 | INT8;
IntType : INTTYPE;
FPType : FLOAT | DOUBLE;
// OptAssign - Value producing statements have an optional assignment component
@ -1181,7 +1181,7 @@ GlobalVarAttribute : SectionString {
// Derived types are added later...
//
PrimType : BOOL | INT8 | INT16 | INT32 | INT64 | FLOAT | DOUBLE | LABEL ;
PrimType : BOOL | INTTYPE | FLOAT | DOUBLE | LABEL ;
Types
: OPAQUE {
@ -1257,8 +1257,8 @@ Types
const llvm::Type* ElemTy = $4->get();
if ((unsigned)$2 != $2)
GEN_ERROR("Unsigned result not equal to signed result");
if (!ElemTy->isPrimitiveType())
GEN_ERROR("Elemental type of a PackedType must be primitive");
if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger())
GEN_ERROR("Element type of a PackedType must be primitive");
if (!isPowerOf2_32($2))
GEN_ERROR("Vector length should be a power of 2!");
$$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2)));
@ -2780,7 +2780,7 @@ MemoryInst : MALLOC Types OptCAlign {
delete $2;
CHECK_FOR_ERROR
}
| MALLOC Types ',' INT32 ValueRef OptCAlign {
| MALLOC Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
Value* tmpVal = getVal($4, $5);
@ -2795,7 +2795,7 @@ MemoryInst : MALLOC Types OptCAlign {
delete $2;
CHECK_FOR_ERROR
}
| ALLOCA Types ',' INT32 ValueRef OptCAlign {
| ALLOCA Types ',' INTTYPE ValueRef OptCAlign {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
Value* tmpVal = getVal($4, $5);

View File

@ -189,7 +189,7 @@ inline bool BytecodeReader::hasImplicitNull(unsigned TyID) {
/// Obtain a type given a typeid and account for things like compaction tables,
/// function level vs module level, and the offsetting for the primitive types.
const Type *BytecodeReader::getType(unsigned ID) {
if (ID < Type::FirstDerivedTyID)
if (ID <= Type::LastPrimitiveTyID)
if (const Type *T = Type::getPrimitiveType((Type::TypeID)ID))
return T; // Asked for a primitive type...
@ -573,7 +573,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
if (Oprnds.size() != 2)
error("Invalid extractelement instruction!");
Value *V1 = getValue(iType, Oprnds[0]);
Value *V2 = getValue(Type::Int32TyID, Oprnds[1]);
Value *V2 = getValue(Int32TySlot, Oprnds[1]);
if (!ExtractElementInst::isValidOperands(V1, V2))
error("Invalid extractelement instruction!");
@ -588,7 +588,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
Value *V1 = getValue(iType, Oprnds[0]);
Value *V2 = getValue(getTypeSlot(PackedTy->getElementType()),Oprnds[1]);
Value *V3 = getValue(Type::Int32TyID, Oprnds[2]);
Value *V3 = getValue(Int32TySlot, Oprnds[2]);
if (!InsertElementInst::isValidOperands(V1, V2, V3))
error("Invalid insertelement instruction!");
@ -684,7 +684,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
case Instruction::Select:
if (Oprnds.size() != 3)
error("Invalid Select instruction!");
Result = new SelectInst(getValue(Type::Int1TyID, Oprnds[0]),
Result = new SelectInst(getValue(BoolTySlot, Oprnds[0]),
getValue(iType, Oprnds[1]),
getValue(iType, Oprnds[2]));
break;
@ -714,7 +714,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
case Instruction::AShr:
Result = new ShiftInst(Instruction::OtherOps(Opcode),
getValue(iType, Oprnds[0]),
getValue(Type::Int8TyID, Oprnds[1]));
getValue(Int8TySlot, Oprnds[1]));
break;
case Instruction::Ret:
if (Oprnds.size() == 0)
@ -730,7 +730,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
Result = new BranchInst(getBasicBlock(Oprnds[0]));
else if (Oprnds.size() == 3)
Result = new BranchInst(getBasicBlock(Oprnds[0]),
getBasicBlock(Oprnds[1]), getValue(Type::Int1TyID , Oprnds[2]));
getBasicBlock(Oprnds[1]), getValue(BoolTySlot, Oprnds[2]));
else
error("Invalid number of operands for a 'br' instruction!");
break;
@ -877,7 +877,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
error("Invalid malloc instruction!");
Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
getValue(Type::Int32TyID, Oprnds[0]), Align);
getValue(Int32TySlot, Oprnds[0]), Align);
break;
}
case Instruction::Alloca: {
@ -890,7 +890,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
error("Invalid alloca instruction!");
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
getValue(Type::Int32TyID, Oprnds[0]), Align);
getValue(Int32TySlot, Oprnds[0]), Align);
break;
}
case Instruction::Free:
@ -916,12 +916,12 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
// any of the 32 or 64-bit integer types. The actual choice of
// type is encoded in the low bit of the slot number.
if (isa<StructType>(TopTy))
IdxTy = Type::Int32TyID;
IdxTy = Int32TySlot;
else {
switch (ValIdx & 1) {
default:
case 0: IdxTy = Type::Int32TyID; break;
case 1: IdxTy = Type::Int64TyID; break;
case 0: IdxTy = Int32TySlot; break;
case 1: IdxTy = Int64TySlot; break;
}
ValIdx >>= 1;
}
@ -1064,7 +1064,7 @@ void BytecodeReader::ParseValueSymbolTable(Function *CurrentFunction,
unsigned slot = read_vbr_uint();
std::string Name = read_str();
Value *V = 0;
if (Typ == Type::LabelTyID) {
if (Typ == LabelTySlot) {
if (slot < BBMap.size())
V = BBMap[slot];
} else {
@ -1160,6 +1160,11 @@ const Type *BytecodeReader::ParseType() {
return Result;
switch (PrimType) {
case Type::IntegerTyID: {
unsigned NumBits = read_vbr_uint();
Result = IntegerType::get(NumBits);
break;
}
case Type::FunctionTyID: {
const Type *RetType = readType();
unsigned RetAttr = read_vbr_uint();
@ -1204,7 +1209,7 @@ const Type *BytecodeReader::ParseType() {
Result = StructType::get(Elements, false);
break;
}
case Type::BC_ONLY_PackedStructTyID: {
case Type::PackedStructTyID: {
std::vector<const Type*> Elements;
unsigned Typ = read_vbr_uint();
while (Typ) { // List is terminated by void/0 typeid
@ -1399,32 +1404,29 @@ Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
const Type *Ty = getType(TypeID);
Constant *Result = 0;
switch (Ty->getTypeID()) {
case Type::Int1TyID: {
unsigned Val = read_vbr_uint();
if (Val != 0 && Val != 1)
error("Invalid boolean value read.");
Result = ConstantInt::get(Type::Int1Ty, Val == 1);
if (Handler) Handler->handleConstantValue(Result);
break;
}
case Type::Int8TyID: // Unsigned integer types...
case Type::Int16TyID:
case Type::Int32TyID: {
unsigned Val = read_vbr_uint();
if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
error("Invalid unsigned byte/short/int read.");
Result = ConstantInt::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
break;
}
case Type::Int64TyID: {
uint64_t Val = read_vbr_uint64();
if (!ConstantInt::isValueValidForType(Ty, Val))
error("Invalid constant integer read.");
Result = ConstantInt::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
case Type::IntegerTyID: {
const IntegerType *IT = cast<IntegerType>(Ty);
if (IT->getBitWidth() <= 32) {
uint32_t Val = read_vbr_uint();
if (IT->getBitWidth() == 1) {
if (Val != 0 && Val != 1)
error("Invalid boolean value read.");
Result = ConstantInt::get(Type::Int1Ty, Val == 1);
if (Handler) Handler->handleConstantValue(Result);
} else {
if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
error("Integer value read is invalid for type.");
Result = ConstantInt::get(IT, Val);
if (Handler) Handler->handleConstantValue(Result);
}
} else if (IT->getBitWidth() <= 64) {
uint64_t Val = read_vbr_uint64();
if (!ConstantInt::isValueValidForType(Ty, Val))
error("Invalid constant integer read.");
Result = ConstantInt::get(IT, Val);
if (Handler) Handler->handleConstantValue(Result);
} else
assert("Integer types > 64 bits not supported");
break;
}
case Type::FloatTyID: {

View File

@ -415,6 +415,20 @@ private:
BytecodeReader(const BytecodeReader &); // DO NOT IMPLEMENT
void operator=(const BytecodeReader &); // DO NOT IMPLEMENT
// This enum provides the values of the well-known type slots that are always
// emitted as the first few types in the table by the BytecodeWriter class.
enum WellKnownTypeSlots {
VoidTypeSlot = 0, ///< TypeID == VoidTyID
FloatTySlot = 1, ///< TypeID == FloatTyID
DoubleTySlot = 2, ///< TypeID == DoubleTyID
LabelTySlot = 3, ///< TypeID == LabelTyID
BoolTySlot = 4, ///< TypeID == IntegerTyID, width = 1
Int8TySlot = 5, ///< TypeID == IntegerTyID, width = 8
Int16TySlot = 6, ///< TypeID == IntegerTyID, width = 16
Int32TySlot = 7, ///< TypeID == IntegerTyID, width = 32
Int64TySlot = 8 ///< TypeID == IntegerTyID, width = 64
};
/// @}
/// @name Reader Primitives
/// @{

View File

@ -31,26 +31,45 @@
#include <functional>
using namespace llvm;
#if 0
#ifndef NDEBUG
#include "llvm/Support/Streams.h"
#define SC_DEBUG(X) cerr << X
#include "llvm/Support/CommandLine.h"
static cl::opt<bool> SlotCalculatorDebugOption("scdebug",cl::init(false),
cl::desc("Enable SlotCalculator debug output"), cl::Hidden);
#define SC_DEBUG(X) if (SlotCalculatorDebugOption) cerr << X
#else
#define SC_DEBUG(X)
#endif
void SlotCalculator::insertPrimitives() {
// Preload the table with the built-in types. These built-in types are
// inserted first to ensure that they have low integer indices which helps to
// keep bytecode sizes small. Note that the first group of indices must match
// the Type::TypeIDs for the primitive types. After that the integer types are
// added, but the order and value is not critical. What is critical is that
// the indices of these "well known" slot numbers be properly maintained in
// Reader.h which uses them directly to extract values of these types.
SC_DEBUG("Inserting primitive types:\n");
// See WellKnownTypeSlots in Reader.h
insertType(Type::VoidTy, true); // 0: VoidTySlot
insertType(Type::FloatTy, true); // 1: FloatTySlot
insertType(Type::DoubleTy, true); // 2: DoubleTySlot
insertType(Type::LabelTy, true); // 3: LabelTySlot
assert(TypeMap.size() == Type::FirstDerivedTyID && "Invalid primitive insert");
// Above here *must* correspond 1:1 with the primitive types.
insertType(Type::Int1Ty, true); // 4: BoolTySlot
insertType(Type::Int8Ty, true); // 5: Int8TySlot
insertType(Type::Int16Ty, true); // 6: Int16TySlot
insertType(Type::Int32Ty, true); // 7: Int32TySlot
insertType(Type::Int64Ty, true); // 8: Int64TySlot
}
SlotCalculator::SlotCalculator(const Module *M ) {
ModuleContainsAllFunctionConstants = false;
ModuleTypeLevel = 0;
TheModule = M;
// Preload table... Make sure that all of the primitive types are in the table
// and that their Primitive ID is equal to their slot #
//
SC_DEBUG("Inserting primitive types:\n");
for (unsigned i = 0; i < Type::FirstDerivedTyID; ++i) {
assert(Type::getPrimitiveType((Type::TypeID)i));
insertType(Type::getPrimitiveType((Type::TypeID)i), true);
}
insertPrimitives();
if (M == 0) return; // Empty table...
processModule();
@ -60,14 +79,7 @@ SlotCalculator::SlotCalculator(const Function *M ) {
ModuleContainsAllFunctionConstants = false;
TheModule = M ? M->getParent() : 0;
// Preload table... Make sure that all of the primitive types are in the table
// and that their Primitive ID is equal to their slot #
//
SC_DEBUG("Inserting primitive types:\n");
for (unsigned i = 0; i < Type::FirstDerivedTyID; ++i) {
assert(Type::getPrimitiveType((Type::TypeID)i));
insertType(Type::getPrimitiveType((Type::TypeID)i), true);
}
insertPrimitives();
if (TheModule == 0) return; // Empty table...
@ -423,15 +435,14 @@ unsigned SlotCalculator::getOrCreateCompactionTableSlot(const Value *V) {
/// getOrCreateCompactionTableSlot - This method is used to build up the initial
/// approximation of the compaction table.
unsigned SlotCalculator::getOrCreateCompactionTableSlot(const Type *T) {
std::map<const Type*, unsigned>::iterator I =
CompactionTypeMap.lower_bound(T);
CompactionTypeMapType::iterator I = CompactionTypeMap.lower_bound(T);
if (I != CompactionTypeMap.end() && I->first == T)
return I->second; // Already exists?
unsigned SlotNo = CompactionTypes.size();
SC_DEBUG("Inserting Compaction Type #" << SlotNo << ": " << T << "\n");
SC_DEBUG("Inserting Compaction Type #" << SlotNo << ": " << *T << "\n");
CompactionTypes.push_back(T);
CompactionTypeMap.insert(std::make_pair(T, SlotNo));
CompactionTypeMap[T] = SlotNo;
return SlotNo;
}
@ -452,6 +463,16 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
CompactionTypes.push_back(PrimTy);
CompactionTypeMap[PrimTy] = i;
}
CompactionTypeMap[Type::Int1Ty] = CompactionTypes.size();
CompactionTypes.push_back(Type::Int1Ty);
CompactionTypeMap[Type::Int8Ty] = CompactionTypes.size();
CompactionTypes.push_back(Type::Int8Ty);
CompactionTypeMap[Type::Int16Ty] = CompactionTypes.size();
CompactionTypes.push_back(Type::Int16Ty);
CompactionTypeMap[Type::Int32Ty] = CompactionTypes.size();
CompactionTypes.push_back(Type::Int32Ty);
CompactionTypeMap[Type::Int64Ty] = CompactionTypes.size();
CompactionTypes.push_back(Type::Int64Ty);
// Next, include any types used by function arguments.
for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
@ -485,7 +506,7 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
if (CompactionTable[i].empty() && (i != Type::VoidTyID) &&
i != Type::LabelTyID) {
const Type *Ty = CompactionTypes[i];
SC_DEBUG("Getting Null Value #" << i << " for Type " << Ty << "\n");
SC_DEBUG("Getting Null Value #" << i << " for Type " << *Ty << "\n");
assert(Ty->getTypeID() != Type::VoidTyID);
assert(Ty->getTypeID() != Type::LabelTyID);
getOrCreateCompactionTableSlot(Constant::getNullValue(Ty));
@ -618,7 +639,8 @@ void SlotCalculator::pruneCompactionTable() {
/// to determine if its actually empty.
bool SlotCalculator::CompactionTableIsEmpty() const {
// Check a degenerate case, just in case.
if (CompactionTable.size() == 0) return true;
if (CompactionTable.size() == 0)
return true;
// Check each plane
for (unsigned i = 0, e = CompactionTable.size(); i < e; ++i) {
@ -830,7 +852,7 @@ int SlotCalculator::doInsertValue(const Value *D) {
unsigned DestSlot = NodeMap[D] = Table[Ty].size();
Table[Ty].push_back(D);
SC_DEBUG(" Inserting value [" << Ty << "] = " << D << " slot=" <<
SC_DEBUG(" Inserting value [" << Ty << "] = " << *D << " slot=" <<
DestSlot << " [");
// G = Global, C = Constant, T = Type, F = Function, o = other
SC_DEBUG((isa<GlobalVariable>(D) ? "G" : (isa<Constant>(D) ? "C" :
@ -848,7 +870,6 @@ int SlotCalculator::doInsertType(const Type *Ty) {
unsigned DestSlot = TypeMap[Ty] = Types.size();
Types.push_back(Ty);
SC_DEBUG(" Inserting type [" << DestSlot << "] = " << Ty << "\n" );
SC_DEBUG(" Inserting type [" << DestSlot << "] = " << *Ty << "\n" );
return (int)DestSlot;
}

View File

@ -177,6 +177,9 @@ private:
unsigned getOrCreateCompactionTableSlot(const Value *V);
unsigned getOrCreateCompactionTableSlot(const Type *V);
void pruneCompactionTable();
// insertPrimitives - helper for constructors to insert primitive types.
void insertPrimitives();
};
} // End llvm namespace

View File

@ -200,16 +200,18 @@ inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
void BytecodeWriter::outputType(const Type *T) {
const StructType* STy = dyn_cast<StructType>(T);
if(STy && STy->isPacked())
output_vbr((unsigned)Type::BC_ONLY_PackedStructTyID);
output_vbr((unsigned)Type::PackedStructTyID);
else
output_vbr((unsigned)T->getTypeID());
// That's all there is to handling primitive types...
if (T->isPrimitiveType()) {
if (T->isPrimitiveType())
return; // We might do this if we alias a prim type: %x = type int
}
switch (T->getTypeID()) { // Handle derived types now.
case Type::IntegerTyID:
output_vbr(cast<IntegerType>(T)->getBitWidth());
break;
case Type::FunctionTyID: {
const FunctionType *MT = cast<FunctionType>(T);
int Slot = Table.getSlot(MT->getReturnType());
@ -290,8 +292,8 @@ void BytecodeWriter::outputType(const Type *T) {
}
void BytecodeWriter::outputConstant(const Constant *CPV) {
assert((CPV->getType()->isPrimitiveType() || !CPV->isNullValue()) &&
"Shouldn't output null constants!");
assert(((CPV->getType()->isPrimitiveType() || CPV->getType()->isIntegral()) ||
!CPV->isNullValue()) && "Shouldn't output null constants!");
// We must check for a ConstantExpr before switching by type because
// a ConstantExpr can be of any type, and has no explicit value.
@ -321,19 +323,21 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
}
switch (CPV->getType()->getTypeID()) {
case Type::Int1TyID: // Boolean Types
if (cast<ConstantInt>(CPV)->getZExtValue())
output_vbr(1U);
else
output_vbr(0U);
break;
case Type::Int8TyID: // Unsigned integer types...
case Type::Int16TyID:
case Type::Int32TyID:
case Type::Int64TyID:
output_vbr(cast<ConstantInt>(CPV)->getZExtValue());
case Type::IntegerTyID: { // Integer types...
unsigned NumBits = cast<IntegerType>(CPV->getType())->getBitWidth();
if (NumBits == 1)
if (cast<ConstantInt>(CPV)->getZExtValue())
output_vbr(1U);
else
output_vbr(0U);
else if (NumBits <= 32)
output_vbr(uint32_t(cast<ConstantInt>(CPV)->getZExtValue()));
else if (NumBits <= 64)
output_vbr(uint64_t(cast<ConstantInt>(CPV)->getZExtValue()));
else
assert("Integer types > 64 bits not supported.");
break;
}
case Type::ArrayTyID: {
const ConstantArray *CPA = cast<ConstantArray>(CPV);
@ -484,12 +488,12 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
assert(Slot >= 0 && "No slot number for value!?!?");
if (isa<SequentialType>(*TI)) {
unsigned IdxId;
switch (I->getOperand(Idx)->getType()->getTypeID()) {
default: assert(0 && "Unknown index type!");
case Type::Int32TyID: IdxId = 0; break;
case Type::Int64TyID: IdxId = 1; break;
}
// These should be either 32-bits or 64-bits, however, with bit
// accurate types we just distinguish between less than or equal to
// 32-bits or greater than 32-bits.
const IntegerType *IdxTy =
cast<IntegerType>(I->getOperand(Idx)->getType());
unsigned IdxId = IdxTy->getBitWidth() <= 32 ? 0 : 1;
Slot = (Slot << 1) | IdxId;
}
output_vbr(unsigned(Slot));
@ -735,12 +739,12 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
I != E; ++I, ++Idx)
if (isa<SequentialType>(*I)) {
unsigned IdxId;
switch (GEP->getOperand(Idx)->getType()->getTypeID()) {
default: assert(0 && "Unknown index type!");
case Type::Int32TyID: IdxId = 0; break;
case Type::Int64TyID: IdxId = 1; break;
}
// These should be either 32-bits or 64-bits, however, with bit
// accurate types we just distinguish between less than or equal to
// 32-bits or greater than 32-bits.
const IntegerType *IdxTy =
cast<IntegerType>(GEP->getOperand(Idx)->getType());
unsigned IdxId = IdxTy->getBitWidth() <= 32 ? 0 : 1;
Slots[Idx] = (Slots[Idx] << 1) | IdxId;
if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx];
}

View File

@ -459,7 +459,7 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
// We can emit the pointer value into this slot if the slot is an
// integer slot greater or equal to the size of the pointer.
if (Ty->isIntegral() &&
Ty->getPrimitiveSize() >= TD->getTypeSize(Op->getType()))
TD->getTypeSize(Ty) >= TD->getTypeSize(Op->getType()))
return EmitConstantValueOnly(Op);
assert(0 && "FIXME: Don't yet support this kind of constant cast expr");
@ -917,28 +917,29 @@ void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2,
void AsmPrinter::printDataDirective(const Type *type) {
const TargetData *TD = TM.getTargetData();
switch (type->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID:
O << TAI->getData8bitsDirective();
break;
case Type::Int16TyID:
O << TAI->getData16bitsDirective();
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(type)->getBitWidth();
if (BitWidth <= 8)
O << TAI->getData8bitsDirective();
else if (BitWidth <= 16)
O << TAI->getData16bitsDirective();
else if (BitWidth <= 32)
O << TAI->getData32bitsDirective();
else if (BitWidth <= 64) {
assert(TAI->getData64bitsDirective() &&
"Target cannot handle 64-bit constant exprs!");
O << TAI->getData64bitsDirective();
}
break;
}
case Type::PointerTyID:
if (TD->getPointerSize() == 8) {
assert(TAI->getData64bitsDirective() &&
"Target cannot handle 64-bit pointer exprs!");
O << TAI->getData64bitsDirective();
break;
} else {
O << TAI->getData32bitsDirective();
}
//Fall through for pointer size == int size
case Type::Int32TyID:
O << TAI->getData32bitsDirective();
break;
case Type::Int64TyID:
assert(TAI->getData64bitsDirective() &&
"Target cannot handle 64-bit constant exprs!");
O << TAI->getData64bitsDirective();
break;
case Type::FloatTyID: case Type::DoubleTyID:
assert (0 && "Should have already output floating point constant.");

View File

@ -708,8 +708,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
if (isa<UndefValue>(PC)) {
continue;
} else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(PC)) {
unsigned ElementSize =
CP->getType()->getElementType()->getPrimitiveSize();
unsigned ElementSize = TD->getTypeSize(CP->getType()->getElementType());
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize));
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(PC)) {
@ -726,27 +725,42 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
}
} else if (PC->getType()->isFirstClassType()) {
unsigned char *ptr = (unsigned char *)PA;
uint64_t val;
switch (PC->getType()->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID:
ptr[0] = cast<ConstantInt>(PC)->getZExtValue();
break;
case Type::Int16TyID:
val = cast<ConstantInt>(PC)->getZExtValue();
if (TD->isBigEndian())
val = ByteSwap_16(val);
ptr[0] = val;
ptr[1] = val >> 8;
break;
case Type::Int32TyID:
case Type::FloatTyID:
if (PC->getType()->getTypeID() == Type::FloatTyID) {
val = FloatToBits(cast<ConstantFP>(PC)->getValue());
case Type::IntegerTyID: {
unsigned NumBits = cast<IntegerType>(PC->getType())->getBitWidth();
uint64_t val = cast<ConstantInt>(PC)->getZExtValue();
if (NumBits <= 8)
ptr[0] = val;
else if (NumBits <= 16) {
if (TD->isBigEndian())
val = ByteSwap_16(val);
ptr[0] = val;
ptr[1] = val >> 8;
} else if (NumBits <= 32) {
if (TD->isBigEndian())
val = ByteSwap_32(val);
ptr[0] = val;
ptr[1] = val >> 8;
ptr[2] = val >> 16;
ptr[3] = val >> 24;
} else if (NumBits <= 64) {
if (TD->isBigEndian())
val = ByteSwap_64(val);
ptr[0] = val;
ptr[1] = val >> 8;
ptr[2] = val >> 16;
ptr[3] = val >> 24;
ptr[4] = val >> 32;
ptr[5] = val >> 40;
ptr[6] = val >> 48;
ptr[7] = val >> 56;
} else {
val = cast<ConstantInt>(PC)->getZExtValue();
assert(0 && "Not implemented: bit widths > 64");
}
break;
}
case Type::FloatTyID: {
uint64_t val = FloatToBits(cast<ConstantFP>(PC)->getValue());
if (TD->isBigEndian())
val = ByteSwap_32(val);
ptr[0] = val;
@ -754,13 +768,9 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
ptr[2] = val >> 16;
ptr[3] = val >> 24;
break;
case Type::DoubleTyID:
case Type::Int64TyID:
if (PC->getType()->getTypeID() == Type::DoubleTyID) {
val = DoubleToBits(cast<ConstantFP>(PC)->getValue());
} else {
val = cast<ConstantInt>(PC)->getZExtValue();
}
}
case Type::DoubleTyID: {
uint64_t val = DoubleToBits(cast<ConstantFP>(PC)->getValue());
if (TD->isBigEndian())
val = ByteSwap_64(val);
ptr[0] = val;
@ -772,6 +782,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
ptr[6] = val >> 48;
ptr[7] = val >> 56;
break;
}
case Type::PointerTyID:
if (isa<ConstantPointerNull>(C))
memset(ptr, 0, TD->getPointerSize());
@ -790,8 +801,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
} else if (isa<ConstantAggregateZero>(PC)) {
memset((void*)PA, 0, (size_t)TD->getTypeSize(PC->getType()));
} else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(PC)) {
unsigned ElementSize =
CPA->getType()->getElementType()->getPrimitiveSize();
unsigned ElementSize = TD->getTypeSize(CPA->getType()->getElementType());
for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize));
} else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(PC)) {

View File

@ -296,6 +296,28 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
return state.getGlobalAddressMap(locked)[GV];
}
/// This macro is used to handle a variety of situations involing integer
/// values where the action should be done to one of the GenericValue members.
/// THEINTTY is a const Type * for the integer type. ACTION1 comes before
/// the GenericValue, ACTION2 comes after.
#define DO_FOR_INTEGER(THEINTTY, ACTION) \
{ \
unsigned BitWidth = cast<IntegerType>(THEINTTY)->getBitWidth(); \
if (BitWidth == 1) {\
ACTION(Int1Val); \
} else if (BitWidth <= 8) {\
ACTION(Int8Val); \
} else if (BitWidth <= 16) {\
ACTION(Int16Val); \
} else if (BitWidth <= 32) { \
ACTION(Int32Val); \
} else if (BitWidth <= 64) { \
ACTION(Int64Val); \
} else {\
assert(0 && "Not implemented: integer types > 64 bits"); \
} \
}
/// This function converts a Constant* into a GenericValue. The interesting
/// part is if C is a ConstantExpr.
/// @brief Get a GenericValue for a Constnat*
@ -350,34 +372,21 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
// IntToPtr casts are just so special. Cast to intptr_t first.
Constant *Op = CE->getOperand(0);
GenericValue GV = getConstantValue(Op);
switch (Op->getType()->getTypeID()) {
case Type::Int1TyID: return PTOGV((void*)(uintptr_t)GV.Int1Val);
case Type::Int8TyID: return PTOGV((void*)(uintptr_t)GV.Int8Val);
case Type::Int16TyID: return PTOGV((void*)(uintptr_t)GV.Int16Val);
case Type::Int32TyID: return PTOGV((void*)(uintptr_t)GV.Int32Val);
case Type::Int64TyID: return PTOGV((void*)(uintptr_t)GV.Int64Val);
default: assert(0 && "Unknown integral type!");
}
#define INT_TO_PTR_ACTION(FIELD) \
return PTOGV((void*)(uintptr_t)GV.FIELD)
DO_FOR_INTEGER(Op->getType(), INT_TO_PTR_ACTION)
#undef INT_TO_PTR_ACTION
break;
}
case Instruction::Add:
switch (CE->getOperand(0)->getType()->getTypeID()) {
default: assert(0 && "Bad add type!"); abort();
case Type::Int64TyID:
Result.Int64Val = getConstantValue(CE->getOperand(0)).Int64Val +
getConstantValue(CE->getOperand(1)).Int64Val;
break;
case Type::Int32TyID:
Result.Int32Val = getConstantValue(CE->getOperand(0)).Int32Val +
getConstantValue(CE->getOperand(1)).Int32Val;
break;
case Type::Int16TyID:
Result.Int16Val = getConstantValue(CE->getOperand(0)).Int16Val +
getConstantValue(CE->getOperand(1)).Int16Val;
break;
case Type::Int8TyID:
Result.Int8Val = getConstantValue(CE->getOperand(0)).Int8Val +
getConstantValue(CE->getOperand(1)).Int8Val;
case Type::IntegerTyID:
#define ADD_ACTION(FIELD) \
Result.FIELD = getConstantValue(CE->getOperand(0)).FIELD + \
getConstantValue(CE->getOperand(1)).FIELD;
DO_FOR_INTEGER(CE->getOperand(0)->getType(),ADD_ACTION);
#undef ADD_ACTION
break;
case Type::FloatTyID:
Result.FloatVal = getConstantValue(CE->getOperand(0)).FloatVal +
@ -399,14 +408,26 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
switch (C->getType()->getTypeID()) {
#define GET_CONST_VAL(TY, CTY, CLASS, GETMETH) \
case Type::TY##TyID: Result.TY##Val = (CTY)cast<CLASS>(C)->GETMETH(); break
GET_CONST_VAL(Int1 , bool , ConstantInt, getZExtValue);
GET_CONST_VAL(Int8 , unsigned char , ConstantInt, getZExtValue);
GET_CONST_VAL(Int16 , unsigned short, ConstantInt, getZExtValue);
GET_CONST_VAL(Int32 , unsigned int , ConstantInt, getZExtValue);
GET_CONST_VAL(Int64 , uint64_t , ConstantInt, getZExtValue);
GET_CONST_VAL(Float , float , ConstantFP, getValue);
GET_CONST_VAL(Double, double , ConstantFP, getValue);
#undef GET_CONST_VAL
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(C->getType())->getBitWidth();
if (BitWidth == 1)
Result.Int1Val = (bool)cast<ConstantInt>(C)->getZExtValue();
else if (BitWidth <= 8)
Result.Int8Val = (uint8_t )cast<ConstantInt>(C)->getZExtValue();
else if (BitWidth <= 16)
Result.Int16Val = (uint16_t )cast<ConstantInt>(C)->getZExtValue();
else if (BitWidth <= 32)
Result.Int32Val = (uint32_t )cast<ConstantInt>(C)->getZExtValue();
else if (BitWidth <= 64)
Result.Int64Val = (uint64_t )cast<ConstantInt>(C)->getZExtValue();
else
assert("Integers with > 64-bits not implemented");
break;
}
case Type::PointerTyID:
if (isa<ConstantPointerNull>(C))
Result.PointerVal = 0;
@ -433,22 +454,43 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
const Type *Ty) {
if (getTargetData()->isLittleEndian()) {
switch (Ty->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID: Ptr->Untyped[0] = Val.Int8Val; break;
case Type::Int16TyID: Ptr->Untyped[0] = Val.Int16Val & 255;
Ptr->Untyped[1] = (Val.Int16Val >> 8) & 255;
break;
Store4BytesLittleEndian:
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth <= 8)
Ptr->Untyped[0] = Val.Int8Val;
else if (BitWidth <= 16) {
Ptr->Untyped[0] = Val.Int16Val & 255;
Ptr->Untyped[1] = (Val.Int16Val >> 8) & 255;
} else if (BitWidth <= 32) {
Ptr->Untyped[0] = Val.Int32Val & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
} else if (BitWidth <= 64) {
Ptr->Untyped[0] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 16);
Ptr->Untyped[3] = (unsigned char)(Val.Int64Val >> 24);
Ptr->Untyped[4] = (unsigned char)(Val.Int64Val >> 32);
Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 40);
Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 48);
Ptr->Untyped[7] = (unsigned char)(Val.Int64Val >> 56);
} else
assert(0 && "Integer types > 64 bits not supported");
break;
}
Store4BytesLittleEndian:
case Type::FloatTyID:
case Type::Int32TyID: Ptr->Untyped[0] = Val.Int32Val & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
break;
case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
goto Store4BytesLittleEndian;
Ptr->Untyped[0] = Val.Int32Val & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
break;
case Type::PointerTyID:
if (getTargetData()->getPointerSize() == 4)
goto Store4BytesLittleEndian;
/* FALL THROUGH */
case Type::DoubleTyID:
case Type::Int64TyID:
Ptr->Untyped[0] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 16);
@ -463,22 +505,43 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
}
} else {
switch (Ty->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID: Ptr->Untyped[0] = Val.Int8Val; break;
case Type::Int16TyID: Ptr->Untyped[1] = Val.Int16Val & 255;
Ptr->Untyped[0] = (Val.Int16Val >> 8) & 255;
break;
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth <= 8)
Ptr->Untyped[0] = Val.Int8Val;
else if (BitWidth <= 16) {
Ptr->Untyped[1] = Val.Int16Val & 255;
Ptr->Untyped[0] = (Val.Int16Val >> 8) & 255;
} else if (BitWidth <= 32) {
Ptr->Untyped[3] = Val.Int32Val & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
} else if (BitWidth <= 64) {
Ptr->Untyped[7] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 16);
Ptr->Untyped[4] = (unsigned char)(Val.Int64Val >> 24);
Ptr->Untyped[3] = (unsigned char)(Val.Int64Val >> 32);
Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 40);
Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 48);
Ptr->Untyped[0] = (unsigned char)(Val.Int64Val >> 56);
} else
assert(0 && "Integer types > 64 bits not supported");
break;
}
Store4BytesBigEndian:
case Type::FloatTyID:
case Type::Int32TyID: Ptr->Untyped[3] = Val.Int32Val & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
break;
case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
goto Store4BytesBigEndian;
Ptr->Untyped[3] = Val.Int32Val & 255;
Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
break;
case Type::PointerTyID:
if (getTargetData()->getPointerSize() == 4)
goto Store4BytesBigEndian;
/* FALL THROUGH */
case Type::DoubleTyID:
case Type::Int64TyID:
Ptr->Untyped[7] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 16);
@ -501,60 +564,104 @@ GenericValue ExecutionEngine::LoadValueFromMemory(GenericValue *Ptr,
GenericValue Result;
if (getTargetData()->isLittleEndian()) {
switch (Ty->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID: Result.Int8Val = Ptr->Untyped[0]; break;
case Type::Int16TyID: Result.Int16Val = (unsigned)Ptr->Untyped[0] |
((unsigned)Ptr->Untyped[1] << 8);
break;
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth <= 8)
Result.Int8Val = Ptr->Untyped[0];
else if (BitWidth <= 16) {
Result.Int16Val = (unsigned)Ptr->Untyped[0] |
((unsigned)Ptr->Untyped[1] << 8);
} else if (BitWidth <= 32) {
Result.Int32Val = (unsigned)Ptr->Untyped[0] |
((unsigned)Ptr->Untyped[1] << 8) |
((unsigned)Ptr->Untyped[2] << 16) |
((unsigned)Ptr->Untyped[3] << 24);
} else if (BitWidth <= 64) {
Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
((uint64_t)Ptr->Untyped[1] << 8) |
((uint64_t)Ptr->Untyped[2] << 16) |
((uint64_t)Ptr->Untyped[3] << 24) |
((uint64_t)Ptr->Untyped[4] << 32) |
((uint64_t)Ptr->Untyped[5] << 40) |
((uint64_t)Ptr->Untyped[6] << 48) |
((uint64_t)Ptr->Untyped[7] << 56);
} else
assert(0 && "Integer types > 64 bits not supported");
break;
}
Load4BytesLittleEndian:
case Type::FloatTyID:
case Type::Int32TyID: Result.Int32Val = (unsigned)Ptr->Untyped[0] |
((unsigned)Ptr->Untyped[1] << 8) |
((unsigned)Ptr->Untyped[2] << 16) |
((unsigned)Ptr->Untyped[3] << 24);
break;
case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
goto Load4BytesLittleEndian;
Result.Int32Val = (unsigned)Ptr->Untyped[0] |
((unsigned)Ptr->Untyped[1] << 8) |
((unsigned)Ptr->Untyped[2] << 16) |
((unsigned)Ptr->Untyped[3] << 24);
break;
case Type::PointerTyID:
if (getTargetData()->getPointerSize() == 4)
goto Load4BytesLittleEndian;
/* FALL THROUGH */
case Type::DoubleTyID:
case Type::Int64TyID: Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
((uint64_t)Ptr->Untyped[1] << 8) |
((uint64_t)Ptr->Untyped[2] << 16) |
((uint64_t)Ptr->Untyped[3] << 24) |
((uint64_t)Ptr->Untyped[4] << 32) |
((uint64_t)Ptr->Untyped[5] << 40) |
((uint64_t)Ptr->Untyped[6] << 48) |
((uint64_t)Ptr->Untyped[7] << 56);
break;
Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
((uint64_t)Ptr->Untyped[1] << 8) |
((uint64_t)Ptr->Untyped[2] << 16) |
((uint64_t)Ptr->Untyped[3] << 24) |
((uint64_t)Ptr->Untyped[4] << 32) |
((uint64_t)Ptr->Untyped[5] << 40) |
((uint64_t)Ptr->Untyped[6] << 48) |
((uint64_t)Ptr->Untyped[7] << 56);
break;
default:
cerr << "Cannot load value of type " << *Ty << "!\n";
abort();
}
} else {
switch (Ty->getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID: Result.Int8Val = Ptr->Untyped[0]; break;
case Type::Int16TyID: Result.Int16Val = (unsigned)Ptr->Untyped[1] |
((unsigned)Ptr->Untyped[0] << 8);
break;
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth <= 8)
Result.Int8Val = Ptr->Untyped[0];
else if (BitWidth <= 16) {
Result.Int16Val = (unsigned)Ptr->Untyped[1] |
((unsigned)Ptr->Untyped[0] << 8);
} else if (BitWidth <= 32) {
Result.Int32Val = (unsigned)Ptr->Untyped[3] |
((unsigned)Ptr->Untyped[2] << 8) |
((unsigned)Ptr->Untyped[1] << 16) |
((unsigned)Ptr->Untyped[0] << 24);
} else if (BitWidth <= 64) {
Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
((uint64_t)Ptr->Untyped[6] << 8) |
((uint64_t)Ptr->Untyped[5] << 16) |
((uint64_t)Ptr->Untyped[4] << 24) |
((uint64_t)Ptr->Untyped[3] << 32) |
((uint64_t)Ptr->Untyped[2] << 40) |
((uint64_t)Ptr->Untyped[1] << 48) |
((uint64_t)Ptr->Untyped[0] << 56);
} else
assert(0 && "Integer types > 64 bits not supported");
break;
}
Load4BytesBigEndian:
case Type::FloatTyID:
case Type::Int32TyID: Result.Int32Val =(unsigned)Ptr->Untyped[3] |
((unsigned)Ptr->Untyped[2] << 8) |
((unsigned)Ptr->Untyped[1] << 16) |
((unsigned)Ptr->Untyped[0] << 24);
Result.Int32Val = (unsigned)Ptr->Untyped[3] |
((unsigned)Ptr->Untyped[2] << 8) |
((unsigned)Ptr->Untyped[1] << 16) |
((unsigned)Ptr->Untyped[0] << 24);
break;
case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
goto Load4BytesBigEndian;
case Type::PointerTyID:
if (getTargetData()->getPointerSize() == 4)
goto Load4BytesBigEndian;
/* FALL THROUGH */
case Type::DoubleTyID:
case Type::Int64TyID: Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
((uint64_t)Ptr->Untyped[6] << 8) |
((uint64_t)Ptr->Untyped[5] << 16) |
((uint64_t)Ptr->Untyped[4] << 24) |
((uint64_t)Ptr->Untyped[3] << 32) |
((uint64_t)Ptr->Untyped[2] << 40) |
((uint64_t)Ptr->Untyped[1] << 48) |
((uint64_t)Ptr->Untyped[0] << 56);
break;
Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
((uint64_t)Ptr->Untyped[6] << 8) |
((uint64_t)Ptr->Untyped[5] << 16) |
((uint64_t)Ptr->Untyped[4] << 24) |
((uint64_t)Ptr->Untyped[3] << 32) |
((uint64_t)Ptr->Untyped[2] << 40) |
((uint64_t)Ptr->Untyped[1] << 48) |
((uint64_t)Ptr->Untyped[0] << 56);
break;
default:
cerr << "Cannot load value of type " << *Ty << "!\n";
abort();
@ -708,8 +815,8 @@ void ExecutionEngine::emitGlobals() {
}
}
// Now that all of the globals are set up in memory, loop through them all and
// initialize their contents.
// Now that all of the globals are set up in memory, loop through them all
// and initialize their contents.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (!I->isExternal()) {

File diff suppressed because it is too large Load Diff

View File

@ -41,11 +41,15 @@ static Interpreter *TheInterpreter;
static char getTypeID(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: return 'V';
case Type::Int1TyID: return 'o';
case Type::Int8TyID: return 'B';
case Type::Int16TyID: return 'S';
case Type::Int32TyID: return 'I';
case Type::Int64TyID: return 'L';
case Type::IntegerTyID:
switch (cast<IntegerType>(Ty)->getBitWidth()) {
case 1: return 'o';
case 8: return 'B';
case 16: return 'S';
case 32: return 'I';
case 64: return 'L';
default: return 'N';
}
case Type::FloatTyID: return 'F';
case Type::DoubleTyID: return 'D';
case Type::PointerTyID: return 'P';

View File

@ -144,7 +144,18 @@ public:
void visitStoreInst(StoreInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitPHINode(PHINode &PN) { assert(0 && "PHI nodes already handled!"); }
void visitCastInst(CastInst &I);
void visitTruncInst(TruncInst &I);
void visitZExtInst(ZExtInst &I);
void visitSExtInst(SExtInst &I);
void visitFPTruncInst(FPTruncInst &I);
void visitFPExtInst(FPExtInst &I);
void visitUIToFPInst(UIToFPInst &I);
void visitSIToFPInst(SIToFPInst &I);
void visitFPToUIInst(FPToUIInst &I);
void visitFPToSIInst(FPToSIInst &I);
void visitPtrToIntInst(PtrToIntInst &I);
void visitIntToPtrInst(IntToPtrInst &I);
void visitBitCastInst(BitCastInst &I);
void visitSelectInst(SelectInst &I);
@ -193,6 +204,30 @@ private: // Helper functions
void initializeExternalFunctions();
GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF);
GenericValue getOperandValue(Value *V, ExecutionContext &SF);
GenericValue executeTruncInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeSExtInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeZExtInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeFPTruncInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeFPExtInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeFPToUIInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeFPToSIInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeUIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeSIToFPInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executePtrToIntInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeIntToPtrInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeBitCastInst(Value *SrcVal, const Type *DstTy,
ExecutionContext &SF);
GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal,
const Type *Ty, ExecutionContext &SF);
void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result);

View File

@ -142,22 +142,25 @@ GenericValue JIT::runFunction(Function *F,
GenericValue rv;
switch (RetTy->getTypeID()) {
default: assert(0 && "Unknown return type for function call!");
case Type::Int1TyID:
rv.Int1Val = ((bool(*)())(intptr_t)FPtr)();
return rv;
case Type::Int8TyID:
rv.Int8Val = ((char(*)())(intptr_t)FPtr)();
return rv;
case Type::Int16TyID:
rv.Int16Val = ((short(*)())(intptr_t)FPtr)();
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
if (BitWidth == 1)
rv.Int1Val = ((bool(*)())(intptr_t)FPtr)();
else if (BitWidth <= 8)
rv.Int8Val = ((char(*)())(intptr_t)FPtr)();
else if (BitWidth <= 16)
rv.Int16Val = ((short(*)())(intptr_t)FPtr)();
else if (BitWidth <= 32)
rv.Int32Val = ((int(*)())(intptr_t)FPtr)();
else if (BitWidth <= 64)
rv.Int64Val = ((int64_t(*)())(intptr_t)FPtr)();
else
assert(0 && "Integer types > 64 bits not supported");
return rv;
}
case Type::VoidTyID:
case Type::Int32TyID:
rv.Int32Val = ((int(*)())(intptr_t)FPtr)();
return rv;
case Type::Int64TyID:
rv.Int64Val = ((int64_t(*)())(intptr_t)FPtr)();
return rv;
case Type::FloatTyID:
rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
return rv;
@ -191,11 +194,22 @@ GenericValue JIT::runFunction(Function *F,
const GenericValue &AV = ArgValues[i];
switch (ArgTy->getTypeID()) {
default: assert(0 && "Unknown argument type for function call!");
case Type::Int1TyID: C = ConstantInt::get(ArgTy, AV.Int1Val); break;
case Type::Int8TyID: C = ConstantInt::get(ArgTy, AV.Int8Val); break;
case Type::Int16TyID: C = ConstantInt::get(ArgTy, AV.Int16Val); break;
case Type::Int32TyID: C = ConstantInt::get(ArgTy, AV.Int32Val); break;
case Type::Int64TyID: C = ConstantInt::get(ArgTy, AV.Int64Val); break;
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(ArgTy)->getBitWidth();
if (BitWidth == 1)
C = ConstantInt::get(ArgTy, AV.Int1Val);
else if (BitWidth <= 8)
C = ConstantInt::get(ArgTy, AV.Int8Val);
else if (BitWidth <= 16)
C = ConstantInt::get(ArgTy, AV.Int16Val);
else if (BitWidth <= 32)
C = ConstantInt::get(ArgTy, AV.Int32Val);
else if (BitWidth <= 64)
C = ConstantInt::get(ArgTy, AV.Int64Val);
else
assert(0 && "Integer types > 64 bits not supported");
break;
}
case Type::FloatTyID: C = ConstantFP ::get(ArgTy, AV.FloatVal); break;
case Type::DoubleTyID: C = ConstantFP ::get(ArgTy, AV.DoubleVal); break;
case Type::PointerTyID:

View File

@ -111,6 +111,12 @@ static bool RecursiveResolveTypesI(const PATypeHolder &DestTy,
// Otherwise, resolve the used type used by this derived type...
switch (DestTyT->getTypeID()) {
case Type::IntegerTyID: {
if (cast<IntegerType>(DestTyT)->getBitWidth() !=
cast<IntegerType>(SrcTyT)->getBitWidth())
return true;
return false;
}
case Type::FunctionTyID: {
if (cast<FunctionType>(DestTyT)->isVarArg() !=
cast<FunctionType>(SrcTyT)->isVarArg() ||
@ -275,7 +281,7 @@ static Value *RemapOperand(const Value *In,
Value *Result = 0;
if (const Constant *CPV = dyn_cast<Constant>(In)) {
if ((!isa<DerivedType>(CPV->getType()) && !isa<ConstantExpr>(CPV)) ||
isa<ConstantAggregateZero>(CPV))
isa<ConstantInt>(CPV) || isa<ConstantAggregateZero>(CPV))
return const_cast<Constant*>(CPV); // Simple constants stay identical.
if (const ConstantArray *CPA = dyn_cast<ConstantArray>(CPV)) {

View File

@ -118,7 +118,7 @@ namespace {
bool isSigned = false,
const std::string &VariableName = "",
bool IgnoreName = false);
std::ostream &printPrimitiveType(std::ostream &Out, const Type *Ty,
std::ostream &printSimpleType(std::ostream &Out, const Type *Ty,
bool isSigned,
const std::string &NameSoFar = "");
@ -364,22 +364,29 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
}
std::ostream &
CWriter::printPrimitiveType(std::ostream &Out, const Type *Ty, bool isSigned,
CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
const std::string &NameSoFar) {
assert(Ty->isPrimitiveType() && "Invalid type for printPrimitiveType");
assert((Ty->isPrimitiveType() || Ty->isIntegral()) &&
"Invalid type for printSimpleType");
switch (Ty->getTypeID()) {
case Type::VoidTyID: return Out << "void " << NameSoFar;
case Type::Int1TyID: return Out << "bool " << NameSoFar;
case Type::Int8TyID:
return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar;
case Type::Int16TyID:
return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar;
case Type::Int32TyID:
return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar;
case Type::Int64TyID:
return Out << (isSigned?"signed":"unsigned") << " long long " << NameSoFar;
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
case Type::VoidTyID: return Out << "void " << NameSoFar;
case Type::IntegerTyID: {
unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
if (NumBits == 1)
return Out << "bool " << NameSoFar;
else if (NumBits <= 8)
return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar;
else if (NumBits <= 16)
return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar;
else if (NumBits <= 32)
return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar;
else {
assert(NumBits <= 64 && "Bit widths > 64 not implemented yet");
return Out << (isSigned?"signed":"unsigned") << " long long "<< NameSoFar;
}
}
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
default :
cerr << "Unknown primitive type: " << *Ty << "\n";
abort();
@ -392,11 +399,11 @@ CWriter::printPrimitiveType(std::ostream &Out, const Type *Ty, bool isSigned,
std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
bool isSigned, const std::string &NameSoFar,
bool IgnoreName) {
if (Ty->isPrimitiveType()) {
if (Ty->isPrimitiveType() || Ty->isIntegral()) {
// FIXME:Signedness. When integer types are signless, this should just
// always pass "false" for the sign of the primitive type. The instructions
// will figure out how the value is to be interpreted.
printPrimitiveType(Out, Ty, isSigned, NameSoFar);
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
}
@ -624,13 +631,13 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) {
case Instruction::PtrToInt:
case Instruction::FPToUI: // For these, make sure we get an unsigned dest
Out << '(';
printPrimitiveType(Out, DstTy, false);
printSimpleType(Out, DstTy, false);
Out << ')';
break;
case Instruction::SExt:
case Instruction::FPToSI: // For these, make sure we get a signed dest
Out << '(';
printPrimitiveType(Out, DstTy, true);
printSimpleType(Out, DstTy, true);
Out << ')';
break;
default:
@ -642,13 +649,13 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) {
case Instruction::UIToFP:
case Instruction::ZExt:
Out << '(';
printPrimitiveType(Out, SrcTy, false);
printSimpleType(Out, SrcTy, false);
Out << ')';
break;
case Instruction::SIToFP:
case Instruction::SExt:
Out << '(';
printPrimitiveType(Out, SrcTy, true);
printSimpleType(Out, SrcTy, true);
Out << ')';
break;
case Instruction::IntToPtr:
@ -832,7 +839,7 @@ void CWriter::printConstant(Constant *CPV) {
Out << (CI->getZExtValue() ? '1' : '0') ;
else {
Out << "((";
printPrimitiveType(Out, Ty, false) << ')';
printSimpleType(Out, Ty, false) << ')';
if (CI->isMinValue(true))
Out << CI->getZExtValue() << 'u';
else
@ -1019,7 +1026,7 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE) {
if (NeedsExplicitCast) {
Out << "((";
if (Ty->isInteger())
printPrimitiveType(Out, Ty, TypeIsSigned);
printSimpleType(Out, Ty, TypeIsSigned);
else
printType(Out, Ty); // not integer, sign doesn't matter
Out << ")(";
@ -1064,7 +1071,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
// operand.
if (shouldCast) {
Out << "((";
printPrimitiveType(Out, OpTy, typeIsSigned);
printSimpleType(Out, OpTy, typeIsSigned);
Out << ")";
printConstant(CPV);
Out << ")";
@ -1120,14 +1127,14 @@ bool CWriter::writeInstructionCast(const Instruction &I) {
case Instruction::URem:
case Instruction::UDiv:
Out << "((";
printPrimitiveType(Out, Ty, false);
printSimpleType(Out, Ty, false);
Out << ")(";
return true;
case Instruction::AShr:
case Instruction::SRem:
case Instruction::SDiv:
Out << "((";
printPrimitiveType(Out, Ty, true);
printSimpleType(Out, Ty, true);
Out << ")(";
return true;
default: break;
@ -1174,7 +1181,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
// operand.
if (shouldCast) {
Out << "((";
printPrimitiveType(Out, OpTy, castIsSigned);
printSimpleType(Out, OpTy, castIsSigned);
Out << ")";
writeOperand(Operand);
Out << ")";
@ -1222,7 +1229,7 @@ void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate
if (shouldCast) {
Out << "((";
if (OpTy->isInteger())
printPrimitiveType(Out, OpTy, castIsSigned);
printSimpleType(Out, OpTy, castIsSigned);
else
printType(Out, OpTy); // not integer, sign doesn't matter
Out << ")";
@ -1711,7 +1718,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
void CWriter::printContainedStructs(const Type *Ty,
std::set<const StructType*> &StructPrinted){
// Don't walk through pointers.
if (isa<PointerType>(Ty) || Ty->isPrimitiveType()) return;
if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isIntegral()) return;
// Print all contained types first.
for (Type::subtype_iterator I = Ty->subtype_begin(),
@ -2237,9 +2244,14 @@ static const char * getFloatBitCastField(const Type *Ty) {
switch (Ty->getTypeID()) {
default: assert(0 && "Invalid Type");
case Type::FloatTyID: return "Float";
case Type::Int32TyID: return "Int32";
case Type::DoubleTyID: return "Double";
case Type::Int64TyID: return "Int64";
case Type::IntegerTyID: {
unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
if (NumBits <= 32)
return "Int32";
else
return "Int64";
}
}
}

View File

@ -241,12 +241,21 @@ static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
uint64_t &Size, unsigned char &Alignment) {
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
switch (Ty->getTypeID()) {
case Type::Int1TyID: Size = 1; Alignment = TD->getBoolAlignment(); return;
case Type::VoidTyID:
case Type::Int8TyID: Size = 1; Alignment = TD->getByteAlignment(); return;
case Type::Int16TyID: Size = 2; Alignment = TD->getShortAlignment(); return;
case Type::Int32TyID: Size = 4; Alignment = TD->getIntAlignment(); return;
case Type::Int64TyID: Size = 8; Alignment = TD->getLongAlignment(); return;
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth <= 8) {
Size = 1; Alignment = TD->getByteAlignment();
} else if (BitWidth <= 16) {
Size = 2; Alignment = TD->getShortAlignment();
} else if (BitWidth <= 32) {
Size = 4; Alignment = TD->getIntAlignment();
} else if (BitWidth <= 64) {
Size = 8; Alignment = TD->getLongAlignment();
} else
assert(0 && "Integer types > 64 bits not supported.");
return;
}
case Type::VoidTyID: Size = 1; Alignment = TD->getByteAlignment(); return;
case Type::FloatTyID: Size = 4; Alignment = TD->getFloatAlignment(); return;
case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
case Type::LabelTyID:

View File

@ -176,12 +176,18 @@ bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const {
const Type *Ty = CI->getType();
const char *IntName;
switch (Ty->getTypeID()) {
default: return false;
case Type::Int16TyID: IntName = "llvm.bswap.i16"; break;
case Type::Int32TyID: IntName = "llvm.bswap.i32"; break;
case Type::Int64TyID: IntName = "llvm.bswap.i64"; break;
}
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
unsigned BitWidth = ITy->getBitWidth();
if (BitWidth > 8 && BitWidth <= 16)
IntName = "llvm.bswap.i16";
else if (BitWidth > 24 && BitWidth <= 32)
IntName = "llvm.bswap.i32";
else if (BitWidth > 56 && BitWidth <= 64)
IntName = "llvm.bswap.i64";
else
return false;
} else
return false;
// Okay, we can do this xform, do so now.
Module *M = CI->getParent()->getParent()->getParent();

View File

@ -52,11 +52,14 @@ ModulePass *llvm::createDeadTypeEliminationPass() {
//
static inline bool ShouldNukeSymtabEntry(const Type *Ty){
// Nuke all names for primitive types!
if (Ty->isPrimitiveType()) return true;
if (Ty->isPrimitiveType() || Ty->isIntegral())
return true;
// Nuke all pointers to primitive types as well...
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
if (PT->getElementType()->isPrimitiveType()) return true;
if (PT->getElementType()->isPrimitiveType() ||
PT->getElementType()->isIntegral())
return true;
return false;
}

View File

@ -1820,13 +1820,17 @@ public:
// ffsll(x) -> x == 0 ? 0 : llvm.cttz(x)+1
const Type *ArgType = TheCall->getOperand(1)->getType();
const char *CTTZName;
switch (ArgType->getTypeID()) {
default: assert(0 && "Unknown unsigned type!");
case Type::Int8TyID : CTTZName = "llvm.cttz.i8" ; break;
case Type::Int16TyID: CTTZName = "llvm.cttz.i16"; break;
case Type::Int32TyID : CTTZName = "llvm.cttz.i32"; break;
case Type::Int64TyID : CTTZName = "llvm.cttz.i64"; break;
}
assert(ArgType->getTypeID() == Type::IntegerTyID &&
"llvm.cttz argument is not an integer?");
unsigned BitWidth = cast<IntegerType>(ArgType)->getBitWidth();
if (BitWidth <= 8)
CTTZName = "llvm.cttz.i8";
else if (BitWidth <= 16)
CTTZName = "llvm.cttz.i16";
else if (BitWidth <= 32)
CTTZName = "llvm.cttz.i32";
else
CTTZName = "llvm.cttz.i64";
Constant *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
ArgType, NULL);

View File

@ -50,6 +50,7 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
@ -528,18 +529,27 @@ void IndVarSimplify::runOnLoop(Loop *L) {
// induction variable to the right size for them, avoiding the need for the
// code evaluation methods to insert induction variables of different sizes.
if (DifferingSizes) {
bool InsertedSizes[17] = { false };
InsertedSizes[LargestType->getPrimitiveSize()] = true;
for (unsigned i = 0, e = IndVars.size(); i != e; ++i)
if (!InsertedSizes[IndVars[i].first->getType()->getPrimitiveSize()]) {
SmallVector<unsigned,4> InsertedSizes;
InsertedSizes.push_back(LargestType->getPrimitiveSizeInBits());
for (unsigned i = 0, e = IndVars.size(); i != e; ++i) {
unsigned ithSize = IndVars[i].first->getType()->getPrimitiveSizeInBits();
bool alreadyInsertedSize = false;
for (SmallVector<unsigned,4>::iterator I = InsertedSizes.begin(),
E = InsertedSizes.end(); I != E; ++I)
if (*I == ithSize) {
alreadyInsertedSize = true;
break;
}
if (!alreadyInsertedSize) {
PHINode *PN = IndVars[i].first;
InsertedSizes[PN->getType()->getPrimitiveSize()] = true;
InsertedSizes.push_back(ithSize);
Instruction *New = new TruncInst(IndVar, PN->getType(), "indvar",
InsertPt);
Rewriter.addInsertedValue(New, SE->getSCEV(New));
DOUT << "INDVARS: Made trunc IV for " << *PN
<< " NewVal = " << *New << "\n";
}
}
}
// Rewrite all induction variables in terms of the canonical induction

View File

@ -339,12 +339,12 @@ static bool isOnlyUse(Value *V) {
// getPromotedType - Return the specified type promoted as it would be to pass
// though a va_arg area...
static const Type *getPromotedType(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::Int8TyID:
case Type::Int16TyID: return Type::Int32Ty;
case Type::FloatTyID: return Type::DoubleTy;
default: return Ty;
}
if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty)) {
if (ITy->getBitWidth() < 32)
return Type::Int32Ty;
} else if (Ty == Type::FloatTy)
return Type::DoubleTy;
return Ty;
}
/// getBitCastOperand - If the specified operand is a CastInst or a constant
@ -531,7 +531,6 @@ static ConstantInt *SubOne(ConstantInt *C) {
ConstantInt::get(C->getType(), 1)));
}
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
@ -3516,7 +3515,7 @@ Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) {
/// ByteValues - For each byte of the result, we keep track of which value
/// defines each byte.
std::vector<Value*> ByteValues;
ByteValues.resize(I.getType()->getPrimitiveSize());
ByteValues.resize(TD->getTypeSize(I.getType()));
// Try to find all the pieces corresponding to the bswap.
if (CollectBSwapParts(I.getOperand(0), ByteValues) ||
@ -6580,9 +6579,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
}
if (SI.getType() == Type::Int1Ty) {
ConstantInt *C;
if ((C = dyn_cast<ConstantInt>(TrueVal)) &&
C->getType() == Type::Int1Ty) {
if (ConstantInt *C = dyn_cast<ConstantInt>(TrueVal)) {
if (C->getZExtValue()) {
// Change: A = select B, true, C --> A = or B, C
return BinaryOperator::createOr(CondVal, FalseVal);
@ -6593,8 +6590,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
"not."+CondVal->getName()), SI);
return BinaryOperator::createAnd(NotCond, FalseVal);
}
} else if ((C = dyn_cast<ConstantInt>(FalseVal)) &&
C->getType() == Type::Int1Ty) {
} else if (ConstantInt *C = dyn_cast<ConstantInt>(FalseVal)) {
if (C->getZExtValue() == false) {
// Change: A = select B, C, false --> A = and B, C
return BinaryOperator::createAnd(CondVal, TrueVal);
@ -7649,7 +7645,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
}
} else if (SrcTy->getPrimitiveSizeInBits() <
DestTy->getPrimitiveSizeInBits() &&
SrcTy->getPrimitiveSize() == 4) {
SrcTy->getPrimitiveSizeInBits() == 32) {
// We can eliminate a cast from [u]int to [u]long iff the target
// is a 32-bit pointer target.
if (SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) {
@ -7664,7 +7660,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// insert it. This explicit cast can make subsequent optimizations more
// obvious.
Value *Op = GEP.getOperand(i);
if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
if (TD->getTypeSize(Op->getType()) > TD->getPointerSize())
if (Constant *C = dyn_cast<Constant>(Op)) {
GEP.setOperand(i, ConstantExpr::getTrunc(C, TD->getIntPtrType()));
MadeChange = true;
@ -7722,11 +7718,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GO1 = ConstantExpr::getIntegerCast(GO1C, SO1->getType(), true);
} else {
unsigned PS = TD->getPointerSize();
if (SO1->getType()->getPrimitiveSize() == PS) {
if (TD->getTypeSize(SO1->getType()) == PS) {
// Convert GO1 to SO1's type.
GO1 = InsertCastToIntPtrTy(GO1, SO1->getType(), &GEP, this);
} else if (GO1->getType()->getPrimitiveSize() == PS) {
} else if (TD->getTypeSize(GO1->getType()) == PS) {
// Convert SO1 to GO1's type.
SO1 = InsertCastToIntPtrTy(SO1, GO1->getType(), &GEP, this);
} else {
@ -9056,8 +9052,7 @@ static void AddReachableCodeToWorklist(BasicBlock *BB,
// only visit the reachable successor.
TerminatorInst *TI = BB->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (BI->isConditional() && isa<ConstantInt>(BI->getCondition()) &&
BI->getCondition()->getType() == Type::Int1Ty) {
if (BI->isConditional() && isa<ConstantInt>(BI->getCondition())) {
bool CondVal = cast<ConstantInt>(BI->getCondition())->getZExtValue();
AddReachableCodeToWorklist(BI->getSuccessor(!CondVal), Visited, WorkList,
TD);

View File

@ -1611,7 +1611,7 @@ bool IPSCCP::runOnModule(Module &M) {
Instruction *I = cast<Instruction>(DeadBB->use_back());
bool Folded = ConstantFoldTerminator(I->getParent());
if (!Folded) {
// The constant folder may not have been able to fold the termiantor
// The constant folder may not have been able to fold the terminator
// if this is a branch or switch on undef. Fold it manually as a
// branch to the first successor.
if (BranchInst *BI = dyn_cast<BranchInst>(I)) {

View File

@ -444,7 +444,8 @@ static bool MergeInType(const Type *In, const Type *&Accum,
// Noop.
} else if (In->isIntegral() && Accum->isIntegral()) { // integer union.
// Otherwise pick whichever type is larger.
if (In->getTypeID() > Accum->getTypeID())
if (cast<IntegerType>(In)->getBitWidth() >
cast<IntegerType>(Accum)->getBitWidth())
Accum = In;
} else if (isa<PointerType>(In) && isa<PointerType>(Accum)) {
// Pointer unions just stay as one of the pointers.
@ -643,8 +644,8 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) {
} else {
// Must be an element access.
unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
NV = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt),
"tmp", LI);
NV = new ExtractElementInst(
NV, ConstantInt::get(Type::Int32Ty, Elt), "tmp", LI);
}
} else if (isa<PointerType>(NV->getType())) {
assert(isa<PointerType>(LI->getType()));

View File

@ -222,6 +222,7 @@ static void fillTypeNameTable(const Module *M,
const Type *Ty = cast<Type>(TI->second);
if (!isa<PointerType>(Ty) ||
!cast<PointerType>(Ty)->getElementType()->isPrimitiveType() ||
!cast<PointerType>(Ty)->getElementType()->isIntegral() ||
isa<OpaqueType>(cast<PointerType>(Ty)->getElementType()))
TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first)));
}
@ -233,7 +234,7 @@ static void calcTypeName(const Type *Ty,
std::vector<const Type *> &TypeStack,
std::map<const Type *, std::string> &TypeNames,
std::string & Result){
if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)) {
if (Ty->isIntegral() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
Result += Ty->getDescription(); // Base case
return;
}
@ -265,6 +266,15 @@ static void calcTypeName(const Type *Ty,
TypeStack.push_back(Ty); // Recursive case: Add us to the stack..
switch (Ty->getTypeID()) {
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
if (BitWidth == 1)
Result += "bool";
else {
Result += "i" + utostr(BitWidth);
}
break;
}
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
@ -347,7 +357,7 @@ static std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,
// Primitive types always print out their description, regardless of whether
// they have been named or not.
//
if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))
if (Ty->isIntegral() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)))
return Out << Ty->getDescription();
// Check to see if the type is named.
@ -706,7 +716,9 @@ private:
/// without considering any symbolic types that we may have equal to it.
///
std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
Out << "i" << utostr(ITy->getBitWidth());
else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
printType(FTy->getReturnType());
Out << " (";
unsigned Idx = 1;

View File

@ -1364,22 +1364,6 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C,
assert(Ty != 0 && "Invalid indices for GEP!");
return ConstantPointerNull::get(PointerType::get(Ty));
}
if (IdxList.size() == 1) {
const Type *ElTy = cast<PointerType>(C->getType())->getElementType();
if (uint32_t ElSize = ElTy->getPrimitiveSize()) {
// gep null, C is equal to C*sizeof(nullty). If nullty is a known llvm
// type, we can statically fold this.
Constant *R = ConstantInt::get(Type::Int32Ty, ElSize);
// We know R is unsigned, Idx0 is signed because it must be an index
// through a sequential type (gep pointer operand) which is always
// signed.
R = ConstantExpr::getSExtOrBitCast(R, Idx0->getType());
R = ConstantExpr::getMul(R, Idx0); // signed multiply
// R is a signed integer, C is the GEP pointer so -> IntToPtr
return ConstantExpr::getIntToPtr(R, C->getType());
}
}
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) {

View File

@ -92,25 +92,32 @@ bool Constant::canTrap() const {
// Static constructor to create a '0' constant of arbitrary type...
Constant *Constant::getNullValue(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::Int1TyID: {
static Constant *NullBool = ConstantInt::get(Type::Int1Ty, false);
return NullBool;
}
case Type::Int8TyID: {
static Constant *NullInt8 = ConstantInt::get(Type::Int8Ty, 0);
return NullInt8;
}
case Type::Int16TyID: {
static Constant *NullInt16 = ConstantInt::get(Type::Int16Ty, 0);
return NullInt16;
}
case Type::Int32TyID: {
static Constant *NullInt32 = ConstantInt::get(Type::Int32Ty, 0);
return NullInt32;
}
case Type::Int64TyID: {
static Constant *NullInt64 = ConstantInt::get(Type::Int64Ty, 0);
return NullInt64;
case Type::IntegerTyID: {
const IntegerType *ITy = dyn_cast<IntegerType>(Ty);
switch (ITy->getBitWidth()) {
case 1: {
static Constant *NullBool = ConstantInt::get(Ty, false);
return NullBool;
}
case 8: {
static Constant *NullInt8 = ConstantInt::get(Ty, 0);
return NullInt8;
}
case 16: {
static Constant *NullInt16 = ConstantInt::get(Ty, 0);
return NullInt16;
}
case 32: {
static Constant *NullInt32 = ConstantInt::get(Ty, 0);
return NullInt32;
}
case 64: {
static Constant *NullInt64 = ConstantInt::get(Ty, 0);
return NullInt64;
}
default:
return ConstantInt::get(Ty, 0);
}
}
case Type::FloatTyID: {
static Constant *NullFloat = ConstantFP::get(Type::FloatTy, 0);
@ -136,14 +143,12 @@ Constant *Constant::getNullValue(const Type *Ty) {
// Static constructor to create an integral constant with all bits set
ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::Int1TyID: return ConstantInt::getTrue();
case Type::Int8TyID:
case Type::Int16TyID:
case Type::Int32TyID:
case Type::Int64TyID: return ConstantInt::get(Ty, int64_t(-1));
default: return 0;
}
if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
if (ITy->getBitWidth() == 1)
return ConstantInt::getTrue();
else
return ConstantInt::get(Ty, int64_t(-1));
return 0;
}
/// @returns the value for an packed integer constant of the given type that
@ -549,25 +554,26 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
// isValueValidForType implementations
bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) {
switch (Ty->getTypeID()) {
default: return false; // These can't be represented as integers!
case Type::Int1TyID: return Val == 0 || Val == 1;
case Type::Int8TyID: return Val <= UINT8_MAX;
case Type::Int16TyID: return Val <= UINT16_MAX;
case Type::Int32TyID: return Val <= UINT32_MAX;
case Type::Int64TyID: return true; // always true, has to fit in largest type
}
unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay
assert(NumBits <= 64 && "Not implemented: integers > 64-bits");
if (Ty == Type::Int1Ty)
return Val == 0 || Val == 1;
if (NumBits == 64)
return true; // always true, has to fit in largest type
uint64_t Max = (1ll << NumBits) - 1;
return Val <= Max;
}
bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
switch (Ty->getTypeID()) {
default: return false; // These can't be represented as integers!
case Type::Int1TyID: return (Val == 0 || Val == 1);
case Type::Int8TyID: return (Val >= INT8_MIN && Val <= INT8_MAX);
case Type::Int16TyID: return (Val >= INT16_MIN && Val <= UINT16_MAX);
case Type::Int32TyID: return (Val >= INT32_MIN && Val <= UINT32_MAX);
case Type::Int64TyID: return true; // always true, has to fit in largest type
}
unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay
assert(NumBits <= 64 && "Not implemented: integers > 64-bits");
if (Ty == Type::Int1Ty)
return Val == 0 || Val == 1;
if (NumBits == 64)
return true; // always true, has to fit in largest type
int64_t Min = -(1ll << (NumBits-1));
int64_t Max = (1ll << (NumBits-1)) - 1;
return (Val >= Min && Val <= Max);
}
bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
@ -1441,8 +1447,7 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
"Invalid cast");
assert((Ty->isIntegral() || isa<PointerType>(Ty)) && "Invalid cast");
if (Ty->isIntegral())
return getCast(Instruction::PtrToInt, S, Ty);

View File

@ -1528,7 +1528,7 @@ CastInst *CastInst::createPointerCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
assert((Ty->isIntegral() || isa<PointerType>(Ty)) &&
"Invalid cast");
if (Ty->isIntegral())
@ -1541,7 +1541,7 @@ CastInst *CastInst::createPointerCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
assert(isa<PointerType>(S->getType()) && "Invalid cast");
assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
assert((Ty->isIntegral() || isa<PointerType>(Ty)) &&
"Invalid cast");
if (Ty->isIntegral())
@ -1913,7 +1913,7 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
assert(Op0Ty == Op1Ty &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
assert(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty) ||
(isa<PackedType>(Op0Ty) &&
cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) &&
"Invalid operand types for ICmp instruction");
@ -1948,7 +1948,7 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
assert(Op0Ty == Op1Ty &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
assert(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty) ||
(isa<PackedType>(Op0Ty) &&
cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) &&
"Invalid operand types for ICmp instruction");

View File

@ -64,7 +64,7 @@ static ManagedStatic<std::map<const Type*,
std::string> > AbstractTypeDescriptions;
Type::Type(const char *Name, TypeID id)
: ID(id), Abstract(false), RefCount(0), ForwardType(0) {
: ID(id), Abstract(false), SubclassData(0), RefCount(0), ForwardType(0) {
assert(Name && Name[0] && "Should use other ctor if no name!");
(*ConcreteTypeDescriptions)[this] = Name;
}
@ -73,11 +73,6 @@ Type::Type(const char *Name, TypeID id)
const Type *Type::getPrimitiveType(TypeID IDNumber) {
switch (IDNumber) {
case VoidTyID : return VoidTy;
case Int1TyID : return Int1Ty;
case Int8TyID : return Int8Ty;
case Int16TyID : return Int16Ty;
case Int32TyID : return Int32Ty;
case Int64TyID : return Int64Ty;
case FloatTyID : return FloatTy;
case DoubleTyID: return DoubleTy;
case LabelTyID : return LabelTy;
@ -116,41 +111,17 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
// At this point we have only various mismatches of the first class types
// remaining and ptr->ptr. Just select the lossless conversions. Everything
// else is not lossless.
if (getTypeID() == Type::PointerTyID)
if (isa<PointerType>(this))
return isa<PointerType>(Ty);
return false; // Other types have no identity values
}
// getPrimitiveSize - Return the basic size of this type if it is a primitive
// type. These are fixed by LLVM and are not target dependent. This will
// return zero if the type does not have a size or is not a primitive type.
//
unsigned Type::getPrimitiveSize() const {
switch (getTypeID()) {
case Type::Int1TyID:
case Type::Int8TyID: return 1;
case Type::Int16TyID: return 2;
case Type::FloatTyID:
case Type::Int32TyID: return 4;
case Type::Int64TyID:
case Type::DoubleTyID: return 8;
default: return 0;
}
}
unsigned Type::getPrimitiveSizeInBits() const {
switch (getTypeID()) {
case Type::Int1TyID: return 1;
case Type::Int8TyID: return 8;
case Type::Int16TyID: return 16;
case Type::FloatTyID:
case Type::Int32TyID:return 32;
case Type::Int64TyID:
case Type::FloatTyID: return 32;
case Type::DoubleTyID: return 64;
case Type::PackedTyID: {
const PackedType *PTy = cast<PackedType>(this);
return PTy->getBitWidth();
}
case Type::IntegerTyID: return cast<IntegerType>(this)->getBitWidth();
case Type::PackedTyID: return cast<PackedType>(this)->getBitWidth();
default: return 0;
}
}
@ -165,11 +136,13 @@ bool Type::isSizedDerivedType() const {
if (const PackedType *PTy = dyn_cast<PackedType>(this))
return PTy->getElementType()->isSized();
if (!isa<StructType>(this)) return false;
if (!isa<StructType>(this))
return false;
// Okay, our struct is sized if all of the elements are...
for (subtype_iterator I = subtype_begin(), E = subtype_end(); I != E; ++I)
if (!(*I)->isSized()) return false;
if (!(*I)->isSized())
return false;
return true;
}
@ -243,6 +216,14 @@ static std::string getTypeDescription(const Type *Ty,
TypeStack.push_back(Ty); // Add us to the stack..
switch (Ty->getTypeID()) {
case Type::IntegerTyID: {
const IntegerType *ITy = cast<IntegerType>(Ty);
if (ITy->getBitWidth() == 1)
Result = "bool"; // FIXME: eventually this becomes i1
else
Result = "i" + utostr(ITy->getBitWidth());
break;
}
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
if (!Result.empty())
@ -267,6 +248,7 @@ static std::string getTypeDescription(const Type *Ty,
}
break;
}
case Type::PackedStructTyID:
case Type::StructTyID: {
const StructType *STy = cast<StructType>(Ty);
if (STy->isPacked())
@ -353,7 +335,6 @@ const Type *StructType::getTypeAtIndex(const Value *V) const {
return ContainedTys[Idx];
}
//===----------------------------------------------------------------------===//
// Primitive 'Type' data
//===----------------------------------------------------------------------===//
@ -365,17 +346,26 @@ const Type *StructType::getTypeAtIndex(const Value *V) const {
}; \
} \
static ManagedStatic<TY##Type> The##TY##Ty; \
Type *Type::TY##Ty = &*The##TY##Ty
const Type *Type::TY##Ty = &*The##TY##Ty
#define DeclareIntegerType(TY, BitWidth) \
namespace { \
struct VISIBILITY_HIDDEN TY##Type : public IntegerType { \
TY##Type() : IntegerType(BitWidth) {} \
}; \
} \
static ManagedStatic<TY##Type> The##TY##Ty; \
const Type *Type::TY##Ty = &*The##TY##Ty
DeclarePrimType(Void, "void");
DeclarePrimType(Int1, "bool");
DeclarePrimType(Int8, "i8");
DeclarePrimType(Int16, "i16");
DeclarePrimType(Int32, "i32");
DeclarePrimType(Int64, "i64");
DeclarePrimType(Float, "float");
DeclarePrimType(Double, "double");
DeclarePrimType(Label, "label");
DeclareIntegerType(Int1, 1);
DeclareIntegerType(Int8, 8);
DeclareIntegerType(Int16, 16);
DeclareIntegerType(Int32, 32);
DeclareIntegerType(Int64, 64);
#undef DeclarePrimType
@ -584,7 +574,10 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
// algorithm is the fact that arraytypes have sizes that differentiates types,
// and that function types can be varargs or not. Consider this now.
//
if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
const IntegerType *ITy2 = cast<IntegerType>(Ty2);
return ITy->getBitWidth() == ITy2->getBitWidth();
} else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
return TypesEqual(PTy->getElementType(),
cast<PointerType>(Ty2)->getElementType(), EqTypes);
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
@ -695,6 +688,9 @@ static unsigned getSubElementHash(const Type *Ty) {
switch (SubTy->getTypeID()) {
default: break;
case Type::OpaqueTyID: return 0; // Opaque -> hash = 0 no matter what.
case Type::IntegerTyID:
HashVal ^= (cast<IntegerType>(SubTy)->getBitWidth() << 3);
break;
case Type::FunctionTyID:
HashVal ^= cast<FunctionType>(SubTy)->getNumParams()*2 +
cast<FunctionType>(SubTy)->isVarArg();
@ -928,6 +924,60 @@ public:
// Function Type Factory and Value Class...
//
//===----------------------------------------------------------------------===//
// Integer Type Factory...
//
namespace llvm {
class IntegerValType {
uint16_t bits;
public:
IntegerValType(uint16_t numbits) : bits(numbits) {}
static IntegerValType get(const IntegerType *Ty) {
return IntegerValType(Ty->getBitWidth());
}
static unsigned hashTypeStructure(const IntegerType *Ty) {
return (unsigned)Ty->getBitWidth();
}
inline bool operator<(const IntegerValType &IVT) const {
return bits < IVT.bits;
}
};
}
static ManagedStatic<TypeMap<IntegerValType, IntegerType> > IntegerTypes;
const IntegerType *IntegerType::get(unsigned NumBits) {
assert(NumBits >= MIN_INT_BITS && "bitwidth too small");
assert(NumBits <= MAX_INT_BITS && "bitwidth too large");
// Check for the built-in integer types
switch (NumBits) {
case 1: return cast<IntegerType>(Type::Int1Ty);
case 8: return cast<IntegerType>(Type::Int8Ty);
case 16: return cast<IntegerType>(Type::Int16Ty);
case 32: return cast<IntegerType>(Type::Int32Ty);
case 64: return cast<IntegerType>(Type::Int64Ty);
default:
break;
}
IntegerValType IVT(NumBits);
IntegerType *ITy = IntegerTypes->get(IVT);
if (ITy) return ITy; // Found a match, return it!
// Value not found. Derive a new type!
ITy = new IntegerType(NumBits);
IntegerTypes->add(IVT, ITy);
#ifdef DEBUG_MERGE_TYPES
DOUT << "Derived new type: " << *ITy << "\n";
#endif
return ITy;
}
// FunctionValType - Define a class to hold the key that goes into the TypeMap
//
namespace llvm {
@ -1440,14 +1490,9 @@ void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
}
bool SequentialType::indexValid(const Value *V) const {
const Type *Ty = V->getType();
switch (Ty->getTypeID()) {
case Type::Int32TyID:
case Type::Int64TyID:
return true;
default:
return false;
}
if (const IntegerType *IT = dyn_cast<IntegerType>(V->getType()))
return IT->getBitWidth() == 32 || IT->getBitWidth() == 64;
return false;
}
namespace llvm {

View File

@ -743,7 +743,7 @@ void Verifier::visitICmpInst(ICmpInst& IC) {
Assert1(Op0Ty == Op1Ty,
"Both operands to ICmp instruction are not of the same type!", &IC);
// Check that the operands are the right type
Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID,
Assert1(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty),
"Invalid operand types for ICmp instruction", &IC);
visitInstruction(IC);
}
@ -1005,7 +1005,7 @@ void Verifier::VerifyIntrinsicPrototype(Function *F, ...) {
else
Ty = FTy->getParamType(ArgNo-1);
if (Ty->getTypeID() != TypeID) {
if (TypeID != Ty->getTypeID()) {
if (ArgNo == 0)
CheckFailed("Intrinsic prototype has incorrect result type!", F);
else
@ -1013,18 +1013,43 @@ void Verifier::VerifyIntrinsicPrototype(Function *F, ...) {
break;
}
// If this is a packed argument, verify the number and type of elements.
if (TypeID == Type::PackedTyID) {
const PackedType *PTy = cast<PackedType>(Ty);
if (va_arg(VA, int) != PTy->getElementType()->getTypeID()) {
CheckFailed("Intrinsic prototype has incorrect vector element type!",F);
if (TypeID == Type::IntegerTyID) {
unsigned GotBits = (unsigned) va_arg(VA, int);
unsigned ExpectBits = cast<IntegerType>(Ty)->getBitWidth();
if (GotBits != ExpectBits) {
std::string bitmsg = " Expecting " + utostr(ExpectBits) + " but got " +
utostr(GotBits) + " bits.";
if (ArgNo == 0)
CheckFailed("Intrinsic prototype has incorrect integer result width!"
+ bitmsg, F);
else
CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " has "
"incorrect integer width!" + bitmsg, F);
break;
}
} else if (TypeID == Type::PackedTyID) {
// If this is a packed argument, verify the number and type of elements.
const PackedType *PTy = cast<PackedType>(Ty);
int ElemTy = va_arg(VA, int);
if (ElemTy != PTy->getElementType()->getTypeID()) {
CheckFailed("Intrinsic prototype has incorrect vector element type!",
F);
break;
}
if (ElemTy == Type::IntegerTyID) {
unsigned NumBits = (unsigned)va_arg(VA, int);
unsigned ExpectedBits =
cast<IntegerType>(PTy->getElementType())->getBitWidth();
if (NumBits != ExpectedBits) {
CheckFailed("Intrinsic prototype has incorrect vector element type!",
F);
break;
}
}
if ((unsigned)va_arg(VA, int) != PTy->getNumElements()) {
CheckFailed("Intrinsic prototype has incorrect number of "
"vector elements!",F);
break;
break;
}
}
}

View File

@ -161,28 +161,25 @@ sanitize(std::string& str) {
str[i] = '_';
}
inline const char*
inline std::string
getTypePrefix(const Type* Ty ) {
const char* prefix;
switch (Ty->getTypeID()) {
case Type::VoidTyID: prefix = "void_"; break;
case Type::Int1TyID: prefix = "bool_"; break;
case Type::Int8TyID: prefix = "int8_"; break;
case Type::Int16TyID: prefix = "int16_"; break;
case Type::Int32TyID: prefix = "int32_"; break;
case Type::Int64TyID: prefix = "int64_"; break;
case Type::FloatTyID: prefix = "float_"; break;
case Type::DoubleTyID: prefix = "double_"; break;
case Type::LabelTyID: prefix = "label_"; break;
case Type::FunctionTyID: prefix = "func_"; break;
case Type::StructTyID: prefix = "struct_"; break;
case Type::ArrayTyID: prefix = "array_"; break;
case Type::PointerTyID: prefix = "ptr_"; break;
case Type::PackedTyID: prefix = "packed_"; break;
case Type::OpaqueTyID: prefix = "opaque_"; break;
default: prefix = "other_"; break;
case Type::VoidTyID: return "void_";
case Type::IntegerTyID:
return std::string("int") + utostr(cast<IntegerType>(Ty)->getBitWidth()) +
"_";
case Type::FloatTyID: return "float_";
case Type::DoubleTyID: return "double_";
case Type::LabelTyID: return "label_";
case Type::FunctionTyID: return "func_";
case Type::StructTyID: return "struct_";
case Type::ArrayTyID: return "array_";
case Type::PointerTyID: return "ptr_";
case Type::PackedTyID: return "packed_";
case Type::OpaqueTyID: return "opaque_";
default: return "other_";
}
return prefix;
return "unknown_";
}
// Looks up the type in the symbol table and returns a pointer to its name or
@ -313,14 +310,13 @@ std::string
CppWriter::getCppName(const Type* Ty)
{
// First, handle the primitive types .. easy
if (Ty->isPrimitiveType()) {
if (Ty->isPrimitiveType() || Ty->isIntegral()) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: return "Type::VoidTy";
case Type::Int1TyID: return "Type::Int1Ty";
case Type::Int8TyID: return "Type::Int8Ty";
case Type::Int16TyID: return "Type::Int16Ty";
case Type::Int32TyID: return "Type::Int32Ty";
case Type::Int64TyID: return "Type::Int64Ty";
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
return "IntegerType::get(" + utostr(BitWidth) + ")";
}
case Type::FloatTyID: return "Type::FloatTy";
case Type::DoubleTyID: return "Type::DoubleTy";
case Type::LabelTyID: return "Type::LabelTy";
@ -414,7 +410,7 @@ CppWriter::printCppName(const Value* val) {
bool
CppWriter::printTypeInternal(const Type* Ty) {
// We don't print definitions for primitive types
if (Ty->isPrimitiveType())
if (Ty->isPrimitiveType() || Ty->isIntegral())
return false;
// If we already defined this type, we don't need to define it again.
@ -603,7 +599,8 @@ CppWriter::printTypes(const Module* M) {
// For primitive types and types already defined, just add a name
TypeMap::const_iterator TNI = TypeNames.find(TI->second);
if (TI->second->isPrimitiveType() || TNI != TypeNames.end()) {
if (TI->second->isIntegral() || TI->second->isPrimitiveType() ||
TNI != TypeNames.end()) {
Out << "mod->addTypeName(\"";
printEscapedString(TI->first);
Out << "\", " << getCppName(TI->second) << ");";

View File

@ -110,12 +110,14 @@ EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
static void EmitTypeVerify(std::ostream &OS, Record *ArgType) {
OS << "(int)" << ArgType->getValueAsString("TypeVal") << ", ";
// If this is an integer type, check the width is correct.
if (ArgType->isSubClassOf("LLVMIntegerType"))
OS << ArgType->getValueAsInt("Width") << ", ";
// If this is a packed type, check that the subtype and size are correct.
if (ArgType->isSubClassOf("LLVMPackedType")) {
Record *SubType = ArgType->getValueAsDef("ElTy");
OS << "(int)" << SubType->getValueAsString("TypeVal") << ", "
<< ArgType->getValueAsInt("NumElts") << ", ";
else if (ArgType->isSubClassOf("LLVMPackedType")) {
EmitTypeVerify(OS, ArgType->getValueAsDef("ElTy"));
OS << ArgType->getValueAsInt("NumElts") << ", ";
}
}