aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Analysis.h10
-rw-r--r--include/llvm-c/BitReader.h10
-rw-r--r--include/llvm-c/BitWriter.h10
-rw-r--r--include/llvm-c/Core.h1730
-rw-r--r--include/llvm-c/Disassembler.h11
-rw-r--r--include/llvm-c/EnhancedDisassembly.h17
-rw-r--r--include/llvm-c/ExecutionEngine.h11
-rw-r--r--include/llvm-c/Initialization.h13
-rw-r--r--include/llvm-c/LinkTimeOptimizer.h11
-rw-r--r--include/llvm-c/Object.h10
-rw-r--r--include/llvm-c/Target.h10
-rw-r--r--include/llvm-c/Transforms/IPO.h11
-rw-r--r--include/llvm-c/Transforms/PassManagerBuilder.h11
-rw-r--r--include/llvm-c/Transforms/Scalar.h10
-rw-r--r--include/llvm-c/Transforms/Vectorize.h11
-rw-r--r--include/llvm-c/lto.h10
-rw-r--r--include/llvm/ADT/APInt.h16
-rw-r--r--include/llvm/ADT/Hashing.h24
-rw-r--r--include/llvm/ADT/ImmutableSet.h9
-rw-r--r--include/llvm/ADT/IntervalMap.h2
-rw-r--r--include/llvm/ADT/PointerIntPair.h6
-rw-r--r--include/llvm/ADT/PointerUnion.h21
-rw-r--r--include/llvm/ADT/SmallPtrSet.h16
-rw-r--r--include/llvm/ADT/SmallVector.h24
-rw-r--r--include/llvm/ADT/SparseBitVector.h21
-rw-r--r--include/llvm/ADT/StringRef.h39
-rw-r--r--include/llvm/ADT/TinyPtrVector.h35
-rw-r--r--include/llvm/ADT/Triple.h1
-rw-r--r--include/llvm/ADT/ilist.h4
-rw-r--r--include/llvm/Analysis/CFGPrinter.h5
-rw-r--r--include/llvm/Analysis/CodeMetrics.h77
-rw-r--r--include/llvm/Analysis/IVUsers.h3
-rw-r--r--include/llvm/Analysis/InlineCost.h47
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h16
-rw-r--r--include/llvm/Analysis/Loads.h8
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h2
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h12
-rw-r--r--include/llvm/CodeGen/DFAPacketizer.h3
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h4
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h4
-rw-r--r--include/llvm/CodeGen/MachineInstr.h26
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h91
-rw-r--r--include/llvm/CodeGen/Passes.h9
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h6
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h66
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h340
-rw-r--r--include/llvm/Config/config.h.cmake9
-rw-r--r--include/llvm/Config/config.h.in9
-rw-r--r--include/llvm/DerivedTypes.h8
-rw-r--r--include/llvm/ExecutionEngine/IntelJITEventsWrapper.h102
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h42
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h11
-rw-r--r--include/llvm/ExecutionEngine/OProfileWrapper.h124
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h12
-rw-r--r--include/llvm/Function.h2
-rw-r--r--include/llvm/Instructions.h246
-rw-r--r--include/llvm/MC/MCInstrDesc.h24
-rw-r--r--include/llvm/MC/MCRegisterInfo.h14
-rw-r--r--include/llvm/Object/Archive.h2
-rw-r--r--include/llvm/Object/Binary.h51
-rw-r--r--include/llvm/Object/COFF.h8
-rw-r--r--include/llvm/Object/ELF.h375
-rw-r--r--include/llvm/Object/MachO.h2
-rw-r--r--include/llvm/Object/ObjectFile.h3
-rw-r--r--include/llvm/Support/Compiler.h18
-rw-r--r--include/llvm/Support/DataTypes.h.cmake3
-rw-r--r--include/llvm/Support/ELF.h38
-rw-r--r--include/llvm/Support/InstVisitor.h83
-rw-r--r--include/llvm/Support/MachO.h4
-rw-r--r--include/llvm/Support/type_traits.h34
-rw-r--r--include/llvm/Target/TargetLowering.h12
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h12
-rw-r--r--include/llvm/Transforms/Utils/BasicInliner.h55
-rw-r--r--include/llvm/Value.h24
74 files changed, 3548 insertions, 612 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..5c5e4a1 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -734,15 +734,14 @@ 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_ATTRIBUTES= 0x6ffffff5, // Object attributes.
+ SHT_GNU_HASH = 0x6ffffff6, // GNU style dynamic hash table.
+ 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.
- SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
- SHT_GNU_HASH = 0x6ffffff6, // GNU style dynamic hash table.
- SHT_GNU_verdef = 0x6ffffffd, // Versions defined by file.
- SHT_GNU_verneed = 0x6ffffffe, // Versions needed by file.
- SHT_GNU_versym = 0x6fffffff, // Symbol versions.
-
// Fixme: All this is duplicated in MCSectionELF. Why??
// Exception Index table
SHT_ARM_EXIDX = 0x70000001U,
@@ -1109,6 +1108,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;