diff options
Diffstat (limited to 'include')
74 files changed, 3546 insertions, 606 deletions
diff --git a/include/llvm-c/Analysis.h b/include/llvm-c/Analysis.h index e1e4487..f0bdddc 100644 --- a/include/llvm-c/Analysis.h +++ b/include/llvm-c/Analysis.h @@ -25,6 +25,12 @@ extern "C" { #endif +/** + * @defgroup LLVMCAnalysis Analysis + * @ingroup LLVMC + * + * @{ + */ typedef enum { LLVMAbortProcessAction, /* verifier will print to stderr and abort() */ @@ -48,6 +54,10 @@ LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action); void LLVMViewFunctionCFG(LLVMValueRef Fn); void LLVMViewFunctionCFGOnly(LLVMValueRef Fn); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/BitReader.h b/include/llvm-c/BitReader.h index 6db6607..5228035 100644 --- a/include/llvm-c/BitReader.h +++ b/include/llvm-c/BitReader.h @@ -25,6 +25,12 @@ extern "C" { #endif +/** + * @defgroup LLVMCBitReader Bit Reader + * @ingroup LLVMC + * + * @{ + */ /* Builds a module from the bitcode in the specified memory buffer, returning a reference to the module via the OutModule parameter. Returns 0 on success. @@ -59,6 +65,10 @@ LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef *OutMP, char **OutMessage); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/BitWriter.h b/include/llvm-c/BitWriter.h index bcbfb11..ba5a677 100644 --- a/include/llvm-c/BitWriter.h +++ b/include/llvm-c/BitWriter.h @@ -25,6 +25,12 @@ extern "C" { #endif +/** + * @defgroup LLVMCBitWriter Bit Writer + * @ingroup LLVMC + * + * @{ + */ /*===-- Operations on modules ---------------------------------------------===*/ @@ -39,6 +45,10 @@ int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose, descriptor. Returns 0 on success. Closes the Handle. */ int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index e0195e0..52b8b1c 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -10,24 +10,6 @@ |* This header declares the C interface to libLLVMCore.a, which implements *| |* the LLVM intermediate representation. *| |* *| -|* LLVM uses a polymorphic type hierarchy which C cannot represent, therefore *| -|* parameters must be passed as base types. Despite the declared types, most *| -|* of the functions provided operate only on branches of the type hierarchy. *| -|* The declared parameter names are descriptive and specify which type is *| -|* required. Additionally, each type hierarchy is documented along with the *| -|* functions that operate upon it. For more detail, refer to LLVM's C++ code. *| -|* If in doubt, refer to Core.cpp, which performs paramter downcasts in the *| -|* form unwrap<RequiredType>(Param). *| -|* *| -|* Many exotic languages can interoperate with C code but have a harder time *| -|* with C++ due to name mangling. So in addition to C, this interface enables *| -|* tools written in such languages. *| -|* *| -|* When included into a C++ source file, also declares 'wrap' and 'unwrap' *| -|* helpers to perform opaque reference<-->pointer conversions. These helpers *| -|* are shorter and more tightly typed than writing the casts by hand when *| -|* authoring bindings. In assert builds, they will do runtime type checking. *| -|* *| \*===----------------------------------------------------------------------===*/ #ifndef LLVM_C_CORE_H @@ -46,50 +28,121 @@ extern "C" { #endif +/** + * @defgroup LLVMC LLVM-C: C interface to LLVM + * + * This module exposes parts of the LLVM library as a C API. + * + * @{ + */ + +/** + * @defgroup LLVMCTransforms Transforms + */ + +/** + * @defgroup LLVMCCore Core + * + * This modules provide an interface to libLLVMCore, which implements + * the LLVM intermediate representation as well as other related types + * and utilities. + * + * LLVM uses a polymorphic type hierarchy which C cannot represent, therefore + * parameters must be passed as base types. Despite the declared types, most + * of the functions provided operate only on branches of the type hierarchy. + * The declared parameter names are descriptive and specify which type is + * required. Additionally, each type hierarchy is documented along with the + * functions that operate upon it. For more detail, refer to LLVM's C++ code. + * If in doubt, refer to Core.cpp, which performs paramter downcasts in the + * form unwrap<RequiredType>(Param). + * + * Many exotic languages can interoperate with C code but have a harder time + * with C++ due to name mangling. So in addition to C, this interface enables + * tools written in such languages. + * + * When included into a C++ source file, also declares 'wrap' and 'unwrap' + * helpers to perform opaque reference<-->pointer conversions. These helpers + * are shorter and more tightly typed than writing the casts by hand when + * authoring bindings. In assert builds, they will do runtime type checking. + * + * @{ + */ + +/** + * @defgroup LLVMCCoreTypes Types and Enumerations + * + * @{ + */ typedef int LLVMBool; /* Opaque types. */ /** - * The top-level container for all LLVM global data. See the LLVMContext class. + * The top-level container for all LLVM global data. See the LLVMContext class. */ typedef struct LLVMOpaqueContext *LLVMContextRef; /** * The top-level container for all other LLVM Intermediate Representation (IR) - * objects. See the llvm::Module class. + * objects. + * + * @see llvm::Module */ typedef struct LLVMOpaqueModule *LLVMModuleRef; /** - * Each value in the LLVM IR has a type, an LLVMTypeRef. See the llvm::Type - * class. + * Each value in the LLVM IR has a type, an LLVMTypeRef. + * + * @see llvm::Type */ typedef struct LLVMOpaqueType *LLVMTypeRef; +/** + * Represents an individual value in LLVM IR. + * + * This models llvm::Value. + */ typedef struct LLVMOpaqueValue *LLVMValueRef; + +/** + * Represents a basic block of instruction in LLVM IR. + * + * This models llvm::BasicBlock. + */ typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; + +/** + * Represents an LLVM basic block builder. + * + * This models llvm::IRBuilder. + */ typedef struct LLVMOpaqueBuilder *LLVMBuilderRef; -/* Interface used to provide a module to JIT or interpreter. This is now just a - * synonym for llvm::Module, but we have to keep using the different type to - * keep binary compatibility. +/** + * Interface used to provide a module to JIT or interpreter. + * This is now just a synonym for llvm::Module, but we have to keep using the + * different type to keep binary compatibility. */ typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef; -/* Used to provide a module to JIT or interpreter. - * See the llvm::MemoryBuffer class. +/** + * Used to provide a module to JIT or interpreter. + * + * @see llvm::MemoryBuffer */ typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef; -/** See the llvm::PassManagerBase class. */ +/** @see llvm::PassManagerBase */ typedef struct LLVMOpaquePassManager *LLVMPassManagerRef; -/** See the llvm::PassRegistry class. */ +/** @see llvm::PassRegistry */ typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef; -/** Used to get the users and usees of a Value. See the llvm::Use class. */ +/** + * Used to get the users and usees of a Value. + * + * @see llvm::Use */ typedef struct LLVMOpaqueUse *LLVMUseRef; typedef enum { @@ -298,6 +351,10 @@ typedef enum { LLVMLandingPadFilter /**< A filter clause */ } LLVMLandingPadClauseTy; +/** + * @} + */ + void LLVMInitializeCore(LLVMPassRegistryRef R); @@ -306,49 +363,233 @@ void LLVMInitializeCore(LLVMPassRegistryRef R); void LLVMDisposeMessage(char *Message); -/*===-- Contexts ----------------------------------------------------------===*/ +/** + * @defgroup LLVMCCoreContext Contexts + * + * Contexts are execution states for the core LLVM IR system. + * + * Most types are tied to a context instance. Multiple contexts can + * exist simultaneously. A single context is not thread safe. However, + * different contexts can execute on different threads simultaneously. + * + * @{ + */ -/* Create and destroy contexts. */ +/** + * Create a new context. + * + * Every call to this function should be paired with a call to + * LLVMContextDispose() or the context will leak memory. + */ LLVMContextRef LLVMContextCreate(void); + +/** + * Obtain the global context instance. + */ LLVMContextRef LLVMGetGlobalContext(void); + +/** + * Destroy a context instance. + * + * This should be called for every call to LLVMContextCreate() or memory + * will be leaked. + */ void LLVMContextDispose(LLVMContextRef C); unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name, unsigned SLen); unsigned LLVMGetMDKindID(const char* Name, unsigned SLen); -/*===-- Modules -----------------------------------------------------------===*/ +/** + * @} + */ -/* Create and destroy modules. */ -/** See llvm::Module::Module. */ +/** + * @defgroup LLVMCCoreModule Modules + * + * Modules represent the top-level structure in a LLVM program. An LLVM + * module is effectively a translation unit or a collection of + * translation units merged together. + * + * @{ + */ + +/** + * Create a new, empty module in the global context. + * + * This is equivalent to calling LLVMModuleCreateWithNameInContext with + * LLVMGetGlobalContext() as the context parameter. + * + * Every invocation should be paired with LLVMDisposeModule() or memory + * will be leaked. + */ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID); + +/** + * Create a new, empty module in a specific context. + * + * Every invocation should be paired with LLVMDisposeModule() or memory + * will be leaked. + */ LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, LLVMContextRef C); -/** See llvm::Module::~Module. */ +/** + * Destroy a module instance. + * + * This must be called for every created module or memory will be + * leaked. + */ void LLVMDisposeModule(LLVMModuleRef M); -/** Data layout. See Module::getDataLayout. */ +/** + * Obtain the data layout for a module. + * + * @see Module::getDataLayout() + */ const char *LLVMGetDataLayout(LLVMModuleRef M); + +/** + * Set the data layout for a module. + * + * @see Module::setDataLayout() + */ void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple); -/** Target triple. See Module::getTargetTriple. */ +/** + * Obtain the target triple for a module. + * + * @see Module::getTargetTriple() + */ const char *LLVMGetTarget(LLVMModuleRef M); + +/** + * Set the target triple for a module. + * + * @see Module::setTargetTriple() + */ void LLVMSetTarget(LLVMModuleRef M, const char *Triple); -/** See Module::dump. */ +/** + * Dump a representation of a module to stderr. + * + * @see Module::dump() + */ void LLVMDumpModule(LLVMModuleRef M); -/** See Module::setModuleInlineAsm. */ +/** + * Set inline assembly for a module. + * + * @see Module::setModuleInlineAsm() + */ void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm); -/** See Module::getContext. */ +/** + * Obtain the context to which this module is associated. + * + * @see Module::getContext() + */ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M); -/*===-- Types -------------------------------------------------------------===*/ +/** + * Obtain a Type from a module by its registered name. + */ +LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name); + +/** + * Obtain the number of operands for named metadata in a module. + * + * @see llvm::Module::getNamedMetadata() + */ +unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name); + +/** + * Obtain the named metadata operands for a module. + * + * The passed LLVMValueRef pointer should refer to an array of + * LLVMValueRef at least LLVMGetNamedMetadataNumOperands long. This + * array will be populated with the LLVMValueRef instances. Each + * instance corresponds to a llvm::MDNode. + * + * @see llvm::Module::getNamedMetadata() + * @see llvm::MDNode::getOperand() + */ +void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest); + +/** + * Add an operand to named metadata. + * + * @see llvm::Module::getNamedMetadata() + * @see llvm::MDNode::addOperand() + */ +void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, + LLVMValueRef Val); -/* LLVM types conform to the following hierarchy: - * +/** + * Add a function to a module under a specified name. + * + * @see llvm::Function::Create() + */ +LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, + LLVMTypeRef FunctionTy); + +/** + * Obtain a Function value from a Module by its name. + * + * The returned value corresponds to a llvm::Function value. + * + * @see llvm::Module::getFunction() + */ +LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name); + +/** + * Obtain an iterator to the first Function in a Module. + * + * @see llvm::Module::begin() + */ +LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M); + +/** + * Obtain an iterator to the last Function in a Module. + * + * @see llvm::Module::end() + */ +LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M); + +/** + * Advance a Function iterator to the next Function. + * + * Returns NULL if the iterator was already at the end and there are no more + * functions. + */ +LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn); + +/** + * Decrement a Function iterator to the previous Function. + * + * Returns NULL if the iterator was already at the beginning and there are + * no previous functions. + */ +LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn); + +/** + * @} + */ + +/** + * @defgroup LLVMCCoreType Types + * + * Types represent the type of a value. + * + * Types are associated with a context instance. The context internally + * deduplicates types so there is only 1 instance of a specific type + * alive at a time. In other words, a unique type is shared among all + * consumers within a context. + * + * A Type in the C API corresponds to llvm::Type. + * + * Types have the following hierarchy: + * * types: * integer type * real type @@ -360,16 +601,44 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M); * void type * label type * opaque type + * + * @{ */ -/** See llvm::LLVMTypeKind::getTypeID. */ +/** + * Obtain the enumerated type of a Type instance. + * + * @see llvm::Type:getTypeID() + */ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty); + +/** + * Whether the type has a known size. + * + * Things that don't have a size are abstract types, labels, and void.a + * + * @see llvm::Type::isSized() + */ LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty); -/** See llvm::LLVMType::getContext. */ +/** + * Obtain the context to which this type instance is associated. + * + * @see llvm::Type::getContext() + */ LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty); -/* Operations on integer types */ +/** + * @defgroup LLVMCCoreTypeInt Integer Types + * + * Functions in this section operate on integer types. + * + * @{ + */ + +/** + * Obtain an integer type from a context with specified bit width. + */ LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C); @@ -377,6 +646,10 @@ LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C); LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits); +/** + * Obtain an integer type from the global context with a specified bit + * width. + */ LLVMTypeRef LLVMInt1Type(void); LLVMTypeRef LLVMInt8Type(void); LLVMTypeRef LLVMInt16Type(void); @@ -385,14 +658,52 @@ LLVMTypeRef LLVMInt64Type(void); LLVMTypeRef LLVMIntType(unsigned NumBits); unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy); -/* Operations on real types */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreTypeFloat Floating Point Types + * + * @{ + */ + +/** + * Obtain a 16-bit floating point type from a context. + */ LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C); + +/** + * Obtain a 32-bit floating point type from a context. + */ LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C); + +/** + * Obtain a 64-bit floating point type from a context. + */ LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C); + +/** + * Obtain a 80-bit floating point type (X87) from a context. + */ LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C); + +/** + * Obtain a 128-bit floating point type (112-bit mantissa) from a + * context. + */ LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C); + +/** + * Obtain a 128-bit floating point type (two 64-bits) from a context. + */ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C); +/** + * Obtain a floating point type from the global context. + * + * These map to the functions in this group of the same name. + */ LLVMTypeRef LLVMHalfType(void); LLVMTypeRef LLVMFloatType(void); LLVMTypeRef LLVMDoubleType(void); @@ -400,55 +711,283 @@ LLVMTypeRef LLVMX86FP80Type(void); LLVMTypeRef LLVMFP128Type(void); LLVMTypeRef LLVMPPCFP128Type(void); -/* Operations on function types */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreTypeFunction Function Types + * + * @{ + */ + +/** + * Obtain a function type consisting of a specified signature. + * + * The function is defined as a tuple of a return Type, a list of + * parameter types, and whether the function is variadic. + */ LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType, LLVMTypeRef *ParamTypes, unsigned ParamCount, LLVMBool IsVarArg); + +/** + * Returns whether a function type is variadic. + */ LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy); + +/** + * Obtain the Type this function Type returns. + */ LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy); + +/** + * Obtain the number of parameters this function accepts. + */ unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy); + +/** + * Obtain the types of a function's parameters. + * + * The Dest parameter should point to a pre-allocated array of + * LLVMTypeRef at least LLVMCountParamTypes() large. On return, the + * first LLVMCountParamTypes() entries in the array will be populated + * with LLVMTypeRef instances. + * + * @param FunctionTy The function type to operate on. + * @param Dest Memory address of an array to be filled with result. + */ void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest); -/* Operations on struct types */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreTypeStruct Structure Types + * + * These functions relate to LLVMTypeRef instances. + * + * @see llvm::StructType + * + * @{ + */ + +/** + * Create a new structure type in a context. + * + * A structure is specified by a list of inner elements/types and + * whether these can be packed together. + * + * @see llvm::StructType::create() + */ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); + +/** + * Create a new structure type in the global context. + * + * @see llvm::StructType::create() + */ LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); + +/** + * Create an empty structure in a context having a specified name. + * + * @see llvm::StructType::create() + */ LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name); + +/** + * Obtain the name of a structure. + * + * @see llvm::StructType::getName() + */ const char *LLVMGetStructName(LLVMTypeRef Ty); + +/** + * Set the contents of a structure type. + * + * @see llvm::StructType::setBody() + */ void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); +/** + * Get the number of elements defined inside the structure. + * + * @see llvm::StructType::getNumElements() + */ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); + +/** + * Get the elements within a structure. + * + * The function is passed the address of a pre-allocated array of + * LLVMTypeRef at least LLVMCountStructElementTypes() long. After + * invocation, this array will be populated with the structure's + * elements. The objects in the destination array will have a lifetime + * of the structure type itself, which is the lifetime of the context it + * is contained in. + */ void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); + +/** + * Determine whether a structure is packed. + * + * @see llvm::StructType::isPacked() + */ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); + +/** + * Determine whether a structure is opaque. + * + * @see llvm::StructType::isOpaque() + */ LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy); -LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name); +/** + * @} + */ -/* Operations on array, pointer, and vector types (sequence types) */ -LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); -LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); -LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount); +/** + * @defgroup LLVMCCoreTypeSequential Sequential Types + * + * Sequential types represents "arrays" of types. This is a super class + * for array, vector, and pointer types. + * + * @{ + */ + +/** + * Obtain the type of elements within a sequential type. + * + * This works on array, vector, and pointer types. + * + * @see llvm::SequentialType::getElementType() + */ LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty); + +/** + * Create a fixed size array type that refers to a specific type. + * + * The created type will exist in the context that its element type + * exists in. + * + * @see llvm::ArrayType::get() + */ +LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); + +/** + * Obtain the length of an array type. + * + * This only works on types that represent arrays. + * + * @see llvm::ArrayType::getNumElements() + */ unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy); + +/** + * Create a pointer type that points to a defined type. + * + * The created type will exist in the context that its pointee type + * exists in. + * + * @see llvm::PointerType::get() + */ +LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); + +/** + * Obtain the address space of a pointer type. + * + * This only works on types that represent pointers. + * + * @see llvm::PointerType::getAddressSpace() + */ unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy); + +/** + * Create a vector type that contains a defined type and has a specific + * number of elements. + * + * The created type will exist in the context thats its element type + * exists in. + * + * @see llvm::VectorType::get() + */ +LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount); + +/** + * Obtain the number of elements in a vector type. + * + * This only works on types that represent vectors. + * + * @see llvm::VectorType::getNumElements() + */ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy); -/* Operations on other types */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreTypeOther Other Types + * + * @{ + */ + +/** + * Create a void type in a context. + */ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C); + +/** + * Create a label type in a context. + */ LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C); + +/** + * Create a X86 MMX type in a context. + */ LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C); +/** + * These are similar to the above functions except they operate on the + * global context. + */ LLVMTypeRef LLVMVoidType(void); LLVMTypeRef LLVMLabelType(void); LLVMTypeRef LLVMX86MMXType(void); -/*===-- Values ------------------------------------------------------------===*/ +/** + * @} + */ -/* The bulk of LLVM's object model consists of values, which comprise a very +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValues Values + * + * The bulk of LLVM's object model consists of values, which comprise a very * rich type hierarchy. + * + * LLVMValueRef essentially represents llvm::Value. There is a rich + * hierarchy of classes within this type. Depending on the instance + * obtain, not all APIs are available. + * + * Callers can determine the type of a LLVMValueRef by calling the + * LLVMIsA* family of functions (e.g. LLVMIsAArgument()). These + * functions are defined by a macro, so it isn't obvious which are + * available by looking at the Doxygen source code. Instead, look at the + * source definition of LLVM_FOR_EACH_VALUE_SUBCLASS and note the list + * of value names given. These value names also correspond to classes in + * the llvm::Value hierarchy. + * + * @{ */ #define LLVM_FOR_EACH_VALUE_SUBCLASS(macro) \ @@ -522,92 +1061,399 @@ LLVMTypeRef LLVMX86MMXType(void); macro(LoadInst) \ macro(VAArgInst) -/* Operations on all values */ +/** + * @defgroup LLVMCCoreValueGeneral General APIs + * + * Functions in this section work on all LLVMValueRef instances, + * regardless of their sub-type. They correspond to functions available + * on llvm::Value. + * + * @{ + */ + +/** + * Obtain the type of a value. + * + * @see llvm::Value::getType() + */ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val); + +/** + * Obtain the string name of a value. + * + * @see llvm::Value::getName() + */ const char *LLVMGetValueName(LLVMValueRef Val); + +/** + * Set the string name of a value. + * + * @see llvm::Value::setName() + */ void LLVMSetValueName(LLVMValueRef Val, const char *Name); + +/** + * Dump a representation of a value to stderr. + * + * @see llvm::Value::dump() + */ void LLVMDumpValue(LLVMValueRef Val); + +/** + * Replace all uses of a value with another one. + * + * @see llvm::Value::replaceAllUsesWith() + */ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal); -int LLVMHasMetadata(LLVMValueRef Val); -LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID); -void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); -/* Conversion functions. Return the input value if it is an instance of the - specified class, otherwise NULL. See llvm::dyn_cast_or_null<>. */ +/** + * Determine whether the specified constant instance is constant. + */ +LLVMBool LLVMIsConstant(LLVMValueRef Val); + +/** + * Determine whether a value instance is undefined. + */ +LLVMBool LLVMIsUndef(LLVMValueRef Val); + +/** + * Convert value instances between types. + * + * Internally, a LLVMValueRef is "pinned" to a specific type. This + * series of functions allows you to cast an instance to a specific + * type. + * + * If the cast is not valid for the specified type, NULL is returned. + * + * @see llvm::dyn_cast_or_null<> + */ #define LLVM_DECLARE_VALUE_CAST(name) \ LLVMValueRef LLVMIsA##name(LLVMValueRef Val); LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST) -/* Operations on Uses */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueUses Usage + * + * This module defines functions that allow you to inspect the uses of a + * LLVMValueRef. + * + * It is possible to obtain a LLVMUseRef for any LLVMValueRef instance. + * Each LLVMUseRef (which corresponds to a llvm::Use instance) holds a + * llvm::User and llvm::Value. + * + * @{ + */ + +/** + * Obtain the first use of a value. + * + * Uses are obtained in an iterator fashion. First, call this function + * to obtain a reference to the first use. Then, call LLVMGetNextUse() + * on that instance and all subsequently obtained instances untl + * LLVMGetNextUse() returns NULL. + * + * @see llvm::Value::use_begin() + */ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val); + +/** + * Obtain the next use of a value. + * + * This effectively advances the iterator. It returns NULL if you are on + * the final use and no more are available. + */ LLVMUseRef LLVMGetNextUse(LLVMUseRef U); + +/** + * Obtain the user value for a user. + * + * The returned value corresponds to a llvm::User type. + * + * @see llvm::Use::getUser() + */ LLVMValueRef LLVMGetUser(LLVMUseRef U); + +/** + * Obtain the value this use corresponds to. + * + * @see llvm::Use::get(). + */ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U); -/* Operations on Users and metadata */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueUser User value + * + * Function in this group pertain to LLVMValueRef instances that descent + * from llvm::User. This includes constants, instructions, and + * operators. + * + * @{ + */ + +/** + * Obtain an operand at a specific index in a llvm::User value. + * + * @see llvm::User::getOperand() + */ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index); + +/** + * Set an operand at a specific index in a llvm::User value. + * + * @see llvm::User::setOperand() + */ void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val); + +/** + * Obtain the number of operands in a llvm::User value. + * + * @see llvm::User::getNumOperands() + */ int LLVMGetNumOperands(LLVMValueRef Val); -/* Operations on constants of any type */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueConstant Constants + * + * This section contains APIs for interacting with LLVMValueRef that + * correspond to llvm::Constant instances. + * + * These functions will work for any LLVMValueRef in the llvm::Constant + * class hierarchy. + * + * @{ + */ + +/** + * Obtain a constant value referring to the null instance of a type. + * + * @see llvm::Constant::getNullValue() + */ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */ -LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty); /* only for int/vector */ + +/** + * Obtain a constant value referring to the instance of a type + * consisting of all ones. + * + * This is only valid for integer types. + * + * @see llvm::Constant::getAllOnesValue() + */ +LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty); + +/** + * Obtain a constant value referring to an undefined value of a type. + * + * @see llvm::UndefValue::get() + */ LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty); -LLVMBool LLVMIsConstant(LLVMValueRef Val); + +/** + * Determine whether a value instance is null. + * + * @see llvm::Constant::isNullValue() + */ LLVMBool LLVMIsNull(LLVMValueRef Val); -LLVMBool LLVMIsUndef(LLVMValueRef Val); + +/** + * Obtain a constant that is a constant pointer pointing to NULL for a + * specified type. + */ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); -/* Operations on metadata */ -LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, - unsigned SLen); -LLVMValueRef LLVMMDString(const char *Str, unsigned SLen); -LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, - unsigned Count); -LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); -const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len); -unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name); -void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest); -void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, - LLVMValueRef Val); +/** + * @defgroup LLVMCCoreValueConstantScalar Scalar constants + * + * Functions in this group model LLVMValueRef instances that correspond + * to constants referring to scalar types. + * + * For integer types, the LLVMTypeRef parameter should correspond to a + * llvm::IntegerType instance and the returned LLVMValueRef will + * correspond to a llvm::ConstantInt. + * + * For floating point types, the LLVMTypeRef returned corresponds to a + * llvm::ConstantFP. + * + * @{ + */ -/* Operations on scalar constants */ +/** + * Obtain a constant value for an integer type. + * + * The returned value corresponds to a llvm::ConstantInt. + * + * @see llvm::ConstantInt::get() + * + * @param IntTy Integer type to obtain value of. + * @param N The value the returned instance should refer to. + * @param SignExtend Whether to sign extend the produced value. + */ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, LLVMBool SignExtend); + +/** + * Obtain a constant value for an integer of arbitrary precision. + * + * @see llvm::ConstantInt::get() + */ LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, unsigned NumWords, const uint64_t Words[]); + +/** + * Obtain a constant value for an integer parsed from a string. + * + * A similar API, LLVMConstIntOfStringAndSize is also available. If the + * string's length is available, it is preferred to call that function + * instead. + * + * @see llvm::ConstantInt::get() + */ LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char *Text, uint8_t Radix); + +/** + * Obtain a constant value for an integer parsed from a string with + * specified length. + * + * @see llvm::ConstantInt::get() + */ LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char *Text, unsigned SLen, uint8_t Radix); + +/** + * Obtain a constant value referring to a double floating point value. + */ LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N); + +/** + * Obtain a constant for a floating point value parsed from a string. + * + * A similar API, LLVMConstRealOfStringAndSize is also available. It + * should be used if the input string's length is known. + */ LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text); + +/** + * Obtain a constant for a floating point value parsed from a string. + */ LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char *Text, unsigned SLen); + +/** + * Obtain the zero extended value for an integer constant value. + * + * @see llvm::ConstantInt::getZExtValue() + */ unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal); + +/** + * Obtain the sign extended value for an integer constant value. + * + * @see llvm::ConstantInt::getSExtValue() + */ long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal); +/** + * @} + */ -/* Operations on composite constants */ +/** + * @defgroup LLVMCCoreValueConstantComposite Composite Constants + * + * Functions in this group operate on composite constants. + * + * @{ + */ + +/** + * Create a ConstantDataSequential and initialize it with a string. + * + * @see llvm::ConstantDataArray::getString() + */ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, unsigned Length, LLVMBool DontNullTerminate); -LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, - LLVMValueRef *ConstantVals, - unsigned Count, LLVMBool Packed); +/** + * Create a ConstantDataSequential with string content in the global context. + * + * This is the same as LLVMConstStringInContext except it operates on the + * global context. + * + * @see LLVMConstStringInContext() + * @see llvm::ConstantDataArray::getString() + */ LLVMValueRef LLVMConstString(const char *Str, unsigned Length, LLVMBool DontNullTerminate); -LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, - LLVMValueRef *ConstantVals, unsigned Length); + +/** + * Create an anonymous ConstantStruct with the specified values. + * + * @see llvm::ConstantStruct::getAnon() + */ +LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, + LLVMValueRef *ConstantVals, + unsigned Count, LLVMBool Packed); + +/** + * Create a ConstantStruct in the global Context. + * + * This is the same as LLVMConstStructInContext except it operates on the + * global Context. + * + * @see LLVMConstStructInContext() + */ LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed); + +/** + * Create a ConstantArray from values. + * + * @see llvm::ConstantArray::get() + */ +LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, + LLVMValueRef *ConstantVals, unsigned Length); + +/** + * Create a non-anonymous ConstantStruct from values. + * + * @see llvm::ConstantStruct::get() + */ LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, LLVMValueRef *ConstantVals, unsigned Count); + +/** + * Create a ConstantVector from values. + * + * @see llvm::ConstantVector::get() + */ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size); -/* Constant expressions */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueConstantExpressions Constant Expressions + * + * Functions in this group correspond to APIs on llvm::ConstantExpr. + * + * @see llvm::ConstantExpr. + * + * @{ + */ LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal); LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty); LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty); @@ -694,7 +1540,21 @@ LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, LLVMBool HasSideEffects, LLVMBool IsAlignStack); LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB); -/* Operations on global variables, functions, and aliases (globals) */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueConstantGlobals Global Values + * + * This group contains functions that operate on global values. Functions in + * this group relate to functions in the llvm::GlobalValue class tree. + * + * @see llvm::GlobalValue + * + * @{ + */ + LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global); LLVMBool LLVMIsDeclaration(LLVMValueRef Global); LLVMLinkage LLVMGetLinkage(LLVMValueRef Global); @@ -706,7 +1566,15 @@ void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz); unsigned LLVMGetAlignment(LLVMValueRef Global); void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes); -/* Operations on global variables */ +/** + * @defgroup LLVMCoreValueConstantGlobalVariable Global Variables + * + * This group contains functions that operate on global variable values. + * + * @see llvm::GlobalVariable + * + * @{ + */ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name); LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name, @@ -724,110 +1592,672 @@ void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal); LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar); void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant); -/* Operations on aliases */ +/** + * @} + */ + +/** + * @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases + * + * This group contains function that operate on global alias values. + * + * @see llvm::GlobalAlias + * + * @{ + */ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name); -/* Operations on functions */ -LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, - LLVMTypeRef FunctionTy); -LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name); -LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M); -LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M); -LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn); -LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn); +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueFunction Function values + * + * Functions in this group operate on LLVMValueRef instances that + * correspond to llvm::Function instances. + * + * @see llvm::Function + * + * @{ + */ + +/** + * Remove a function from its containing module and deletes it. + * + * @see llvm::Function::eraseFromParent() + */ void LLVMDeleteFunction(LLVMValueRef Fn); + +/** + * Obtain the ID number from a function instance. + * + * @see llvm::Function::getIntrinsicID() + */ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn); + +/** + * Obtain the calling function of a function. + * + * The returned value corresponds to the LLVMCallConv enumeration. + * + * @see llvm::Function::getCallingConv() + */ unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn); + +/** + * Set the calling convention of a function. + * + * @see llvm::Function::setCallingConv() + * + * @param Fn Function to operate on + * @param CC LLVMCallConv to set calling convention to + */ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC); + +/** + * Obtain the name of the garbage collector to use during code + * generation. + * + * @see llvm::Function::getGC() + */ const char *LLVMGetGC(LLVMValueRef Fn); + +/** + * Define the garbage collector to use during code generation. + * + * @see llvm::Function::setGC() + */ void LLVMSetGC(LLVMValueRef Fn, const char *Name); + +/** + * Add an attribute to a function. + * + * @see llvm::Function::addAttribute() + */ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); + +/** + * Obtain an attribute from a function. + * + * @see llvm::Function::getAttributes() + */ LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn); + +/** + * Remove an attribute from a function. + */ void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA); -/* Operations on parameters */ +/** + * @defgroup LLVMCCoreValueFunctionParameters Function Parameters + * + * Functions in this group relate to arguments/parameters on functions. + * + * Functions in this group expect LLVMValueRef instances that correspond + * to llvm::Function instances. + * + * @{ + */ + +/** + * Obtain the number of parameters in a function. + * + * @see llvm::Function::arg_size() + */ unsigned LLVMCountParams(LLVMValueRef Fn); + +/** + * Obtain the parameters in a function. + * + * The takes a pointer to a pre-allocated array of LLVMValueRef that is + * at least LLVMCountParams() long. This array will be filled with + * LLVMValueRef instances which correspond to the parameters the + * function receives. Each LLVMValueRef corresponds to a llvm::Argument + * instance. + * + * @see llvm::Function::arg_begin() + */ void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params); + +/** + * Obtain the parameter at the specified index. + * + * Parameters are indexed from 0. + * + * @see llvm::Function::arg_begin() + */ LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index); + +/** + * Obtain the function to which this argument belongs. + * + * Unlike other functions in this group, this one takes a LLVMValueRef + * that corresponds to a llvm::Attribute. + * + * The returned LLVMValueRef is the llvm::Function to which this + * argument belongs. + */ LLVMValueRef LLVMGetParamParent(LLVMValueRef Inst); + +/** + * Obtain the first parameter to a function. + * + * @see llvm::Function::arg_begin() + */ LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn); + +/** + * Obtain the last parameter to a function. + * + * @see llvm::Function::arg_end() + */ LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn); + +/** + * Obtain the next parameter to a function. + * + * This takes a LLVMValueRef obtained from LLVMGetFirstParam() (which is + * actually a wrapped iterator) and obtains the next parameter from the + * underlying iterator. + */ LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg); + +/** + * Obtain the previous parameter to a function. + * + * This is the opposite of LLVMGetNextParam(). + */ LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg); + +/** + * Add an attribute to a function argument. + * + * @see llvm::Argument::addAttr() + */ void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA); + +/** + * Remove an attribute from a function argument. + * + * @see llvm::Argument::removeAttr() + */ void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA); + +/** + * Get an attribute from a function argument. + */ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg); + +/** + * Set the alignment for a function parameter. + * + * @see llvm::Argument::addAttr() + * @see llvm::Attribute::constructAlignmentFromInt() + */ void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align); -/* Operations on basic blocks */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueMetadata Metadata + * + * @{ + */ + +/** + * Obtain a MDString value from a context. + * + * The returned instance corresponds to the llvm::MDString class. + * + * The instance is specified by string data of a specified length. The + * string content is copied, so the backing memory can be freed after + * this function returns. + */ +LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, + unsigned SLen); + +/** + * Obtain a MDString value from the global context. + */ +LLVMValueRef LLVMMDString(const char *Str, unsigned SLen); + +/** + * Obtain a MDNode value from a context. + * + * The returned value corresponds to the llvm::MDNode class. + */ +LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, + unsigned Count); + +/** + * Obtain a MDNode value from the global context. + */ +LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); + +/** + * Obtain the underlying string from a MDString value. + * + * @param V Instance to obtain string from. + * @param Len Memory address which will hold length of returned string. + * @return String data in MDString. + */ +const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len); + +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueBasicBlock Basic Block + * + * A basic block represents a single entry single exit section of code. + * Basic blocks contain a list of instructions which form the body of + * the block. + * + * Basic blocks belong to functions. They have the type of label. + * + * Basic blocks are themselves values. However, the C API models them as + * LLVMBasicBlockRef. + * + * @see llvm::BasicBlock + * + * @{ + */ + +/** + * Convert a basic block instance to a value type. + */ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB); + +/** + * Determine whether a LLVMValueRef is itself a basic block. + */ LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val); + +/** + * Convert a LLVMValueRef to a LLVMBasicBlockRef instance. + */ LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val); + +/** + * Obtain the function to which a basic block belongs. + * + * @see llvm::BasicBlock::getParent() + */ LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB); + +/** + * Obtain the terminator instruction for a basic block. + * + * If the basic block does not have a terminator (it is not well-formed + * if it doesn't), then NULL is returned. + * + * The returned LLVMValueRef corresponds to a llvm::TerminatorInst. + * + * @see llvm::BasicBlock::getTerminator() + */ LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB); + +/** + * Obtain the number of basic blocks in a function. + * + * @param Fn Function value to operate on. + */ unsigned LLVMCountBasicBlocks(LLVMValueRef Fn); + +/** + * Obtain all of the basic blocks in a function. + * + * This operates on a function value. The BasicBlocks parameter is a + * pointer to a pre-allocated array of LLVMBasicBlockRef of at least + * LLVMCountBasicBlocks() in length. This array is populated with + * LLVMBasicBlockRef instances. + */ void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks); + +/** + * Obtain the first basic block in a function. + * + * The returned basic block can be used as an iterator. You will likely + * eventually call into LLVMGetNextBasicBlock() with it. + * + * @see llvm::Function::begin() + */ LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn); + +/** + * Obtain the last basic block in a function. + * + * @see llvm::Function::end() + */ LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn); + +/** + * Advance a basic block iterator. + */ LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB); + +/** + * Go backwards in a basic block iterator. + */ LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB); + +/** + * Obtain the basic block that corresponds to the entry point of a + * function. + * + * @see llvm::Function::getEntryBlock() + */ LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn); +/** + * Append a basic block to the end of a function. + * + * @see llvm::BasicBlock::Create() + */ LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C, LLVMValueRef Fn, const char *Name); + +/** + * Append a basic block to the end of a function using the global + * context. + * + * @see llvm::BasicBlock::Create() + */ +LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name); + +/** + * Insert a basic block in a function before another basic block. + * + * The function to add to is determined by the function of the + * passed basic block. + * + * @see llvm::BasicBlock::Create() + */ LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C, LLVMBasicBlockRef BB, const char *Name); -LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name); +/** + * Insert a basic block in a function using the global context. + * + * @see llvm::BasicBlock::Create() + */ LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB, const char *Name); + +/** + * Remove a basic block from a function and delete it. + * + * This deletes the basic block from its containing function and deletes + * the basic block itself. + * + * @see llvm::BasicBlock::eraseFromParent() + */ void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); + +/** + * Remove a basic block from a function. + * + * This deletes the basic block from its containing function but keep + * the basic block alive. + * + * @see llvm::BasicBlock::removeFromParent() + */ void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB); +/** + * Move a basic block to before another one. + * + * @see llvm::BasicBlock::moveBefore() + */ void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); + +/** + * Move a basic block to after another one. + * + * @see llvm::BasicBlock::moveAfter() + */ void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); +/** + * Obtain the first instruction in a basic block. + * + * The returned LLVMValueRef corresponds to a llvm::Instruction + * instance. + */ LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB); + +/** + * Obtain the last instruction in a basic block. + * + * The returned LLVMValueRef corresponds to a LLVM:Instruction. + */ LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB); -/* Operations on instructions */ +/** + * @} + */ + +/** + * @defgroup LLVMCCoreValueInstruction Instructions + * + * Functions in this group relate to the inspection and manipulation of + * individual instructions. + * + * In the C++ API, an instruction is modeled by llvm::Instruction. This + * class has a large number of descendents. llvm::Instruction is a + * llvm::Value and in the C API, instructions are modeled by + * LLVMValueRef. + * + * This group also contains sub-groups which operate on specific + * llvm::Instruction types, e.g. llvm::CallInst. + * + * @{ + */ + +/** + * Determine whether an instruction has any metadata attached. + */ +int LLVMHasMetadata(LLVMValueRef Val); + +/** + * Return metadata associated with an instruction value. + */ +LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID); + +/** + * Set metadata associated with an instruction value. + */ +void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node); + +/** + * Obtain the basic block to which an instruction belongs. + * + * @see llvm::Instruction::getParent() + */ LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst); + +/** + * Obtain the instruction that occurs after the one specified. + * + * The next instruction will be from the same basic block. + * + * If this is the last instruction in a basic block, NULL will be + * returned. + */ LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst); + +/** + * Obtain the instruction that occured before this one. + * + * If the instruction is the first instruction in a basic block, NULL + * will be returned. + */ LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst); + +/** + * Remove and delete an instruction. + * + * The instruction specified is removed from its containing building + * block and then deleted. + * + * @see llvm::Instruction::eraseFromParent() + */ void LLVMInstructionEraseFromParent(LLVMValueRef Inst); + +/** + * Obtain the code opcode for an individual instruction. + * + * @see llvm::Instruction::getOpCode() + */ LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst); + +/** + * Obtain the predicate of an instruction. + * + * This is only valid for instructions that correspond to llvm::ICmpInst + * or llvm::ConstantExpr whose opcode is llvm::Instruction::ICmp. + * + * @see llvm::ICmpInst::getPredicate() + */ LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst); -/* Operations on call sites */ +/** + * @defgroup LLVMCCoreValueInstructionCall Call Sites and Invocations + * + * Functions in this group apply to instructions that refer to call + * sites and invocations. These correspond to C++ types in the + * llvm::CallInst class tree. + * + * @{ + */ + +/** + * Set the calling convention for a call instruction. + * + * This expects an LLVMValueRef that corresponds to a llvm::CallInst or + * llvm::InvokeInst. + * + * @see llvm::CallInst::setCallingConv() + * @see llvm::InvokeInst::setCallingConv() + */ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC); + +/** + * Obtain the calling convention for a call instruction. + * + * This is the opposite of LLVMSetInstructionCallConv(). Reads its + * usage. + * + * @see LLVMSetInstructionCallConv() + */ unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr); + + void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute); -void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, +void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute); -void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, +void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, unsigned align); -/* Operations on call instructions (only) */ +/** + * Obtain whether a call instruction is a tail call. + * + * This only works on llvm::CallInst instructions. + * + * @see llvm::CallInst::isTailCall() + */ LLVMBool LLVMIsTailCall(LLVMValueRef CallInst); + +/** + * Set whether a call instruction is a tail call. + * + * This only works on llvm::CallInst instructions. + * + * @see llvm::CallInst::setTailCall() + */ void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall); -/* Operations on switch instructions (only) */ +/** + * @} + */ + +/** + * Obtain the default destination basic block of a switch instruction. + * + * This only works on llvm::SwitchInst instructions. + * + * @see llvm::SwitchInst::getDefaultDest() + */ LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr); -/* Operations on phi nodes */ +/** + * @defgroup LLVMCCoreValueInstructionPHINode PHI Nodes + * + * Functions in this group only apply to instructions that map to + * llvm::PHINode instances. + * + * @{ + */ + +/** + * Add an incoming value to the end of a PHI list. + */ void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, LLVMBasicBlockRef *IncomingBlocks, unsigned Count); + +/** + * Obtain the number of incoming basic blocks to a PHI node. + */ unsigned LLVMCountIncoming(LLVMValueRef PhiNode); + +/** + * Obtain an incoming value to a PHI node as a LLVMValueRef. + */ LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index); + +/** + * Obtain an incoming value to a PHI node as a LLVMBasicBlockRef. + */ LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index); -/*===-- Instruction builders ----------------------------------------------===*/ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ -/* An instruction builder represents a point within a basic block, and is the - * exclusive means of building instructions using the C interface. +/** + * @defgroup LLVMCCoreInstructionBuilder Instruction Builders + * + * An instruction builder represents a point within a basic block and is + * the exclusive means of building instructions using the C interface. + * + * @{ */ LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C); @@ -1048,21 +2478,37 @@ LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); +/** + * @} + */ -/*===-- Module providers --------------------------------------------------===*/ +/** + * @defgroup LLVMCCoreModuleProvider Module Providers + * + * @{ + */ -/* Changes the type of M so it can be passed to FunctionPassManagers and the +/** + * Changes the type of M so it can be passed to FunctionPassManagers and the * JIT. They take ModuleProviders for historical reasons. */ LLVMModuleProviderRef LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M); -/* Destroys the module M. +/** + * Destroys the module M. */ void LLVMDisposeModuleProvider(LLVMModuleProviderRef M); +/** + * @} + */ -/*===-- Memory buffers ----------------------------------------------------===*/ +/** + * @defgroup LLVMCCoreMemoryBuffers Memory Buffers + * + * @{ + */ LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path, LLVMMemoryBufferRef *OutMemBuf, @@ -1071,23 +2517,39 @@ LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage); void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf); -/*===-- Pass Registry -----------------------------------------------------===*/ +/** + * @} + */ + +/** + * @defgroup LLVMCCorePassRegistry Pass Registry + * + * @{ + */ /** Return the global pass registry, for use with initialization functions. - See llvm::PassRegistry::getPassRegistry. */ + @see llvm::PassRegistry::getPassRegistry */ LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void); -/*===-- Pass Managers -----------------------------------------------------===*/ +/** + * @} + */ + +/** + * @defgroup LLVMCCorePassManagers Pass Managers + * + * @{ + */ /** Constructs a new whole-module pass pipeline. This type of pipeline is suitable for link-time optimization and whole-module transformations. - See llvm::PassManager::PassManager. */ + @see llvm::PassManager::PassManager */ LLVMPassManagerRef LLVMCreatePassManager(void); /** Constructs a new function-by-function pass pipeline over the module provider. It does not take ownership of the module provider. This type of pipeline is suitable for code generation and JIT compilation tasks. - See llvm::FunctionPassManager::FunctionPassManager. */ + @see llvm::FunctionPassManager::FunctionPassManager */ LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M); /** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */ @@ -1095,30 +2557,42 @@ LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP); /** Initializes, executes on the provided module, and finalizes all of the passes scheduled in the pass manager. Returns 1 if any of the passes - modified the module, 0 otherwise. See llvm::PassManager::run(Module&). */ + modified the module, 0 otherwise. + @see llvm::PassManager::run(Module&) */ LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M); /** Initializes all of the function passes scheduled in the function pass manager. Returns 1 if any of the passes modified the module, 0 otherwise. - See llvm::FunctionPassManager::doInitialization. */ + @see llvm::FunctionPassManager::doInitialization */ LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM); /** Executes all of the function passes scheduled in the function pass manager on the provided function. Returns 1 if any of the passes modified the function, false otherwise. - See llvm::FunctionPassManager::run(Function&). */ + @see llvm::FunctionPassManager::run(Function&) */ LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F); /** Finalizes all of the function passes scheduled in in the function pass manager. Returns 1 if any of the passes modified the module, 0 otherwise. - See llvm::FunctionPassManager::doFinalization. */ + @see llvm::FunctionPassManager::doFinalization */ LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM); /** Frees the memory of a pass pipeline. For function pipelines, does not free the module provider. - See llvm::PassManagerBase::~PassManagerBase. */ + @see llvm::PassManagerBase::~PassManagerBase. */ void LLVMDisposePassManager(LLVMPassManagerRef PM); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ #ifdef __cplusplus } diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index bf2f276..a676e37 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -19,6 +19,13 @@ #include <stddef.h> /** + * @defgroup LLVMCDisassembler Disassembler + * @ingroup LLVMC + * + * @{ + */ + +/** * An opaque reference to a disassembler context. */ typedef void *LLVMDisasmContextRef; @@ -157,6 +164,10 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DC, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize); +/** + * @} + */ + #ifdef __cplusplus } #endif /* !defined(__cplusplus) */ diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h index 0c173c2..71a0d49 100644 --- a/include/llvm-c/EnhancedDisassembly.h +++ b/include/llvm-c/EnhancedDisassembly.h @@ -25,6 +25,19 @@ extern "C" { #endif +/** + * @defgroup LLVMCEnhancedDisassembly Enhanced Disassembly + * @ingroup LLVMC + * @deprecated + * + * This module contains an interface to the Enhanced Disassembly (edis) + * library. The edis library is deprecated and will likely disappear in + * the near future. You should use the @ref LLVMCDisassembler interface + * instead. + * + * @{ + */ + /*! @typedef EDByteReaderCallback Interface to memory from which instructions may be read. @@ -504,6 +517,10 @@ int EDBlockEvaluateOperand(uint64_t *result, int EDBlockVisitTokens(EDInstRef inst, EDTokenVisitor_t visitor); +/** + * @} + */ + #endif #ifdef __cplusplus diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h index f5f4061..cb77bb2 100644 --- a/include/llvm-c/ExecutionEngine.h +++ b/include/llvm-c/ExecutionEngine.h @@ -26,6 +26,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCExecutionEngine Execution Engine + * @ingroup LLVMC + * + * @{ + */ + void LLVMLinkInJIT(void); void LLVMLinkInInterpreter(void); @@ -125,6 +132,10 @@ void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global); +/** + * @} + */ + #ifdef __cplusplus } diff --git a/include/llvm-c/Initialization.h b/include/llvm-c/Initialization.h index cbe60df..cb3ab9e 100644 --- a/include/llvm-c/Initialization.h +++ b/include/llvm-c/Initialization.h @@ -22,6 +22,15 @@ extern "C" { #endif +/** + * @defgroup LLVMCInitialization Initialization Routines + * @ingroup LLVMC + * + * This module contains routines used to initialize the LLVM system. + * + * @{ + */ + void LLVMInitializeCore(LLVMPassRegistryRef R); void LLVMInitializeTransformUtils(LLVMPassRegistryRef R); void LLVMInitializeScalarOpts(LLVMPassRegistryRef R); @@ -34,6 +43,10 @@ void LLVMInitializeIPA(LLVMPassRegistryRef R); void LLVMInitializeCodeGen(LLVMPassRegistryRef R); void LLVMInitializeTarget(LLVMPassRegistryRef R); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/LinkTimeOptimizer.h b/include/llvm-c/LinkTimeOptimizer.h index fca3946..5338d3f 100644 --- a/include/llvm-c/LinkTimeOptimizer.h +++ b/include/llvm-c/LinkTimeOptimizer.h @@ -20,6 +20,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCLinkTimeOptimizer Link Time Optimization + * @ingroup LLVMC + * + * @{ + */ + /// This provides a dummy type for pointers to the LTO object. typedef void* llvm_lto_t; @@ -51,6 +58,10 @@ extern "C" { extern llvm_lto_status_t llvm_optimize_modules (llvm_lto_t lto, const char* output_filename); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h index 6b465b3..e2dad62 100644 --- a/include/llvm-c/Object.h +++ b/include/llvm-c/Object.h @@ -28,6 +28,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCObject Object file reading and writing + * @ingroup LLVMC + * + * @{ + */ + // Opaque type wrappers typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef; typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef; @@ -86,6 +93,9 @@ uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI); const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI); const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI); +/** + * @} + */ #ifdef __cplusplus } diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index e4f177b..258a2be 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -26,6 +26,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCTarget Target information + * @ingroup LLVMC + * + * @{ + */ + enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian }; typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; @@ -209,6 +216,9 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy, See the destructor llvm::TargetData::~TargetData. */ void LLVMDisposeTargetData(LLVMTargetDataRef); +/** + * @} + */ #ifdef __cplusplus } diff --git a/include/llvm-c/Transforms/IPO.h b/include/llvm-c/Transforms/IPO.h index 710bebe..4480780 100644 --- a/include/llvm-c/Transforms/IPO.h +++ b/include/llvm-c/Transforms/IPO.h @@ -21,6 +21,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCTransformsIPO Interprocedural transformations + * @ingroup LLVMCTransforms + * + * @{ + */ + /** See llvm::createArgumentPromotionPass function. */ void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM); @@ -63,6 +70,10 @@ void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM); /** See llvm::createStripSymbolsPass function. */ void LLVMAddStripSymbolsPass(LLVMPassManagerRef PM); +/** + * @} + */ + #ifdef __cplusplus } #endif /* defined(__cplusplus) */ diff --git a/include/llvm-c/Transforms/PassManagerBuilder.h b/include/llvm-c/Transforms/PassManagerBuilder.h index fa722c9..cee6e5a 100644 --- a/include/llvm-c/Transforms/PassManagerBuilder.h +++ b/include/llvm-c/Transforms/PassManagerBuilder.h @@ -23,6 +23,13 @@ typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef; extern "C" { #endif +/** + * @defgroup LLVMCTransformsPassManagerBuilder Pass manager builder + * @ingroup LLVMCTransforms + * + * @{ + */ + /** See llvm::PassManagerBuilder. */ LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void); void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB); @@ -73,6 +80,10 @@ void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB, bool Internalize, bool RunInliner); +/** + * @} + */ + #ifdef __cplusplus } diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h index 6015ef9..a2c4d61 100644 --- a/include/llvm-c/Transforms/Scalar.h +++ b/include/llvm-c/Transforms/Scalar.h @@ -25,6 +25,13 @@ extern "C" { #endif +/** + * @defgroup LLVMCTransformsScalar Scalar transformations + * @ingroup LLVMCTransforms + * + * @{ + */ + /** See llvm::createAggressiveDCEPass function. */ void LLVMAddAggressiveDCEPass(LLVMPassManagerRef PM); @@ -116,6 +123,9 @@ void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM); /** See llvm::createBasicAliasAnalysisPass function */ void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM); +/** + * @} + */ #ifdef __cplusplus } diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h index ce92eaa..9e7c754 100644 --- a/include/llvm-c/Transforms/Vectorize.h +++ b/include/llvm-c/Transforms/Vectorize.h @@ -26,9 +26,20 @@ extern "C" { #endif +/** + * @defgroup LLVMCTransformsVectorize Vectorization transformations + * @ingroup LLVMCTransforms + * + * @{ + */ + /** See llvm::createBBVectorizePass function. */ void LLVMAddBBVectorizePass(LLVMPassManagerRef PM); +/** + * @} + */ + #ifdef __cplusplus } #endif /* defined(__cplusplus) */ diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 7ea7ad0..43ef9dc 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -20,6 +20,13 @@ #include <stddef.h> #include <unistd.h> +/** + * @defgroup LLVMCLTO LTO + * @ingroup LLVMC + * + * @{ + */ + #define LTO_API_VERSION 4 typedef enum { @@ -289,5 +296,8 @@ lto_codegen_debug_options(lto_code_gen_t cg, const char *); } #endif +/** + * @} + */ #endif diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index b08564c..4101989 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -561,7 +561,15 @@ public: /// Performs logical negation operation on this APInt. /// @returns true if *this is zero, false otherwise. /// @brief Logical negation operator. - bool operator!() const; + bool operator!() const { + if (isSingleWord()) + return !VAL; + + for (unsigned i = 0; i != getNumWords(); ++i) + if (pVal[i]) + return false; + return true; + } /// @} /// @name Assignment Operators @@ -834,7 +842,11 @@ public: /// @returns the bit value at bitPosition /// @brief Array-indexing support. - bool operator[](unsigned bitPosition) const; + bool operator[](unsigned bitPosition) const { + assert(bitPosition < getBitWidth() && "Bit position out of bounds!"); + return (maskBit(bitPosition) & + (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) != 0; + } /// @} /// @name Comparison Operators diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 06f4ce2..81a5117 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -113,7 +113,7 @@ public: /// differing argument types even if they would implicit promote to a common /// type without changing the value. template <typename T> -typename enable_if<is_integral<T>, hash_code>::type hash_value(T value); +typename enable_if<is_integral_or_enum<T>, hash_code>::type hash_value(T value); /// \brief Compute a hash_code for a pointer's address. /// @@ -349,14 +349,15 @@ inline size_t get_execution_seed() { /// reading the underlying data. It is false if values of this type must /// first be passed to hash_value, and the resulting hash_codes combined. // -// FIXME: We want to replace is_integral and is_pointer here with a predicate -// which asserts that comparing the underlying storage of two values of the -// type for equality is equivalent to comparing the two values for equality. -// For all the platforms we care about, this holds for integers and pointers, -// but there are platforms where it doesn't and we would like to support -// user-defined types which happen to satisfy this property. +// FIXME: We want to replace is_integral_or_enum and is_pointer here with +// a predicate which asserts that comparing the underlying storage of two +// values of the type for equality is equivalent to comparing the two values +// for equality. For all the platforms we care about, this holds for integers +// and pointers, but there are platforms where it doesn't and we would like to +// support user-defined types which happen to satisfy this property. template <typename T> struct is_hashable_data - : integral_constant<bool, ((is_integral<T>::value || is_pointer<T>::value) && + : integral_constant<bool, ((is_integral_or_enum<T>::value || + is_pointer<T>::value) && 64 % sizeof(T) == 0)> {}; // Special case std::pair to detect when both types are viable and when there @@ -419,8 +420,6 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { while (first != last && store_and_advance(buffer_ptr, buffer_end, get_hashable_data(*first))) ++first; -/// \brief Metafunction that determines whether the given type is an integral -/// type. if (first == last) return hash_short(buffer, buffer_ptr - buffer, seed); assert(buffer_ptr == buffer_end); @@ -458,7 +457,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { /// and directly reads from the underlying memory. template <typename ValueT> typename enable_if<is_hashable_data<ValueT>, hash_code>::type -hash_combine_range_impl(const ValueT *first, const ValueT *last) { +hash_combine_range_impl(ValueT *first, ValueT *last) { const size_t seed = get_execution_seed(); const char *s_begin = reinterpret_cast<const char *>(first); const char *s_end = reinterpret_cast<const char *>(last); @@ -734,7 +733,8 @@ inline hash_code hash_integer_value(uint64_t value) { // Declared and documented above, but defined here so that any of the hashing // infrastructure is available. template <typename T> -typename enable_if<is_integral<T>, hash_code>::type hash_value(T value) { +typename enable_if<is_integral_or_enum<T>, hash_code>::type +hash_value(T value) { return ::llvm::hashing::detail::hash_integer_value(value); } diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 2926462..89b1648 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -347,7 +347,7 @@ public: if (prev) prev->next = next; else - factory->Cache[computeDigest()] = next; + factory->Cache[factory->maskCacheIndex(computeDigest())] = next; } // We need to clear the mutability bit in case we are @@ -429,6 +429,11 @@ protected: TreeTy* getRight(TreeTy* T) const { return T->getRight(); } value_type_ref getValue(TreeTy* T) const { return T->value; } + // Make sure the index is not the Tombstone or Entry key of the DenseMap. + static inline unsigned maskCacheIndex(unsigned I) { + return (I & ~0x02); + } + unsigned incrementHeight(TreeTy* L, TreeTy* R) const { unsigned hl = getHeight(L); unsigned hr = getHeight(R); @@ -611,7 +616,7 @@ public: // Search the hashtable for another tree with the same digest, and // if find a collision compare those trees by their contents. unsigned digest = TNew->computeDigest(); - TreeTy *&entry = Cache[digest]; + TreeTy *&entry = Cache[maskCacheIndex(digest)]; do { if (!entry) break; diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 83e225c..931b67e 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -1977,7 +1977,7 @@ iterator::overflow(unsigned Level) { CurSize[Nodes] = CurSize[NewNode]; Node[Nodes] = Node[NewNode]; CurSize[NewNode] = 0; - Node[NewNode] = this->map->newNode<NodeT>(); + Node[NewNode] = this->map->template newNode<NodeT>(); ++Nodes; } diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 85dbba2..ccdcd1a 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -92,10 +92,14 @@ public: } PointerTy const *getAddrOfPointer() const { + return const_cast<PointerIntPair *>(this)->getAddrOfPointer(); + } + + PointerTy *getAddrOfPointer() { assert(Value == reinterpret_cast<intptr_t>(getPointer()) && "Can only return the address if IntBits is cleared and " "PtrTraits doesn't change the pointer"); - return reinterpret_cast<PointerTy const *>(&Value); + return reinterpret_cast<PointerTy *>(&Value); } void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 487096a..614b59c 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -142,16 +142,19 @@ namespace llvm { return T(); } - /// \brief If the union is set to the first pointer type we can get an - /// address pointing to it. - template <typename T> - PT1 const *getAddrOf() const { + /// \brief If the union is set to the first pointer type get an address + /// pointing to it. + PT1 const *getAddrOfPtr1() const { + return const_cast<PointerUnion *>(this)->getAddrOfPtr1(); + } + + /// \brief If the union is set to the first pointer type get an address + /// pointing to it. + PT1 *getAddrOfPtr1() { assert(is<PT1>() && "Val is not the first pointer"); assert(get<PT1>() == Val.getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"); - T const *can_only_get_address_of_first_pointer_type - = reinterpret_cast<PT1 const *>(Val.getAddrOfPointer()); - return can_only_get_address_of_first_pointer_type; + return (PT1 *)Val.getAddrOfPointer(); } /// Assignment operators - Allow assigning into this union from either @@ -263,7 +266,7 @@ namespace llvm { ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion, ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 > >::Return Ty; - return Ty(Val).is<T>(); + return Ty(Val).template is<T>(); } /// get<T>() - Return the value of the specified pointer type. If the @@ -276,7 +279,7 @@ namespace llvm { ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion, ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 > >::Return Ty; - return Ty(Val).get<T>(); + return Ty(Val).template get<T>(); } /// dyn_cast<T>() - If the current value is of the specified pointer type, diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 9992858..70693d5 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -137,6 +137,10 @@ private: void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT. protected: + /// swap - Swaps the elements of two sets. + /// Note: This method assumes that both sets have the same small size. + void swap(SmallPtrSetImpl &RHS); + void CopyFrom(const SmallPtrSetImpl &RHS); }; @@ -287,8 +291,20 @@ public: return *this; } + /// swap - Swaps the elements of two sets. + void swap(SmallPtrSet<PtrType, SmallSize> &RHS) { + SmallPtrSetImpl::swap(RHS); + } }; } +namespace std { + /// Implement std::swap in terms of SmallPtrSet swap. + template<class T, unsigned N> + inline void swap(llvm::SmallPtrSet<T, N> &LHS, llvm::SmallPtrSet<T, N> &RHS) { + LHS.swap(RHS); + } +} + #endif diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index d01cf32..0d9d0d1 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -23,30 +23,6 @@ #include <iterator> #include <memory> -#ifdef _MSC_VER -namespace std { -#if _MSC_VER <= 1310 - // Work around flawed VC++ implementation of std::uninitialized_copy. Define - // additional overloads so that elements with pointer types are recognized as - // scalars and not objects, causing bizarre type conversion errors. - template<class T1, class T2> - inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) { - _Scalar_ptr_iterator_tag _Cat; - return _Cat; - } - - template<class T1, class T2> - inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) { - _Scalar_ptr_iterator_tag _Cat; - return _Cat; - } -#else -// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear -// is that the above hack won't work if it wasn't fixed. -#endif -} -#endif - namespace llvm { /// SmallVectorBase - This is all the non-templated stuff common to all diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index 7c824ee..89774c3 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -260,15 +260,6 @@ public: } BecameZero = allzero; } - - // Get a hash value for this element; - uint64_t getHashValue() const { - uint64_t HashVal = 0; - for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { - HashVal ^= Bits[i]; - } - return HashVal; - } }; template <unsigned ElementSize = 128> @@ -809,18 +800,6 @@ public: iterator end() const { return iterator(this, true); } - - // Get a hash value for this bitmap. - uint64_t getHashValue() const { - uint64_t HashVal = 0; - for (ElementListConstIter Iter = Elements.begin(); - Iter != Elements.end(); - ++Iter) { - HashVal ^= Iter->index(); - HashVal ^= Iter->getHashValue(); - } - return HashVal; - } }; // Convenience functions to allow Or and And without dereferencing in the user diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index a2bb7fe..76ba66e 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -10,16 +10,26 @@ #ifndef LLVM_ADT_STRINGREF_H #define LLVM_ADT_STRINGREF_H +#include "llvm/Support/type_traits.h" + #include <cassert> #include <cstring> -#include <utility> +#include <limits> #include <string> +#include <utility> namespace llvm { template<typename T> class SmallVectorImpl; class APInt; class hash_code; + class StringRef; + + /// Helper functions for StringRef::getAsInteger. + bool getAsUnsignedInteger(StringRef Str, unsigned Radix, + unsigned long long &Result); + + bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result); /// StringRef - Represent a constant reference to a string, i.e. a character /// array and a length, which need not be null terminated. @@ -305,14 +315,29 @@ namespace llvm { /// /// If the string is invalid or if only a subset of the string is valid, /// this returns true to signify the error. The string is considered - /// erroneous if empty. + /// erroneous if empty or if it overflows T. /// - bool getAsInteger(unsigned Radix, long long &Result) const; - bool getAsInteger(unsigned Radix, unsigned long long &Result) const; - bool getAsInteger(unsigned Radix, int &Result) const; - bool getAsInteger(unsigned Radix, unsigned &Result) const; + template <typename T> + typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const { + long long LLVal; + if (getAsSignedInteger(*this, Radix, LLVal) || + static_cast<T>(LLVal) != LLVal) + return true; + Result = LLVal; + return false; + } - // TODO: Provide overloads for int/unsigned that check for overflow. + template <typename T> + typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const { + unsigned long long ULLVal; + if (getAsUnsignedInteger(*this, Radix, ULLVal) || + static_cast<T>(ULLVal) != ULLVal) + return true; + Result = ULLVal; + return false; + } /// getAsInteger - Parse the current string as an integer of the /// specified radix, or of an autosensed radix if the radix given diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index e27dd4b..5014517 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -42,7 +42,7 @@ public: if (Val.isNull()) return ArrayRef<EltTy>(); if (Val.template is<EltTy>()) - return *Val.template getAddrOf<EltTy>(); + return *Val.getAddrOfPtr1(); return *Val.template get<VecTy*>(); } @@ -63,18 +63,20 @@ public: return Val.template get<VecTy*>()->size(); } - typedef const EltTy *iterator; - iterator begin() const { + typedef const EltTy *const_iterator; + typedef EltTy *iterator; + + iterator begin() { if (empty()) return 0; if (Val.template is<EltTy>()) - return Val.template getAddrOf<EltTy>(); + return Val.getAddrOfPtr1(); return Val.template get<VecTy *>()->begin(); } - iterator end() const { + iterator end() { if (empty()) return 0; @@ -84,7 +86,14 @@ public: return Val.template get<VecTy *>()->end(); } - + const_iterator begin() const { + return (const_iterator)const_cast<TinyPtrVector*>(this)->begin(); + } + + const_iterator end() const { + return (const_iterator)const_cast<TinyPtrVector*>(this)->end(); + } + EltTy operator[](unsigned i) const { assert(!Val.isNull() && "can't index into an empty vector"); if (EltTy V = Val.template dyn_cast<EltTy>()) { @@ -133,6 +142,20 @@ public: } // Otherwise, we're already empty. } + + iterator erase(iterator I) { + // If we have a single value, convert to empty. + if (Val.template is<EltTy>()) { + if (I == begin()) + Val = (EltTy)0; + } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { + // multiple items in a vector; just do the erase, there is no + // benefit to collapsing back to a pointer + return Vec->erase(I); + } + + return 0; + } private: void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 98f0b62..102c95a 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -53,6 +53,7 @@ public: msp430, // MSP430: msp430 ppc, // PPC: powerpc ppc64, // PPC64: powerpc64, ppu + r600, // R600: AMD GPUs HD2XXX - HD6XXX sparc, // Sparc: sparc sparcv9, // Sparcv9: Sparcv9 tce, // TCE (http://tce.cs.tut.fi/): tce diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index bcacfd9..ba9864a 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -652,10 +652,6 @@ struct ilist : public iplist<NodeTy> { void push_front(const NodeTy &val) { insert(this->begin(), val); } void push_back(const NodeTy &val) { insert(this->end(), val); } - // Special forms of insert... - template<class InIt> void insert(iterator where, InIt first, InIt last) { - for (; first != last; ++first) insert(where, *first); - } void insert(iterator where, size_type count, const NodeTy &val) { for (; count != 0; --count) insert(where, val); } diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h index 2cde838..4704a92 100644 --- a/include/llvm/Analysis/CFGPrinter.h +++ b/include/llvm/Analysis/CFGPrinter.h @@ -95,8 +95,9 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { std::string Str; raw_string_ostream OS(Str); - unsigned Case = SI->resolveCaseIndex(SuccNo); - OS << SI->getCaseValue(Case)->getValue(); + SwitchInst::ConstCaseIt Case = + SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo); + OS << Case.getCaseValue()->getValue(); return OS.str(); } return ""; diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 6d34781..033e19b 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -1,4 +1,4 @@ -//===- CodeMetrics.h - Measures the weight of a function---------*- C++ -*-===// +//===- CodeMetrics.h - Code cost measurements -------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,53 +18,58 @@ #include "llvm/ADT/DenseMap.h" namespace llvm { - class BasicBlock; class Function; class TargetData; class Value; - // CodeMetrics - Calculate size and a few similar metrics for a set of - // basic blocks. - struct CodeMetrics { - /// NeverInline - True if this callee should never be inlined into a - /// caller. - // bool NeverInline; + /// \brief Check whether a call will lower to something small. + /// + /// This tests checks whether calls to this function will lower to something + /// significantly cheaper than a traditional call, often a single + /// instruction. + bool callIsSmall(const Function *F); - // True if this function contains a call to setjmp or other functions - // with attribute "returns twice" without having the attribute itself. + /// \brief Utility to calculate the size and a few similar metrics for a set + /// of basic blocks. + struct CodeMetrics { + /// \brief True if this function contains a call to setjmp or other functions + /// with attribute "returns twice" without having the attribute itself. bool exposesReturnsTwice; - // True if this function calls itself + /// \brief True if this function calls itself. bool isRecursive; - // True if this function contains one or more indirect branches + /// \brief True if this function contains one or more indirect branches. bool containsIndirectBr; - /// usesDynamicAlloca - True if this function calls alloca (in the C sense). + /// \brief True if this function calls alloca (in the C sense). bool usesDynamicAlloca; - /// NumInsts, NumBlocks - Keep track of how large each function is, which - /// is used to estimate the code size cost of inlining it. - unsigned NumInsts, NumBlocks; + /// \brief Number of instructions in the analyzed blocks. + unsigned NumInsts; - /// NumBBInsts - Keeps track of basic block code size estimates. + /// \brief Number of analyzed blocks. + unsigned NumBlocks; + + /// \brief Keeps track of basic block code size estimates. DenseMap<const BasicBlock *, unsigned> NumBBInsts; - /// NumCalls - Keep track of the number of calls to 'big' functions. + /// \brief Keep track of the number of calls to 'big' functions. unsigned NumCalls; - /// NumInlineCandidates - Keep track of the number of calls to internal - /// functions with only a single caller. These are likely targets for - /// future inlining, likely exposed by interleaved devirtualization. + /// \brief The number of calls to internal functions with a single caller. + /// + /// These are likely targets for future inlining, likely exposed by + /// interleaved devirtualization. unsigned NumInlineCandidates; - /// NumVectorInsts - Keep track of how many instructions produce vector - /// values. The inliner is being more aggressive with inlining vector - /// kernels. + /// \brief How many instructions produce vector values. + /// + /// The inliner is more aggressive with inlining vector kernels. unsigned NumVectorInsts; - /// NumRets - Keep track of how many Ret instructions the block contains. + /// \brief How many 'ret' instructions the blocks contain. unsigned NumRets; CodeMetrics() : exposesReturnsTwice(false), isRecursive(false), @@ -73,29 +78,11 @@ namespace llvm { NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {} - /// analyzeBasicBlock - Add information about the specified basic block - /// to the current structure. + /// \brief Add information about a block to the current state. void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0); - /// analyzeFunction - Add information about the specified function - /// to the current structure. + /// \brief Add information about a function to the current state. void analyzeFunction(Function *F, const TargetData *TD = 0); - - /// CountCodeReductionForConstant - Figure out an approximation for how - /// many instructions will be constant folded if the specified value is - /// constant. - unsigned CountCodeReductionForConstant(Value *V); - - /// CountBonusForConstant - Figure out an approximation for how much - /// per-call performance boost we can expect if the specified value is - /// constant. - unsigned CountBonusForConstant(Value *V); - - /// CountCodeReductionForAlloca - Figure out an approximation of how much - /// smaller the function will be if it is inlined into a context where an - /// argument becomes an alloca. - /// - unsigned CountCodeReductionForAlloca(Value *V); }; } diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 2a3bb9b..11d2cf0 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -145,7 +145,8 @@ public: /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. - bool AddUsersIfInteresting(Instruction *I); + bool AddUsersIfInteresting(Instruction *I, + SmallPtrSet<Loop*,16> &SimpleLoopNests); IVStrideUse &AddUser(Instruction *User, Value *Operand); diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index fdcd5a8..c804c46 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -110,6 +110,34 @@ namespace llvm { /// entry here. std::vector<ArgInfo> ArgumentWeights; + /// PointerArgPairWeights - Weights to use when giving an inline bonus to + /// a call site due to correlated pairs of pointers. + DenseMap<std::pair<unsigned, unsigned>, unsigned> PointerArgPairWeights; + + /// countCodeReductionForConstant - Figure out an approximation for how + /// many instructions will be constant folded if the specified value is + /// constant. + unsigned countCodeReductionForConstant(const CodeMetrics &Metrics, + Value *V); + + /// countCodeReductionForAlloca - Figure out an approximation of how much + /// smaller the function will be if it is inlined into a context where an + /// argument becomes an alloca. + unsigned countCodeReductionForAlloca(const CodeMetrics &Metrics, + Value *V); + + /// countCodeReductionForPointerPair - Count the bonus to apply to an + /// inline call site where a pair of arguments are pointers and one + /// argument is a constant offset from the other. The idea is to + /// recognize a common C++ idiom where a begin and end iterator are + /// actually pointers, and many operations on the pair of them will be + /// constants if the function is called with arguments that have + /// a constant offset. + void countCodeReductionForPointerPair( + const CodeMetrics &Metrics, + DenseMap<Value *, unsigned> &PointerArgs, + Value *V, unsigned ArgIdx); + /// analyzeFunction - Add information about the specified function /// to the current structure. void analyzeFunction(Function *F, const TargetData *TD); @@ -138,28 +166,13 @@ namespace llvm { /// getInlineCost - The heuristic used to determine if we should inline the /// function call or not. /// - InlineCost getInlineCost(CallSite CS, - SmallPtrSet<const Function *, 16> &NeverInline); + InlineCost getInlineCost(CallSite CS); /// getCalledFunction - The heuristic used to determine if we should inline /// the function call or not. The callee is explicitly specified, to allow /// you to calculate the cost of inlining a function via a pointer. The /// result assumes that the inlined version will always be used. You should /// weight it yourself in cases where this callee will not always be called. - InlineCost getInlineCost(CallSite CS, - Function *Callee, - SmallPtrSet<const Function *, 16> &NeverInline); - - /// getSpecializationBonus - The heuristic used to determine the per-call - /// performance boost for using a specialization of Callee with argument - /// SpecializedArgNos replaced by a constant. - int getSpecializationBonus(Function *Callee, - SmallVectorImpl<unsigned> &SpecializedArgNo); - - /// getSpecializationCost - The heuristic used to determine the code-size - /// impact of creating a specialized version of Callee with argument - /// SpecializedArgNo replaced by a constant. - InlineCost getSpecializationCost(Function *Callee, - SmallVectorImpl<unsigned> &SpecializedArgNo); + InlineCost getInlineCost(CallSite CS, Function *Callee); /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a /// higher threshold to determine if the function call should be inlined. diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 3dd194c..fb07b03 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -20,13 +20,14 @@ #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H namespace llvm { + template<typename T> + class ArrayRef; class DominatorTree; class Instruction; - class Value; class TargetData; class TargetLibraryInfo; - template<typename T> - class ArrayRef; + class Type; + class Value; /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. @@ -141,11 +142,13 @@ namespace llvm { /// the result. If not, this returns null. Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we @@ -153,8 +156,15 @@ namespace llvm { Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, const DominatorTree *DT = 0); + /// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold + /// the result. If not, this returns null. + Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + //=== Helper functions for higher up the class hierarchy. diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index 1574262..5f0aefb 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -20,6 +20,7 @@ namespace llvm { class AliasAnalysis; class TargetData; +class MDNode; /// isSafeToLoadUnconditionally - Return true if we know that executing a load /// from this value cannot trap. If it is not obviously safe to load from the @@ -41,10 +42,15 @@ bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, /// MaxInstsToScan specifies the maximum instructions to scan in the block. /// If it is set to 0, it will scan the whole block. You can also optionally /// specify an alias analysis implementation, which makes this more precise. +/// +/// If TBAATag is non-null and a load or store is found, the TBAA tag from the +/// load or store is recorded there. If there is no TBAA tag or if no access +/// is found, it is left unmodified. Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan = 6, - AliasAnalysis *AA = 0); + AliasAnalysis *AA = 0, + MDNode **TBAATag = 0); } diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 42c68aa..475da13 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -501,7 +501,7 @@ public: /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. void EnterBlockInfoBlock(unsigned CodeWidth) { EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth); - BlockInfoCurBID = -1U; + BlockInfoCurBID = ~0U; } private: /// SwitchToBlockID - If we aren't already talking about the specified block diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 77dc644..3afe309 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -229,7 +229,7 @@ public: /// getFirstUnallocated - Return the first unallocated register in the set, or /// NumRegs if they are all allocated. - unsigned getFirstUnallocated(const unsigned *Regs, unsigned NumRegs) const { + unsigned getFirstUnallocated(const uint16_t *Regs, unsigned NumRegs) const { for (unsigned i = 0; i != NumRegs; ++i) if (!isAllocated(Regs[i])) return i; @@ -256,7 +256,7 @@ public: /// AllocateReg - Attempt to allocate one of the specified registers. If none /// are available, return zero. Otherwise, return the first one available, /// marking it and any aliases as allocated. - unsigned AllocateReg(const unsigned *Regs, unsigned NumRegs) { + unsigned AllocateReg(const uint16_t *Regs, unsigned NumRegs) { unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); if (FirstUnalloc == NumRegs) return 0; // Didn't find the reg. @@ -268,7 +268,7 @@ public: } /// Version of AllocateReg with list of registers to be shadowed. - unsigned AllocateReg(const unsigned *Regs, const unsigned *ShadowRegs, + unsigned AllocateReg(const uint16_t *Regs, const uint16_t *ShadowRegs, unsigned NumRegs) { unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); if (FirstUnalloc == NumRegs) @@ -306,12 +306,12 @@ public: // First GPR that carries part of a byval aggregate that's split // between registers and memory. - unsigned getFirstByValReg() { return FirstByValRegValid ? FirstByValReg : 0; } + unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByValReg : 0; } void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; } void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } - bool isFirstByValRegValid() { return FirstByValRegValid; } + bool isFirstByValRegValid() const { return FirstByValRegValid; } - ParmContext getCallOrPrologue() { return CallOrPrologue; } + ParmContext getCallOrPrologue() const { return CallOrPrologue; } private: /// MarkAllocated - Mark a register and all of its aliases as allocated. diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h index 0694caa..ee1ed07 100644 --- a/include/llvm/CodeGen/DFAPacketizer.h +++ b/include/llvm/CodeGen/DFAPacketizer.h @@ -36,6 +36,7 @@ class MachineInstr; class MachineLoopInfo; class MachineDominatorTree; class InstrItineraryData; +class ScheduleDAGInstrs; class SUnit; class DFAPacketizer { @@ -91,7 +92,7 @@ class VLIWPacketizerList { const TargetInstrInfo *TII; // Encapsulate data types not exposed to the target interface. - void *SchedulerImpl; + ScheduleDAGInstrs *SchedulerImpl; protected: // Vector of instructions assigned to the current packet. diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h index 1ed2547..8fb31aa 100644 --- a/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -85,11 +85,11 @@ namespace llvm { virtual void dump(ScheduleDAG* DAG) const; - // ScheduledNode - As nodes are scheduled, we look to see if there are any + // scheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make // the node available. - void ScheduledNode(SUnit *Node); + void scheduledNode(SUnit *Node); private: void AdjustPriorityOfUnscheduledPreds(SUnit *SU); diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 576ce94..ef9c0c2 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -117,6 +117,10 @@ public: /// "(null)". StringRef getName() const; + /// getFullName - Return a formatted string to identify this block and its + /// parent function. + std::string getFullName() const; + /// hasAddressTaken - Test whether this block is potentially the target /// of an indirect branch. bool hasAddressTaken() const { return AddressTaken; } diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 7f29d31..65093d7 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -74,9 +74,10 @@ private: // anything other than to convey comment // information to AsmPrinter. + uint16_t NumMemRefs; // information on memory references + mmo_iterator MemRefs; + std::vector<MachineOperand> Operands; // the operands - mmo_iterator MemRefs; // information on memory references - mmo_iterator MemRefsEnd; MachineBasicBlock *Parent; // Pointer to the owning basic block. DebugLoc debugLoc; // Source line information. @@ -284,13 +285,13 @@ public: /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } - mmo_iterator memoperands_end() const { return MemRefsEnd; } - bool memoperands_empty() const { return MemRefsEnd == MemRefs; } + mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } + bool memoperands_empty() const { return NumMemRefs == 0; } /// hasOneMemOperand - Return true if this instruction has exactly one /// MachineMemOperand. bool hasOneMemOperand() const { - return MemRefsEnd - MemRefs == 1; + return NumMemRefs == 1; } /// API for querying MachineInstr properties. They are the same as MCInstrDesc @@ -307,7 +308,14 @@ public: /// The first argument is the property being queried. /// The second argument indicates whether the query should look inside /// instruction bundles. - bool hasProperty(unsigned Flag, QueryType Type = AnyInBundle) const; + bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const { + // Inline the fast path. + if (Type == IgnoreBundle || !isBundle()) + return getDesc().getFlags() & (1 << MCFlag); + + // If we have a bundle, take the slow path. + return hasPropertyInBundle(1 << MCFlag, Type); + } /// isVariadic - Return true if this instruction can have a variable number of /// operands. In this case, the variable operands will be after the normal @@ -888,7 +896,7 @@ public: /// list. This does not transfer ownership. void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { MemRefs = NewMemRefs; - MemRefsEnd = NewMemRefsEnd; + NumMemRefs = NewMemRefsEnd - NewMemRefs; } private: @@ -910,6 +918,10 @@ private: /// this instruction from their respective use lists. This requires that the /// operands not be on their use lists yet. void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo); + + /// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a + /// bundle. + bool hasPropertyInBundle(unsigned Mask, QueryType Type) const; }; /// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h new file mode 100644 index 0000000..e852009 --- /dev/null +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -0,0 +1,91 @@ +//==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a MachineSchedRegistry for registering alternative machine +// schedulers. A Target may provide an alternative scheduler implementation by +// implementing the following boilerplate: +// +// static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) { +// return new CustomMachineScheduler(C); +// } +// static MachineSchedRegistry +// SchedCustomRegistry("custom", "Run my target's custom scheduler", +// createCustomMachineSched); +// +// Inside <Target>PassConfig: +// enablePass(MachineSchedulerID); +// MachineSchedRegistry::setDefault(createCustomMachineSched); +// +//===----------------------------------------------------------------------===// + +#ifndef MACHINESCHEDULER_H +#define MACHINESCHEDULER_H + +#include "llvm/CodeGen/MachinePassRegistry.h" + +namespace llvm { + +class AliasAnalysis; +class LiveIntervals; +class MachineDominatorTree; +class MachineLoopInfo; +class ScheduleDAGInstrs; + +/// MachineSchedContext provides enough context from the MachineScheduler pass +/// for the target to instantiate a scheduler. +struct MachineSchedContext { + MachineFunction *MF; + const MachineLoopInfo *MLI; + const MachineDominatorTree *MDT; + const TargetPassConfig *PassConfig; + AliasAnalysis *AA; + LiveIntervals *LIS; + + MachineSchedContext(): MF(0), MLI(0), MDT(0), PassConfig(0), AA(0), LIS(0) {} +}; + +/// MachineSchedRegistry provides a selection of available machine instruction +/// schedulers. +class MachineSchedRegistry : public MachinePassRegistryNode { +public: + typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *); + + // RegisterPassParser requires a (misnamed) FunctionPassCtor type. + typedef ScheduleDAGCtor FunctionPassCtor; + + static MachinePassRegistry Registry; + + MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C) + : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { + Registry.Add(this); + } + ~MachineSchedRegistry() { Registry.Remove(this); } + + // Accessors. + // + MachineSchedRegistry *getNext() const { + return (MachineSchedRegistry *)MachinePassRegistryNode::getNext(); + } + static MachineSchedRegistry *getList() { + return (MachineSchedRegistry *)Registry.getList(); + } + static ScheduleDAGCtor getDefault() { + return (ScheduleDAGCtor)Registry.getDefault(); + } + static void setDefault(ScheduleDAGCtor C) { + Registry.setDefault((MachinePassCtor)C); + } + static void setListener(MachinePassRegistryListener *L) { + Registry.setListener(L); + } +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 8ce339d..d6ca148e 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -101,7 +101,10 @@ public: /// point where StadardID is expected, add TargetID in its place. void substitutePass(char &StandardID, char &TargetID); - /// Allow the target to disable a specific standard pass. + /// Allow the target to enable a specific standard pass by default. + void enablePass(char &ID) { substitutePass(ID, ID); } + + /// Allow the target to disable a specific standard pass by default. void disablePass(char &ID) { substitutePass(ID, NoPassID); } /// Return the pass ssubtituted for StandardID by the target. @@ -420,10 +423,10 @@ namespace llvm { /// adapted to code generation. Required if using dwarf exception handling. FunctionPass *createDwarfEHPass(const TargetMachine *tm); - /// createSjLjEHPass - This pass adapts exception handling code to use + /// createSjLjEHPreparePass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. /// - FunctionPass *createSjLjEHPass(const TargetLowering *tli); + FunctionPass *createSjLjEHPreparePass(const TargetLowering *tli); /// LocalStackSlotAllocation - This pass assigns local frame indices to stack /// slots relative to one another and allocates base registers to access them diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h index fa7011d..56b5855 100644 --- a/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -76,7 +76,7 @@ namespace llvm { public: ResourcePriorityQueue(SelectionDAGISel *IS); - + ~ResourcePriorityQueue() { delete ResourcesModel; } @@ -126,8 +126,8 @@ namespace llvm { virtual void dump(ScheduleDAG* DAG) const; - /// ScheduledNode - Main resource tracking point. - void ScheduledNode(SUnit *Node); + /// scheduledNode - Main resource tracking point. + void scheduledNode(SUnit *Node); bool isResourceAvailable(SUnit *SU); void reserveResources(SUnit *SU); diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 72eadd9..f4de693 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -8,7 +8,8 @@ //===----------------------------------------------------------------------===// // // This file implements the ScheduleDAG class, which is used as the common -// base class for instruction schedulers. +// base class for instruction schedulers. This encapsulates the scheduling DAG, +// which is shared between SelectionDAG and MachineInstr scheduling. // //===----------------------------------------------------------------------===// @@ -409,6 +410,13 @@ namespace llvm { return false; } + bool isTopReady() const { + return NumPredsLeft == 0; + } + bool isBottomReady() const { + return NumSuccsLeft == 0; + } + void dump(const ScheduleDAG *G) const; void dumpAll(const ScheduleDAG *G) const; void print(raw_ostream &O, const ScheduleDAG *G) const; @@ -466,13 +474,13 @@ namespace llvm { virtual void dump(ScheduleDAG *) const {} - /// ScheduledNode - As each node is scheduled, this method is invoked. This + /// scheduledNode - As each node is scheduled, this method is invoked. This /// allows the priority function to adjust the priority of related /// unscheduled nodes, for example. /// - virtual void ScheduledNode(SUnit *) {} + virtual void scheduledNode(SUnit *) {} - virtual void UnscheduledNode(SUnit *) {} + virtual void unscheduledNode(SUnit *) {} void setCurCycle(unsigned Cycle) { CurCycle = Cycle; @@ -485,15 +493,11 @@ namespace llvm { class ScheduleDAG { public: - MachineBasicBlock *BB; // The block in which to insert instructions - MachineBasicBlock::iterator InsertPos;// The position to insert instructions const TargetMachine &TM; // Target processor const TargetInstrInfo *TII; // Target instruction information const TargetRegisterInfo *TRI; // Target processor register info MachineFunction &MF; // Machine function MachineRegisterInfo &MRI; // Virtual/real register map - std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s - // represent noop instructions. std::vector<SUnit> SUnits; // The scheduling units. SUnit EntrySU; // Special node for the region entry. SUnit ExitSU; // Special node for the region exit. @@ -508,6 +512,9 @@ namespace llvm { virtual ~ScheduleDAG(); + /// clearDAG - clear the DAG state (between regions). + void clearDAG(); + /// getInstrDesc - Return the MCInstrDesc of this SUnit. /// Return NULL for SDNodes without a machine opcode. const MCInstrDesc *getInstrDesc(const SUnit *SU) const { @@ -518,66 +525,43 @@ namespace llvm { /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered /// using 'dot'. /// + void viewGraph(const Twine &Name, const Twine &Title); void viewGraph(); - /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock - /// according to the order specified in Sequence. - /// - virtual MachineBasicBlock *EmitSchedule() = 0; - - void dumpSchedule() const; - virtual void dumpNode(const SUnit *SU) const = 0; /// getGraphNodeLabel - Return a label for an SUnit node in a visualization /// of the ScheduleDAG. virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0; + /// getDAGLabel - Return a label for the region of code covered by the DAG. + virtual std::string getDAGName() const = 0; + /// addCustomGraphFeatures - Add custom features for a visualization of /// the ScheduleDAG. virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {} #ifndef NDEBUG - /// VerifySchedule - Verify that all SUnits were scheduled and that - /// their state is consistent. - void VerifySchedule(bool isBottomUp); + /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that + /// their state is consistent. Return the number of scheduled SUnits. + unsigned VerifyScheduledDAG(bool isBottomUp); #endif protected: - /// Run - perform scheduling. - /// - void Run(MachineBasicBlock *bb, MachineBasicBlock::iterator insertPos); - - /// BuildSchedGraph - Build SUnits and set up their Preds and Succs - /// to form the scheduling dependency graph. - /// - virtual void BuildSchedGraph(AliasAnalysis *AA) = 0; - /// ComputeLatency - Compute node latency. /// - virtual void ComputeLatency(SUnit *SU) = 0; + virtual void computeLatency(SUnit *SU) = 0; /// ComputeOperandLatency - Override dependence edge latency using /// operand use/def information /// - virtual void ComputeOperandLatency(SUnit *, SUnit *, + virtual void computeOperandLatency(SUnit *, SUnit *, SDep&) const { } - /// Schedule - Order nodes according to selected style, filling - /// in the Sequence member. - /// - virtual void Schedule() = 0; - /// ForceUnitLatencies - Return true if all scheduling edges should be given /// a latency value of one. The default is to return false; schedulers may /// override this as needed. - virtual bool ForceUnitLatencies() const { return false; } - - /// EmitNoop - Emit a noop instruction. - /// - void EmitNoop(); - - void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap); + virtual bool forceUnitLatencies() const { return false; } private: // Return the MCInstrDesc of this SDNode or NULL. diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h new file mode 100644 index 0000000..a08f6cc --- /dev/null +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -0,0 +1,340 @@ +//==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the ScheduleDAGInstrs class, which implements +// scheduling for a MachineInstr-based dependency graph. +// +//===----------------------------------------------------------------------===// + +#ifndef SCHEDULEDAGINSTRS_H +#define SCHEDULEDAGINSTRS_H + +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SparseSet.h" +#include <map> + +namespace llvm { + class MachineLoopInfo; + class MachineDominatorTree; + class LiveIntervals; + + /// LoopDependencies - This class analyzes loop-oriented register + /// dependencies, which are used to guide scheduling decisions. + /// For example, loop induction variable increments should be + /// scheduled as soon as possible after the variable's last use. + /// + class LoopDependencies { + const MachineLoopInfo &MLI; + const MachineDominatorTree &MDT; + + public: + typedef std::map<unsigned, std::pair<const MachineOperand *, unsigned> > + LoopDeps; + LoopDeps Deps; + + LoopDependencies(const MachineLoopInfo &mli, + const MachineDominatorTree &mdt) : + MLI(mli), MDT(mdt) {} + + /// VisitLoop - Clear out any previous state and analyze the given loop. + /// + void VisitLoop(const MachineLoop *Loop) { + assert(Deps.empty() && "stale loop dependencies"); + + MachineBasicBlock *Header = Loop->getHeader(); + SmallSet<unsigned, 8> LoopLiveIns; + for (MachineBasicBlock::livein_iterator LI = Header->livein_begin(), + LE = Header->livein_end(); LI != LE; ++LI) + LoopLiveIns.insert(*LI); + + const MachineDomTreeNode *Node = MDT.getNode(Header); + const MachineBasicBlock *MBB = Node->getBlock(); + assert(Loop->contains(MBB) && + "Loop does not contain header!"); + VisitRegion(Node, MBB, Loop, LoopLiveIns); + } + + private: + void VisitRegion(const MachineDomTreeNode *Node, + const MachineBasicBlock *MBB, + const MachineLoop *Loop, + const SmallSet<unsigned, 8> &LoopLiveIns) { + unsigned Count = 0; + for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); + I != E; ++I) { + const MachineInstr *MI = I; + if (MI->isDebugValue()) + continue; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isUse()) + continue; + unsigned MOReg = MO.getReg(); + if (LoopLiveIns.count(MOReg)) + Deps.insert(std::make_pair(MOReg, std::make_pair(&MO, Count))); + } + ++Count; // Not every iteration due to dbg_value above. + } + + const std::vector<MachineDomTreeNode*> &Children = Node->getChildren(); + for (std::vector<MachineDomTreeNode*>::const_iterator I = + Children.begin(), E = Children.end(); I != E; ++I) { + const MachineDomTreeNode *ChildNode = *I; + MachineBasicBlock *ChildBlock = ChildNode->getBlock(); + if (Loop->contains(ChildBlock)) + VisitRegion(ChildNode, ChildBlock, Loop, LoopLiveIns); + } + } + }; + + /// An individual mapping from virtual register number to SUnit. + struct VReg2SUnit { + unsigned VirtReg; + SUnit *SU; + + VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {} + + unsigned getSparseSetKey() const { + return TargetRegisterInfo::virtReg2Index(VirtReg); + } + }; + + /// Combine a SparseSet with a 1x1 vector to track physical registers. + /// The SparseSet allows iterating over the (few) live registers for quickly + /// comparing against a regmask or clearing the set. + /// + /// Storage for the map is allocated once for the pass. The map can be + /// cleared between scheduling regions without freeing unused entries. + class Reg2SUnitsMap { + SparseSet<unsigned> PhysRegSet; + std::vector<std::vector<SUnit*> > SUnits; + public: + typedef SparseSet<unsigned>::const_iterator const_iterator; + + // Allow iteration over register numbers (keys) in the map. If needed, we + // can provide an iterator over SUnits (values) as well. + const_iterator reg_begin() const { return PhysRegSet.begin(); } + const_iterator reg_end() const { return PhysRegSet.end(); } + + /// Initialize the map with the number of registers. + /// If the map is already large enough, no allocation occurs. + /// For simplicity we expect the map to be empty(). + void setRegLimit(unsigned Limit); + + /// Returns true if the map is empty. + bool empty() const { return PhysRegSet.empty(); } + + /// Clear the map without deallocating storage. + void clear(); + + bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); } + + /// If this register is mapped, return its existing SUnits vector. + /// Otherwise map the register and return an empty SUnits vector. + std::vector<SUnit *> &operator[](unsigned Reg) { + bool New = PhysRegSet.insert(Reg).second; + assert((!New || SUnits[Reg].empty()) && "stale SUnits vector"); + (void)New; + return SUnits[Reg]; + } + + /// Erase an existing element without freeing memory. + void erase(unsigned Reg) { + PhysRegSet.erase(Reg); + SUnits[Reg].clear(); + } + }; + + /// Use SparseSet as a SparseMap by relying on the fact that it never + /// compares ValueT's, only unsigned keys. This allows the set to be cleared + /// between scheduling regions in constant time as long as ValueT does not + /// require a destructor. + typedef SparseSet<VReg2SUnit> VReg2SUnitMap; + + /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of + /// MachineInstrs. + class ScheduleDAGInstrs : public ScheduleDAG { + protected: + const MachineLoopInfo &MLI; + const MachineDominatorTree &MDT; + const MachineFrameInfo *MFI; + const InstrItineraryData *InstrItins; + + /// Live Intervals provides reaching defs in preRA scheduling. + LiveIntervals *LIS; + + /// isPostRA flag indicates vregs cannot be present. + bool IsPostRA; + + /// UnitLatencies (misnamed) flag avoids computing def-use latencies, using + /// the def-side latency only. + bool UnitLatencies; + + /// State specific to the current scheduling region. + /// ------------------------------------------------ + + /// The block in which to insert instructions + MachineBasicBlock *BB; + + /// The beginning of the range to be scheduled. + MachineBasicBlock::iterator RegionBegin; + + /// The end of the range to be scheduled. + MachineBasicBlock::iterator RegionEnd; + + /// The index in BB of RegionEnd. + unsigned EndIndex; + + /// After calling BuildSchedGraph, each machine instruction in the current + /// scheduling region is mapped to an SUnit. + DenseMap<MachineInstr*, SUnit*> MISUnitMap; + + /// State internal to DAG building. + /// ------------------------------- + + /// Defs, Uses - Remember where defs and uses of each register are as we + /// iterate upward through the instructions. This is allocated here instead + /// of inside BuildSchedGraph to avoid the need for it to be initialized and + /// destructed for each block. + Reg2SUnitsMap Defs; + Reg2SUnitsMap Uses; + + /// Track the last instructon in this region defining each virtual register. + VReg2SUnitMap VRegDefs; + + /// PendingLoads - Remember where unknown loads are after the most recent + /// unknown store, as we iterate. As with Defs and Uses, this is here + /// to minimize construction/destruction. + std::vector<SUnit *> PendingLoads; + + /// LoopRegs - Track which registers are used for loop-carried dependencies. + /// + LoopDependencies LoopRegs; + + /// DbgValues - Remember instruction that preceeds DBG_VALUE. + /// These are generated by buildSchedGraph but persist so they can be + /// referenced when emitting the final schedule. + typedef std::vector<std::pair<MachineInstr *, MachineInstr *> > + DbgValueVector; + DbgValueVector DbgValues; + MachineInstr *FirstDbgValue; + + public: + explicit ScheduleDAGInstrs(MachineFunction &mf, + const MachineLoopInfo &mli, + const MachineDominatorTree &mdt, + bool IsPostRAFlag, + LiveIntervals *LIS = 0); + + virtual ~ScheduleDAGInstrs() {} + + /// begin - Return an iterator to the top of the current scheduling region. + MachineBasicBlock::iterator begin() const { return RegionBegin; } + + /// end - Return an iterator to the bottom of the current scheduling region. + MachineBasicBlock::iterator end() const { return RegionEnd; } + + /// newSUnit - Creates a new SUnit and return a ptr to it. + SUnit *newSUnit(MachineInstr *MI); + + /// getSUnit - Return an existing SUnit for this MI, or NULL. + SUnit *getSUnit(MachineInstr *MI) const; + + /// startBlock - Prepare to perform scheduling in the given block. + virtual void startBlock(MachineBasicBlock *BB); + + /// finishBlock - Clean up after scheduling in the given block. + virtual void finishBlock(); + + /// Initialize the scheduler state for the next scheduling region. + virtual void enterRegion(MachineBasicBlock *bb, + MachineBasicBlock::iterator begin, + MachineBasicBlock::iterator end, + unsigned endcount); + + /// Notify that the scheduler has finished scheduling the current region. + virtual void exitRegion(); + + /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are + /// input. + void buildSchedGraph(AliasAnalysis *AA); + + /// addSchedBarrierDeps - Add dependencies from instructions in the current + /// list of instructions being scheduled to scheduling barrier. We want to + /// make sure instructions which define registers that are either used by + /// the terminator or are live-out are properly scheduled. This is + /// especially important when the definition latency of the return value(s) + /// are too high to be hidden by the branch or when the liveout registers + /// used by instructions in the fallthrough block. + void addSchedBarrierDeps(); + + /// computeLatency - Compute node latency. + /// + virtual void computeLatency(SUnit *SU); + + /// computeOperandLatency - Override dependence edge latency using + /// operand use/def information + /// + virtual void computeOperandLatency(SUnit *Def, SUnit *Use, + SDep& dep) const; + + /// schedule - Order nodes according to selected style, filling + /// in the Sequence member. + /// + /// Typically, a scheduling algorithm will implement schedule() without + /// overriding enterRegion() or exitRegion(). + virtual void schedule() = 0; + + virtual void dumpNode(const SUnit *SU) const; + + /// Return a label for a DAG node that points to an instruction. + virtual std::string getGraphNodeLabel(const SUnit *SU) const; + + /// Return a label for the region of code covered by the DAG. + virtual std::string getDAGName() const; + + protected: + void initSUnits(); + void addPhysRegDataDeps(SUnit *SU, const MachineOperand &MO); + void addPhysRegDeps(SUnit *SU, unsigned OperIdx); + void addVRegDefDeps(SUnit *SU, unsigned OperIdx); + void addVRegUseDeps(SUnit *SU, unsigned OperIdx); + + VReg2SUnitMap::iterator findVRegDef(unsigned VirtReg) { + return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg)); + } + }; + + /// newSUnit - Creates a new SUnit and return a ptr to it. + inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) { +#ifndef NDEBUG + const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0]; +#endif + SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); + assert((Addr == 0 || Addr == &SUnits[0]) && + "SUnits std::vector reallocated on the fly!"); + SUnits.back().OrigNode = &SUnits.back(); + return &SUnits.back(); + } + + /// getSUnit - Return an existing SUnit for this MI, or NULL. + inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const { + DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI); + if (I == MISUnitMap.end()) + return 0; + return I->second; + } +} // namespace llvm + +#endif diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index c475014..e50bff5 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -677,9 +677,6 @@ /* Define to 1 if your <sys/time.h> declares `struct tm'. */ #undef TM_IN_SYS_TIME -/* Define if we have the oprofile JIT-support library */ -#undef USE_OPROFILE - /* Define if use udis86 library */ #undef USE_UDIS86 @@ -716,4 +713,10 @@ /* Added by Kevin -- Maximum path length */ #cmakedefine MAXPATHLEN ${MAXPATHLEN} +/* Support for Intel JIT Events API is enabled */ +#cmakedefine LLVM_USE_INTEL_JITEVENTS 1 + +/* Support for OProfile JIT API is enabled */ +#cmakedefine LLVM_USE_OPROFILE 1 + #endif diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 1a996a2..723a5f6 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -615,6 +615,12 @@ /* Installation prefix directory */ #undef LLVM_PREFIX +/* Define if we have the Intel JIT API runtime support library */ +#undef LLVM_USE_INTEL_JITEVENTS + +/* Define if we have the oprofile JIT-support library */ +#undef LLVM_USE_OPROFILE + /* Major version of the LLVM API */ #undef LLVM_VERSION_MAJOR @@ -675,9 +681,6 @@ /* Define to 1 if your <sys/time.h> declares `struct tm'. */ #undef TM_IN_SYS_TIME -/* Define if we have the oprofile JIT-support library */ -#undef USE_OPROFILE - /* Define if use udis86 library */ #undef USE_UDIS86 diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index b9ade51..da5ad27 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -195,9 +195,10 @@ class StructType : public CompositeType { // This is the contents of the SubClassData field. SCDB_HasBody = 1, SCDB_Packed = 2, - SCDB_IsLiteral = 4 + SCDB_IsLiteral = 4, + SCDB_IsSized = 8 }; - + /// SymbolTableEntry - For a named struct that actually has a name, this is a /// pointer to the symbol table entry (maintained by LLVMContext) for the /// struct. This is null if the type is an literal struct or if it is @@ -248,6 +249,9 @@ public: /// isOpaque - Return true if this is a type with an identity that has no body /// specified yet. These prints as 'opaque' in .ll files. bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; } + + /// isSized - Return true if this is a sized type. + bool isSized() const; /// hasName - Return true if this is a named struct that has a non-empty name. bool hasName() const { return SymbolTableEntry != 0; } diff --git a/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h b/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h new file mode 100644 index 0000000..ca87342 --- /dev/null +++ b/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h @@ -0,0 +1,102 @@ +//===-- IntelJITEventsWrapper.h - Intel JIT Events API Wrapper --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a wrapper for the Intel JIT Events API. It allows for the +// implementation of the jitprofiling library to be swapped with an alternative +// implementation (for testing). To include this file, you must have the +// jitprofiling.h header available; it is available in Intel(R) VTune(TM) +// Amplifier XE 2011. +// +//===----------------------------------------------------------------------===// + +#ifndef INTEL_JIT_EVENTS_WRAPPER_H +#define INTEL_JIT_EVENTS_WRAPPER_H + +#include <jitprofiling.h> + +namespace llvm { + +class IntelJITEventsWrapper { + // Function pointer types for testing implementation of Intel jitprofiling + // library + typedef int (*NotifyEventPtr)(iJIT_JVM_EVENT, void*); + typedef void (*RegisterCallbackExPtr)(void *, iJIT_ModeChangedEx ); + typedef iJIT_IsProfilingActiveFlags (*IsProfilingActivePtr)(void); + typedef void (*FinalizeThreadPtr)(void); + typedef void (*FinalizeProcessPtr)(void); + typedef unsigned int (*GetNewMethodIDPtr)(void); + + NotifyEventPtr NotifyEventFunc; + RegisterCallbackExPtr RegisterCallbackExFunc; + IsProfilingActivePtr IsProfilingActiveFunc; + FinalizeThreadPtr FinalizeThreadFunc; + FinalizeProcessPtr FinalizeProcessFunc; + GetNewMethodIDPtr GetNewMethodIDFunc; + +public: + bool isAmplifierRunning() { + return iJIT_IsProfilingActive() == iJIT_SAMPLING_ON; + } + + IntelJITEventsWrapper() + : NotifyEventFunc(::iJIT_NotifyEvent), + RegisterCallbackExFunc(::iJIT_RegisterCallbackEx), + IsProfilingActiveFunc(::iJIT_IsProfilingActive), + FinalizeThreadFunc(::FinalizeThread), + FinalizeProcessFunc(::FinalizeProcess), + GetNewMethodIDFunc(::iJIT_GetNewMethodID) { + } + + IntelJITEventsWrapper(NotifyEventPtr NotifyEventImpl, + RegisterCallbackExPtr RegisterCallbackExImpl, + IsProfilingActivePtr IsProfilingActiveImpl, + FinalizeThreadPtr FinalizeThreadImpl, + FinalizeProcessPtr FinalizeProcessImpl, + GetNewMethodIDPtr GetNewMethodIDImpl) + : NotifyEventFunc(NotifyEventImpl), + RegisterCallbackExFunc(RegisterCallbackExImpl), + IsProfilingActiveFunc(IsProfilingActiveImpl), + FinalizeThreadFunc(FinalizeThreadImpl), + FinalizeProcessFunc(FinalizeProcessImpl), + GetNewMethodIDFunc(GetNewMethodIDImpl) { + } + + // Sends an event anncouncing that a function has been emitted + // return values are event-specific. See Intel documentation for details. + int iJIT_NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) { + if (!NotifyEventFunc) + return -1; + return NotifyEventFunc(EventType, EventSpecificData); + } + + // Registers a callback function to receive notice of profiling state changes + void iJIT_RegisterCallbackEx(void *UserData, + iJIT_ModeChangedEx NewModeCallBackFuncEx) { + if (RegisterCallbackExFunc) + RegisterCallbackExFunc(UserData, NewModeCallBackFuncEx); + } + + // Returns the current profiler mode + iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive(void) { + if (!IsProfilingActiveFunc) + return iJIT_NOTHING_RUNNING; + return IsProfilingActiveFunc(); + } + + // Generates a locally unique method ID for use in code registration + unsigned int iJIT_GetNewMethodID(void) { + if (!GetNewMethodIDFunc) + return -1; + return GetNewMethodIDFunc(); + } +}; + +} //namespace llvm + +#endif //INTEL_JIT_EVENTS_WRAPPER_H diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index 94212e1..eea603f 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,6 +15,7 @@ #ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H #define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H +#include "llvm/Config/config.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" @@ -23,6 +24,8 @@ namespace llvm { class Function; class MachineFunction; +class OProfileWrapper; +class IntelJITEventsWrapper; /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -72,11 +75,42 @@ public: /// to NotifyFunctionEmitted may have been destroyed by the time of the /// matching NotifyFreeingMachineCode call. virtual void NotifyFreeingMachineCode(void *) {} -}; -// This returns NULL if support isn't available. -JITEventListener *createOProfileJITEventListener(); +#if LLVM_USE_INTEL_JITEVENTS + // Construct an IntelJITEventListener + static JITEventListener *createIntelJITEventListener(); + + // Construct an IntelJITEventListener with a test Intel JIT API implementation + static JITEventListener *createIntelJITEventListener( + IntelJITEventsWrapper* AlternativeImpl); +#else + static JITEventListener *createIntelJITEventListener() { return 0; } + + static JITEventListener *createIntelJITEventListener( + IntelJITEventsWrapper* AlternativeImpl) { + return 0; + } +#endif // USE_INTEL_JITEVENTS + +#if LLVM_USE_OPROFILE + // Construct an OProfileJITEventListener + static JITEventListener *createOProfileJITEventListener(); + + // Construct an OProfileJITEventListener with a test opagent implementation + static JITEventListener *createOProfileJITEventListener( + OProfileWrapper* AlternativeImpl); +#else + + static JITEventListener *createOProfileJITEventListener() { return 0; } + + static JITEventListener *createOProfileJITEventListener( + OProfileWrapper* AlternativeImpl) { + return 0; + } +#endif // USE_OPROFILE + +}; } // end namespace llvm. -#endif +#endif // defined LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 8eb7590..3587e38 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -47,6 +47,17 @@ public: /// debugging, and may be turned on by default in debug mode. virtual void setPoisonMemory(bool poison) = 0; + /// getPointerToNamedFunction - This method returns the address of the + /// specified function by using the dlsym function call. As such it is only + /// useful for resolving library symbols, not code generated symbols. + /// + /// If AbortOnFailure is false and no function with the given name is + /// found, this function silently returns a null pointer. Otherwise, + /// it prints a message to stderr and aborts. + /// + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) = 0; + //===--------------------------------------------------------------------===// // Global Offset Table Management //===--------------------------------------------------------------------===// diff --git a/include/llvm/ExecutionEngine/OProfileWrapper.h b/include/llvm/ExecutionEngine/OProfileWrapper.h new file mode 100644 index 0000000..ab7f25e --- /dev/null +++ b/include/llvm/ExecutionEngine/OProfileWrapper.h @@ -0,0 +1,124 @@ +//===-- OProfileWrapper.h - OProfile JIT API Wrapper ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This file defines a OProfileWrapper object that detects if the oprofile +// daemon is running, and provides wrappers for opagent functions used to +// communicate with the oprofile JIT interface. The dynamic library libopagent +// does not need to be linked directly as this object lazily loads the library +// when the first op_ function is called. +// +// See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the +// definition of the interface. +// +//===----------------------------------------------------------------------===// + +#ifndef OPROFILE_WRAPPER_H +#define OPROFILE_WRAPPER_H + +#include "llvm/Support/DataTypes.h" +#include <opagent.h> + +namespace llvm { + + +class OProfileWrapper { + typedef op_agent_t (*op_open_agent_ptr_t)(); + typedef int (*op_close_agent_ptr_t)(op_agent_t); + typedef int (*op_write_native_code_ptr_t)(op_agent_t, + const char*, + uint64_t, + void const*, + const unsigned int); + typedef int (*op_write_debug_line_info_ptr_t)(op_agent_t, + void const*, + size_t, + struct debug_line_info const*); + typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t); + + // Also used for op_minor_version function which has the same signature + typedef int (*op_major_version_ptr_t)(void); + + // This is not a part of the opagent API, but is useful nonetheless + typedef bool (*IsOProfileRunningPtrT)(void); + + + op_agent_t Agent; + op_open_agent_ptr_t OpenAgentFunc; + op_close_agent_ptr_t CloseAgentFunc; + op_write_native_code_ptr_t WriteNativeCodeFunc; + op_write_debug_line_info_ptr_t WriteDebugLineInfoFunc; + op_unload_native_code_ptr_t UnloadNativeCodeFunc; + op_major_version_ptr_t MajorVersionFunc; + op_major_version_ptr_t MinorVersionFunc; + IsOProfileRunningPtrT IsOProfileRunningFunc; + + bool Initialized; + +public: + OProfileWrapper(); + + // For testing with a mock opagent implementation, skips the dynamic load and + // the function resolution. + OProfileWrapper(op_open_agent_ptr_t OpenAgentImpl, + op_close_agent_ptr_t CloseAgentImpl, + op_write_native_code_ptr_t WriteNativeCodeImpl, + op_write_debug_line_info_ptr_t WriteDebugLineInfoImpl, + op_unload_native_code_ptr_t UnloadNativeCodeImpl, + op_major_version_ptr_t MajorVersionImpl, + op_major_version_ptr_t MinorVersionImpl, + IsOProfileRunningPtrT MockIsOProfileRunningImpl = 0) + : OpenAgentFunc(OpenAgentImpl), + CloseAgentFunc(CloseAgentImpl), + WriteNativeCodeFunc(WriteNativeCodeImpl), + WriteDebugLineInfoFunc(WriteDebugLineInfoImpl), + UnloadNativeCodeFunc(UnloadNativeCodeImpl), + MajorVersionFunc(MajorVersionImpl), + MinorVersionFunc(MinorVersionImpl), + IsOProfileRunningFunc(MockIsOProfileRunningImpl), + Initialized(true) + { + } + + // Calls op_open_agent in the oprofile JIT library and saves the returned + // op_agent_t handle internally so it can be used when calling all the other + // op_* functions. Callers of this class do not need to keep track of + // op_agent_t objects. + bool op_open_agent(); + + int op_close_agent(); + int op_write_native_code(const char* name, + uint64_t addr, + void const* code, + const unsigned int size); + int op_write_debug_line_info(void const* code, + size_t num_entries, + struct debug_line_info const* info); + int op_unload_native_code(uint64_t addr); + int op_major_version(void); + int op_minor_version(void); + + // Returns true if the oprofiled process is running, the opagent library is + // loaded and a connection to the agent has been established, and false + // otherwise. + bool isAgentAvailable(); + +private: + // Loads the libopagent library and initializes this wrapper if the oprofile + // daemon is running + bool initialize(); + + // Searches /proc for the oprofile daemon and returns true if the process if + // found, or false otherwise. + bool checkForOProfileProcEntry(); + + bool isOProfileRunning(); +}; + +} // namespace llvm + +#endif //OPROFILE_WRAPPER_H diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 8ad316b..aabfd03 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -45,15 +45,9 @@ public: virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) = 0; - // Allocate ActualSize bytes, or more, for the named function. Return - // a pointer to the allocated memory and update Size to reflect how much - // memory was acutally allocated. - virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0; - - // Mark the end of the function, including how much of the allocated - // memory was actually used. - virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart, - uint8_t *FunctionEnd) = 0; + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) = 0; + }; class RuntimeDyld { diff --git a/include/llvm/Function.h b/include/llvm/Function.h index b5916b7..e17cd87 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -146,7 +146,7 @@ public: /// The particular intrinsic functions which correspond to this value are /// defined in llvm/Intrinsics.h. /// - unsigned getIntrinsicID() const LLVM_ATTRIBUTE_READONLY; + unsigned getIntrinsicID() const LLVM_READONLY; bool isIntrinsic() const { return getIntrinsicID() != 0; } /// getCallingConv()/setCallingConv(CC) - These method get and set the diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 52fa8d7..e3676fe 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -24,7 +24,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" #include <iterator> -#include <limits.h> namespace llvm { @@ -2468,8 +2467,120 @@ class SwitchInst : public TerminatorInst { protected: virtual SwitchInst *clone_impl() const; public: + + // -2 + static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1); + + template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy> + class CaseIteratorT { + protected: + + SwitchInstTy *SI; + unsigned Index; + + public: + + typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self; + + /// Initializes case iterator for given SwitchInst and for given + /// case number. + CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) { + this->SI = SI; + Index = CaseNum; + } + + /// Initializes case iterator for given SwitchInst and for given + /// TerminatorInst's successor index. + static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) { + assert(SuccessorIndex < SI->getNumSuccessors() && + "Successor index # out of range!"); + return SuccessorIndex != 0 ? + Self(SI, SuccessorIndex - 1) : + Self(SI, DefaultPseudoIndex); + } + + /// Resolves case value for current case. + ConstantIntTy *getCaseValue() { + assert(Index < SI->getNumCases() && "Index out the number of cases."); + return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2)); + } + + /// Resolves successor for current case. + BasicBlockTy *getCaseSuccessor() { + assert((Index < SI->getNumCases() || DefaultPseudoIndex) && + "Index out the number of cases."); + return SI->getSuccessor(getSuccessorIndex()); + } + + /// Returns number of current case. + unsigned getCaseIndex() const { return Index; } + + /// Returns TerminatorInst's successor index for current case successor. + unsigned getSuccessorIndex() const { + assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) && + "Index out the number of cases."); + return Index != DefaultPseudoIndex ? Index + 1 : 0; + } + + Self operator++() { + // Check index correctness after increment. + // Note: Index == getNumCases() means end(). + assert(Index+1 <= SI->getNumCases() && "Index out the number of cases."); + ++Index; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++(*this); + return tmp; + } + Self operator--() { + // Check index correctness after decrement. + // Note: Index == getNumCases() means end(). + // Also allow "-1" iterator here. That will became valid after ++. + assert((Index == 0 || Index-1 <= SI->getNumCases()) && + "Index out the number of cases."); + --Index; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --(*this); + return tmp; + } + bool operator==(const Self& RHS) const { + assert(RHS.SI == SI && "Incompatible operators."); + return RHS.Index == Index; + } + bool operator!=(const Self& RHS) const { + assert(RHS.SI == SI && "Incompatible operators."); + return RHS.Index != Index; + } + }; + + typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock> + ConstCaseIt; - enum { ErrorIndex = UINT_MAX }; + class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> { + + typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy; + + public: + + CaseIt(const ParentTy& Src) : ParentTy(Src) {} + CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} + + /// Sets the new value for current case. + void setValue(ConstantInt *V) { + assert(Index < SI->getNumCases() && "Index out the number of cases."); + SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V)); + } + + /// Sets the new successor for current case. + void setSuccessor(BasicBlock *S) { + SI->setSuccessor(getSuccessorIndex(), S); + } + }; static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0) { @@ -2479,6 +2590,7 @@ public: unsigned NumCases, BasicBlock *InsertAtEnd) { return new SwitchInst(Value, Default, NumCases, InsertAtEnd); } + ~SwitchInst(); /// Provide fast operand accessors @@ -2502,78 +2614,84 @@ public: return getNumOperands()/2 - 1; } - /// getCaseValue - Return the specified case value. Note that case #0, means - /// first case, not a default case. - ConstantInt *getCaseValue(unsigned i) { - assert(i < getNumCases() && "Illegal case value to get!"); - return reinterpret_cast<ConstantInt*>(getOperand(2 + i*2)); + /// Returns a read/write iterator that points to the first + /// case in SwitchInst. + CaseIt case_begin() { + return CaseIt(this, 0); } - - /// getCaseValue - Return the specified case value. Note that case #0, means - /// first case, not a default case. - const ConstantInt *getCaseValue(unsigned i) const { - assert(i < getNumCases() && "Illegal case value to get!"); - return reinterpret_cast<const ConstantInt*>(getOperand(2 + i*2)); + /// Returns a read-only iterator that points to the first + /// case in the SwitchInst. + ConstCaseIt case_begin() const { + return ConstCaseIt(this, 0); } - - // setSuccessorValue - Updates the value associated with the specified - // case. - void setCaseValue(unsigned i, ConstantInt *CaseValue) { - assert(i < getNumCases() && "Case index # out of range!"); - setOperand(2 + i*2, reinterpret_cast<Value*>(CaseValue)); + + /// Returns a read/write iterator that points one past the last + /// in the SwitchInst. + CaseIt case_end() { + return CaseIt(this, getNumCases()); + } + /// Returns a read-only iterator that points one past the last + /// in the SwitchInst. + ConstCaseIt case_end() const { + return ConstCaseIt(this, getNumCases()); + } + /// Returns an iterator that points to the default case. + /// Note: this iterator allows to resolve successor only. Attempt + /// to resolve case value causes an assertion. + /// Also note, that increment and decrement also causes an assertion and + /// makes iterator invalid. + CaseIt case_default() { + return CaseIt(this, DefaultPseudoIndex); + } + ConstCaseIt case_default() const { + return ConstCaseIt(this, DefaultPseudoIndex); } - + /// findCaseValue - Search all of the case values for the specified constant. - /// If it is explicitly handled, return the case number of it, otherwise - /// return ErrorIndex to indicate that it is handled by the default handler. - unsigned findCaseValue(const ConstantInt *C) const { - for (unsigned i = 0, e = getNumCases(); i != e; ++i) - if (getCaseValue(i) == C) + /// If it is explicitly handled, return the case iterator of it, otherwise + /// return default case iterator to indicate + /// that it is handled by the default handler. + CaseIt findCaseValue(const ConstantInt *C) { + for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) + if (i.getCaseValue() == C) return i; - return ErrorIndex; - } - - /// resolveSuccessorIndex - Converts case index to index of its successor - /// index in TerminatorInst successors collection. - /// If CaseIndex == ErrorIndex, "default" successor will returned then. - unsigned resolveSuccessorIndex(unsigned CaseIndex) const { - assert((CaseIndex == ErrorIndex || CaseIndex < getNumCases()) && - "Case index # out of range!"); - return CaseIndex != ErrorIndex ? CaseIndex + 1 : 0; + return case_default(); } + ConstCaseIt findCaseValue(const ConstantInt *C) const { + for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i) + if (i.getCaseValue() == C) + return i; + return case_default(); + } - /// resolveCaseIndex - Converts index of successor in TerminatorInst - /// collection to index of case that corresponds to this successor. - unsigned resolveCaseIndex(unsigned SuccessorIndex) const { - assert(SuccessorIndex < getNumSuccessors() && - "Successor index # out of range!"); - return SuccessorIndex != 0 ? SuccessorIndex - 1 : ErrorIndex; - } - /// findCaseDest - Finds the unique case value for a given successor. Returns /// null if the successor is not found, not unique, or is the default case. ConstantInt *findCaseDest(BasicBlock *BB) { if (BB == getDefaultDest()) return NULL; ConstantInt *CI = NULL; - for (unsigned i = 0, e = getNumCases(); i != e; ++i) { - if (getSuccessor(i + 1) == BB) { + for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) { + if (i.getCaseSuccessor() == BB) { if (CI) return NULL; // Multiple cases lead to BB. - else CI = getCaseValue(i); + else CI = i.getCaseValue(); } } return CI; } /// addCase - Add an entry to the switch instruction... - /// + /// Note: + /// This action invalidates case_end(). Old case_end() iterator will + /// point to the added case. void addCase(ConstantInt *OnVal, BasicBlock *Dest); /// removeCase - This method removes the specified case and its successor /// from the switch instruction. Note that this operation may reorder the /// remaining cases at index idx and above. - /// - void removeCase(unsigned idx); + /// Note: + /// This action invalidates iterators for all cases following the one removed, + /// including the case_end() iterator. + void removeCase(CaseIt i); unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { @@ -2585,36 +2703,6 @@ public: setOperand(idx*2+1, (Value*)NewSucc); } - /// Resolves successor for idx-th case. - /// Use getCaseSuccessor instead of TerminatorInst::getSuccessor, - /// since internal SwitchInst organization of operands/successors is - /// hidden and may be changed in any moment. - BasicBlock *getCaseSuccessor(unsigned idx) const { - return getSuccessor(resolveSuccessorIndex(idx)); - } - - /// Set new successor for idx-th case. - /// Use setCaseSuccessor instead of TerminatorInst::setSuccessor, - /// since internal SwitchInst organization of operands/successors is - /// hidden and may be changed in any moment. - void setCaseSuccessor(unsigned idx, BasicBlock *NewSucc) { - setSuccessor(resolveSuccessorIndex(idx), NewSucc); - } - - // getSuccessorValue - Return the value associated with the specified - // successor. - ConstantInt *getSuccessorValue(unsigned idx) const { - assert(idx < getNumSuccessors() && "Successor # out of range!"); - return reinterpret_cast<ConstantInt*>(getOperand(idx*2)); - } - - // setSuccessorValue - Updates the value associated with the specified - // successor. - void setSuccessorValue(unsigned idx, ConstantInt* SuccessorValue) { - assert(idx < getNumSuccessors() && "Successor # out of range!"); - setOperand(idx*2, reinterpret_cast<Value*>(SuccessorValue)); - } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index ca497b8..186612d 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -58,17 +58,17 @@ public: /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. - short RegClass; + int16_t RegClass; /// Flags - These are flags from the MCOI::OperandFlags enum. - unsigned short Flags; + uint8_t Flags; + + /// OperandType - Information about the type of the operand. + uint8_t OperandType; /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). - unsigned Constraints; - - /// OperandType - Information about the type of the operand. - MCOI::OperandType OperandType; + uint32_t Constraints; /// Currently no other information. /// isLookupPtrRegClass - Set if this operand is a pointer value and it @@ -139,8 +139,8 @@ public: unsigned short Size; // Number of bytes in encoding. unsigned Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values - const unsigned *ImplicitUses; // Registers implicitly read by this instr - const unsigned *ImplicitDefs; // Registers implicitly defined by this instr + const uint16_t *ImplicitUses; // Registers implicitly read by this instr + const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands /// getOperandConstraint - Returns the value of the specific constraint if @@ -448,7 +448,7 @@ public: /// does. /// /// This method returns null if the instruction has no implicit uses. - const unsigned *getImplicitUses() const { + const uint16_t *getImplicitUses() const { return ImplicitUses; } @@ -471,7 +471,7 @@ public: /// EAX/EDX/EFLAGS registers. /// /// This method returns null if the instruction has no implicit defs. - const unsigned *getImplicitDefs() const { + const uint16_t *getImplicitDefs() const { return ImplicitDefs; } @@ -487,7 +487,7 @@ public: /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpUses = ImplicitUses) + if (const uint16_t *ImpUses = ImplicitUses) for (; *ImpUses; ++ImpUses) if (*ImpUses == Reg) return true; return false; @@ -496,7 +496,7 @@ public: /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly /// defines the specified physical register. bool hasImplicitDefOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpDefs = ImplicitDefs) + if (const uint16_t *ImpDefs = ImplicitDefs) for (; *ImpDefs; ++ImpDefs) if (*ImpDefs == Reg) return true; return false; diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 762558d..1937fdc 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -31,10 +31,10 @@ public: const char *Name; const iterator RegsBegin; const uint8_t *const RegSet; - const uint8_t RegsSize; - const uint8_t RegSetSize; - const uint8_t ID; - const uint8_t RegSize, Alignment; // Size & Alignment of register in bytes + const uint16_t RegsSize; + const uint16_t RegSetSize; + const uint16_t ID; + const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes const int8_t CopyCost; const bool Allocatable; @@ -107,9 +107,9 @@ public: /// struct MCRegisterDesc { const char *Name; // Printable name for the reg (for debugging) - uint16_t Overlaps; // Overlapping registers, described above - uint16_t SubRegs; // Sub-register set, described above - uint16_t SuperRegs; // Super-register set, described above + uint32_t Overlaps; // Overlapping registers, described above + uint32_t SubRegs; // Sub-register set, described above + uint32_t SuperRegs; // Super-register set, described above }; /// MCRegisterInfo base class - We assume that the target defines a static diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index e6df856..358b27a 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -131,7 +131,7 @@ public: // Cast methods. static inline bool classof(Archive const *v) { return true; } static inline bool classof(Binary const *v) { - return v->getType() == Binary::isArchive; + return v->isArchive(); } private: diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index cd092fd..77a08d5 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -37,16 +37,25 @@ protected: Binary(unsigned int Type, MemoryBuffer *Source); enum { - isArchive, - + ID_Archive, // Object and children. - isObject, - isCOFF, - isELF, - isMachO, - lastObject + ID_StartObjects, + ID_COFF, + ID_ELF32L, // ELF 32-bit, little endian + ID_ELF32B, // ELF 32-bit, big endian + ID_ELF64L, // ELF 64-bit, little endian + ID_ELF64B, // ELF 64-bit, big endian + ID_MachO, + ID_EndObjects }; + static inline unsigned int getELFType(bool isLittleEndian, bool is64Bits) { + if (isLittleEndian) + return is64Bits ? ID_ELF64L : ID_ELF32L; + else + return is64Bits ? ID_ELF64B : ID_ELF32B; + } + public: virtual ~Binary(); @@ -56,9 +65,37 @@ public: // Cast methods. unsigned int getType() const { return TypeID; } static inline bool classof(const Binary *v) { return true; } + + // Convenience methods + bool isObject() const { + return TypeID > ID_StartObjects && TypeID < ID_EndObjects; + } + + bool isArchive() const { + return TypeID == ID_Archive; + } + + bool isELF() const { + return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B; + } + + bool isMachO() const { + return TypeID == ID_MachO; + } + + bool isCOFF() const { + return TypeID == ID_COFF; + } }; +/// @brief Create a Binary from Source, autodetecting the file type. +/// +/// @param Source The data to create the Binary from. Ownership is transfered +/// to Result if successful. If an error is returned, Source is destroyed +/// by createBinary before returning. +/// @param Result A pointer to the resulting Binary if no error occured. error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); + error_code createBinary(StringRef Path, OwningPtr<Binary> &Result); } diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 4f90187..91971bb 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -19,6 +19,9 @@ #include "llvm/Support/Endian.h" namespace llvm { + template <typename T> + class ArrayRef; + namespace object { struct coff_file_header { @@ -177,9 +180,12 @@ public: return ec; } error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const; + error_code getSectionName(const coff_section *Sec, StringRef &Res) const; + error_code getSectionContents(const coff_section *Sec, + ArrayRef<uint8_t> &Res) const; static inline bool classof(const Binary *v) { - return v->getType() == isCOFF; + return v->isCOFF(); } static inline bool classof(const COFFObjectFile *v) { return true; } }; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index e746b0a..d33f317 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" @@ -176,7 +177,72 @@ struct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { } }; -// Elf_Dyn: Entry in the dynamic table +/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section +/// (.gnu.version). This structure is identical for ELF32 and ELF64. +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Versym_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) +}; + +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Verdaux_Impl; + +/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section +/// (.gnu.version_d). This structure is identical for ELF32 and ELF64. +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Verdef_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; + Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) + Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) + Elf_Half vd_ndx; // Version index, used in .gnu.version entries + Elf_Half vd_cnt; // Number of Verdaux entries + Elf_Word vd_hash; // Hash of name + Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) + Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) + + /// Get the first Verdaux entry for this Verdef. + const Elf_Verdaux *getAux() const { + return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux); + } +}; + +/// Elf_Verdaux: This is the structure of auxilary data in the SHT_GNU_verdef +/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Verdaux_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + Elf_Word vda_name; // Version name (offset in string table) + Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) +}; + +/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed +/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Verneed_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) + Elf_Half vn_cnt; // Number of associated Vernaux entries + Elf_Word vn_file; // Library name (string table offset) + Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) + Elf_Word vn_next; // Offset to next Verneed entry (in bytes) +}; + +/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed +/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. +template<support::endianness target_endianness, bool is64Bits> +struct Elf_Vernaux_Impl { + LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) + Elf_Word vna_hash; // Hash of dependency name + Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) + Elf_Half vna_other; // Version index, used in .gnu.version entries + Elf_Word vna_name; // Dependency name + Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) +}; + +/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic +/// table section (.dynamic) look like. template<support::endianness target_endianness, bool is64Bits> struct Elf_Dyn_Base; @@ -200,6 +266,7 @@ struct Elf_Dyn_Base<target_endianness, true> { } d_un; }; +/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters. template<support::endianness target_endianness, bool is64Bits> struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> { using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag; @@ -323,6 +390,11 @@ class ELFObjectFile : public ObjectFile { typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; + typedef Elf_Verdef_Impl<target_endianness, is64Bits> Elf_Verdef; + typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; + typedef Elf_Verneed_Impl<target_endianness, is64Bits> Elf_Verneed; + typedef Elf_Vernaux_Impl<target_endianness, is64Bits> Elf_Vernaux; + typedef Elf_Versym_Impl<target_endianness, is64Bits> Elf_Versym; typedef DynRefImpl<target_endianness, is64Bits> DynRef; typedef content_iterator<DynRef> dyn_iterator; @@ -364,15 +436,48 @@ private: const Elf_Shdr *dot_shstrtab_sec; // Section header string table. const Elf_Shdr *dot_strtab_sec; // Symbol header string table. const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. + + // SymbolTableSections[0] always points to the dynamic string table section + // header, or NULL if there is no dynamic string table. Sections_t SymbolTableSections; IndexMap_t SymbolTableSectionsIndexMap; DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; - const Elf_Shdr *dot_dynamic_sec; // .dynamic + const Elf_Shdr *dot_dynamic_sec; // .dynamic + const Elf_Shdr *dot_gnu_version_sec; // .gnu.version + const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r + const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d + // Pointer to SONAME entry in dynamic string table // This is set the first time getLoadName is called. mutable const char *dt_soname; + // Records for each version index the corresponding Verdef or Vernaux entry. + // This is filled the first time LoadVersionMap() is called. + class VersionMapEntry : public PointerIntPair<const void*, 1> { + public: + // If the integer is 0, this is an Elf_Verdef*. + // If the integer is 1, this is an Elf_Vernaux*. + VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } + VersionMapEntry(const Elf_Verdef *verdef) + : PointerIntPair<const void*, 1>(verdef, 0) { } + VersionMapEntry(const Elf_Vernaux *vernaux) + : PointerIntPair<const void*, 1>(vernaux, 1) { } + bool isNull() const { return getPointer() == NULL; } + bool isVerdef() const { return !isNull() && getInt() == 0; } + bool isVernaux() const { return !isNull() && getInt() == 1; } + const Elf_Verdef *getVerdef() const { + return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL; + } + const Elf_Vernaux *getVernaux() const { + return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL; + } + }; + mutable SmallVector<VersionMapEntry, 16> VersionMap; + void LoadVersionDefs(const Elf_Shdr *sec) const; + void LoadVersionNeeds(const Elf_Shdr *ec) const; + void LoadVersionMap() const; + /// @brief Map sections to an array of relocation sections that reference /// them sorted by section index. RelocMap_t SectionRelocMap; @@ -396,6 +501,10 @@ private: error_code getSymbolName(const Elf_Shdr *section, const Elf_Sym *Symb, StringRef &Res) const; + error_code getSymbolVersion(const Elf_Shdr *section, + const Elf_Sym *Symb, + StringRef &Version, + bool &IsDefault) const; void VerifyStrTab(const Elf_Shdr *sh) const; protected: @@ -404,7 +513,8 @@ protected: public: const Elf_Dyn *getDyn(DataRefImpl DynData) const; - + error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const; protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; @@ -473,6 +583,7 @@ public: virtual uint8_t getBytesInAddress() const; virtual StringRef getFileFormatName() const; + virtual StringRef getObjectType() const { return "ELF"; } virtual unsigned getArch() const; virtual StringRef getLoadName() const; @@ -484,11 +595,95 @@ public: // Methods for type inquiry through isa, cast, and dyn_cast bool isDyldType() const { return isDyldELFObject; } static inline bool classof(const Binary *v) { - return v->getType() == Binary::isELF; + return v->getType() == getELFType(target_endianness == support::little, + is64Bits); } static inline bool classof(const ELFObjectFile *v) { return true; } }; +// Iterate through the version definitions, and place each Elf_Verdef +// in the VersionMap according to its index. +template<support::endianness target_endianness, bool is64Bits> +void ELFObjectFile<target_endianness, is64Bits>:: + LoadVersionDefs(const Elf_Shdr *sec) const { + unsigned vd_size = sec->sh_size; // Size of section in bytes + unsigned vd_count = sec->sh_info; // Number of Verdef entries + const char *sec_start = (const char*)base() + sec->sh_offset; + const char *sec_end = sec_start + vd_size; + // The first Verdef entry is at the start of the section. + const char *p = sec_start; + for (unsigned i = 0; i < vd_count; i++) { + if (p + sizeof(Elf_Verdef) > sec_end) + report_fatal_error("Section ended unexpectedly while scanning " + "version definitions."); + const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p); + if (vd->vd_version != ELF::VER_DEF_CURRENT) + report_fatal_error("Unexpected verdef version"); + size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; + if (index >= VersionMap.size()) + VersionMap.resize(index+1); + VersionMap[index] = VersionMapEntry(vd); + p += vd->vd_next; + } +} + +// Iterate through the versions needed section, and place each Elf_Vernaux +// in the VersionMap according to its index. +template<support::endianness target_endianness, bool is64Bits> +void ELFObjectFile<target_endianness, is64Bits>:: + LoadVersionNeeds(const Elf_Shdr *sec) const { + unsigned vn_size = sec->sh_size; // Size of section in bytes + unsigned vn_count = sec->sh_info; // Number of Verneed entries + const char *sec_start = (const char*)base() + sec->sh_offset; + const char *sec_end = sec_start + vn_size; + // The first Verneed entry is at the start of the section. + const char *p = sec_start; + for (unsigned i = 0; i < vn_count; i++) { + if (p + sizeof(Elf_Verneed) > sec_end) + report_fatal_error("Section ended unexpectedly while scanning " + "version needed records."); + const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p); + if (vn->vn_version != ELF::VER_NEED_CURRENT) + report_fatal_error("Unexpected verneed version"); + // Iterate through the Vernaux entries + const char *paux = p + vn->vn_aux; + for (unsigned j = 0; j < vn->vn_cnt; j++) { + if (paux + sizeof(Elf_Vernaux) > sec_end) + report_fatal_error("Section ended unexpected while scanning auxiliary " + "version needed records."); + const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux); + size_t index = vna->vna_other & ELF::VERSYM_VERSION; + if (index >= VersionMap.size()) + VersionMap.resize(index+1); + VersionMap[index] = VersionMapEntry(vna); + paux += vna->vna_next; + } + p += vn->vn_next; + } +} + +template<support::endianness target_endianness, bool is64Bits> +void ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const { + // If there is no dynamic symtab or version table, there is nothing to do. + if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) + return; + + // Has the VersionMap already been loaded? + if (VersionMap.size() > 0) + return; + + // The first two version indexes are reserved. + // Index 0 is LOCAL, index 1 is GLOBAL. + VersionMap.push_back(VersionMapEntry()); + VersionMap.push_back(VersionMapEntry()); + + if (dot_gnu_version_d_sec) + LoadVersionDefs(dot_gnu_version_d_sec); + + if (dot_gnu_version_r_sec) + LoadVersionNeeds(dot_gnu_version_r_sec); +} + template<support::endianness target_endianness, bool is64Bits> void ELFObjectFile<target_endianness, is64Bits> ::validateSymbol(DataRefImpl Symb) const { @@ -546,6 +741,18 @@ error_code ELFObjectFile<target_endianness, is64Bits> } template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> + ::getSymbolVersion(SymbolRef SymRef, + StringRef &Version, + bool &IsDefault) const { + DataRefImpl Symb = SymRef.getRawDataRefImpl(); + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + return getSymbolVersion(SymbolTableSections[Symb.d.b], symb, + Version, IsDefault); +} + +template<support::endianness target_endianness, bool is64Bits> ELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits> ::getSymbolTableIndex(const Elf_Sym *symb) const { if (symb->st_shndx == ELF::SHN_XINDEX) @@ -1257,14 +1464,19 @@ void ELFObjectFile<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object , error_code &ec) - : ObjectFile(Binary::isELF, Object, ec) + : ObjectFile(getELFType(target_endianness == support::little, is64Bits), + Object, ec) , isDyldELFObject(false) , SectionHeaderTable(0) , dot_shstrtab_sec(0) , dot_strtab_sec(0) , dot_dynstr_sec(0) , dot_dynamic_sec(0) - , dt_soname(0) { + , dot_gnu_version_sec(0) + , dot_gnu_version_r_sec(0) + , dot_gnu_version_d_sec(0) + , dt_soname(0) + { const uint64_t FileSize = Data->getBufferSize(); @@ -1300,31 +1512,60 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object SymbolTableSections.push_back(NULL); for (uint64_t i = 0, e = getNumSections(); i != e; ++i) { - if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) { + switch (sh->sh_type) { + case ELF::SHT_SYMTAB_SHNDX: { if (SymbolTableSectionHeaderIndex) // FIXME: Proper error handling. report_fatal_error("More than one .symtab_shndx!"); SymbolTableSectionHeaderIndex = sh; + break; } - if (sh->sh_type == ELF::SHT_SYMTAB) { + case ELF::SHT_SYMTAB: { SymbolTableSectionsIndexMap[i] = SymbolTableSections.size(); SymbolTableSections.push_back(sh); + break; } - if (sh->sh_type == ELF::SHT_DYNSYM) { + case ELF::SHT_DYNSYM: { if (SymbolTableSections[0] != NULL) // FIXME: Proper error handling. report_fatal_error("More than one .dynsym!"); SymbolTableSectionsIndexMap[i] = 0; SymbolTableSections[0] = sh; + break; } - if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) { + case ELF::SHT_REL: + case ELF::SHT_RELA: { SectionRelocMap[getSection(sh->sh_info)].push_back(i); + break; } - if (sh->sh_type == ELF::SHT_DYNAMIC) { + case ELF::SHT_DYNAMIC: { if (dot_dynamic_sec != NULL) // FIXME: Proper error handling. report_fatal_error("More than one .dynamic!"); dot_dynamic_sec = sh; + break; + } + case ELF::SHT_GNU_versym: { + if (dot_gnu_version_sec != NULL) + // FIXME: Proper error handling. + report_fatal_error("More than one .gnu.version section!"); + dot_gnu_version_sec = sh; + break; + } + case ELF::SHT_GNU_verdef: { + if (dot_gnu_version_d_sec != NULL) + // FIXME: Proper error handling. + report_fatal_error("More than one .gnu.version_d section!"); + dot_gnu_version_d_sec = sh; + break; + } + case ELF::SHT_GNU_verneed: { + if (dot_gnu_version_r_sec != NULL) + // FIXME: Proper error handling. + report_fatal_error("More than one .gnu.version_r section!"); + dot_gnu_version_r_sec = sh; + break; + } } ++sh; } @@ -1774,6 +2015,89 @@ error_code ELFObjectFile<target_endianness, is64Bits> } template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> + ::getSymbolVersion(const Elf_Shdr *section, + const Elf_Sym *symb, + StringRef &Version, + bool &IsDefault) const { + // Handle non-dynamic symbols. + if (section != SymbolTableSections[0]) { + // Non-dynamic symbols can have versions in their names + // A name of the form 'foo@V1' indicates version 'V1', non-default. + // A name of the form 'foo@@V2' indicates version 'V2', default version. + StringRef Name; + error_code ec = getSymbolName(section, symb, Name); + if (ec != object_error::success) + return ec; + size_t atpos = Name.find('@'); + if (atpos == StringRef::npos) { + Version = ""; + IsDefault = false; + return object_error::success; + } + ++atpos; + if (atpos < Name.size() && Name[atpos] == '@') { + IsDefault = true; + ++atpos; + } else { + IsDefault = false; + } + Version = Name.substr(atpos); + return object_error::success; + } + + // This is a dynamic symbol. Look in the GNU symbol version table. + if (dot_gnu_version_sec == NULL) { + // No version table. + Version = ""; + IsDefault = false; + return object_error::success; + } + + // Determine the position in the symbol table of this entry. + const char *sec_start = (const char*)base() + section->sh_offset; + size_t entry_index = ((const char*)symb - sec_start)/section->sh_entsize; + + // Get the corresponding version index entry + const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); + size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; + + // Special markers for unversioned symbols. + if (version_index == ELF::VER_NDX_LOCAL || + version_index == ELF::VER_NDX_GLOBAL) { + Version = ""; + IsDefault = false; + return object_error::success; + } + + // Lookup this symbol in the version table + LoadVersionMap(); + if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) + report_fatal_error("Symbol has version index without corresponding " + "define or reference entry"); + const VersionMapEntry &entry = VersionMap[version_index]; + + // Get the version name string + size_t name_offset; + if (entry.isVerdef()) { + // The first Verdaux entry holds the name. + name_offset = entry.getVerdef()->getAux()->vda_name; + } else { + name_offset = entry.getVernaux()->vna_name; + } + Version = getString(dot_dynstr_sec, name_offset); + + // Set IsDefault + if (entry.isVerdef()) { + IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); + } else { + IsDefault = false; + } + + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> inline DynRefImpl<target_endianness, is64Bits> ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner) : DynPimpl(DynP) @@ -1821,6 +2145,35 @@ inline DataRefImpl DynRefImpl<target_endianness, is64Bits> return DynPimpl; } +/// This is a generic interface for retrieving GNU symbol version +/// information from an ELFObjectFile. +static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, + const SymbolRef &Sym, + StringRef &Version, + bool &IsDefault) { + // Little-endian 32-bit + if (const ELFObjectFile<support::little, false> *ELFObj = + dyn_cast<ELFObjectFile<support::little, false> >(Obj)) + return ELFObj->getSymbolVersion(Sym, Version, IsDefault); + + // Big-endian 32-bit + if (const ELFObjectFile<support::big, false> *ELFObj = + dyn_cast<ELFObjectFile<support::big, false> >(Obj)) + return ELFObj->getSymbolVersion(Sym, Version, IsDefault); + + // Little-endian 64-bit + if (const ELFObjectFile<support::little, true> *ELFObj = + dyn_cast<ELFObjectFile<support::little, true> >(Obj)) + return ELFObj->getSymbolVersion(Sym, Version, IsDefault); + + // Big-endian 64-bit + if (const ELFObjectFile<support::big, true> *ELFObj = + dyn_cast<ELFObjectFile<support::big, true> >(Obj)) + return ELFObj->getSymbolVersion(Sym, Version, IsDefault); + + llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); +} + } } diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1aae85a..1e409b2 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -47,7 +47,7 @@ public: MachOObject *getObject() { return MachOObj; } static inline bool classof(const Binary *v) { - return v->getType() == isMachO; + return v->isMachO(); } static inline bool classof(const MachOObjectFile *v) { return true; } diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 1e9d895..09eb7fc 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -372,8 +372,7 @@ public: static ObjectFile *createObjectFile(MemoryBuffer *Object); static inline bool classof(const Binary *v) { - return v->getType() >= isObject && - v->getType() < lastObject; + return v->isObject(); } static inline bool classof(const ObjectFile *v) { return true; } diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 9c5e7ec..d0b186e 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -49,22 +49,22 @@ #define LLVM_ATTRIBUTE_UNUSED #endif -#ifdef __GNUC__ // aka 'ATTRIBUTE_CONST' but following LLVM Conventions. -#define LLVM_ATTRIBUTE_READNONE __attribute__((__const__)) +#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) +#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else -#define LLVM_ATTRIBUTE_READNONE +#define LLVM_ATTRIBUTE_WEAK #endif -#ifdef __GNUC__ // aka 'ATTRIBUTE_PURE' but following LLVM Conventions. -#define LLVM_ATTRIBUTE_READONLY __attribute__((__pure__)) +#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions. +#define LLVM_READNONE __attribute__((__const__)) #else -#define LLVM_ATTRIBUTE_READONLY +#define LLVM_READNONE #endif -#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) -#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) +#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions. +#define LLVM_READONLY __attribute__((__pure__)) #else -#define LLVM_ATTRIBUTE_WEAK +#define LLVM_READONLY #endif #if (__GNUC__ >= 4) diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index d17f35f..a3a6489 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -94,6 +94,9 @@ typedef u_int64_t uint64_t; #else /* _MSC_VER */ /* Visual C++ doesn't provide standard integer headers, but it does provide built-in data types. */ +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif #include <stdlib.h> #include <stddef.h> #include <sys/types.h> diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 7ee363b..7123432 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -734,6 +734,9 @@ enum { SHT_GROUP = 17, // Section group. SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. SHT_LOOS = 0x60000000, // Lowest operating system-specific type. + SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. + SHT_GNU_verneed = 0x6ffffffe, // GNU version references. + SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type. @@ -1109,6 +1112,33 @@ enum { DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically. }; +// ElfXX_VerDef structure version (GNU versioning) +enum { + VER_DEF_NONE = 0, + VER_DEF_CURRENT = 1 +}; + +// VerDef Flags (ElfXX_VerDef::vd_flags) +enum { + VER_FLG_BASE = 0x1, + VER_FLG_WEAK = 0x2, + VER_FLG_INFO = 0x4 +}; + +// Special constants for the version table. (SHT_GNU_versym/.gnu.version) +enum { + VER_NDX_LOCAL = 0, // Unversioned local symbol + VER_NDX_GLOBAL = 1, // Unversioned global symbol + VERSYM_VERSION = 0x7fff, // Version Index mask + VERSYM_HIDDEN = 0x8000 // Hidden bit (non-default version) +}; + +// ElfXX_VerNeed structure version (GNU versioning) +enum { + VER_NEED_NONE = 0, + VER_NEED_CURRENT = 1 +}; + } // end namespace ELF } // end namespace llvm diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 4b1f3c9..2001456 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -157,53 +157,54 @@ public: // Specific Instruction type classes... note that all of the casts are // necessary because we use the instruction classes as opaque types... // - RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);} - RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);} - RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} - RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} - RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} - RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} - RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} - RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} - RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} - RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } - RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } - RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } - RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I){ DELEGATE(Instruction); } - RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction); } - RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); } - RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } - RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } - RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); } - RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); } - RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); } - RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); } - RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); } - RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); } - RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); } - RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); } - RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); } - RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); } - RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); } - RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); } - RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); } - RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); } - RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); } + RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);} + RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);} + RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} + RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} + RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} + RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} + RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} + RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} + RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} + RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);} + RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);} + RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);} + RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);} + RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);} + RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);} + RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);} + RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);} + RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);} + RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);} + RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);} + RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);} + RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);} + RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);} + RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);} + RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);} + RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);} + RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);} + RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);} + RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);} + RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);} + RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction);} + RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);} RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} - RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); } - RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } - RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} - RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } - RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } + RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);} + RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);} + RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);} + RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } + RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } // Next level propagators: If the user does not overload a specific // instruction type, they can overload one of these to get the whole class // of instructions... // - RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); } - RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); } - RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); } - RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); } + RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);} + RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);} + RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);} + RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction);} + RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);} // If the user wants a 'default' case, they can choose to override this // function. If this function is not overloaded in the user's subclass, then diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 493491a..44a7a79 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -114,6 +114,10 @@ namespace llvm { LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT + LoadCommandMain = 0x80000028u, // LC_MAIN + LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE + LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION + LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS // Constant bits for the "flags" field in llvm::MachO::segment_command SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 85d90b1..0cb8e97 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -121,12 +121,44 @@ template <> struct is_integral_impl<unsigned long long> : true_type {}; template <typename T> struct is_integral : is_integral_impl<T> {}; +/// \brief Metafunction to remove reference from a type. +template <typename T> struct remove_reference { typedef T type; }; +template <typename T> struct remove_reference<T&> { typedef T type; }; + /// \brief Metafunction that determines whether the given type is a pointer /// type. template <typename T> struct is_pointer : false_type {}; template <typename T> struct is_pointer<T*> : true_type {}; +template <typename T> struct is_pointer<T* const> : true_type {}; +template <typename T> struct is_pointer<T* volatile> : true_type {}; +template <typename T> struct is_pointer<T* const volatile> : true_type {}; + +/// \brief Metafunction that determines whether the given type is either an +/// integral type or an enumeration type. +/// +/// Note that this accepts potentially more integral types than we whitelist +/// above for is_integral because it is based on merely being convertible +/// implicitly to an integral type. +template <typename T> class is_integral_or_enum { + // Provide an overload which can be called with anything implicitly + // convertible to an unsigned long long. This should catch integer types and + // enumeration types at least. We blacklist classes with conversion operators + // below. + static double check_int_convertible(unsigned long long); + static char check_int_convertible(...); + + typedef typename remove_reference<T>::type UnderlyingT; + static UnderlyingT &nonce_instance; + +public: + enum { + value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && + !is_same<UnderlyingT, float>::value && + !is_same<UnderlyingT, double>::value && + sizeof(char) != sizeof(check_int_convertible(nonce_instance))) + }; +}; - // enable_if_c - Enable/disable a template based on a metafunction template<bool Cond, typename T = void> struct enable_if_c { diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 4f3e432..793b080 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -41,6 +41,7 @@ namespace llvm { class FastISel; class FunctionLoweringInfo; class ImmutableCallSite; + class IntrinsicInst; class MachineBasicBlock; class MachineFunction; class MachineInstr; @@ -1539,6 +1540,17 @@ public: AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} }; + /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the + /// same BB as Load/Store instructions reading the address. This allows as + /// much computation as possible to be done in the address mode for that + /// operand. This hook lets targets also pass back when this should be done + /// on intrinsics which load/store. + virtual bool GetAddrModeArguments(IntrinsicInst *I, + SmallVectorImpl<Value*> &Ops, + Type *&AccessTy) const { + return false; + } + /// isLegalAddressingMode - Return true if the addressing mode represented by /// AM is legal for this target, for a load/store of the specified type. /// The type may be VoidTy, in which case only return true if the addressing diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index 1feaaa4..f59479d 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -79,10 +79,14 @@ struct Inliner : public CallGraphSCCPass { /// has been inlined. virtual void growCachedCostInfo(Function *Caller, Function *Callee) = 0; - /// removeDeadFunctions - Remove dead functions that are not included in - /// DNR (Do Not Remove) list. - bool removeDeadFunctions(CallGraph &CG, - SmallPtrSet<const Function *, 16> *DNR = NULL); + /// removeDeadFunctions - Remove dead functions. + /// + /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag + /// which restricts it to deleting functions with an 'AlwaysInline' + /// attribute. This is useful for the InlineAlways pass that only wants to + /// deal with that subset of the functions. + bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false); + private: // InlineThreshold - Cache the value here for easy access. unsigned InlineThreshold; diff --git a/include/llvm/Transforms/Utils/BasicInliner.h b/include/llvm/Transforms/Utils/BasicInliner.h deleted file mode 100644 index 4bca6b8..0000000 --- a/include/llvm/Transforms/Utils/BasicInliner.h +++ /dev/null @@ -1,55 +0,0 @@ -//===- BasicInliner.h - Basic function level inliner ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a simple function based inliner that does not use -// call graph information. -// -//===----------------------------------------------------------------------===// - -#ifndef BASICINLINER_H -#define BASICINLINER_H - -#include "llvm/Analysis/InlineCost.h" - -namespace llvm { - - class Function; - class TargetData; - struct BasicInlinerImpl; - - /// BasicInliner - BasicInliner provides function level inlining interface. - /// Clients provide list of functions which are inline without using - /// module level call graph information. Note that the BasicInliner is - /// free to delete a function if it is inlined into all call sites. - class BasicInliner { - public: - - explicit BasicInliner(TargetData *T = NULL); - ~BasicInliner(); - - /// addFunction - Add function into the list of functions to process. - /// All functions must be inserted using this interface before invoking - /// inlineFunctions(). - void addFunction(Function *F); - - /// neverInlineFunction - Sometimes a function is never to be inlined - /// because of one or other reason. - void neverInlineFunction(Function *F); - - /// inlineFuctions - Walk all call sites in all functions supplied by - /// client. Inline as many call sites as possible. Delete completely - /// inlined functions. - void inlineFunctions(); - - private: - BasicInlinerImpl *Impl; - }; -} - -#endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 9c658cf..380af0b 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -263,14 +263,32 @@ public: return true; // Values are always values. } - /// stripPointerCasts - This method strips off any unneeded pointer - /// casts from the specified value, returning the original uncasted value. - /// Note that the returned value has pointer type if the specified value does. + /// stripPointerCasts - This method strips off any unneeded pointer casts and + /// all-zero GEPs from the specified value, returning the original uncasted + /// value. If this is called on a non-pointer value, it returns 'this'. Value *stripPointerCasts(); const Value *stripPointerCasts() const { return const_cast<Value*>(this)->stripPointerCasts(); } + /// stripInBoundsConstantOffsets - This method strips off unneeded pointer casts and + /// all-constant GEPs from the specified value, returning the original + /// pointer value. If this is called on a non-pointer value, it returns + /// 'this'. + Value *stripInBoundsConstantOffsets(); + const Value *stripInBoundsConstantOffsets() const { + return const_cast<Value*>(this)->stripInBoundsConstantOffsets(); + } + + /// stripInBoundsOffsets - This method strips off unneeded pointer casts and + /// any in-bounds Offsets from the specified value, returning the original + /// pointer value. If this is called on a non-pointer value, it returns + /// 'this'. + Value *stripInBoundsOffsets(); + const Value *stripInBoundsOffsets() const { + return const_cast<Value*>(this)->stripInBoundsOffsets(); + } + /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. bool isDereferenceablePointer() const; |
