Upgrade our copy of llvm/clang to 3.3 release.
Release notes are still in the works, these will follow soon. MFC after: 1 month
This commit is contained in:
commit
284c197886
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251662
@ -18,13 +18,6 @@
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
|
||||
and 'unwrap' conversion functions. */
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/PassRegistry.h"
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -60,11 +53,6 @@ extern "C" {
|
||||
* 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.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -352,6 +340,63 @@ typedef enum {
|
||||
LLVMLandingPadFilter /**< A filter clause */
|
||||
} LLVMLandingPadClauseTy;
|
||||
|
||||
typedef enum {
|
||||
LLVMNotThreadLocal = 0,
|
||||
LLVMGeneralDynamicTLSModel,
|
||||
LLVMLocalDynamicTLSModel,
|
||||
LLVMInitialExecTLSModel,
|
||||
LLVMLocalExecTLSModel
|
||||
} LLVMThreadLocalMode;
|
||||
|
||||
typedef enum {
|
||||
LLVMAtomicOrderingNotAtomic = 0, /**< A load or store which is not atomic */
|
||||
LLVMAtomicOrderingUnordered = 1, /**< Lowest level of atomicity, guarantees
|
||||
somewhat sane results, lock free. */
|
||||
LLVMAtomicOrderingMonotonic = 2, /**< guarantees that if you take all the
|
||||
operations affecting a specific address,
|
||||
a consistent ordering exists */
|
||||
LLVMAtomicOrderingAcquire = 4, /**< Acquire provides a barrier of the sort
|
||||
necessary to acquire a lock to access other
|
||||
memory with normal loads and stores. */
|
||||
LLVMAtomicOrderingRelease = 5, /**< Release is similar to Acquire, but with
|
||||
a barrier of the sort necessary to release
|
||||
a lock. */
|
||||
LLVMAtomicOrderingAcquireRelease = 6, /**< provides both an Acquire and a
|
||||
Release barrier (for fences and
|
||||
operations which both read and write
|
||||
memory). */
|
||||
LLVMAtomicOrderingSequentiallyConsistent = 7 /**< provides Acquire semantics
|
||||
for loads and Release
|
||||
semantics for stores.
|
||||
Additionally, it guarantees
|
||||
that a total ordering exists
|
||||
between all
|
||||
SequentiallyConsistent
|
||||
operations. */
|
||||
} LLVMAtomicOrdering;
|
||||
|
||||
typedef enum {
|
||||
LLVMAtomicRMWBinOpXchg, /**< Set the new value and return the one old */
|
||||
LLVMAtomicRMWBinOpAdd, /**< Add a value and return the old one */
|
||||
LLVMAtomicRMWBinOpSub, /**< Subtract a value and return the old one */
|
||||
LLVMAtomicRMWBinOpAnd, /**< And a value and return the old one */
|
||||
LLVMAtomicRMWBinOpNand, /**< Not-And a value and return the old one */
|
||||
LLVMAtomicRMWBinOpOr, /**< OR a value and return the old one */
|
||||
LLVMAtomicRMWBinOpXor, /**< Xor a value and return the old one */
|
||||
LLVMAtomicRMWBinOpMax, /**< Sets the value if it's greater than the
|
||||
original using a signed comparison and return
|
||||
the old one */
|
||||
LLVMAtomicRMWBinOpMin, /**< Sets the value if it's Smaller than the
|
||||
original using a signed comparison and return
|
||||
the old one */
|
||||
LLVMAtomicRMWBinOpUMax, /**< Sets the value if it's greater than the
|
||||
original using an unsigned comparison and return
|
||||
the old one */
|
||||
LLVMAtomicRMWBinOpUMin /**< Sets the value if it's greater than the
|
||||
original using an unsigned comparison and return
|
||||
the old one */
|
||||
} LLVMAtomicRMWBinOp;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@ -1057,24 +1102,24 @@ LLVMTypeRef LLVMX86MMXType(void);
|
||||
macro(SwitchInst) \
|
||||
macro(UnreachableInst) \
|
||||
macro(ResumeInst) \
|
||||
macro(UnaryInstruction) \
|
||||
macro(AllocaInst) \
|
||||
macro(CastInst) \
|
||||
macro(BitCastInst) \
|
||||
macro(FPExtInst) \
|
||||
macro(FPToSIInst) \
|
||||
macro(FPToUIInst) \
|
||||
macro(FPTruncInst) \
|
||||
macro(IntToPtrInst) \
|
||||
macro(PtrToIntInst) \
|
||||
macro(SExtInst) \
|
||||
macro(SIToFPInst) \
|
||||
macro(TruncInst) \
|
||||
macro(UIToFPInst) \
|
||||
macro(ZExtInst) \
|
||||
macro(ExtractValueInst) \
|
||||
macro(LoadInst) \
|
||||
macro(VAArgInst)
|
||||
macro(UnaryInstruction) \
|
||||
macro(AllocaInst) \
|
||||
macro(CastInst) \
|
||||
macro(BitCastInst) \
|
||||
macro(FPExtInst) \
|
||||
macro(FPToSIInst) \
|
||||
macro(FPToUIInst) \
|
||||
macro(FPTruncInst) \
|
||||
macro(IntToPtrInst) \
|
||||
macro(PtrToIntInst) \
|
||||
macro(SExtInst) \
|
||||
macro(SIToFPInst) \
|
||||
macro(TruncInst) \
|
||||
macro(UIToFPInst) \
|
||||
macro(ZExtInst) \
|
||||
macro(ExtractValueInst) \
|
||||
macro(LoadInst) \
|
||||
macro(VAArgInst)
|
||||
|
||||
/**
|
||||
* @defgroup LLVMCCoreValueGeneral General APIs
|
||||
@ -1606,6 +1651,10 @@ LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar);
|
||||
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal);
|
||||
LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
|
||||
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant);
|
||||
LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar);
|
||||
void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode);
|
||||
LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar);
|
||||
void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -1693,6 +1742,13 @@ void LLVMSetGC(LLVMValueRef Fn, const char *Name);
|
||||
*/
|
||||
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);
|
||||
|
||||
/**
|
||||
* Add a target-dependent attribute to a fuction
|
||||
* @see llvm::AttrBuilder::addAttribute()
|
||||
*/
|
||||
void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A,
|
||||
const char *V);
|
||||
|
||||
/**
|
||||
* Obtain an attribute from a function.
|
||||
*
|
||||
@ -2515,6 +2571,10 @@ LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
|
||||
LLVMValueRef RHS, const char *Name);
|
||||
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op,
|
||||
LLVMValueRef PTR, LLVMValueRef Val,
|
||||
LLVMAtomicOrdering ordering,
|
||||
LLVMBool singleThread);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -2560,6 +2620,8 @@ LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData,
|
||||
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData,
|
||||
size_t InputDataLength,
|
||||
const char *BufferName);
|
||||
const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf);
|
||||
size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf);
|
||||
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
|
||||
|
||||
/**
|
||||
@ -2669,100 +2731,6 @@ LLVMBool LLVMIsMultithreaded();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class PassManagerBase;
|
||||
|
||||
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
inline ty *unwrap(ref P) { \
|
||||
return reinterpret_cast<ty*>(P); \
|
||||
} \
|
||||
\
|
||||
inline ref wrap(const ty *P) { \
|
||||
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
|
||||
}
|
||||
|
||||
#define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
\
|
||||
template<typename T> \
|
||||
inline T *unwrap(ref P) { \
|
||||
return cast<T>(unwrap(P)); \
|
||||
}
|
||||
|
||||
#define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
\
|
||||
template<typename T> \
|
||||
inline T *unwrap(ref P) { \
|
||||
T *Q = (T*)unwrap(P); \
|
||||
assert(Q && "Invalid cast!"); \
|
||||
return Q; \
|
||||
}
|
||||
|
||||
DEFINE_ISA_CONVERSION_FUNCTIONS (Type, LLVMTypeRef )
|
||||
DEFINE_ISA_CONVERSION_FUNCTIONS (Value, LLVMValueRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef )
|
||||
/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
|
||||
* Module.
|
||||
*/
|
||||
inline Module *unwrap(LLVMModuleProviderRef MP) {
|
||||
return reinterpret_cast<Module*>(MP);
|
||||
}
|
||||
|
||||
#undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
|
||||
#undef DEFINE_ISA_CONVERSION_FUNCTIONS
|
||||
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
|
||||
|
||||
/* Specialized opaque context conversions.
|
||||
*/
|
||||
inline LLVMContext **unwrap(LLVMContextRef* Tys) {
|
||||
return reinterpret_cast<LLVMContext**>(Tys);
|
||||
}
|
||||
|
||||
inline LLVMContextRef *wrap(const LLVMContext **Tys) {
|
||||
return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
|
||||
}
|
||||
|
||||
/* Specialized opaque type conversions.
|
||||
*/
|
||||
inline Type **unwrap(LLVMTypeRef* Tys) {
|
||||
return reinterpret_cast<Type**>(Tys);
|
||||
}
|
||||
|
||||
inline LLVMTypeRef *wrap(Type **Tys) {
|
||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
|
||||
}
|
||||
|
||||
/* Specialized opaque value conversions.
|
||||
*/
|
||||
inline Value **unwrap(LLVMValueRef *Vals) {
|
||||
return reinterpret_cast<Value**>(Vals);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
|
||||
#ifdef DEBUG
|
||||
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
|
||||
cast<T>(*I);
|
||||
#endif
|
||||
(void)Length;
|
||||
return reinterpret_cast<T**>(Vals);
|
||||
}
|
||||
|
||||
inline LLVMValueRef *wrap(const Value **Vals) {
|
||||
return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined(__cplusplus) */
|
||||
|
||||
#endif /* !defined(LLVM_C_CORE_H) */
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm-c/Target.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -34,11 +35,19 @@ extern "C" {
|
||||
*/
|
||||
|
||||
void LLVMLinkInJIT(void);
|
||||
void LLVMLinkInMCJIT(void);
|
||||
void LLVMLinkInInterpreter(void);
|
||||
|
||||
typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
|
||||
typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
|
||||
|
||||
struct LLVMMCJITCompilerOptions {
|
||||
unsigned OptLevel;
|
||||
LLVMCodeModel CodeModel;
|
||||
LLVMBool NoFramePointerElim;
|
||||
LLVMBool EnableFastISel;
|
||||
};
|
||||
|
||||
/*===-- Operations on generic values --------------------------------------===*/
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
|
||||
@ -75,6 +84,31 @@ LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
unsigned OptLevel,
|
||||
char **OutError);
|
||||
|
||||
void LLVMInitializeMCJITCompilerOptions(
|
||||
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions);
|
||||
|
||||
/**
|
||||
* Create an MCJIT execution engine for a module, with the given options. It is
|
||||
* the responsibility of the caller to ensure that all fields in Options up to
|
||||
* the given SizeOfOptions are initialized. It is correct to pass a smaller
|
||||
* value of SizeOfOptions that omits some fields. The canonical way of using
|
||||
* this is:
|
||||
*
|
||||
* LLVMMCJITCompilerOptions options;
|
||||
* LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
|
||||
* ... fill in those options you care about
|
||||
* LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options),
|
||||
* &error);
|
||||
*
|
||||
* Note that this is also correct, though possibly suboptimal:
|
||||
*
|
||||
* LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error);
|
||||
*/
|
||||
LLVMBool LLVMCreateMCJITCompilerForModule(
|
||||
LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
|
||||
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions,
|
||||
char **OutError);
|
||||
|
||||
/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */
|
||||
LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleProviderRef MP,
|
||||
@ -123,7 +157,8 @@ LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
|
||||
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
||||
LLVMValueRef *OutFn);
|
||||
|
||||
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn);
|
||||
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
|
||||
LLVMValueRef Fn);
|
||||
|
||||
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
|
||||
|
||||
@ -137,27 +172,7 @@ void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global);
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
struct GenericValue;
|
||||
class ExecutionEngine;
|
||||
|
||||
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
inline ty *unwrap(ref P) { \
|
||||
return reinterpret_cast<ty*>(P); \
|
||||
} \
|
||||
\
|
||||
inline ref wrap(const ty *P) { \
|
||||
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
|
||||
|
||||
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -99,50 +97,6 @@ const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
|
||||
return reinterpret_cast<ObjectFile*>(OF);
|
||||
}
|
||||
|
||||
inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
|
||||
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
|
||||
}
|
||||
|
||||
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
|
||||
return reinterpret_cast<section_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMSectionIteratorRef
|
||||
wrap(const section_iterator *SI) {
|
||||
return reinterpret_cast<LLVMSectionIteratorRef>
|
||||
(const_cast<section_iterator*>(SI));
|
||||
}
|
||||
|
||||
inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
|
||||
return reinterpret_cast<symbol_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMSymbolIteratorRef
|
||||
wrap(const symbol_iterator *SI) {
|
||||
return reinterpret_cast<LLVMSymbolIteratorRef>
|
||||
(const_cast<symbol_iterator*>(SI));
|
||||
}
|
||||
|
||||
inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
|
||||
return reinterpret_cast<relocation_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMRelocationIteratorRef
|
||||
wrap(const relocation_iterator *SI) {
|
||||
return reinterpret_cast<LLVMRelocationIteratorRef>
|
||||
(const_cast<relocation_iterator*>(SI));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
||||
|
@ -235,29 +235,6 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
class DataLayout;
|
||||
class TargetLibraryInfo;
|
||||
|
||||
inline DataLayout *unwrap(LLVMTargetDataRef P) {
|
||||
return reinterpret_cast<DataLayout*>(P);
|
||||
}
|
||||
|
||||
inline LLVMTargetDataRef wrap(const DataLayout *P) {
|
||||
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
|
||||
}
|
||||
|
||||
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
|
||||
return reinterpret_cast<TargetLibraryInfo*>(P);
|
||||
}
|
||||
|
||||
inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
|
||||
TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
|
||||
return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
||||
|
@ -25,7 +25,7 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct LLVMTargetMachine *LLVMTargetMachineRef;
|
||||
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
|
||||
typedef struct LLVMTarget *LLVMTargetRef;
|
||||
|
||||
typedef enum {
|
||||
@ -114,30 +114,11 @@ LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
|
||||
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
|
||||
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
|
||||
|
||||
|
||||
|
||||
|
||||
/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */
|
||||
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
|
||||
LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
class TargetMachine;
|
||||
class Target;
|
||||
|
||||
inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
|
||||
return reinterpret_cast<TargetMachine*>(P);
|
||||
}
|
||||
inline Target *unwrap(LLVMTargetRef P) {
|
||||
return reinterpret_cast<Target*>(P);
|
||||
}
|
||||
inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
|
||||
return reinterpret_cast<LLVMTargetMachineRef>(
|
||||
const_cast<TargetMachine*>(P));
|
||||
}
|
||||
inline LLVMTargetRef wrap(const Target * P) {
|
||||
return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -86,16 +86,6 @@ void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
|
||||
return reinterpret_cast<PassManagerBuilder*>(P);
|
||||
}
|
||||
|
||||
inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
|
||||
return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,9 @@ void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
|
||||
/** See llvm::createLoopVectorizePass function. */
|
||||
void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createSLPVectorizerPass function. */
|
||||
void LLVMAddSLPVectorizePass(LLVMPassManagerRef PM);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_ADT_ARRAYREF_H
|
||||
#define LLVM_ADT_ARRAYREF_H
|
||||
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <vector>
|
||||
|
||||
@ -49,6 +50,9 @@ namespace llvm {
|
||||
/// Construct an empty ArrayRef.
|
||||
/*implicit*/ ArrayRef() : Data(0), Length(0) {}
|
||||
|
||||
/// Construct an empty ArrayRef from None.
|
||||
/*implicit*/ ArrayRef(NoneType) : Data(0), Length(0) {}
|
||||
|
||||
/// Construct an ArrayRef from a single element.
|
||||
/*implicit*/ ArrayRef(const T &OneElt)
|
||||
: Data(&OneElt), Length(1) {}
|
||||
@ -174,9 +178,12 @@ namespace llvm {
|
||||
public:
|
||||
typedef T *iterator;
|
||||
|
||||
/// Construct an empty ArrayRef.
|
||||
/// Construct an empty MutableArrayRef.
|
||||
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
|
||||
|
||||
/// Construct an empty MutableArrayRef from None.
|
||||
/*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
|
||||
|
||||
/// Construct an MutableArrayRef from a single element.
|
||||
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
|
||||
|
||||
|
@ -618,7 +618,7 @@ class DenseMap
|
||||
unsigned OldNumBuckets = NumBuckets;
|
||||
BucketT *OldBuckets = Buckets;
|
||||
|
||||
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast-1)));
|
||||
allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
|
||||
assert(Buckets);
|
||||
if (!OldBuckets) {
|
||||
this->BaseT::initEmpty();
|
||||
|
@ -151,7 +151,7 @@ namespace detail {
|
||||
inline uint64_t fetch64(const char *p) {
|
||||
uint64_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
if (sys::isBigEndianHost())
|
||||
if (sys::IsBigEndianHost)
|
||||
return sys::SwapByteOrder(result);
|
||||
return result;
|
||||
}
|
||||
@ -159,7 +159,7 @@ inline uint64_t fetch64(const char *p) {
|
||||
inline uint32_t fetch32(const char *p) {
|
||||
uint32_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
if (sys::isBigEndianHost())
|
||||
if (sys::IsBigEndianHost)
|
||||
return sys::SwapByteOrder(result);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_INMEMORYSTRUCT_H
|
||||
#define LLVM_ADT_INMEMORYSTRUCT_H
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief Helper object for abstracting access to an in-memory structure which
|
||||
/// may require some kind of temporary storage.
|
||||
///
|
||||
/// This class is designed to be used for accessing file data structures which
|
||||
/// in the common case can be accessed from a direct pointer to a memory mapped
|
||||
/// object, but which in some cases may require indirect access to a temporary
|
||||
/// structure (which, for example, may have undergone endianness translation).
|
||||
template<typename T>
|
||||
class InMemoryStruct {
|
||||
typedef T value_type;
|
||||
typedef value_type &reference;
|
||||
typedef value_type *pointer;
|
||||
typedef const value_type &const_reference;
|
||||
typedef const value_type *const_pointer;
|
||||
|
||||
/// \brief The smart pointer target.
|
||||
value_type *Target;
|
||||
|
||||
/// \brief A temporary object which can be used as a target of the smart
|
||||
/// pointer.
|
||||
value_type Contents;
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
InMemoryStruct() : Target(0) {}
|
||||
InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {}
|
||||
InMemoryStruct(pointer Value) : Target(Value) {}
|
||||
InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; }
|
||||
|
||||
void operator=(const InMemoryStruct<T> &Value) {
|
||||
if (Value.Target != &Value.Contents) {
|
||||
Target = Value.Target;
|
||||
} else {
|
||||
Target = &Contents;
|
||||
Contents = Value.Contents;
|
||||
}
|
||||
}
|
||||
|
||||
const_reference operator*() const {
|
||||
assert(Target && "Cannot dereference null pointer");
|
||||
return *Target;
|
||||
}
|
||||
reference operator*() {
|
||||
assert(Target && "Cannot dereference null pointer");
|
||||
return *Target;
|
||||
}
|
||||
|
||||
const_pointer operator->() const {
|
||||
return Target;
|
||||
}
|
||||
pointer operator->() {
|
||||
return Target;
|
||||
}
|
||||
|
||||
operator bool() const { return Target != 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -29,7 +29,7 @@ struct DenseMapInfo;
|
||||
/// on the number of bits available according to PointerLikeTypeTraits for the
|
||||
/// type.
|
||||
///
|
||||
/// Note that PointerIntPair always puts the Int part in the highest bits
|
||||
/// Note that PointerIntPair always puts the IntVal part in the highest bits
|
||||
/// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
|
||||
/// the bool into bit #2, not bit #0, which allows the low two bits to be used
|
||||
/// for something else. For example, this allows:
|
||||
@ -57,13 +57,13 @@ class PointerIntPair {
|
||||
};
|
||||
public:
|
||||
PointerIntPair() : Value(0) {}
|
||||
PointerIntPair(PointerTy Ptr, IntType Int) {
|
||||
PointerIntPair(PointerTy PtrVal, IntType IntVal) {
|
||||
assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
|
||||
"PointerIntPair formed with integer size too large for pointer");
|
||||
setPointerAndInt(Ptr, Int);
|
||||
setPointerAndInt(PtrVal, IntVal);
|
||||
}
|
||||
explicit PointerIntPair(PointerTy Ptr) {
|
||||
initWithPointer(Ptr);
|
||||
explicit PointerIntPair(PointerTy PtrVal) {
|
||||
initWithPointer(PtrVal);
|
||||
}
|
||||
|
||||
PointerTy getPointer() const {
|
||||
@ -75,41 +75,41 @@ class PointerIntPair {
|
||||
return (IntType)((Value >> IntShift) & IntMask);
|
||||
}
|
||||
|
||||
void setPointer(PointerTy Ptr) {
|
||||
intptr_t PtrVal
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
|
||||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
void setPointer(PointerTy PtrVal) {
|
||||
intptr_t PtrWord
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
|
||||
assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
"Pointer is not sufficiently aligned");
|
||||
// Preserve all low bits, just update the pointer.
|
||||
Value = PtrVal | (Value & ~PointerBitMask);
|
||||
Value = PtrWord | (Value & ~PointerBitMask);
|
||||
}
|
||||
|
||||
void setInt(IntType Int) {
|
||||
intptr_t IntVal = Int;
|
||||
assert(IntVal < (1 << IntBits) && "Integer too large for field");
|
||||
void setInt(IntType IntVal) {
|
||||
intptr_t IntWord = static_cast<intptr_t>(IntVal);
|
||||
assert(IntWord < (1 << IntBits) && "Integer too large for field");
|
||||
|
||||
// Preserve all bits other than the ones we are updating.
|
||||
Value &= ~ShiftedIntMask; // Remove integer field.
|
||||
Value |= IntVal << IntShift; // Set new integer.
|
||||
Value |= IntWord << IntShift; // Set new integer.
|
||||
}
|
||||
|
||||
void initWithPointer(PointerTy Ptr) {
|
||||
intptr_t PtrVal
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
|
||||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
void initWithPointer(PointerTy PtrVal) {
|
||||
intptr_t PtrWord
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
|
||||
assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
"Pointer is not sufficiently aligned");
|
||||
Value = PtrVal;
|
||||
Value = PtrWord;
|
||||
}
|
||||
|
||||
void setPointerAndInt(PointerTy Ptr, IntType Int) {
|
||||
intptr_t PtrVal
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
|
||||
assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
|
||||
intptr_t PtrWord
|
||||
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
|
||||
assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
|
||||
"Pointer is not sufficiently aligned");
|
||||
intptr_t IntVal = Int;
|
||||
assert(IntVal < (1 << IntBits) && "Integer too large for field");
|
||||
intptr_t IntWord = static_cast<intptr_t>(IntVal);
|
||||
assert(IntWord < (1 << IntBits) && "Integer too large for field");
|
||||
|
||||
Value = PtrVal | (IntVal << IntShift);
|
||||
Value = PtrWord | (IntWord << IntShift);
|
||||
}
|
||||
|
||||
PointerTy const *getAddrOfPointer() const {
|
||||
|
@ -260,7 +260,7 @@ namespace llvm {
|
||||
|
||||
/// Find the first character in the string that is \p C, or npos if not
|
||||
/// found. Same as find.
|
||||
size_type find_first_of(char C, size_t From = 0) const {
|
||||
size_t find_first_of(char C, size_t From = 0) const {
|
||||
return find(C, From);
|
||||
}
|
||||
|
||||
@ -268,21 +268,21 @@ namespace llvm {
|
||||
/// not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_type find_first_of(StringRef Chars, size_t From = 0) const;
|
||||
size_t find_first_of(StringRef Chars, size_t From = 0) const;
|
||||
|
||||
/// Find the first character in the string that is not \p C or npos if not
|
||||
/// found.
|
||||
size_type find_first_not_of(char C, size_t From = 0) const;
|
||||
size_t find_first_not_of(char C, size_t From = 0) const;
|
||||
|
||||
/// Find the first character in the string that is not in the string
|
||||
/// \p Chars, or npos if not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
|
||||
size_t find_first_not_of(StringRef Chars, size_t From = 0) const;
|
||||
|
||||
/// Find the last character in the string that is \p C, or npos if not
|
||||
/// found.
|
||||
size_type find_last_of(char C, size_t From = npos) const {
|
||||
size_t find_last_of(char C, size_t From = npos) const {
|
||||
return rfind(C, From);
|
||||
}
|
||||
|
||||
@ -290,17 +290,17 @@ namespace llvm {
|
||||
/// found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_type find_last_of(StringRef Chars, size_t From = npos) const;
|
||||
size_t find_last_of(StringRef Chars, size_t From = npos) const;
|
||||
|
||||
/// Find the last character in the string that is not \p C, or npos if not
|
||||
/// found.
|
||||
size_type find_last_not_of(char C, size_t From = npos) const;
|
||||
size_t find_last_not_of(char C, size_t From = npos) const;
|
||||
|
||||
/// Find the last character in the string that is not in \p Chars, or
|
||||
/// npos if not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_type find_last_not_of(StringRef Chars, size_t From = npos) const;
|
||||
size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
|
||||
|
||||
/// @}
|
||||
/// @name Helpful Algorithms
|
||||
@ -390,14 +390,14 @@ namespace llvm {
|
||||
|
||||
/// Return a StringRef equal to 'this' but with the first \p N elements
|
||||
/// dropped.
|
||||
StringRef drop_front(unsigned N = 1) const {
|
||||
StringRef drop_front(size_t N = 1) const {
|
||||
assert(size() >= N && "Dropping more elements than exist");
|
||||
return substr(N);
|
||||
}
|
||||
|
||||
/// Return a StringRef equal to 'this' but with the last \p N elements
|
||||
/// dropped.
|
||||
StringRef drop_back(unsigned N = 1) const {
|
||||
StringRef drop_back(size_t N = 1) const {
|
||||
assert(size() >= N && "Dropping more elements than exist");
|
||||
return substr(0, size()-N);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class Triple {
|
||||
enum ArchType {
|
||||
UnknownArch,
|
||||
|
||||
arm, // ARM; arm, armv.*, xscale
|
||||
arm, // ARM: arm, armv.*, xscale
|
||||
aarch64, // AArch64: aarch64
|
||||
hexagon, // Hexagon: hexagon
|
||||
mips, // MIPS: mips, mipsallegrex
|
||||
@ -56,6 +56,7 @@ class Triple {
|
||||
r600, // R600: AMD GPUs HD2XXX - HD6XXX
|
||||
sparc, // Sparc: sparc
|
||||
sparcv9, // Sparcv9: Sparcv9
|
||||
systemz, // SystemZ: s390x
|
||||
tce, // TCE (http://tce.cs.tut.fi/): tce
|
||||
thumb, // Thumb: thumb, thumbv.*
|
||||
x86, // X86: i[3-9]86
|
||||
|
@ -236,7 +236,7 @@ namespace llvm {
|
||||
/// getLHSKind - Get the NodeKind of the left-hand side.
|
||||
NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
|
||||
|
||||
/// getRHSKind - Get the NodeKind of the left-hand side.
|
||||
/// getRHSKind - Get the NodeKind of the right-hand side.
|
||||
NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
|
||||
|
||||
/// printOneChild - Print one child from a twine.
|
||||
|
@ -146,14 +146,6 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
|
||||
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
|
||||
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
|
||||
|
||||
/// \brief Compute the size of the underlying object pointed by Ptr. Returns
|
||||
/// true and the object size in Size if successful, and false otherwise.
|
||||
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
|
||||
/// byval arguments, and global variables.
|
||||
bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
|
||||
const DataLayout *TD, const TargetLibraryInfo *TLI,
|
||||
bool RoundToAlign = false);
|
||||
|
||||
|
||||
|
||||
typedef std::pair<APInt, APInt> SizeOffsetType;
|
||||
@ -163,14 +155,12 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
|
||||
class ObjectSizeOffsetVisitor
|
||||
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
|
||||
|
||||
typedef DenseMap<const Value*, SizeOffsetType> CacheMapTy;
|
||||
|
||||
const DataLayout *TD;
|
||||
const TargetLibraryInfo *TLI;
|
||||
bool RoundToAlign;
|
||||
unsigned IntTyBits;
|
||||
APInt Zero;
|
||||
CacheMapTy CacheMap;
|
||||
SmallPtrSet<Instruction *, 8> SeenInsts;
|
||||
|
||||
APInt align(APInt Size, uint64_t Align);
|
||||
|
||||
|
@ -266,6 +266,24 @@ class Region : public RegionNode {
|
||||
/// @param BB The new exit basic block of the region.
|
||||
void replaceExit(BasicBlock *BB);
|
||||
|
||||
/// @brief Recursively replace the entry basic block of the region.
|
||||
///
|
||||
/// This function replaces the entry basic block with a new basic block. It
|
||||
/// also updates all child regions that have the same entry basic block as
|
||||
/// this region.
|
||||
///
|
||||
/// @param NewEntry The new entry basic block.
|
||||
void replaceEntryRecursive(BasicBlock *NewEntry);
|
||||
|
||||
/// @brief Recursively replace the exit basic block of the region.
|
||||
///
|
||||
/// This function replaces the exit basic block with a new basic block. It
|
||||
/// also updates all child regions that have the same exit basic block as
|
||||
/// this region.
|
||||
///
|
||||
/// @param NewExit The new exit basic block.
|
||||
void replaceExitRecursive(BasicBlock *NewExit);
|
||||
|
||||
/// @brief Get the exit BasicBlock of the Region.
|
||||
/// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
|
||||
/// Region.
|
||||
|
@ -453,7 +453,8 @@ namespace llvm {
|
||||
ExitLimit ComputeExitLimitFromCond(const Loop *L,
|
||||
Value *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB);
|
||||
BasicBlock *FBB,
|
||||
bool IsSubExpr);
|
||||
|
||||
/// ComputeExitLimitFromICmp - Compute the number of times the backedge of
|
||||
/// the specified loop will execute if its exit condition were a conditional
|
||||
@ -461,7 +462,8 @@ namespace llvm {
|
||||
ExitLimit ComputeExitLimitFromICmp(const Loop *L,
|
||||
ICmpInst *ExitCond,
|
||||
BasicBlock *TBB,
|
||||
BasicBlock *FBB);
|
||||
BasicBlock *FBB,
|
||||
bool IsSubExpr);
|
||||
|
||||
/// ComputeLoadConstantCompareExitLimit - Given an exit condition
|
||||
/// of 'icmp op load X, cst', try to see if we can compute the
|
||||
@ -483,7 +485,7 @@ namespace llvm {
|
||||
/// HowFarToZero - Return the number of times an exit condition comparing
|
||||
/// the specified value to zero will execute. If not computable, return
|
||||
/// CouldNotCompute.
|
||||
ExitLimit HowFarToZero(const SCEV *V, const Loop *L);
|
||||
ExitLimit HowFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr);
|
||||
|
||||
/// HowFarToNonZero - Return the number of times an exit condition checking
|
||||
/// the specified value for nonzero will execute. If not computable, return
|
||||
@ -495,7 +497,7 @@ namespace llvm {
|
||||
/// computable, return CouldNotCompute. isSigned specifies whether the
|
||||
/// less-than is signed.
|
||||
ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
const Loop *L, bool isSigned);
|
||||
const Loop *L, bool isSigned, bool IsSubExpr);
|
||||
|
||||
/// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB
|
||||
/// (which may not be an immediate predecessor) which has exactly one
|
||||
|
@ -25,6 +25,7 @@ namespace llvm {
|
||||
class BlockAddress;
|
||||
class GCStrategy;
|
||||
class Constant;
|
||||
class ConstantArray;
|
||||
class GCMetadataPrinter;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
@ -134,6 +135,9 @@ namespace llvm {
|
||||
/// getDataLayout - Return information about data layout.
|
||||
const DataLayout &getDataLayout() const;
|
||||
|
||||
/// getTargetTriple - Return the target triple string.
|
||||
StringRef getTargetTriple() const;
|
||||
|
||||
/// getCurrentSection() - Return the current section we are emitting to.
|
||||
const MCSection *getCurrentSection() const;
|
||||
|
||||
@ -480,7 +484,7 @@ namespace llvm {
|
||||
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||
const MachineBasicBlock *MBB,
|
||||
unsigned uid) const;
|
||||
void EmitLLVMUsedList(const Constant *List);
|
||||
void EmitLLVMUsedList(const ConstantArray *InitList);
|
||||
void EmitXXStructorList(const Constant *List, bool isCtor);
|
||||
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
|
||||
};
|
||||
|
@ -163,8 +163,56 @@ class CCState {
|
||||
|
||||
unsigned StackOffset;
|
||||
SmallVector<uint32_t, 16> UsedRegs;
|
||||
unsigned FirstByValReg;
|
||||
bool FirstByValRegValid;
|
||||
|
||||
// ByValInfo and SmallVector<ByValInfo, 4> ByValRegs:
|
||||
//
|
||||
// Vector of ByValInfo instances (ByValRegs) is introduced for byval registers
|
||||
// tracking.
|
||||
// Or, in another words it tracks byval parameters that are stored in
|
||||
// general purpose registers.
|
||||
//
|
||||
// For 4 byte stack alignment,
|
||||
// instance index means byval parameter number in formal
|
||||
// arguments set. Assume, we have some "struct_type" with size = 4 bytes,
|
||||
// then, for function "foo":
|
||||
//
|
||||
// i32 foo(i32 %p, %struct_type* %r, i32 %s, %struct_type* %t)
|
||||
//
|
||||
// ByValRegs[0] describes how "%r" is stored (Begin == r1, End == r2)
|
||||
// ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4).
|
||||
//
|
||||
// In case of 8 bytes stack alignment,
|
||||
// ByValRegs may also contain information about wasted registers.
|
||||
// In function shown above, r3 would be wasted according to AAPCS rules.
|
||||
// And in that case ByValRegs[1].Waste would be "true".
|
||||
// ByValRegs vector size still would be 2,
|
||||
// while "%t" goes to the stack: it wouldn't be described in ByValRegs.
|
||||
//
|
||||
// Supposed use-case for this collection:
|
||||
// 1. Initially ByValRegs is empty, InRegsParamsProceed is 0.
|
||||
// 2. HandleByVal fillups ByValRegs.
|
||||
// 3. Argument analysis (LowerFormatArguments, for example). After
|
||||
// some byval argument was analyzed, InRegsParamsProceed is increased.
|
||||
struct ByValInfo {
|
||||
ByValInfo(unsigned B, unsigned E, bool IsWaste = false) :
|
||||
Begin(B), End(E), Waste(IsWaste) {}
|
||||
// First register allocated for current parameter.
|
||||
unsigned Begin;
|
||||
|
||||
// First after last register allocated for current parameter.
|
||||
unsigned End;
|
||||
|
||||
// Means that current range of registers doesn't belong to any
|
||||
// parameters. It was wasted due to stack alignment rules.
|
||||
// For more information see:
|
||||
// AAPCS, 5.5 Parameter Passing, Stage C, C.3.
|
||||
bool Waste;
|
||||
};
|
||||
SmallVector<ByValInfo, 4 > ByValRegs;
|
||||
|
||||
// InRegsParamsProceed - shows how many instances of ByValRegs was proceed
|
||||
// during argument analysis.
|
||||
unsigned InRegsParamsProceed;
|
||||
|
||||
protected:
|
||||
ParmContext CallOrPrologue;
|
||||
@ -306,12 +354,45 @@ class CCState {
|
||||
MVT LocVT, CCValAssign::LocInfo LocInfo,
|
||||
int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
|
||||
|
||||
// First GPR that carries part of a byval aggregate that's split
|
||||
// between registers and memory.
|
||||
unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByValReg : 0; }
|
||||
void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; }
|
||||
void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; }
|
||||
bool isFirstByValRegValid() const { return FirstByValRegValid; }
|
||||
// Returns count of byval arguments that are to be stored (even partly)
|
||||
// in registers.
|
||||
unsigned getInRegsParamsCount() const { return ByValRegs.size(); }
|
||||
|
||||
// Returns count of byval in-regs arguments proceed.
|
||||
unsigned getInRegsParamsProceed() const { return InRegsParamsProceed; }
|
||||
|
||||
// Get information about N-th byval parameter that is stored in registers.
|
||||
// Here "ByValParamIndex" is N.
|
||||
void getInRegsParamInfo(unsigned InRegsParamRecordIndex,
|
||||
unsigned& BeginReg, unsigned& EndReg) const {
|
||||
assert(InRegsParamRecordIndex < ByValRegs.size() &&
|
||||
"Wrong ByVal parameter index");
|
||||
|
||||
const ByValInfo& info = ByValRegs[InRegsParamRecordIndex];
|
||||
BeginReg = info.Begin;
|
||||
EndReg = info.End;
|
||||
}
|
||||
|
||||
// Add information about parameter that is kept in registers.
|
||||
void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd) {
|
||||
ByValRegs.push_back(ByValInfo(RegBegin, RegEnd));
|
||||
}
|
||||
|
||||
// Goes either to next byval parameter (excluding "waste" record), or
|
||||
// to the end of collection.
|
||||
// Returns false, if end is reached.
|
||||
bool nextInRegsParam() {
|
||||
unsigned e = ByValRegs.size();
|
||||
if (InRegsParamsProceed < e)
|
||||
++InRegsParamsProceed;
|
||||
return InRegsParamsProceed < e;
|
||||
}
|
||||
|
||||
// Clear byval registers tracking info.
|
||||
void clearByValRegsInfo() {
|
||||
InRegsParamsProceed = 0;
|
||||
ByValRegs.clear();
|
||||
}
|
||||
|
||||
ParmContext getCallOrPrologue() const { return CallOrPrologue; }
|
||||
|
||||
|
@ -123,12 +123,28 @@ class FastISel {
|
||||
/// index value.
|
||||
std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
|
||||
|
||||
/// TryToFoldLoad - The specified machine instr operand is a vreg, and that
|
||||
/// \brief We're checking to see if we can fold \p LI into \p FoldInst.
|
||||
/// Note that we could have a sequence where multiple LLVM IR instructions
|
||||
/// are folded into the same machineinstr. For example we could have:
|
||||
/// A: x = load i32 *P
|
||||
/// B: y = icmp A, 42
|
||||
/// C: br y, ...
|
||||
///
|
||||
/// In this scenario, \p LI is "A", and \p FoldInst is "C". We know
|
||||
/// about "B" (and any other folded instructions) because it is between
|
||||
/// A and C.
|
||||
///
|
||||
/// If we succeed folding, return true.
|
||||
///
|
||||
bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst);
|
||||
|
||||
/// \brief The specified machine instr operand is a vreg, and that
|
||||
/// vreg is being provided by the specified load instruction. If possible,
|
||||
/// try to fold the load as an operand to the instruction, returning true if
|
||||
/// possible.
|
||||
virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/,
|
||||
const LoadInst * /*LI*/) {
|
||||
/// This method should be implemented by targets.
|
||||
virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/,
|
||||
const LoadInst * /*LI*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -602,14 +602,6 @@ namespace ISD {
|
||||
/// specifier.
|
||||
PREFETCH,
|
||||
|
||||
/// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
|
||||
/// store-store, device)
|
||||
/// This corresponds to the memory.barrier intrinsic.
|
||||
/// it takes an input chain, 4 operands to specify the type of barrier, an
|
||||
/// operand specifying if the barrier applies to device and uncached memory
|
||||
/// and produces an output chain.
|
||||
MEMBARRIER,
|
||||
|
||||
/// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
|
||||
/// This corresponds to the fence instruction. It takes an input chain, and
|
||||
/// two integer constants: an AtomicOrdering and a SynchronizationScope.
|
||||
|
@ -399,6 +399,15 @@ namespace llvm {
|
||||
return r != end() && r->containsRange(Start, End);
|
||||
}
|
||||
|
||||
/// True iff this live range is a single segment that lies between the
|
||||
/// specified boundaries, exclusively. Vregs live across a backedge are not
|
||||
/// considered local. The boundaries are expected to lie within an extended
|
||||
/// basic block, so vregs that are not live out should contain no holes.
|
||||
bool isLocal(SlotIndex Start, SlotIndex End) const {
|
||||
return beginIndex() > Start.getBaseIndex() &&
|
||||
endIndex() < End.getBoundaryIndex();
|
||||
}
|
||||
|
||||
/// removeRange - Remove the specified range from this interval. Note that
|
||||
/// the range must be a single LiveRange in its entirety.
|
||||
void removeRange(SlotIndex Start, SlotIndex End,
|
||||
|
@ -196,8 +196,7 @@ class LiveRangeEdit {
|
||||
/// allocator. These registers should not be split into new intervals
|
||||
/// as currently those new intervals are not guaranteed to spill.
|
||||
void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||
ArrayRef<unsigned> RegsBeingSpilled
|
||||
= ArrayRef<unsigned>());
|
||||
ArrayRef<unsigned> RegsBeingSpilled = None);
|
||||
|
||||
/// calculateRegClassAndHint - Recompute register class and hint for each new
|
||||
/// register.
|
||||
|
@ -71,7 +71,6 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
std::vector<MachineBasicBlock *> Predecessors;
|
||||
std::vector<MachineBasicBlock *> Successors;
|
||||
|
||||
|
||||
/// Weights - Keep track of the weights to the successors. This vector
|
||||
/// has the same order as Successors, or it is empty if we don't use it
|
||||
/// (disable optimization).
|
||||
@ -96,6 +95,10 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// target of an indirect branch.
|
||||
bool AddressTaken;
|
||||
|
||||
/// \brief since getSymbol is a relatively heavy-weight operation, the symbol
|
||||
/// is only computed once and is cached.
|
||||
mutable MCSymbol *CachedMCSymbol;
|
||||
|
||||
// Intrusive list support
|
||||
MachineBasicBlock() {}
|
||||
|
||||
|
@ -352,8 +352,8 @@ class MachineFunction {
|
||||
// Internal functions used to automatically number MachineBasicBlocks
|
||||
//
|
||||
|
||||
/// getNextMBBNumber - Returns the next unique number to be assigned
|
||||
/// to a MachineBasicBlock in this MachineFunction.
|
||||
/// \brief Adds the MBB to the internal numbering. Returns the unique number
|
||||
/// assigned to the MBB.
|
||||
///
|
||||
unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
|
||||
MBBNumbering.push_back(MBB);
|
||||
|
@ -34,22 +34,22 @@ struct MachinePointerInfo {
|
||||
/// If this is null, then the access is to a pointer in the default address
|
||||
/// space.
|
||||
const Value *V;
|
||||
|
||||
|
||||
/// Offset - This is an offset from the base Value*.
|
||||
int64_t Offset;
|
||||
|
||||
|
||||
explicit MachinePointerInfo(const Value *v = 0, int64_t offset = 0)
|
||||
: V(v), Offset(offset) {}
|
||||
|
||||
|
||||
MachinePointerInfo getWithOffset(int64_t O) const {
|
||||
if (V == 0) return MachinePointerInfo(0, 0);
|
||||
return MachinePointerInfo(V, Offset+O);
|
||||
}
|
||||
|
||||
|
||||
/// getAddrSpace - Return the LLVM IR address space number that this pointer
|
||||
/// points into.
|
||||
unsigned getAddrSpace() const;
|
||||
|
||||
|
||||
/// getConstantPool - Return a MachinePointerInfo record that refers to the
|
||||
/// constant pool.
|
||||
static MachinePointerInfo getConstantPool();
|
||||
@ -57,20 +57,20 @@ struct MachinePointerInfo {
|
||||
/// getFixedStack - Return a MachinePointerInfo record that refers to the
|
||||
/// the specified FrameIndex.
|
||||
static MachinePointerInfo getFixedStack(int FI, int64_t offset = 0);
|
||||
|
||||
|
||||
/// getJumpTable - Return a MachinePointerInfo record that refers to a
|
||||
/// jump table entry.
|
||||
static MachinePointerInfo getJumpTable();
|
||||
|
||||
|
||||
/// getGOT - Return a MachinePointerInfo record that refers to a
|
||||
/// GOT entry.
|
||||
static MachinePointerInfo getGOT();
|
||||
|
||||
|
||||
/// getStack - stack pointer relative access.
|
||||
static MachinePointerInfo getStack(int64_t Offset);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// MachineMemOperand - A description of a memory reference used in the backend.
|
||||
/// Instead of holding a StoreInst or LoadInst, this class holds the address
|
||||
@ -99,8 +99,11 @@ class MachineMemOperand {
|
||||
MONonTemporal = 8,
|
||||
/// The memory access is invariant.
|
||||
MOInvariant = 16,
|
||||
// Target hints allow target passes to annotate memory operations.
|
||||
MOTargetStartBit = 5,
|
||||
MOTargetNumBits = 3,
|
||||
// This is the number of bits we need to represent flags.
|
||||
MOMaxBits = 5
|
||||
MOMaxBits = 8
|
||||
};
|
||||
|
||||
/// MachineMemOperand - Construct an MachineMemOperand object with the
|
||||
@ -110,7 +113,7 @@ class MachineMemOperand {
|
||||
const MDNode *Ranges = 0);
|
||||
|
||||
const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
|
||||
|
||||
|
||||
/// getValue - Return the base address of the memory access. This may either
|
||||
/// be a normal LLVM IR Value, or one of the special values used in CodeGen.
|
||||
/// Special values are those obtained via
|
||||
@ -123,6 +126,9 @@ class MachineMemOperand {
|
||||
/// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
|
||||
unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
|
||||
|
||||
/// Bitwise OR the current flags with the given flags.
|
||||
void setFlags(unsigned f) { Flags |= (f & ((1 << MOMaxBits) - 1)); }
|
||||
|
||||
/// getOffset - For normal values, this is a byte offset added to the base
|
||||
/// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
|
||||
/// number.
|
||||
|
@ -157,6 +157,12 @@ class MachineRegisterInfo {
|
||||
// Strictly for use by MachineInstr.cpp.
|
||||
void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps);
|
||||
|
||||
/// Verify the sanity of the use list for Reg.
|
||||
void verifyUseList(unsigned Reg) const;
|
||||
|
||||
/// Verify the use list of all registers.
|
||||
void verifyUseLists() const;
|
||||
|
||||
/// reg_begin/reg_end - Provide iteration support to walk over all definitions
|
||||
/// and uses of a register within the MachineFunction that corresponds to this
|
||||
/// MachineRegisterInfo object.
|
||||
|
@ -274,6 +274,10 @@ class ScheduleDAGMI : public ScheduleDAGInstrs {
|
||||
Mutations.push_back(Mutation);
|
||||
}
|
||||
|
||||
/// \brief True if an edge can be added from PredSU to SuccSU without creating
|
||||
/// a cycle.
|
||||
bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
|
||||
|
||||
/// \brief Add a DAG edge to the given SU with the given predecessor
|
||||
/// dependence data.
|
||||
///
|
||||
@ -297,6 +301,10 @@ class ScheduleDAGMI : public ScheduleDAGInstrs {
|
||||
/// reorderable instructions.
|
||||
virtual void schedule();
|
||||
|
||||
/// Change the position of an instruction within the basic block and update
|
||||
/// live ranges and region boundary iterators.
|
||||
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
|
||||
|
||||
/// Get current register pressure for the top scheduled instructions.
|
||||
const IntervalPressure &getTopPressure() const { return TopPressure; }
|
||||
const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
|
||||
@ -362,7 +370,6 @@ class ScheduleDAGMI : public ScheduleDAGInstrs {
|
||||
|
||||
void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure);
|
||||
|
||||
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
|
||||
bool checkSchedLimit();
|
||||
|
||||
void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
|
||||
|
@ -260,9 +260,12 @@ class MachineTraceMetrics : public MachineFunctionPass {
|
||||
/// independent, exposing the maximum instruction-level parallelism.
|
||||
///
|
||||
/// Any blocks in Extrablocks are included as if they were part of the
|
||||
/// trace.
|
||||
unsigned getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks =
|
||||
ArrayRef<const MachineBasicBlock*>()) const;
|
||||
/// trace. Likewise, extra resources required by the specified scheduling
|
||||
/// classes are included. For the caller to account for extra machine
|
||||
/// instructions, it must first resolve each instruction's scheduling class.
|
||||
unsigned getResourceLength(
|
||||
ArrayRef<const MachineBasicBlock*> Extrablocks = None,
|
||||
ArrayRef<const MCSchedClassDesc*> ExtraInstrs = None) const;
|
||||
|
||||
/// Return the length of the (data dependency) critical path through the
|
||||
/// trace.
|
||||
|
@ -35,6 +35,48 @@ namespace llvm {
|
||||
|
||||
class PassConfigImpl;
|
||||
|
||||
/// Discriminated union of Pass ID types.
|
||||
///
|
||||
/// The PassConfig API prefers dealing with IDs because they are safer and more
|
||||
/// efficient. IDs decouple configuration from instantiation. This way, when a
|
||||
/// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to
|
||||
/// refer to a Pass pointer after adding it to a pass manager, which deletes
|
||||
/// redundant pass instances.
|
||||
///
|
||||
/// However, it is convient to directly instantiate target passes with
|
||||
/// non-default ctors. These often don't have a registered PassInfo. Rather than
|
||||
/// force all target passes to implement the pass registry boilerplate, allow
|
||||
/// the PassConfig API to handle either type.
|
||||
///
|
||||
/// AnalysisID is sadly char*, so PointerIntPair won't work.
|
||||
class IdentifyingPassPtr {
|
||||
union {
|
||||
AnalysisID ID;
|
||||
Pass *P;
|
||||
};
|
||||
bool IsInstance;
|
||||
public:
|
||||
IdentifyingPassPtr() : P(0), IsInstance(false) {}
|
||||
IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {}
|
||||
IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {}
|
||||
|
||||
bool isValid() const { return P; }
|
||||
bool isInstance() const { return IsInstance; }
|
||||
|
||||
AnalysisID getID() const {
|
||||
assert(!IsInstance && "Not a Pass ID");
|
||||
return ID;
|
||||
}
|
||||
Pass *getInstance() const {
|
||||
assert(IsInstance && "Not a Pass Instance");
|
||||
return P;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct isPodLike<IdentifyingPassPtr> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
/// Target-Independent Code Generator Pass Configuration Options.
|
||||
///
|
||||
/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
|
||||
@ -117,20 +159,22 @@ class TargetPassConfig : public ImmutablePass {
|
||||
/// Allow the target to override a specific pass without overriding the pass
|
||||
/// pipeline. When passes are added to the standard pipeline at the
|
||||
/// point where StandardID is expected, add TargetID in its place.
|
||||
void substitutePass(AnalysisID StandardID, AnalysisID TargetID);
|
||||
void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID);
|
||||
|
||||
/// Insert InsertedPassID pass after TargetPassID pass.
|
||||
void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID);
|
||||
void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID);
|
||||
|
||||
/// Allow the target to enable a specific standard pass by default.
|
||||
void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
|
||||
|
||||
/// Allow the target to disable a specific standard pass by default.
|
||||
void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); }
|
||||
void disablePass(AnalysisID PassID) {
|
||||
substitutePass(PassID, IdentifyingPassPtr());
|
||||
}
|
||||
|
||||
/// Return the pass substituted for StandardID by the target.
|
||||
/// If no substitution exists, return StandardID.
|
||||
AnalysisID getPassSubstitution(AnalysisID StandardID) const;
|
||||
IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;
|
||||
|
||||
/// Return true if the optimized regalloc pipeline is enabled.
|
||||
bool getOptimizeRegAlloc() const;
|
||||
@ -222,17 +266,6 @@ class TargetPassConfig : public ImmutablePass {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// addFinalizeRegAlloc - This method may be implemented by targets that want
|
||||
/// to run passes within the regalloc pipeline, immediately after the register
|
||||
/// allocation pass itself. These passes run as soon as virtual regisiters
|
||||
/// have been rewritten to physical registers but before and other postRA
|
||||
/// optimization happens. Targets that have marked instructions for bundling
|
||||
/// must have finalized those bundles by the time these passes have run,
|
||||
/// because subsequent passes are not guaranteed to be bundle-aware.
|
||||
virtual bool addFinalizeRegAlloc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// addPostRegAlloc - This method may be implemented by targets that want to
|
||||
/// run passes after register allocation pass pipeline but before
|
||||
/// prolog-epilog insertion. This should return true if -print-machineinstrs
|
||||
|
@ -29,6 +29,7 @@ namespace llvm {
|
||||
class MachineFunction;
|
||||
class MachineLoopInfo;
|
||||
class TargetRegisterInfo;
|
||||
template<class T> class OwningPtr;
|
||||
|
||||
/// This class wraps up a PBQP instance representing a register allocation
|
||||
/// problem, plus the structures necessary to map back from the PBQP solution
|
||||
@ -123,11 +124,9 @@ namespace llvm {
|
||||
|
||||
/// Build a PBQP instance to represent the register allocation problem for
|
||||
/// the given MachineFunction.
|
||||
virtual std::auto_ptr<PBQPRAProblem> build(
|
||||
MachineFunction *mf,
|
||||
const LiveIntervals *lis,
|
||||
const MachineLoopInfo *loopInfo,
|
||||
const RegSet &vregs);
|
||||
virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
|
||||
const MachineLoopInfo *loopInfo,
|
||||
const RegSet &vregs);
|
||||
private:
|
||||
|
||||
void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost);
|
||||
@ -144,11 +143,9 @@ namespace llvm {
|
||||
|
||||
/// Build a PBQP instance to represent the register allocation problem for
|
||||
/// the given MachineFunction.
|
||||
virtual std::auto_ptr<PBQPRAProblem> build(
|
||||
MachineFunction *mf,
|
||||
const LiveIntervals *lis,
|
||||
const MachineLoopInfo *loopInfo,
|
||||
const RegSet &vregs);
|
||||
virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
|
||||
const MachineLoopInfo *loopInfo,
|
||||
const RegSet &vregs);
|
||||
|
||||
private:
|
||||
|
||||
@ -161,7 +158,7 @@ namespace llvm {
|
||||
PBQP::PBQPNum benefit);
|
||||
};
|
||||
|
||||
FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder,
|
||||
FunctionPass* createPBQPRegisterAllocator(OwningPtr<PBQPBuilder> &builder,
|
||||
char *customPassID=0);
|
||||
}
|
||||
|
||||
|
@ -302,6 +302,7 @@ namespace llvm {
|
||||
bool isCallOp : 1; // Is a function call operand.
|
||||
bool isTwoAddress : 1; // Is a two-address instruction.
|
||||
bool isCommutable : 1; // Is a commutable instruction.
|
||||
bool hasPhysRegUses : 1; // Has physreg uses.
|
||||
bool hasPhysRegDefs : 1; // Has physreg defs that are being used.
|
||||
bool hasPhysRegClobbers : 1; // Has any physreg defs, used or not.
|
||||
bool isPending : 1; // True once pending.
|
||||
@ -331,10 +332,10 @@ namespace llvm {
|
||||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
|
||||
Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false), isPending(false), isAvailable(false),
|
||||
isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
|
||||
isCloned(false), SchedulingPref(Sched::None),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
|
||||
isAvailable(false), isScheduled(false), isScheduleHigh(false),
|
||||
isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||
|
||||
@ -345,10 +346,10 @@ namespace llvm {
|
||||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
|
||||
Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false), isPending(false), isAvailable(false),
|
||||
isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
|
||||
isCloned(false), SchedulingPref(Sched::None),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
|
||||
isAvailable(false), isScheduled(false), isScheduleHigh(false),
|
||||
isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||
|
||||
@ -358,10 +359,10 @@ namespace llvm {
|
||||
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
|
||||
Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false), isPending(false), isAvailable(false),
|
||||
isScheduled(false), isScheduleHigh(false), isScheduleLow(false),
|
||||
isCloned(false), SchedulingPref(Sched::None),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
|
||||
isAvailable(false), isScheduled(false), isScheduleHigh(false),
|
||||
isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||
|
||||
@ -726,9 +727,8 @@ namespace llvm {
|
||||
/// IsReachable - Checks if SU is reachable from TargetSU.
|
||||
bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
|
||||
|
||||
/// WillCreateCycle - Returns true if adding an edge from SU to TargetSU
|
||||
/// will create a cycle.
|
||||
bool WillCreateCycle(SUnit *SU, SUnit *TargetSU);
|
||||
/// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
|
||||
bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
|
||||
|
||||
/// AddPred - Updates the topological ordering to accommodate an edge
|
||||
/// to be added from SUnit X to SUnit Y.
|
||||
|
@ -105,6 +105,10 @@ namespace llvm {
|
||||
MachineBasicBlock::iterator RegionEnd;
|
||||
|
||||
/// The index in BB of RegionEnd.
|
||||
///
|
||||
/// This is the instruction number from the top of the current block, not
|
||||
/// the SlotIndex. It is only used by the AntiDepBreaker and should be
|
||||
/// removed once that client is obsolete.
|
||||
unsigned EndIndex;
|
||||
|
||||
/// After calling BuildSchedGraph, each machine instruction in the current
|
||||
@ -146,6 +150,9 @@ namespace llvm {
|
||||
|
||||
virtual ~ScheduleDAGInstrs() {}
|
||||
|
||||
/// \brief Expose LiveIntervals for use in DAG mutators and such.
|
||||
LiveIntervals *getLIS() const { return LIS; }
|
||||
|
||||
/// \brief Get the machine model for instruction scheduling.
|
||||
const TargetSchedModel *getSchedModel() const { return &SchedModel; }
|
||||
|
||||
|
@ -810,31 +810,32 @@ class SelectionDAG {
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
|
||||
SDValue Op1, SDValue Op2);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
|
||||
SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
ArrayRef<SDValue> Ops);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
SDValue Op1);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1,
|
||||
EVT VT2, SDValue Op1, SDValue Op2);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1,
|
||||
EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
SDValue Op1);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
SDValue Op1, SDValue Op2);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, SDValue Op1, SDValue Op2);
|
||||
SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
ArrayRef<SDValue> Ops);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, const SDValue *Ops, unsigned NumOps);
|
||||
EVT VT3, SDValue Op1, SDValue Op2);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, EVT VT4, const SDValue *Ops, unsigned NumOps);
|
||||
EVT VT3, SDValue Op1, SDValue Op2,
|
||||
SDValue Op3);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, ArrayRef<SDValue> Ops);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
|
||||
EVT VT3, EVT VT4, ArrayRef<SDValue> Ops);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl,
|
||||
ArrayRef<EVT> ResultTys, const SDValue *Ops,
|
||||
unsigned NumOps);
|
||||
ArrayRef<EVT> ResultTys,
|
||||
ArrayRef<SDValue> Ops);
|
||||
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
ArrayRef<SDValue> Ops);
|
||||
|
||||
/// getTargetExtractSubreg - A convenience function for creating
|
||||
/// TargetInstrInfo::EXTRACT_SUBREG nodes.
|
||||
|
@ -259,9 +259,6 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
void SelectBasicBlock(BasicBlock::const_iterator Begin,
|
||||
BasicBlock::const_iterator End,
|
||||
bool &HadTailCall);
|
||||
|
||||
bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst,
|
||||
FastISel *FastIS);
|
||||
void FinishBasicBlock();
|
||||
|
||||
void CodeGenAndEmitDAG();
|
||||
|
@ -53,6 +53,20 @@ namespace llvm {
|
||||
this->index = index;
|
||||
}
|
||||
|
||||
#ifdef EXPENSIVE_CHECKS
|
||||
// When EXPENSIVE_CHECKS is defined, "erased" index list entries will
|
||||
// actually be moved to a "graveyard" list, and have their pointers
|
||||
// poisoned, so that dangling SlotIndex access can be reliably detected.
|
||||
void setPoison() {
|
||||
intptr_t tmp = reinterpret_cast<intptr_t>(mi);
|
||||
assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?");
|
||||
tmp |= 0x1;
|
||||
mi = reinterpret_cast<MachineInstr*>(tmp);
|
||||
}
|
||||
|
||||
bool isPoisoned() const { return (reinterpret_cast<intptr_t>(mi) & 0x1) == 0x1; }
|
||||
#endif // EXPENSIVE_CHECKS
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -109,6 +123,10 @@ namespace llvm {
|
||||
|
||||
IndexListEntry* listEntry() const {
|
||||
assert(isValid() && "Attempt to compare reserved index.");
|
||||
#ifdef EXPENSIVE_CHECKS
|
||||
assert(!lie.getPointer()->isPoisoned() &&
|
||||
"Attempt to access deleted list-entry.");
|
||||
#endif // EXPENSIVE_CHECKS
|
||||
return lie.getPointer();
|
||||
}
|
||||
|
||||
@ -282,7 +300,6 @@ namespace llvm {
|
||||
|
||||
template <> struct isPodLike<SlotIndex> { static const bool value = true; };
|
||||
|
||||
|
||||
inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
|
||||
li.print(os);
|
||||
return os;
|
||||
@ -313,6 +330,10 @@ namespace llvm {
|
||||
typedef ilist<IndexListEntry> IndexList;
|
||||
IndexList indexList;
|
||||
|
||||
#ifdef EXPENSIVE_CHECKS
|
||||
IndexList graveyardList;
|
||||
#endif // EXPENSIVE_CHECKS
|
||||
|
||||
MachineFunction *mf;
|
||||
|
||||
typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
|
||||
@ -643,6 +664,32 @@ namespace llvm {
|
||||
std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
|
||||
}
|
||||
|
||||
/// \brief Free the resources that were required to maintain a SlotIndex.
|
||||
///
|
||||
/// Once an index is no longer needed (for instance because the instruction
|
||||
/// at that index has been moved), the resources required to maintain the
|
||||
/// index can be relinquished to reduce memory use and improve renumbering
|
||||
/// performance. Any remaining SlotIndex objects that point to the same
|
||||
/// index are left 'dangling' (much the same as a dangling pointer to a
|
||||
/// freed object) and should not be accessed, except to destruct them.
|
||||
///
|
||||
/// Like dangling pointers, access to dangling SlotIndexes can cause
|
||||
/// painful-to-track-down bugs, especially if the memory for the index
|
||||
/// previously pointed to has been re-used. To detect dangling SlotIndex
|
||||
/// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" indexes to
|
||||
/// be retained in a graveyard instead of being freed. Operations on indexes
|
||||
/// in the graveyard will trigger an assertion.
|
||||
void eraseIndex(SlotIndex index) {
|
||||
IndexListEntry *entry = index.listEntry();
|
||||
#ifdef EXPENSIVE_CHECKS
|
||||
indexList.remove(entry);
|
||||
graveyardList.push_back(entry);
|
||||
entry->setPoison();
|
||||
#else
|
||||
indexList.erase(entry);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -128,6 +128,12 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
|
||||
virtual const MCSection *
|
||||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
Mangler *Mang, const TargetMachine &TM) const;
|
||||
|
||||
/// emitModuleFlags - Emit Obj-C garbage collection and linker options. Only
|
||||
/// linker option emission is implemented for COFF.
|
||||
virtual void emitModuleFlags(MCStreamer &Streamer,
|
||||
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
|
||||
Mangler *Mang, const TargetMachine &TM) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -44,13 +44,13 @@ def v4i8 : ValueType<32 , 20>; // 4 x i8 vector value
|
||||
def v8i8 : ValueType<64 , 21>; // 8 x i8 vector value
|
||||
def v16i8 : ValueType<128, 22>; // 16 x i8 vector value
|
||||
def v32i8 : ValueType<256, 23>; // 32 x i8 vector value
|
||||
def v64i8 : ValueType<256, 24>; // 64 x i8 vector value
|
||||
def v64i8 : ValueType<512, 24>; // 64 x i8 vector value
|
||||
def v1i16 : ValueType<16 , 25>; // 1 x i16 vector value
|
||||
def v2i16 : ValueType<32 , 26>; // 2 x i16 vector value
|
||||
def v4i16 : ValueType<64 , 27>; // 4 x i16 vector value
|
||||
def v8i16 : ValueType<128, 28>; // 8 x i16 vector value
|
||||
def v16i16 : ValueType<256, 29>; // 16 x i16 vector value
|
||||
def v32i16 : ValueType<256, 30>; // 32 x i16 vector value
|
||||
def v32i16 : ValueType<512, 30>; // 32 x i16 vector value
|
||||
def v1i32 : ValueType<32 , 31>; // 1 x i32 vector value
|
||||
def v2i32 : ValueType<64 , 32>; // 2 x i32 vector value
|
||||
def v4i32 : ValueType<128, 33>; // 4 x i32 vector value
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a DIBuilder that is useful for creating debugging
|
||||
// This file defines a DIBuilder that is useful for creating debugging
|
||||
// information entries in LLVM IR form.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -37,11 +37,13 @@ namespace llvm {
|
||||
class DIType;
|
||||
class DIArray;
|
||||
class DIGlobalVariable;
|
||||
class DIImportedModule;
|
||||
class DINameSpace;
|
||||
class DIVariable;
|
||||
class DISubrange;
|
||||
class DILexicalBlockFile;
|
||||
class DILexicalBlock;
|
||||
class DIScope;
|
||||
class DISubprogram;
|
||||
class DITemplateTypeParameter;
|
||||
class DITemplateValueParameter;
|
||||
@ -57,6 +59,7 @@ namespace llvm {
|
||||
MDNode *TempRetainTypes;
|
||||
MDNode *TempSubprograms;
|
||||
MDNode *TempGVs;
|
||||
MDNode *TempImportedModules;
|
||||
|
||||
Function *DeclareFn; // llvm.dbg.declare
|
||||
Function *ValueFn; // llvm.dbg.value
|
||||
@ -65,6 +68,7 @@ namespace llvm {
|
||||
SmallVector<Value *, 4> AllRetainTypes;
|
||||
SmallVector<Value *, 4> AllSubprograms;
|
||||
SmallVector<Value *, 4> AllGVs;
|
||||
SmallVector<Value *, 4> AllImportedModules;
|
||||
|
||||
DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;
|
||||
@ -82,18 +86,18 @@ namespace llvm {
|
||||
/// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
|
||||
/// @param File File name
|
||||
/// @param Dir Directory
|
||||
/// @param Producer String identify producer of debugging information.
|
||||
/// @param Producer String identify producer of debugging information.
|
||||
/// Usuall this is a compiler version string.
|
||||
/// @param isOptimized A boolean flag which indicates whether optimization
|
||||
/// is ON or not.
|
||||
/// @param Flags This string lists command line options. This string is
|
||||
/// @param Flags This string lists command line options. This string is
|
||||
/// directly embedded in debug info output which may be used
|
||||
/// by a tool analyzing generated debugging information.
|
||||
/// @param RV This indicates runtime version for languages like
|
||||
/// @param RV This indicates runtime version for languages like
|
||||
/// Objective-C.
|
||||
/// @param SplitName The name of the file that we'll split debug info out
|
||||
/// into.
|
||||
void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
|
||||
void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
|
||||
StringRef Producer, bool isOptimized,
|
||||
StringRef Flags, unsigned RV,
|
||||
StringRef SplitName = StringRef());
|
||||
@ -101,14 +105,14 @@ namespace llvm {
|
||||
/// createFile - Create a file descriptor to hold debugging information
|
||||
/// for a file.
|
||||
DIFile createFile(StringRef Filename, StringRef Directory);
|
||||
|
||||
|
||||
/// createEnumerator - Create a single enumerator value.
|
||||
DIEnumerator createEnumerator(StringRef Name, uint64_t Val);
|
||||
|
||||
/// createNullPtrType - Create C++0x nullptr type.
|
||||
DIType createNullPtrType(StringRef Name);
|
||||
|
||||
/// createBasicType - Create debugging information entry for a basic
|
||||
/// createBasicType - Create debugging information entry for a basic
|
||||
/// type.
|
||||
/// @param Name Type name.
|
||||
/// @param SizeInBits Size of the type.
|
||||
@ -158,7 +162,7 @@ namespace llvm {
|
||||
/// @param Ty Original type.
|
||||
/// @param BaseTy Base type. Ty is inherits from base.
|
||||
/// @param BaseOffset Base offset.
|
||||
/// @param Flags Flags to describe inheritance attribute,
|
||||
/// @param Flags Flags to describe inheritance attribute,
|
||||
/// e.g. private
|
||||
DIDerivedType createInheritance(DIType Ty, DIType BaseTy,
|
||||
uint64_t BaseOffset, unsigned Flags);
|
||||
@ -209,8 +213,8 @@ namespace llvm {
|
||||
/// selector.
|
||||
/// @param PropertyAttributes Objective C property attributes.
|
||||
DIType createObjCIVar(StringRef Name, DIFile File,
|
||||
unsigned LineNo, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned LineNo, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned Flags, DIType Ty,
|
||||
StringRef PropertyName = StringRef(),
|
||||
StringRef PropertyGetterName = StringRef(),
|
||||
@ -229,8 +233,8 @@ namespace llvm {
|
||||
/// @param Ty Parent type.
|
||||
/// @param PropertyNode Property associated with this ivar.
|
||||
DIType createObjCIVar(StringRef Name, DIFile File,
|
||||
unsigned LineNo, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned LineNo, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||
unsigned Flags, DIType Ty,
|
||||
MDNode *PropertyNode);
|
||||
|
||||
@ -249,7 +253,7 @@ namespace llvm {
|
||||
StringRef SetterName,
|
||||
unsigned PropertyAttributes,
|
||||
DIType Ty);
|
||||
|
||||
|
||||
/// createClassType - Create debugging information entry for a class.
|
||||
/// @param Scope Scope in which this class is defined.
|
||||
/// @param Name class name.
|
||||
@ -261,7 +265,7 @@ namespace llvm {
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Elements class members.
|
||||
/// @param VTableHolder Debug info of the base class that contains vtable
|
||||
/// for this type. This is used in
|
||||
/// for this type. This is used in
|
||||
/// DW_AT_containing_type. See DWARF documentation
|
||||
/// for more info.
|
||||
/// @param TemplateParms Template type parameters.
|
||||
@ -346,22 +350,25 @@ namespace llvm {
|
||||
/// @param AlignInBits Alignment.
|
||||
/// @param Ty Element type.
|
||||
/// @param Subscripts Subscripts.
|
||||
DIType createVectorType(uint64_t Size, uint64_t AlignInBits,
|
||||
DIType createVectorType(uint64_t Size, uint64_t AlignInBits,
|
||||
DIType Ty, DIArray Subscripts);
|
||||
|
||||
/// createEnumerationType - Create debugging information entry for an
|
||||
/// createEnumerationType - Create debugging information entry for an
|
||||
/// enumeration.
|
||||
/// @param Scope Scope in which this enumeration is defined.
|
||||
/// @param Name Union name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param Elements Enumeration elements.
|
||||
DICompositeType createEnumerationType(
|
||||
DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements,
|
||||
DIType ClassType);
|
||||
/// @param Scope Scope in which this enumeration is defined.
|
||||
/// @param Name Union name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param Elements Enumeration elements.
|
||||
/// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
|
||||
DICompositeType createEnumerationType(DIDescriptor Scope, StringRef Name,
|
||||
DIFile File, unsigned LineNumber,
|
||||
uint64_t SizeInBits,
|
||||
uint64_t AlignInBits,
|
||||
DIArray Elements,
|
||||
DIType UnderlyingType);
|
||||
|
||||
/// createSubroutineType - Create subroutine type.
|
||||
/// @param File File in which this subroutine is defined.
|
||||
@ -381,7 +388,7 @@ namespace llvm {
|
||||
DIFile F, unsigned Line, unsigned RuntimeLang = 0,
|
||||
uint64_t SizeInBits = 0, uint64_t AlignInBits = 0);
|
||||
|
||||
/// retainType - Retain DIType in a module even if it is not referenced
|
||||
/// retainType - Retain DIType in a module even if it is not referenced
|
||||
/// through debug info anchors.
|
||||
void retainType(DIType T);
|
||||
|
||||
@ -422,7 +429,7 @@ namespace llvm {
|
||||
unsigned LineNo, DIType Ty, bool isLocalToUnit,
|
||||
llvm::Value *Val);
|
||||
|
||||
/// createStaticVariable - Create a new descriptor for the specified
|
||||
/// createStaticVariable - Create a new descriptor for the specified
|
||||
/// variable.
|
||||
/// @param Context Variable scope.
|
||||
/// @param Name Name of the variable.
|
||||
@ -435,13 +442,13 @@ namespace llvm {
|
||||
/// @param Val llvm::Value of the variable.
|
||||
/// @param Decl Reference to the corresponding declaration.
|
||||
DIGlobalVariable
|
||||
createStaticVariable(DIDescriptor Context, StringRef Name,
|
||||
StringRef LinkageName, DIFile File, unsigned LineNo,
|
||||
createStaticVariable(DIDescriptor Context, StringRef Name,
|
||||
StringRef LinkageName, DIFile File, unsigned LineNo,
|
||||
DIType Ty, bool isLocalToUnit, llvm::Value *Val,
|
||||
MDNode *Decl = NULL);
|
||||
|
||||
|
||||
/// createLocalVariable - Create a new descriptor for the specified
|
||||
/// createLocalVariable - Create a new descriptor for the specified
|
||||
/// local variable.
|
||||
/// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
|
||||
/// DW_TAG_arg_variable.
|
||||
@ -518,7 +525,7 @@ namespace llvm {
|
||||
/// @param Ty Function type.
|
||||
/// @param isLocalToUnit True if this function is not externally visible..
|
||||
/// @param isDefinition True if this is a function definition.
|
||||
/// @param Virtuality Attributes describing virtualness. e.g. pure
|
||||
/// @param Virtuality Attributes describing virtualness. e.g. pure
|
||||
/// virtual function.
|
||||
/// @param VTableIndex Index no of this method in virtual table.
|
||||
/// @param VTableHolder Type that holds vtable.
|
||||
@ -556,7 +563,7 @@ namespace llvm {
|
||||
/// @param File Source file.
|
||||
DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
|
||||
DIFile File);
|
||||
|
||||
|
||||
/// createLexicalBlock - This creates a descriptor for a lexical block
|
||||
/// with the specified parent context.
|
||||
/// @param Scope Parent lexical scope.
|
||||
@ -566,6 +573,13 @@ namespace llvm {
|
||||
DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
|
||||
unsigned Line, unsigned Col);
|
||||
|
||||
/// \brief Create a descriptor for an imported module.
|
||||
/// @param Context The scope this module is imported into
|
||||
/// @param NS The namespace being imported here
|
||||
/// @param Line Line number
|
||||
DIImportedModule createImportedModule(DIScope Context, DINameSpace NS,
|
||||
unsigned Line);
|
||||
|
||||
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
/// @param Storage llvm::Value of the variable
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
@ -587,16 +601,16 @@ namespace llvm {
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param InsertAtEnd Location for the new intrinsic.
|
||||
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
|
||||
DIVariable VarInfo,
|
||||
DIVariable VarInfo,
|
||||
BasicBlock *InsertAtEnd);
|
||||
|
||||
|
||||
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
/// @param Val llvm::Value of the variable
|
||||
/// @param Offset Offset
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param InsertBefore Location for the new intrinsic.
|
||||
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
|
||||
DIVariable VarInfo,
|
||||
DIVariable VarInfo,
|
||||
Instruction *InsertBefore);
|
||||
|
||||
};
|
||||
|
@ -125,6 +125,7 @@ namespace llvm {
|
||||
bool isTemplateTypeParameter() const;
|
||||
bool isTemplateValueParameter() const;
|
||||
bool isObjCProperty() const;
|
||||
bool isImportedModule() const;
|
||||
|
||||
/// print - print descriptor.
|
||||
void print(raw_ostream &OS) const;
|
||||
@ -199,8 +200,9 @@ namespace llvm {
|
||||
DIArray getRetainedTypes() const;
|
||||
DIArray getSubprograms() const;
|
||||
DIArray getGlobalVariables() const;
|
||||
DIArray getImportedModules() const;
|
||||
|
||||
StringRef getSplitDebugFilename() const { return getStringField(11); }
|
||||
StringRef getSplitDebugFilename() const { return getStringField(12); }
|
||||
|
||||
/// Verify - Verify that a compile unit is well formed.
|
||||
bool Verify() const;
|
||||
@ -342,7 +344,10 @@ namespace llvm {
|
||||
|
||||
/// DICompositeType - This descriptor holds a type that can refer to multiple
|
||||
/// other types, like a function or struct.
|
||||
/// FIXME: Why is this a DIDerivedType??
|
||||
/// DICompositeType is derived from DIDerivedType because some
|
||||
/// composite types (such as enums) can be derived from basic types
|
||||
// FIXME: Make this derive from DIType directly & just store the
|
||||
// base type in a single DIType field.
|
||||
class DICompositeType : public DIDerivedType {
|
||||
friend class DIDescriptor;
|
||||
void printInternal(raw_ostream &OS) const;
|
||||
@ -678,6 +683,18 @@ namespace llvm {
|
||||
bool Verify() const;
|
||||
};
|
||||
|
||||
/// \brief An imported module (C++ using directive or similar).
|
||||
class DIImportedModule : public DIDescriptor {
|
||||
friend class DIDescriptor;
|
||||
void printInternal(raw_ostream &OS) const;
|
||||
public:
|
||||
explicit DIImportedModule(const MDNode *N) : DIDescriptor(N) { }
|
||||
DIScope getContext() const { return getFieldAs<DIScope>(1); }
|
||||
DINameSpace getNameSpace() const { return getFieldAs<DINameSpace>(2); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(3); }
|
||||
bool Verify() const;
|
||||
};
|
||||
|
||||
/// getDISubprogram - Find subprogram that is enclosing this scope.
|
||||
DISubprogram getDISubprogram(const MDNode *Scope);
|
||||
|
||||
|
@ -74,7 +74,7 @@ class DWARFFormValue {
|
||||
uint32_t *offset_ptr, const DWARFCompileUnit *cu);
|
||||
static bool isBlockForm(uint16_t form);
|
||||
static bool isDataForm(uint16_t form);
|
||||
static const uint8_t *getFixedFormSizesForAddressSize(uint8_t addr_size);
|
||||
static const uint8_t *getFixedFormSizes(uint8_t AddrSize, uint16_t Version);
|
||||
};
|
||||
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
|
||||
#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
|
||||
|
||||
#include "llvm-c/ExecutionEngine.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -42,6 +43,7 @@ class JITMemoryManager;
|
||||
class MachineCodeInfo;
|
||||
class Module;
|
||||
class MutexGuard;
|
||||
class ObjectCache;
|
||||
class DataLayout;
|
||||
class Triple;
|
||||
class Type;
|
||||
@ -371,6 +373,12 @@ class ExecutionEngine {
|
||||
virtual void RegisterJITEventListener(JITEventListener *) {}
|
||||
virtual void UnregisterJITEventListener(JITEventListener *) {}
|
||||
|
||||
/// Sets the pre-compiled object cache. The ownership of the ObjectCache is
|
||||
/// not changed. Supported by MCJIT but not JIT.
|
||||
virtual void setObjectCache(ObjectCache *) {
|
||||
llvm_unreachable("No support for an object cache");
|
||||
}
|
||||
|
||||
/// DisableLazyCompilation - When lazy compilation is off (the default), the
|
||||
/// JIT will eagerly compile every function reachable from the argument to
|
||||
/// getPointerToFunction. If lazy compilation is turned on, the JIT will only
|
||||
@ -625,6 +633,9 @@ class EngineBuilder {
|
||||
ExecutionEngine *create(TargetMachine *TM);
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
54
contrib/llvm/include/llvm/ExecutionEngine/ObjectCache.h
Normal file
54
contrib/llvm/include/llvm/ExecutionEngine/ObjectCache.h
Normal file
@ -0,0 +1,54 @@
|
||||
//===-- ObjectCache.h - Class definition for the ObjectCache -----C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_OBJECTCACHE_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_OBJECTCACHE_H
|
||||
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
|
||||
/// This is the base ObjectCache type which can be provided to an
|
||||
/// ExecutionEngine for the purpose of avoiding compilation for Modules that
|
||||
/// have already been compiled and an object file is available.
|
||||
class ObjectCache {
|
||||
public:
|
||||
ObjectCache() { }
|
||||
|
||||
virtual ~ObjectCache() { }
|
||||
|
||||
/// notifyObjectCompiled - Provides a pointer to compiled code for Module M.
|
||||
virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) = 0;
|
||||
|
||||
/// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that
|
||||
/// contains the object which corresponds with Module M, or 0 if an object is
|
||||
/// not available. The caller owns the MemoryBuffer returned by this function.
|
||||
MemoryBuffer* getObjectCopy(const Module* M) {
|
||||
const MemoryBuffer* Obj = getObject(M);
|
||||
if (Obj)
|
||||
return MemoryBuffer::getMemBufferCopy(Obj->getBuffer());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// getObject - Returns a pointer to a MemoryBuffer that contains an object
|
||||
/// that corresponds with Module M, or 0 if an object is not available.
|
||||
/// The pointer returned by this function is not suitable for loading because
|
||||
/// the memory is read-only and owned by the ObjectCache. To retrieve an
|
||||
/// owning pointer to a MemoryBuffer (which is suitable for calling
|
||||
/// RuntimeDyld::loadObject() with) use getObjectCopy() instead.
|
||||
virtual const MemoryBuffer* getObject(const Module* M) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -66,6 +66,11 @@ class RTDyldMemoryManager {
|
||||
///
|
||||
/// Returns true if an error occurred, false otherwise.
|
||||
virtual bool applyPermissions(std::string *ErrMsg = 0) = 0;
|
||||
|
||||
/// Register the EH frames with the runtime so that c++ exceptions work. The
|
||||
/// default implementation does nothing. Look at SectionMemoryManager for one
|
||||
/// that uses __register_frame.
|
||||
virtual void registerEHFrames(StringRef SectionData);
|
||||
};
|
||||
|
||||
class RuntimeDyld {
|
||||
@ -109,6 +114,8 @@ class RuntimeDyld {
|
||||
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
|
||||
|
||||
StringRef getErrorString();
|
||||
|
||||
StringRef getEHFrameSection();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -72,6 +72,8 @@ class SectionMemoryManager : public JITMemoryManager {
|
||||
/// \returns true if an error occurred, false otherwise.
|
||||
virtual bool applyPermissions(std::string *ErrMsg = 0);
|
||||
|
||||
void registerEHFrames(StringRef SectionData);
|
||||
|
||||
/// This method returns the address of the specified function. As such it is
|
||||
/// only useful for resolving library symbols, not code generated symbols.
|
||||
///
|
||||
@ -87,9 +89,7 @@ class SectionMemoryManager : public JITMemoryManager {
|
||||
/// explicit cache flush, otherwise JIT code manipulations (like resolved
|
||||
/// relocations) will get to the data cache but not to the instruction cache.
|
||||
///
|
||||
/// This method is not called by RuntimeDyld or MCJIT during the load
|
||||
/// process. Clients may call this function when needed. See the lli
|
||||
/// tool for example use.
|
||||
/// This method is called from applyPermissions.
|
||||
virtual void invalidateInstructionCache();
|
||||
|
||||
private:
|
||||
|
@ -78,6 +78,10 @@ class Argument : public Value, public ilist_node<Argument> {
|
||||
/// containing function.
|
||||
bool hasStructRetAttr() const;
|
||||
|
||||
/// \brief Return true if this argument has the returned attribute on it in
|
||||
/// its containing function.
|
||||
bool hasReturnedAttr() const;
|
||||
|
||||
/// \brief Add a Attribute to an argument.
|
||||
void addAttr(AttributeSet AS);
|
||||
|
||||
|
@ -87,6 +87,7 @@ class Attribute {
|
||||
OptimizeForSize, ///< opt_size
|
||||
ReadNone, ///< Function does not access memory
|
||||
ReadOnly, ///< Function only reads from memory
|
||||
Returned, ///< Return value is always equal to this argument
|
||||
ReturnsTwice, ///< Function can return twice
|
||||
SExt, ///< Sign extended before/after call
|
||||
StackAlignment, ///< Alignment of stack for function (3 bits)
|
||||
@ -209,7 +210,7 @@ class AttributeSet {
|
||||
AttributeSetImpl *pImpl;
|
||||
|
||||
/// \brief The attributes for the specified index are returned.
|
||||
AttributeSetNode *getAttributes(unsigned Idx) const;
|
||||
AttributeSetNode *getAttributes(unsigned Index) const;
|
||||
|
||||
/// \brief Create an AttributeSet with the specified parameters in it.
|
||||
static AttributeSet get(LLVMContext &C,
|
||||
@ -233,35 +234,35 @@ class AttributeSet {
|
||||
|
||||
/// \brief Return an AttributeSet with the specified parameters in it.
|
||||
static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
|
||||
static AttributeSet get(LLVMContext &C, unsigned Idx,
|
||||
static AttributeSet get(LLVMContext &C, unsigned Index,
|
||||
ArrayRef<Attribute::AttrKind> Kind);
|
||||
static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
|
||||
static AttributeSet get(LLVMContext &C, unsigned Index, AttrBuilder &B);
|
||||
|
||||
/// \brief Add an attribute to the attribute set at the given index. Since
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttribute(LLVMContext &C, unsigned Idx,
|
||||
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
|
||||
Attribute::AttrKind Attr) const;
|
||||
|
||||
/// \brief Add an attribute to the attribute set at the given index. Since
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttribute(LLVMContext &C, unsigned Idx,
|
||||
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
|
||||
StringRef Kind) const;
|
||||
|
||||
/// \brief Add attributes to the attribute set at the given index. Since
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttributes(LLVMContext &C, unsigned Idx,
|
||||
AttributeSet addAttributes(LLVMContext &C, unsigned Index,
|
||||
AttributeSet Attrs) const;
|
||||
|
||||
/// \brief Remove the specified attribute at the specified index from this
|
||||
/// attribute list. Since attribute lists are immutable, this returns the new
|
||||
/// list.
|
||||
AttributeSet removeAttribute(LLVMContext &C, unsigned Idx,
|
||||
AttributeSet removeAttribute(LLVMContext &C, unsigned Index,
|
||||
Attribute::AttrKind Attr) const;
|
||||
|
||||
/// \brief Remove the specified attributes at the specified index from this
|
||||
/// attribute list. Since attribute lists are immutable, this returns the new
|
||||
/// list.
|
||||
AttributeSet removeAttributes(LLVMContext &C, unsigned Idx,
|
||||
AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
|
||||
AttributeSet Attrs) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -272,7 +273,7 @@ class AttributeSet {
|
||||
LLVMContext &getContext() const;
|
||||
|
||||
/// \brief The attributes for the specified index are returned.
|
||||
AttributeSet getParamAttributes(unsigned Idx) const;
|
||||
AttributeSet getParamAttributes(unsigned Index) const;
|
||||
|
||||
/// \brief The attributes for the ret value are returned.
|
||||
AttributeSet getRetAttributes() const;
|
||||
@ -300,7 +301,7 @@ class AttributeSet {
|
||||
Attribute getAttribute(unsigned Index, StringRef Kind) const;
|
||||
|
||||
/// \brief Return the alignment for the specified function parameter.
|
||||
unsigned getParamAlignment(unsigned Idx) const;
|
||||
unsigned getParamAlignment(unsigned Index) const;
|
||||
|
||||
/// \brief Get the stack alignment.
|
||||
unsigned getStackAlignment(unsigned Index) const;
|
||||
@ -310,8 +311,8 @@ class AttributeSet {
|
||||
|
||||
typedef ArrayRef<Attribute>::iterator iterator;
|
||||
|
||||
iterator begin(unsigned Idx) const;
|
||||
iterator end(unsigned Idx) const;
|
||||
iterator begin(unsigned Slot) const;
|
||||
iterator end(unsigned Slot) const;
|
||||
|
||||
/// operator==/!= - Provide equality predicates.
|
||||
bool operator==(const AttributeSet &RHS) const {
|
||||
@ -344,7 +345,7 @@ class AttributeSet {
|
||||
unsigned getNumSlots() const;
|
||||
|
||||
/// \brief Return the index for the given slot.
|
||||
uint64_t getSlotIndex(unsigned Slot) const;
|
||||
unsigned getSlotIndex(unsigned Slot) const;
|
||||
|
||||
/// \brief Return the attributes at the given slot.
|
||||
AttributeSet getSlotAttributes(unsigned Slot) const;
|
||||
@ -473,9 +474,6 @@ class AttrBuilder {
|
||||
|
||||
bool td_empty() const { return TargetDepAttrs.empty(); }
|
||||
|
||||
/// \brief Remove attributes that are used on functions only.
|
||||
void removeFunctionOnlyAttrs();
|
||||
|
||||
bool operator==(const AttrBuilder &B);
|
||||
bool operator!=(const AttrBuilder &B) {
|
||||
return !(*this == B);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/SymbolTableListTraits.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -298,6 +299,9 @@ class BasicBlock : public Value, // Basic blocks are data objects also
|
||||
}
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/OperandTraits.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -138,7 +139,7 @@ class ConstantInt : public Constant {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline IntegerType *getType() const {
|
||||
return reinterpret_cast<IntegerType*>(Value::getType());
|
||||
return cast<IntegerType>(Value::getType());
|
||||
}
|
||||
|
||||
/// This static method returns true if the type Ty is big enough to
|
||||
@ -354,7 +355,7 @@ class ConstantArray : public Constant {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline ArrayType *getType() const {
|
||||
return reinterpret_cast<ArrayType*>(Value::getType());
|
||||
return cast<ArrayType>(Value::getType());
|
||||
}
|
||||
|
||||
virtual void destroyConstant();
|
||||
@ -412,7 +413,7 @@ class ConstantStruct : public Constant {
|
||||
/// getType() specialization - Reduce amount of casting...
|
||||
///
|
||||
inline StructType *getType() const {
|
||||
return reinterpret_cast<StructType*>(Value::getType());
|
||||
return cast<StructType>(Value::getType());
|
||||
}
|
||||
|
||||
virtual void destroyConstant();
|
||||
@ -455,7 +456,7 @@ class ConstantVector : public Constant {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline VectorType *getType() const {
|
||||
return reinterpret_cast<VectorType*>(Value::getType());
|
||||
return cast<VectorType>(Value::getType());
|
||||
}
|
||||
|
||||
/// getSplatValue - If this is a splat constant, meaning that all of the
|
||||
@ -486,7 +487,7 @@ class ConstantPointerNull : public Constant {
|
||||
ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION;
|
||||
protected:
|
||||
explicit ConstantPointerNull(PointerType *T)
|
||||
: Constant(reinterpret_cast<Type*>(T),
|
||||
: Constant(T,
|
||||
Value::ConstantPointerNullVal, 0, 0) {}
|
||||
|
||||
protected:
|
||||
@ -504,7 +505,7 @@ class ConstantPointerNull : public Constant {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline PointerType *getType() const {
|
||||
return reinterpret_cast<PointerType*>(Value::getType());
|
||||
return cast<PointerType>(Value::getType());
|
||||
}
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -580,7 +581,7 @@ class ConstantDataSequential : public Constant {
|
||||
/// SequentialType, which reduces the amount of casting needed in parts of the
|
||||
/// compiler.
|
||||
inline SequentialType *getType() const {
|
||||
return reinterpret_cast<SequentialType*>(Value::getType());
|
||||
return cast<SequentialType>(Value::getType());
|
||||
}
|
||||
|
||||
/// getElementType - Return the element type of the array/vector.
|
||||
@ -679,7 +680,7 @@ class ConstantDataArray : public ConstantDataSequential {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline ArrayType *getType() const {
|
||||
return reinterpret_cast<ArrayType*>(Value::getType());
|
||||
return cast<ArrayType>(Value::getType());
|
||||
}
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -732,7 +733,7 @@ class ConstantDataVector : public ConstantDataSequential {
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
inline VectorType *getType() const {
|
||||
return reinterpret_cast<VectorType*>(Value::getType());
|
||||
return cast<VectorType>(Value::getType());
|
||||
}
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
|
@ -171,13 +171,13 @@ class DataLayout : public ImmutablePass {
|
||||
/// Initialize target data from properties stored in the module.
|
||||
explicit DataLayout(const Module *M);
|
||||
|
||||
DataLayout(const DataLayout &TD) :
|
||||
DataLayout(const DataLayout &DL) :
|
||||
ImmutablePass(ID),
|
||||
LittleEndian(TD.isLittleEndian()),
|
||||
StackNaturalAlign(TD.StackNaturalAlign),
|
||||
LegalIntWidths(TD.LegalIntWidths),
|
||||
Alignments(TD.Alignments),
|
||||
Pointers(TD.Pointers),
|
||||
LittleEndian(DL.isLittleEndian()),
|
||||
StackNaturalAlign(DL.StackNaturalAlign),
|
||||
LegalIntWidths(DL.LegalIntWidths),
|
||||
Alignments(DL.Alignments),
|
||||
Pointers(DL.Pointers),
|
||||
LayoutMap(0)
|
||||
{ }
|
||||
|
||||
@ -426,7 +426,7 @@ class StructLayout {
|
||||
|
||||
private:
|
||||
friend class DataLayout; // Only DataLayout can create this class
|
||||
StructLayout(StructType *ST, const DataLayout &TD);
|
||||
StructLayout(StructType *ST, const DataLayout &DL);
|
||||
};
|
||||
|
||||
|
||||
|
@ -117,7 +117,7 @@ class FunctionType : public Type {
|
||||
/// argument type.
|
||||
static bool isValidArgumentType(Type *ArgTy);
|
||||
|
||||
bool isVarArg() const { return getSubclassData(); }
|
||||
bool isVarArg() const { return getSubclassData()!=0; }
|
||||
Type *getReturnType() const { return ContainedTys[0]; }
|
||||
|
||||
typedef Type::subtype_iterator param_iterator;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define LLVM_IR_GLOBALVALUE_H
|
||||
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -105,7 +106,7 @@ class GlobalValue : public Constant {
|
||||
|
||||
/// getType - Global values are always pointers.
|
||||
inline PointerType *getType() const {
|
||||
return reinterpret_cast<PointerType*>(User::getType());
|
||||
return cast<PointerType>(User::getType());
|
||||
}
|
||||
|
||||
static LinkageTypes getLinkOnceLinkage(bool ODR) {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/ConstantFolder.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -48,6 +49,10 @@ class IRBuilderDefaultInserter {
|
||||
class IRBuilderBase {
|
||||
DebugLoc CurDbgLocation;
|
||||
protected:
|
||||
/// Save the current debug location here while we are suppressing
|
||||
/// line table entries.
|
||||
llvm::DebugLoc SavedDbgLocation;
|
||||
|
||||
BasicBlock *BB;
|
||||
BasicBlock::iterator InsertPt;
|
||||
LLVMContext &Context;
|
||||
@ -112,6 +117,23 @@ class IRBuilderBase {
|
||||
CurDbgLocation = L;
|
||||
}
|
||||
|
||||
/// \brief Temporarily suppress DebugLocations from being attached
|
||||
/// to emitted instructions, until the next call to
|
||||
/// SetCurrentDebugLocation() or EnableDebugLocations(). Use this
|
||||
/// if you want an instruction to be counted towards the prologue or
|
||||
/// if there is no useful source location.
|
||||
void DisableDebugLocations() {
|
||||
llvm::DebugLoc Empty;
|
||||
SavedDbgLocation = getCurrentDebugLocation();
|
||||
SetCurrentDebugLocation(Empty);
|
||||
}
|
||||
|
||||
/// \brief Restore the previously saved DebugLocation.
|
||||
void EnableDebugLocations() {
|
||||
assert(CurDbgLocation.isUnknown());
|
||||
SetCurrentDebugLocation(SavedDbgLocation);
|
||||
}
|
||||
|
||||
/// \brief Get location information used by debugging information.
|
||||
DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
|
||||
|
||||
@ -1396,6 +1418,9 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
}
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -45,12 +45,12 @@ namespace Intrinsic {
|
||||
|
||||
/// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
|
||||
/// "llvm.ppc.altivec.lvx".
|
||||
std::string getName(ID id, ArrayRef<Type*> Tys = ArrayRef<Type*>());
|
||||
|
||||
std::string getName(ID id, ArrayRef<Type*> Tys = None);
|
||||
|
||||
/// Intrinsic::getType(ID) - Return the function type for an intrinsic.
|
||||
///
|
||||
FunctionType *getType(LLVMContext &Context, ID id,
|
||||
ArrayRef<Type*> Tys = ArrayRef<Type*>());
|
||||
ArrayRef<Type*> Tys = None);
|
||||
|
||||
/// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be
|
||||
/// overloaded.
|
||||
@ -63,14 +63,12 @@ namespace Intrinsic {
|
||||
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
|
||||
/// declaration for an intrinsic, and return it.
|
||||
///
|
||||
/// The Tys and numTys parameters are for intrinsics with overloaded types
|
||||
/// (e.g., those using iAny, fAny, vAny, or iPTRAny). For a declaration for an
|
||||
/// overloaded intrinsic, Tys should point to an array of numTys pointers to
|
||||
/// Type, and must provide exactly one type for each overloaded type in the
|
||||
/// intrinsic.
|
||||
Function *getDeclaration(Module *M, ID id,
|
||||
ArrayRef<Type*> Tys = ArrayRef<Type*>());
|
||||
|
||||
/// The Tys parameter is for intrinsics with overloaded types (e.g., those
|
||||
/// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
|
||||
/// intrinsic, Tys must provide exactly one type for each overloaded type in
|
||||
/// the intrinsic.
|
||||
Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
|
||||
|
||||
/// Map a GCC builtin name to an intrinsic ID.
|
||||
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
|
||||
|
||||
|
@ -195,21 +195,21 @@ def int_mips_dpsq_sa_l_w: GCCBuiltin<"__builtin_mips_dpsq_sa_l_w">,
|
||||
def int_mips_cmpu_eq_qb: GCCBuiltin<"__builtin_mips_cmpu_eq_qb">,
|
||||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
def int_mips_cmpu_lt_qb: GCCBuiltin<"__builtin_mips_cmpu_lt_qb">,
|
||||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
def int_mips_cmpu_le_qb: GCCBuiltin<"__builtin_mips_cmpu_le_qb">,
|
||||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
def int_mips_cmpgu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgu_eq_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
def int_mips_cmpgu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgu_lt_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
def int_mips_cmpgu_le_qb: GCCBuiltin<"__builtin_mips_cmpgu_le_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
def int_mips_cmp_eq_ph: GCCBuiltin<"__builtin_mips_cmp_eq_ph">,
|
||||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
|
||||
def int_mips_cmp_lt_ph: GCCBuiltin<"__builtin_mips_cmp_lt_ph">,
|
||||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
|
||||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>;
|
||||
def int_mips_cmp_le_ph: GCCBuiltin<"__builtin_mips_cmp_le_ph">,
|
||||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
|
||||
Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Extracting
|
||||
@ -307,9 +307,9 @@ def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">,
|
||||
def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
def int_mips_cmpgdu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgdu_lt_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
def int_mips_cmpgdu_le_qb: GCCBuiltin<"__builtin_mips_cmpgdu_le_qb">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
|
||||
|
||||
def int_mips_dpa_w_ph: GCCBuiltin<"__builtin_mips_dpa_w_ph">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
|
||||
|
@ -405,6 +405,8 @@ def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
|
||||
// Sqrt
|
||||
//
|
||||
|
||||
def int_nvvm_sqrt_f : GCCBuiltin<"__nvvm_sqrt_f">,
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
||||
def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">,
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
|
||||
def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">,
|
||||
|
@ -117,28 +117,33 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
||||
// Loads. These don't map directly to GCC builtins because they represent the
|
||||
// source address with a single pointer.
|
||||
def int_ppc_altivec_lvx :
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
|
||||
def int_ppc_altivec_lvxl :
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
|
||||
def int_ppc_altivec_lvebx :
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
|
||||
def int_ppc_altivec_lvehx :
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
|
||||
def int_ppc_altivec_lvewx :
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
|
||||
|
||||
// Stores. These don't map directly to GCC builtins because they represent the
|
||||
// source address with a single pointer.
|
||||
def int_ppc_altivec_stvx :
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrReadWriteArgMem]>;
|
||||
def int_ppc_altivec_stvxl :
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrReadWriteArgMem]>;
|
||||
def int_ppc_altivec_stvebx :
|
||||
Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty], []>;
|
||||
Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty],
|
||||
[IntrReadWriteArgMem]>;
|
||||
def int_ppc_altivec_stvehx :
|
||||
Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty], []>;
|
||||
Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty],
|
||||
[IntrReadWriteArgMem]>;
|
||||
def int_ppc_altivec_stvewx :
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
|
||||
Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
|
||||
[IntrReadWriteArgMem]>;
|
||||
|
||||
// Comparisons setting a vector.
|
||||
def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
|
||||
|
@ -15,7 +15,9 @@
|
||||
#ifndef LLVM_IR_LLVMCONTEXT_H
|
||||
#define LLVM_IR_LLVMCONTEXT_H
|
||||
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -109,6 +111,19 @@ class LLVMContext {
|
||||
/// only care about operating on a single thread.
|
||||
extern LLVMContext &getGlobalContext();
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef)
|
||||
|
||||
/* Specialized opaque context conversions.
|
||||
*/
|
||||
inline LLVMContext **unwrap(LLVMContextRef* Tys) {
|
||||
return reinterpret_cast<LLVMContext**>(Tys);
|
||||
}
|
||||
|
||||
inline LLVMContextRef *wrap(const LLVMContext **Tys) {
|
||||
return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -157,19 +157,31 @@ class MDBuilder {
|
||||
}
|
||||
|
||||
/// \brief Return metadata for a TBAA struct node in the type DAG
|
||||
/// with the given name, parents in the TBAA DAG.
|
||||
/// with the given name, a list of pairs (offset, field type in the type DAG).
|
||||
MDNode *createTBAAStructTypeNode(StringRef Name,
|
||||
ArrayRef<std::pair<uint64_t, MDNode*> > Fields) {
|
||||
ArrayRef<std::pair<MDNode*, uint64_t> > Fields) {
|
||||
SmallVector<Value *, 4> Ops(Fields.size() * 2 + 1);
|
||||
Type *Int64 = IntegerType::get(Context, 64);
|
||||
Ops[0] = createString(Name);
|
||||
for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
|
||||
Ops[i * 2 + 1] = ConstantInt::get(Int64, Fields[i].first);
|
||||
Ops[i * 2 + 2] = Fields[i].second;
|
||||
Ops[i * 2 + 1] = Fields[i].first;
|
||||
Ops[i * 2 + 2] = ConstantInt::get(Int64, Fields[i].second);
|
||||
}
|
||||
return MDNode::get(Context, Ops);
|
||||
}
|
||||
|
||||
/// \brief Return metadata for a TBAA scalar type node with the
|
||||
/// given name, an offset and a parent in the TBAA type DAG.
|
||||
MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
|
||||
uint64_t Offset = 0) {
|
||||
SmallVector<Value *, 4> Ops(3);
|
||||
Type *Int64 = IntegerType::get(Context, 64);
|
||||
Ops[0] = createString(Name);
|
||||
Ops[1] = Parent;
|
||||
Ops[2] = ConstantInt::get(Int64, Offset);
|
||||
return MDNode::get(Context, Ops);
|
||||
}
|
||||
|
||||
/// \brief Return metadata for a TBAA tag node with the given
|
||||
/// base type, access type and offset relative to the base type.
|
||||
MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -584,6 +585,16 @@ inline raw_ostream &operator<<(raw_ostream &O, const Module &M) {
|
||||
return O;
|
||||
}
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef)
|
||||
|
||||
/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
|
||||
* Module.
|
||||
*/
|
||||
inline Module *unwrap(LLVMModuleProviderRef MP) {
|
||||
return reinterpret_cast<Module*>(MP);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -17,8 +17,10 @@
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -467,6 +469,19 @@ template <> struct GraphTraits<const Type*> {
|
||||
}
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef)
|
||||
|
||||
/* Specialized opaque type conversions.
|
||||
*/
|
||||
inline Type **unwrap(LLVMTypeRef* Tys) {
|
||||
return reinterpret_cast<Type**>(Tys);
|
||||
}
|
||||
|
||||
inline LLVMTypeRef *wrap(Type **Tys) {
|
||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,9 @@
|
||||
#define LLVM_IR_USE_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
@ -214,6 +216,9 @@ class value_use_iterator : public std::iterator<std::forward_iterator_tag,
|
||||
unsigned getOperandNo() const;
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,9 @@
|
||||
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -258,14 +260,24 @@ class Value {
|
||||
/// this value.
|
||||
bool hasValueHandle() const { return HasValueHandle; }
|
||||
|
||||
/// 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'.
|
||||
/// \brief This method strips off any unneeded pointer casts,
|
||||
/// all-zero GEPs and aliases 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();
|
||||
}
|
||||
|
||||
/// \brief 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 *stripPointerCastsNoFollowAliases();
|
||||
const Value *stripPointerCastsNoFollowAliases() const {
|
||||
return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases();
|
||||
}
|
||||
|
||||
/// 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
|
||||
@ -406,6 +418,29 @@ class PointerLikeTypeTraits<Value*> {
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_ISA_CONVERSION_FUNCTIONS(Value, LLVMValueRef)
|
||||
|
||||
/* Specialized opaque value conversions.
|
||||
*/
|
||||
inline Value **unwrap(LLVMValueRef *Vals) {
|
||||
return reinterpret_cast<Value**>(Vals);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
|
||||
#ifdef DEBUG
|
||||
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
|
||||
cast<T>(*I);
|
||||
#endif
|
||||
(void)Length;
|
||||
return reinterpret_cast<T**>(Vals);
|
||||
}
|
||||
|
||||
inline LLVMValueRef *wrap(const Value **Vals) {
|
||||
return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -271,6 +271,7 @@ void initializeInstSimplifierPass(PassRegistry&);
|
||||
void initializeUnpackMachineBundlesPass(PassRegistry&);
|
||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||
void initializeLoopVectorizePass(PassRegistry&);
|
||||
void initializeSLPVectorizerPass(PassRegistry&);
|
||||
void initializeBBVectorizePass(PassRegistry&);
|
||||
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ namespace {
|
||||
(void) llvm::createMemDepPrinter();
|
||||
(void) llvm::createInstructionSimplifierPass();
|
||||
(void) llvm::createLoopVectorizePass();
|
||||
(void) llvm::createSLPVectorizerPass();
|
||||
(void) llvm::createBBVectorizePass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
|
@ -10,149 +10,46 @@
|
||||
#ifndef LLVM_LINKER_H
|
||||
#define LLVM_LINKER_H
|
||||
|
||||
#include <memory>
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
class LLVMContext;
|
||||
class StringRef;
|
||||
class StructType;
|
||||
|
||||
/// This class provides the core functionality of linking in LLVM. It retains a
|
||||
/// Module object which is the composite of the modules and libraries linked
|
||||
/// into it. The composite Module can be retrieved via the getModule() method.
|
||||
/// In this case the Linker still retains ownership of the Module. If the
|
||||
/// releaseModule() method is used, the ownership of the Module is transferred
|
||||
/// to the caller and the Linker object is only suitable for destruction.
|
||||
/// The Linker can link Modules from memory. By default, the linker
|
||||
/// will generate error and warning messages to stderr but this capability can
|
||||
/// be turned off with the QuietWarnings and QuietErrors flags. It can also be
|
||||
/// instructed to verbosely print out the linking actions it is taking with
|
||||
/// the Verbose flag.
|
||||
/// @brief The LLVM Linker.
|
||||
/// This class provides the core functionality of linking in LLVM. It keeps a
|
||||
/// pointer to the merged module so far. It doesn't take ownership of the
|
||||
/// module since it is assumed that the user of this class will want to do
|
||||
/// something with it after the linking.
|
||||
class Linker {
|
||||
|
||||
/// @name Types
|
||||
/// @{
|
||||
public:
|
||||
/// This enumeration is used to control various optional features of the
|
||||
/// linker.
|
||||
enum ControlFlags {
|
||||
Verbose = 1, ///< Print to stderr what steps the linker is taking
|
||||
QuietWarnings = 2, ///< Don't print warnings to stderr.
|
||||
QuietErrors = 4 ///< Don't print errors to stderr.
|
||||
};
|
||||
|
||||
enum LinkerMode {
|
||||
DestroySource = 0, // Allow source module to be destroyed.
|
||||
PreserveSource = 1 // Preserve the source module.
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
/// Construct the Linker with an empty module which will be given the
|
||||
/// name \p progname. \p progname will also be used for error messages.
|
||||
/// @brief Construct with empty module
|
||||
Linker(StringRef progname, ///< name of tool running linker
|
||||
StringRef modulename, ///< name of linker's end-result module
|
||||
LLVMContext &C, ///< Context for global info
|
||||
unsigned Flags = 0 ///< ControlFlags (one or more |'d together)
|
||||
);
|
||||
|
||||
/// Construct the Linker with a previously defined module, \p aModule. Use
|
||||
/// \p progname for the name of the program in error messages.
|
||||
/// @brief Construct with existing module
|
||||
Linker(StringRef progname, Module* aModule, unsigned Flags = 0);
|
||||
|
||||
/// Destruct the Linker.
|
||||
/// @brief Destructor
|
||||
Linker(Module *M);
|
||||
~Linker();
|
||||
Module *getModule() const { return Composite; }
|
||||
|
||||
/// @}
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
public:
|
||||
/// This method gets the composite module into which linking is being
|
||||
/// done. The Composite module starts out empty and accumulates modules
|
||||
/// linked into it via the various LinkIn* methods. This method does not
|
||||
/// release the Module to the caller. The Linker retains ownership and will
|
||||
/// destruct the Module when the Linker is destructed.
|
||||
/// @see releaseModule
|
||||
/// @brief Get the linked/composite module.
|
||||
Module* getModule() const { return Composite; }
|
||||
|
||||
/// This method releases the composite Module into which linking is being
|
||||
/// done. Ownership of the composite Module is transferred to the caller who
|
||||
/// must arrange for its destruct. After this method is called, the Linker
|
||||
/// terminates the linking session for the returned Module. It will no
|
||||
/// longer utilize the returned Module but instead resets itself for
|
||||
/// subsequent linking as if the constructor had been called.
|
||||
/// @brief Release the linked/composite module.
|
||||
Module* releaseModule();
|
||||
|
||||
/// This method returns an error string suitable for printing to the user.
|
||||
/// The return value will be empty unless an error occurred in one of the
|
||||
/// LinkIn* methods. In those cases, the LinkIn* methods will have returned
|
||||
/// true, indicating an error occurred. At most one error is retained so
|
||||
/// this function always returns the last error that occurred. Note that if
|
||||
/// the Quiet control flag is not set, the error string will have already
|
||||
/// been printed to stderr.
|
||||
/// @brief Get the text of the last error that occurred.
|
||||
const std::string &getLastError() const { return Error; }
|
||||
|
||||
/// @}
|
||||
/// @name Mutators
|
||||
/// @{
|
||||
public:
|
||||
/// This method links the \p Src module into the Linker's Composite module
|
||||
/// by calling LinkModules.
|
||||
/// @see LinkModules
|
||||
/// @returns True if an error occurs, false otherwise.
|
||||
/// @brief Link in a module.
|
||||
bool LinkInModule(
|
||||
Module* Src, ///< Module linked into \p Dest
|
||||
std::string* ErrorMsg = 0 /// Error/diagnostic string
|
||||
) {
|
||||
return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg);
|
||||
/// \brief Link \p Src into the composite. The source is destroyed if
|
||||
/// \p Mode is DestroySource and preserved if it is PreserveSource.
|
||||
/// If \p ErrorMsg is not null, information about any error is written
|
||||
/// to it.
|
||||
/// Returns true on error.
|
||||
bool linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg);
|
||||
bool linkInModule(Module *Src, std::string *ErrorMsg) {
|
||||
return linkInModule(Src, Linker::DestroySource, ErrorMsg);
|
||||
}
|
||||
|
||||
/// This is the heart of the linker. This method will take unconditional
|
||||
/// control of the \p Src module and link it into the \p Dest module. The
|
||||
/// \p Src module will be destructed or subsumed by this method. In either
|
||||
/// case it is not usable by the caller after this method is invoked. Only
|
||||
/// the \p Dest module will remain. The \p Src module is linked into the
|
||||
/// Linker's composite module such that types, global variables, functions,
|
||||
/// and etc. are matched and resolved. If an error occurs, this function
|
||||
/// returns true and ErrorMsg is set to a descriptive message about the
|
||||
/// error.
|
||||
/// @returns True if an error occurs, false otherwise.
|
||||
/// @brief Generically link two modules together.
|
||||
static bool LinkModules(Module* Dest, Module* Src, unsigned Mode,
|
||||
std::string* ErrorMsg);
|
||||
static bool LinkModules(Module *Dest, Module *Src, unsigned Mode,
|
||||
std::string *ErrorMsg);
|
||||
|
||||
/// @}
|
||||
/// @name Implementation
|
||||
/// @{
|
||||
private:
|
||||
bool warning(StringRef message);
|
||||
bool error(StringRef message);
|
||||
void verbose(StringRef message);
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
LLVMContext& Context; ///< The context for global information
|
||||
Module* Composite; ///< The composite module linked together
|
||||
unsigned Flags; ///< Flags to control optional behavior.
|
||||
std::string Error; ///< Text of error that occurred.
|
||||
std::string ProgramName; ///< Name of the program being linked
|
||||
/// @}
|
||||
|
||||
Module *Composite;
|
||||
SmallPtrSet<StructType*, 32> IdentifiedStructTypes;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -217,6 +217,8 @@ namespace llvm {
|
||||
/// convention.
|
||||
bool HasMicrosoftFastStdCallMangling; // Defaults to false.
|
||||
|
||||
bool NeedsDwarfSectionOffsetDirective;
|
||||
|
||||
//===--- Alignment Information ----------------------------------------===//
|
||||
|
||||
/// AlignDirective - The directive used to emit round up to an alignment
|
||||
@ -320,9 +322,6 @@ namespace llvm {
|
||||
/// encode inline subroutine information.
|
||||
bool DwarfUsesInlineInfoSection; // Defaults to false.
|
||||
|
||||
/// DwarfSectionOffsetDirective - Special section offset directive.
|
||||
const char* DwarfSectionOffsetDirective; // Defaults to NULL
|
||||
|
||||
/// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
|
||||
/// uses relocations for references to other .debug_* sections.
|
||||
bool DwarfUsesRelocationsAcrossSections;
|
||||
@ -412,6 +411,10 @@ namespace llvm {
|
||||
return HasMicrosoftFastStdCallMangling;
|
||||
}
|
||||
|
||||
bool needsDwarfSectionOffsetDirective() const {
|
||||
return NeedsDwarfSectionOffsetDirective;
|
||||
}
|
||||
|
||||
// Accessors.
|
||||
//
|
||||
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
|
||||
@ -557,9 +560,6 @@ namespace llvm {
|
||||
bool doesDwarfUseInlineInfoSection() const {
|
||||
return DwarfUsesInlineInfoSection;
|
||||
}
|
||||
const char *getDwarfSectionOffsetDirective() const {
|
||||
return DwarfSectionOffsetDirective;
|
||||
}
|
||||
bool doesDwarfUseRelocationsAcrossSections() const {
|
||||
return DwarfUsesRelocationsAcrossSections;
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ class MCLEBFragment : public MCFragment {
|
||||
|
||||
SmallString<8> Contents;
|
||||
public:
|
||||
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
|
||||
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
|
||||
: MCFragment(FT_LEB, SD),
|
||||
Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
|
||||
|
||||
@ -487,7 +487,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
|
||||
|
||||
public:
|
||||
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
|
||||
MCSectionData *SD)
|
||||
MCSectionData *SD = 0)
|
||||
: MCFragment(FT_Dwarf, SD),
|
||||
LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
|
||||
|
||||
@ -518,7 +518,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
|
||||
SmallString<8> Contents;
|
||||
|
||||
public:
|
||||
MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD)
|
||||
MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0)
|
||||
: MCFragment(FT_DwarfFrame, SD),
|
||||
AddrDelta(&_AddrDelta) { Contents.push_back(0); }
|
||||
|
||||
@ -590,6 +590,10 @@ class MCSectionData : public ilist_node<MCSectionData> {
|
||||
/// it.
|
||||
unsigned HasInstructions : 1;
|
||||
|
||||
/// Mapping from subsection number to insertion point for subsection numbers
|
||||
/// below that number.
|
||||
SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
|
||||
|
||||
/// @}
|
||||
|
||||
public:
|
||||
@ -633,6 +637,8 @@ class MCSectionData : public ilist_node<MCSectionData> {
|
||||
|
||||
bool empty() const { return Fragments.empty(); }
|
||||
|
||||
iterator getSubsectionInsertionPoint(unsigned Subsection);
|
||||
|
||||
bool isBundleLocked() const {
|
||||
return BundleLockState != NotBundleLocked;
|
||||
}
|
||||
|
@ -45,7 +45,14 @@ struct ELFRelocationEntry {
|
||||
|
||||
// Support lexicographic sorting.
|
||||
bool operator<(const ELFRelocationEntry &RE) const {
|
||||
return RE.r_offset < r_offset;
|
||||
if (RE.r_offset != r_offset)
|
||||
return RE.r_offset < r_offset;
|
||||
if (Type != RE.Type)
|
||||
return Type < RE.Type;
|
||||
if (Index != RE.Index)
|
||||
return Index < RE.Index;
|
||||
llvm_unreachable("ELFRelocs might be unstable!");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,8 @@ class MCELFStreamer : public MCObjectStreamer {
|
||||
|
||||
virtual void InitSections();
|
||||
virtual void InitToTextSection();
|
||||
virtual void ChangeSection(const MCSection *Section);
|
||||
virtual void ChangeSection(const MCSection *Section,
|
||||
const MCExpr *Subsection);
|
||||
virtual void EmitLabel(MCSymbol *Symbol);
|
||||
virtual void EmitDebugLabel(MCSymbol *Symbol);
|
||||
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
|
||||
|
@ -216,7 +216,9 @@ class MCSymbolRefExpr : public MCExpr {
|
||||
VK_Mips_GOT_HI16,
|
||||
VK_Mips_GOT_LO16,
|
||||
VK_Mips_CALL_HI16,
|
||||
VK_Mips_CALL_LO16
|
||||
VK_Mips_CALL_LO16,
|
||||
|
||||
VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -171,7 +171,7 @@ class MCInst {
|
||||
void clear() { Operands.clear(); }
|
||||
size_t size() { return Operands.size(); }
|
||||
|
||||
typedef SmallVector<MCOperand, 8>::iterator iterator;
|
||||
typedef SmallVectorImpl<MCOperand>::iterator iterator;
|
||||
iterator begin() { return Operands.begin(); }
|
||||
iterator end() { return Operands.end(); }
|
||||
iterator insert(iterator I, const MCOperand &Op) {
|
||||
|
@ -46,10 +46,15 @@ class MCObjectFileInfo {
|
||||
unsigned FDEEncoding;
|
||||
unsigned FDECFIEncoding;
|
||||
unsigned TTypeEncoding;
|
||||
// Section flags for eh_frame
|
||||
|
||||
/// Section flags for eh_frame
|
||||
unsigned EHSectionType;
|
||||
unsigned EHSectionFlags;
|
||||
|
||||
/// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we
|
||||
/// should emit only an EH frame.
|
||||
unsigned CompactUnwindDwarfEHFrameOnly;
|
||||
|
||||
/// TextSection - Section directive for standard text.
|
||||
///
|
||||
const MCSection *TextSection;
|
||||
@ -201,6 +206,10 @@ class MCObjectFileInfo {
|
||||
}
|
||||
unsigned getTTypeEncoding() const { return TTypeEncoding; }
|
||||
|
||||
unsigned getCompactUnwindDwarfEHFrameOnly() const {
|
||||
return CompactUnwindDwarfEHFrameOnly;
|
||||
}
|
||||
|
||||
const MCSection *getTextSection() const { return TextSection; }
|
||||
const MCSection *getDataSection() const { return DataSection; }
|
||||
const MCSection *getBSSSection() const { return BSSSection; }
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_MC_MCOBJECTSTREAMER_H
|
||||
#define LLVM_MC_MCOBJECTSTREAMER_H
|
||||
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -32,6 +33,7 @@ class raw_ostream;
|
||||
class MCObjectStreamer : public MCStreamer {
|
||||
MCAssembler *Assembler;
|
||||
MCSectionData *CurSectionData;
|
||||
MCSectionData::iterator CurInsertionPoint;
|
||||
|
||||
virtual void EmitInstToData(const MCInst &Inst) = 0;
|
||||
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
|
||||
@ -56,6 +58,11 @@ class MCObjectStreamer : public MCStreamer {
|
||||
|
||||
MCFragment *getCurrentFragment() const;
|
||||
|
||||
void insert(MCFragment *F) const {
|
||||
CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
|
||||
F->setParent(CurSectionData);
|
||||
}
|
||||
|
||||
/// Get a data fragment to write into, creating a new one if the current
|
||||
/// fragment is not a data fragment.
|
||||
MCDataFragment *getOrCreateDataFragment() const;
|
||||
@ -76,7 +83,8 @@ class MCObjectStreamer : public MCStreamer {
|
||||
virtual void EmitULEB128Value(const MCExpr *Value);
|
||||
virtual void EmitSLEB128Value(const MCExpr *Value);
|
||||
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
|
||||
virtual void ChangeSection(const MCSection *Section);
|
||||
virtual void ChangeSection(const MCSection *Section,
|
||||
const MCExpr *Subsection);
|
||||
virtual void EmitInstruction(const MCInst &Inst);
|
||||
|
||||
/// \brief Emit an instruction to a special fragment, because this instruction
|
||||
|
@ -33,15 +33,31 @@ class Twine;
|
||||
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
|
||||
class MCAsmParserSemaCallback {
|
||||
public:
|
||||
typedef struct {
|
||||
void *OpDecl;
|
||||
bool IsVarDecl;
|
||||
unsigned Length, Size, Type;
|
||||
|
||||
void clear() {
|
||||
OpDecl = 0;
|
||||
IsVarDecl = false;
|
||||
Length = 1;
|
||||
Size = 0;
|
||||
Type = 0;
|
||||
}
|
||||
} InlineAsmIdentifierInfo;
|
||||
|
||||
virtual ~MCAsmParserSemaCallback();
|
||||
virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
|
||||
unsigned &Length, unsigned &Size,
|
||||
unsigned &Type, bool &IsVarDecl) = 0;
|
||||
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
|
||||
InlineAsmIdentifierInfo &Info,
|
||||
bool IsUnevaluatedContext) = 0;
|
||||
|
||||
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
|
||||
unsigned &Offset) = 0;
|
||||
};
|
||||
|
||||
typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo
|
||||
InlineAsmIdentifierInfo;
|
||||
|
||||
/// MCAsmParser - Generic assembler parser interface, for use by target specific
|
||||
/// assembly parsers.
|
||||
@ -106,14 +122,14 @@ class MCAsmParser {
|
||||
///
|
||||
/// \return The return value is true, if warnings are fatal.
|
||||
virtual bool Warning(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
|
||||
ArrayRef<SMRange> Ranges = None) = 0;
|
||||
|
||||
/// Error - Emit an error at the location \p L, with the message \p Msg.
|
||||
///
|
||||
/// \return The return value is always true, as an idiomatic convenience to
|
||||
/// clients.
|
||||
virtual bool Error(SMLoc L, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
|
||||
ArrayRef<SMRange> Ranges = None) = 0;
|
||||
|
||||
/// Lex - Get the next AsmToken in the stream, possibly handling file
|
||||
/// inclusion first.
|
||||
@ -123,8 +139,7 @@ class MCAsmParser {
|
||||
const AsmToken &getTok();
|
||||
|
||||
/// \brief Report an error at the current lexer location.
|
||||
bool TokError(const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
|
||||
bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None);
|
||||
|
||||
/// parseIdentifier - Parse an identifier or string (as a quoted identifier)
|
||||
/// and set \p Res to the identifier contents.
|
||||
@ -151,6 +166,13 @@ class MCAsmParser {
|
||||
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
|
||||
bool parseExpression(const MCExpr *&Res);
|
||||
|
||||
/// parsePrimaryExpr - Parse a primary expression.
|
||||
///
|
||||
/// @param Res - The value of the expression. The result is undefined
|
||||
/// on error.
|
||||
/// @result - False on success.
|
||||
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
|
||||
|
||||
/// parseParenExpression - Parse an arbitrary expression, assuming that an
|
||||
/// initial '(' has already been consumed.
|
||||
///
|
||||
|
@ -37,15 +37,8 @@ class MCParsedAsmOperand {
|
||||
void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
|
||||
unsigned getMCOperandNum() { return MCOperandNum; }
|
||||
|
||||
unsigned getNameLen() {
|
||||
assert (getStartLoc().isValid() && "Invalid StartLoc!");
|
||||
assert (getEndLoc().isValid() && "Invalid EndLoc!");
|
||||
return getEndLoc().getPointer() - getStartLoc().getPointer();
|
||||
}
|
||||
|
||||
StringRef getName() {
|
||||
return StringRef(getStartLoc().getPointer(), getNameLen());
|
||||
}
|
||||
virtual StringRef getSymName() { return StringRef(); }
|
||||
virtual void *getOpDecl() { return 0; }
|
||||
|
||||
/// isToken - Is this a token operand?
|
||||
virtual bool isToken() const = 0;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmInfo;
|
||||
class MCExpr;
|
||||
class raw_ostream;
|
||||
|
||||
/// MCSection - Instances of this class represent a uniqued identifier for a
|
||||
@ -48,7 +49,8 @@ namespace llvm {
|
||||
SectionVariant getVariant() const { return Variant; }
|
||||
|
||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const = 0;
|
||||
raw_ostream &OS,
|
||||
const MCExpr *Subsection) const = 0;
|
||||
|
||||
// Convenience routines to get label names for the beginning/end of a
|
||||
// section.
|
||||
|
@ -60,7 +60,8 @@ namespace llvm {
|
||||
int getSelection () const { return Selection; }
|
||||
|
||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const;
|
||||
raw_ostream &OS,
|
||||
const MCExpr *Subsection) const;
|
||||
virtual bool UseCodeAlign() const;
|
||||
virtual bool isVirtualSection() const;
|
||||
|
||||
|
@ -70,7 +70,8 @@ class MCSectionELF : public MCSection {
|
||||
const MCSymbol *getGroup() const { return Group; }
|
||||
|
||||
void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const;
|
||||
raw_ostream &OS,
|
||||
const MCExpr *Subsection) const;
|
||||
virtual bool UseCodeAlign() const;
|
||||
virtual bool isVirtualSection() const;
|
||||
|
||||
|
@ -175,7 +175,8 @@ class MCSectionMachO : public MCSection {
|
||||
unsigned &StubSize); // Out.
|
||||
|
||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const;
|
||||
raw_ostream &OS,
|
||||
const MCExpr *Subsection) const;
|
||||
virtual bool UseCodeAlign() const;
|
||||
virtual bool isVirtualSection() const;
|
||||
|
||||
|
@ -37,6 +37,8 @@ namespace llvm {
|
||||
class raw_ostream;
|
||||
class formatted_raw_ostream;
|
||||
|
||||
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
|
||||
|
||||
/// MCStreamer - Streaming machine code generation interface. This interface
|
||||
/// is intended to provide a programatic interface that is very similar to the
|
||||
/// level that an assembler .s file provides. It has callbacks to emit bytes,
|
||||
@ -86,8 +88,7 @@ namespace llvm {
|
||||
|
||||
/// SectionStack - This is stack of current and previous section
|
||||
/// values saved by PushSection.
|
||||
SmallVector<std::pair<const MCSection *,
|
||||
const MCSection *>, 4> SectionStack;
|
||||
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
|
||||
|
||||
bool AutoInitSections;
|
||||
|
||||
@ -174,25 +175,25 @@ namespace llvm {
|
||||
|
||||
/// getCurrentSection - Return the current section that the streamer is
|
||||
/// emitting code to.
|
||||
const MCSection *getCurrentSection() const {
|
||||
MCSectionSubPair getCurrentSection() const {
|
||||
if (!SectionStack.empty())
|
||||
return SectionStack.back().first;
|
||||
return NULL;
|
||||
return MCSectionSubPair();
|
||||
}
|
||||
|
||||
/// getPreviousSection - Return the previous section that the streamer is
|
||||
/// emitting code to.
|
||||
const MCSection *getPreviousSection() const {
|
||||
MCSectionSubPair getPreviousSection() const {
|
||||
if (!SectionStack.empty())
|
||||
return SectionStack.back().second;
|
||||
return NULL;
|
||||
return MCSectionSubPair();
|
||||
}
|
||||
|
||||
/// ChangeSection - Update streamer for a new active section.
|
||||
///
|
||||
/// This is called by PopSection and SwitchSection, if the current
|
||||
/// section changes.
|
||||
virtual void ChangeSection(const MCSection *) = 0;
|
||||
virtual void ChangeSection(const MCSection *, const MCExpr *) = 0;
|
||||
|
||||
/// pushSection - Save the current and previous section on the
|
||||
/// section stack.
|
||||
@ -208,11 +209,19 @@ namespace llvm {
|
||||
bool PopSection() {
|
||||
if (SectionStack.size() <= 1)
|
||||
return false;
|
||||
const MCSection *oldSection = SectionStack.pop_back_val().first;
|
||||
const MCSection *curSection = SectionStack.back().first;
|
||||
MCSectionSubPair oldSection = SectionStack.pop_back_val().first;
|
||||
MCSectionSubPair curSection = SectionStack.back().first;
|
||||
|
||||
if (oldSection != curSection)
|
||||
ChangeSection(curSection);
|
||||
ChangeSection(curSection.first, curSection.second);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubSection(const MCExpr *Subsection) {
|
||||
if (SectionStack.empty())
|
||||
return false;
|
||||
|
||||
SwitchSection(SectionStack.back().first.first, Subsection);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -220,25 +229,26 @@ namespace llvm {
|
||||
/// @p Section. This is required to update CurSection.
|
||||
///
|
||||
/// This corresponds to assembler directives like .section, .text, etc.
|
||||
void SwitchSection(const MCSection *Section) {
|
||||
void SwitchSection(const MCSection *Section, const MCExpr *Subsection = 0) {
|
||||
assert(Section && "Cannot switch to a null section!");
|
||||
const MCSection *curSection = SectionStack.back().first;
|
||||
MCSectionSubPair curSection = SectionStack.back().first;
|
||||
SectionStack.back().second = curSection;
|
||||
if (Section != curSection) {
|
||||
SectionStack.back().first = Section;
|
||||
ChangeSection(Section);
|
||||
if (MCSectionSubPair(Section, Subsection) != curSection) {
|
||||
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
|
||||
ChangeSection(Section, Subsection);
|
||||
}
|
||||
}
|
||||
|
||||
/// SwitchSectionNoChange - Set the current section where code is being
|
||||
/// emitted to @p Section. This is required to update CurSection. This
|
||||
/// version does not call ChangeSection.
|
||||
void SwitchSectionNoChange(const MCSection *Section) {
|
||||
void SwitchSectionNoChange(const MCSection *Section,
|
||||
const MCExpr *Subsection = 0) {
|
||||
assert(Section && "Cannot switch to a null section!");
|
||||
const MCSection *curSection = SectionStack.back().first;
|
||||
MCSectionSubPair curSection = SectionStack.back().first;
|
||||
SectionStack.back().second = curSection;
|
||||
if (Section != curSection)
|
||||
SectionStack.back().first = Section;
|
||||
if (MCSectionSubPair(Section, Subsection) != curSection)
|
||||
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
|
||||
}
|
||||
|
||||
/// Initialize the streamer.
|
||||
|
@ -22,6 +22,7 @@ class MCInst;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
enum AsmRewriteKind {
|
||||
AOK_Delete = 0, // Rewrite should be ignored.
|
||||
AOK_Align, // Rewrite align as .align.
|
||||
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
|
||||
// E.g., [eax].foo.bar -> [eax].8
|
||||
@ -34,6 +35,19 @@ enum AsmRewriteKind {
|
||||
AOK_Skip // Skip emission (e.g., offset/type operators).
|
||||
};
|
||||
|
||||
const char AsmRewritePrecedence [] = {
|
||||
0, // AOK_Delete
|
||||
1, // AOK_Align
|
||||
1, // AOK_DotOperator
|
||||
1, // AOK_Emit
|
||||
3, // AOK_Imm
|
||||
3, // AOK_ImmPrefix
|
||||
2, // AOK_Input
|
||||
2, // AOK_Output
|
||||
4, // AOK_SizeDirective
|
||||
1 // AOK_Skip
|
||||
};
|
||||
|
||||
struct AsmRewrite {
|
||||
AsmRewriteKind Kind;
|
||||
SMLoc Loc;
|
||||
|
@ -11,7 +11,9 @@
|
||||
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
|
||||
|
||||
namespace llvm {
|
||||
class MCFixup;
|
||||
class MCObjectWriter;
|
||||
class MCValue;
|
||||
class raw_ostream;
|
||||
|
||||
class MCWinCOFFObjectTargetWriter {
|
||||
@ -24,7 +26,9 @@ namespace llvm {
|
||||
virtual ~MCWinCOFFObjectTargetWriter() {}
|
||||
|
||||
unsigned getMachine() const { return Machine; }
|
||||
virtual unsigned getRelocType(unsigned FixupKind) const = 0;
|
||||
virtual unsigned getRelocType(const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsCrossSection) const = 0;
|
||||
};
|
||||
|
||||
/// \brief Construct a new Win COFF writer instance.
|
||||
|
@ -9,7 +9,7 @@
|
||||
// The MachineLocation class is used to represent a simple location in a machine
|
||||
// frame. Locations will be one of two forms; a register or an address formed
|
||||
// from a base address plus an offset. Register indirection can be specified by
|
||||
// using an offset of zero.
|
||||
// explicitly passing an offset to the constructor.
|
||||
//
|
||||
// The MachineMove class is used to represent abstract move operations in the
|
||||
// prolog/epilog of a compiled function. A collection of these objects can be
|
||||
@ -37,8 +37,10 @@ class MachineLocation {
|
||||
};
|
||||
MachineLocation()
|
||||
: IsRegister(false), Register(0), Offset(0) {}
|
||||
/// Create a direct register location.
|
||||
explicit MachineLocation(unsigned R)
|
||||
: IsRegister(true), Register(R), Offset(0) {}
|
||||
/// Create a register-indirect location with an offset.
|
||||
MachineLocation(unsigned R, int O)
|
||||
: IsRegister(false), Register(R), Offset(O) {}
|
||||
|
||||
@ -48,17 +50,20 @@ class MachineLocation {
|
||||
}
|
||||
|
||||
// Accessors
|
||||
bool isIndirect() const { return !IsRegister; }
|
||||
bool isReg() const { return IsRegister; }
|
||||
unsigned getReg() const { return Register; }
|
||||
int getOffset() const { return Offset; }
|
||||
void setIsRegister(bool Is) { IsRegister = Is; }
|
||||
void setRegister(unsigned R) { Register = R; }
|
||||
void setOffset(int O) { Offset = O; }
|
||||
/// Make this location a direct register location.
|
||||
void set(unsigned R) {
|
||||
IsRegister = true;
|
||||
Register = R;
|
||||
Offset = 0;
|
||||
}
|
||||
/// Make this location a register-indirect+offset location.
|
||||
void set(unsigned R, int O) {
|
||||
IsRegister = false;
|
||||
Register = R;
|
||||
|
@ -62,10 +62,8 @@ struct SubtargetInfoKV {
|
||||
///
|
||||
/// SubtargetFeatures - Manages the enabling and disabling of subtarget
|
||||
/// specific features. Features are encoded as a string of the form
|
||||
/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
|
||||
/// "+attr1,+attr2,-attr3,...,+attrN"
|
||||
/// A comma separates each feature from the next (all lowercase.)
|
||||
/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
|
||||
/// value is "generic" then the CPU subtype should be generic for the target.
|
||||
/// Each of the remaining features is prefixed with + or - indicating whether
|
||||
/// that feature should be enabled or disabled contrary to the cpu
|
||||
/// specification.
|
||||
|
@ -41,11 +41,17 @@ class Binary {
|
||||
// Object and children.
|
||||
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_MachO32L, // MachO 32-bit, little endian
|
||||
ID_MachO32B, // MachO 32-bit, big endian
|
||||
ID_MachO64L, // MachO 64-bit, little endian
|
||||
ID_MachO64B, // MachO 64-bit, big endian
|
||||
|
||||
ID_EndObjects
|
||||
};
|
||||
|
||||
@ -56,6 +62,13 @@ class Binary {
|
||||
return is64Bits ? ID_ELF64B : ID_ELF32B;
|
||||
}
|
||||
|
||||
static unsigned int getMachOType(bool isLE, bool is64Bits) {
|
||||
if (isLE)
|
||||
return is64Bits ? ID_MachO64L : ID_MachO32L;
|
||||
else
|
||||
return is64Bits ? ID_MachO64B : ID_MachO32B;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~Binary();
|
||||
|
||||
@ -79,7 +92,7 @@ class Binary {
|
||||
}
|
||||
|
||||
bool isMachO() const {
|
||||
return TypeID == ID_MachO;
|
||||
return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
|
||||
}
|
||||
|
||||
bool isCOFF() const {
|
||||
@ -87,7 +100,8 @@ class Binary {
|
||||
}
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B);
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -81,9 +81,8 @@ template<class ELFT>
|
||||
struct ELFDataTypeTypedefHelper;
|
||||
|
||||
/// ELF 32bit types.
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> >
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
|
||||
: ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
|
||||
typedef uint32_t value_type;
|
||||
typedef support::detail::packed_endian_specific_integral
|
||||
@ -95,9 +94,8 @@ struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> >
|
||||
};
|
||||
|
||||
/// ELF 64bit types.
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> >
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
|
||||
: ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
|
||||
typedef uint64_t value_type;
|
||||
typedef support::detail::packed_endian_specific_integral
|
||||
@ -109,27 +107,29 @@ struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> >
|
||||
};
|
||||
|
||||
// I really don't like doing this, but the alternative is copypasta.
|
||||
#define LLVM_ELF_IMPORT_TYPES(ELFT) \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Addr Elf_Addr; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Off Elf_Off; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Half Elf_Half; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Word Elf_Word; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sword Elf_Sword; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Xword Elf_Xword; \
|
||||
typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sxword Elf_Sxword;
|
||||
#define LLVM_ELF_IMPORT_TYPES(E, M, W) \
|
||||
typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Addr Elf_Addr; \
|
||||
typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Off Elf_Off; \
|
||||
typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Half Elf_Half; \
|
||||
typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Word Elf_Word; \
|
||||
typedef typename \
|
||||
ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sword Elf_Sword; \
|
||||
typedef typename \
|
||||
ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Xword Elf_Xword; \
|
||||
typedef typename \
|
||||
ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sxword Elf_Sxword;
|
||||
|
||||
// This is required to get template types into a macro :(
|
||||
#define LLVM_ELF_COMMA ,
|
||||
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \
|
||||
ELFT::Is64Bits)
|
||||
|
||||
// Section header.
|
||||
// Section header.
|
||||
template<class ELFT>
|
||||
struct Elf_Shdr_Base;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Word sh_name; // Section name (index into string table)
|
||||
Elf_Word sh_type; // Section type (SHT_*)
|
||||
Elf_Word sh_flags; // Section flags (SHF_*)
|
||||
@ -142,11 +142,9 @@ struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
Elf_Word sh_entsize; // Size of records contained within the section
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Word sh_name; // Section name (index into string table)
|
||||
Elf_Word sh_type; // Section type (SHT_*)
|
||||
Elf_Xword sh_flags; // Section flags (SHF_*)
|
||||
@ -175,11 +173,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
|
||||
template<class ELFT>
|
||||
struct Elf_Sym_Base;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Word st_name; // Symbol name (index into string table)
|
||||
Elf_Addr st_value; // Value or address associated with the symbol
|
||||
Elf_Word st_size; // Size of the symbol
|
||||
@ -188,11 +184,9 @@ struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
Elf_Half st_shndx; // Which section (header table index) it's defined in
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Word st_name; // Symbol name (index into string table)
|
||||
unsigned char st_info; // Symbol's type and binding attributes
|
||||
unsigned char st_other; // Must be zero; reserved
|
||||
@ -220,7 +214,7 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
|
||||
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
|
||||
template<class ELFT>
|
||||
struct Elf_Versym_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
|
||||
};
|
||||
|
||||
@ -231,7 +225,7 @@ struct Elf_Verdaux_Impl;
|
||||
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
|
||||
template<class ELFT>
|
||||
struct Elf_Verdef_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
|
||||
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
|
||||
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
|
||||
@ -251,7 +245,7 @@ struct Elf_Verdef_Impl {
|
||||
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
|
||||
template<class ELFT>
|
||||
struct Elf_Verdaux_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
Elf_Word vda_name; // Version name (offset in string table)
|
||||
Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
|
||||
};
|
||||
@ -260,7 +254,7 @@ struct Elf_Verdaux_Impl {
|
||||
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
|
||||
template<class ELFT>
|
||||
struct Elf_Verneed_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
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)
|
||||
@ -272,7 +266,7 @@ struct Elf_Verneed_Impl {
|
||||
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
|
||||
template<class ELFT>
|
||||
struct Elf_Vernaux_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
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
|
||||
@ -285,11 +279,9 @@ struct Elf_Vernaux_Impl {
|
||||
template<class ELFT>
|
||||
struct Elf_Dyn_Base;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Sword d_tag;
|
||||
union {
|
||||
Elf_Word d_val;
|
||||
@ -297,11 +289,9 @@ struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
} d_un;
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Sxword d_tag;
|
||||
union {
|
||||
Elf_Xword d_val;
|
||||
@ -323,11 +313,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
|
||||
template<class ELFT, bool isRela>
|
||||
struct Elf_Rel_Base;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, false> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
|
||||
Elf_Word r_info; // Symbol table index and type of relocation to apply
|
||||
|
||||
@ -340,11 +328,9 @@ struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, false> {
|
||||
}
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, false> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
|
||||
Elf_Xword r_info; // Symbol table index and type of relocation to apply
|
||||
|
||||
@ -365,11 +351,9 @@ struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, false> {
|
||||
}
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, true> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
|
||||
Elf_Word r_info; // Symbol table index and type of relocation to apply
|
||||
Elf_Sword r_addend; // Compute value for relocatable field by adding this
|
||||
@ -383,11 +367,9 @@ struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, true> {
|
||||
}
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, true> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
|
||||
Elf_Xword r_info; // Symbol table index and type of relocation to apply
|
||||
Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
|
||||
@ -411,12 +393,10 @@ struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, true> {
|
||||
template<class ELFT, bool isRela>
|
||||
struct Elf_Rel_Impl;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
|
||||
struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, true>, isRela>
|
||||
: Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
|
||||
struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, isRela>
|
||||
: Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, isRela> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
|
||||
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
|
||||
// and ELF64_R_INFO macros defined in the ELF specification:
|
||||
@ -433,12 +413,10 @@ struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, true>, isRela>
|
||||
}
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
|
||||
struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, false>, isRela>
|
||||
: Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela> {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
|
||||
struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, isRela>
|
||||
: Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, isRela> {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
|
||||
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
|
||||
// and ELF32_R_INFO macros defined in the ELF specification:
|
||||
@ -457,7 +435,7 @@ struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, false>, isRela>
|
||||
|
||||
template<class ELFT>
|
||||
struct Elf_Ehdr_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
|
||||
Elf_Half e_type; // Type of file (see ET_*)
|
||||
Elf_Half e_machine; // Required architecture for this file (see EM_*)
|
||||
@ -483,11 +461,9 @@ struct Elf_Ehdr_Impl {
|
||||
template<class ELFT>
|
||||
struct Elf_Phdr_Impl;
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA false>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
|
||||
Elf_Word p_type; // Type of segment
|
||||
Elf_Off p_offset; // FileOffset where segment is located, in bytes
|
||||
Elf_Addr p_vaddr; // Virtual Address of beginning of segment
|
||||
@ -498,11 +474,9 @@ struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, false> > {
|
||||
Elf_Word p_align; // Segment alignment constraint
|
||||
};
|
||||
|
||||
template<template<endianness, std::size_t, bool> class ELFT,
|
||||
endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
|
||||
MaxAlign LLVM_ELF_COMMA true>)
|
||||
template<endianness TargetEndianness, std::size_t MaxAlign>
|
||||
struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
|
||||
LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
|
||||
Elf_Word p_type; // Type of segment
|
||||
Elf_Word p_flags; // Segment flags
|
||||
Elf_Off p_offset; // FileOffset where segment is located, in bytes
|
||||
@ -515,7 +489,7 @@ struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, true> > {
|
||||
|
||||
template<class ELFT>
|
||||
class ELFObjectFile : public ObjectFile {
|
||||
LLVM_ELF_IMPORT_TYPES(ELFT)
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
|
||||
public:
|
||||
/// \brief Iterate over constant sized entities.
|
||||
@ -633,6 +607,8 @@ class ELFObjectFile : public ObjectFile {
|
||||
mutable const char *dt_soname;
|
||||
|
||||
private:
|
||||
uint64_t getROffset(DataRefImpl Rel) const;
|
||||
|
||||
// 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> {
|
||||
@ -689,6 +665,7 @@ class ELFObjectFile : public ObjectFile {
|
||||
protected:
|
||||
const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
|
||||
void validateSymbol(DataRefImpl Symb) const;
|
||||
StringRef getRelocationTypeName(uint32_t Type) const;
|
||||
|
||||
public:
|
||||
error_code getSymbolName(const Elf_Shdr *section,
|
||||
@ -705,6 +682,7 @@ class ELFObjectFile : public ObjectFile {
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
|
||||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
|
||||
@ -1137,6 +1115,21 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
|
||||
}
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
|
||||
uint32_t &Res) const {
|
||||
uint32_t flags;
|
||||
getSymbolFlags(Symb, flags);
|
||||
if (flags & SymbolRef::SF_Common) {
|
||||
uint64_t Value;
|
||||
getSymbolValue(Symb, Value);
|
||||
Res = Value;
|
||||
} else {
|
||||
Res = 0;
|
||||
}
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
|
||||
uint64_t &Result) const {
|
||||
@ -1546,45 +1539,32 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
|
||||
uint64_t &Result) const {
|
||||
uint64_t offset;
|
||||
const Elf_Shdr *sec = getSection(Rel.w.b);
|
||||
switch (sec->sh_type) {
|
||||
default :
|
||||
report_fatal_error("Invalid section type in Rel!");
|
||||
case ELF::SHT_REL : {
|
||||
offset = getRel(Rel)->r_offset;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_RELA : {
|
||||
offset = getRela(Rel)->r_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Result = offset;
|
||||
assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) &&
|
||||
"Only executable and shared objects files have addresses");
|
||||
Result = getROffset(Rel);
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
|
||||
uint64_t &Result) const {
|
||||
uint64_t offset;
|
||||
assert(Header->e_type == ELF::ET_REL &&
|
||||
"Only relocatable object files have relocation offsets");
|
||||
Result = getROffset(Rel);
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
|
||||
const Elf_Shdr *sec = getSection(Rel.w.b);
|
||||
switch (sec->sh_type) {
|
||||
default :
|
||||
report_fatal_error("Invalid section type in Rel!");
|
||||
case ELF::SHT_REL : {
|
||||
offset = getRel(Rel)->r_offset;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_RELA : {
|
||||
offset = getRela(Rel)->r_offset;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
report_fatal_error("Invalid section type in Rel!");
|
||||
case ELF::SHT_REL:
|
||||
return getRel(Rel)->r_offset;
|
||||
case ELF::SHT_RELA:
|
||||
return getRela(Rel)->r_offset;
|
||||
}
|
||||
|
||||
Result = offset - sec->sh_addr;
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
@ -1607,29 +1587,14 @@ error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
|
||||
}
|
||||
|
||||
#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
|
||||
case ELF::enum: res = #enum; break;
|
||||
case ELF::enum: Res = #enum; break;
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
|
||||
const Elf_Shdr *sec = getSection(Rel.w.b);
|
||||
uint32_t type;
|
||||
StringRef res;
|
||||
switch (sec->sh_type) {
|
||||
default :
|
||||
return object_error::parse_failed;
|
||||
case ELF::SHT_REL : {
|
||||
type = getRel(Rel)->getType(isMips64EL());
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_RELA : {
|
||||
type = getRela(Rel)->getType(isMips64EL());
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
|
||||
StringRef Res = "Unknown";
|
||||
switch (Header->e_machine) {
|
||||
case ELF::EM_X86_64:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
|
||||
@ -1657,17 +1622,22 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPLT64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLTOFF64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
|
||||
default:
|
||||
res = "Unknown";
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_IRELATIVE);
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_386:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
|
||||
@ -1708,12 +1678,11 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
|
||||
default:
|
||||
res = "Unknown";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_MIPS:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32);
|
||||
@ -1765,12 +1734,12 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT);
|
||||
default:
|
||||
res = "Unknown";
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM);
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_AARCH64:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32);
|
||||
@ -1844,13 +1813,11 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL);
|
||||
|
||||
default:
|
||||
res = "Unknown";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_ARM:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32);
|
||||
@ -1982,12 +1949,11 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32);
|
||||
default:
|
||||
res = "Unknown";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_HEXAGON:
|
||||
switch (type) {
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL);
|
||||
@ -2074,19 +2040,184 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X);
|
||||
default:
|
||||
res = "Unknown";
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = "Unknown";
|
||||
case ELF::EM_PPC:
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR24);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HI);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRTAKEN);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRNTAKEN);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL24);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA);
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_PPC64:
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HI);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR14);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL24);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD);
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_S390:
|
||||
switch (Type) {
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_NONE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_8);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_12);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT12);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_COPY);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GLOB_DAT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_JMP_SLOT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_RELATIVE);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPC);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16DBL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT16DBL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32DBL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32DBL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPCDBL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTENT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT12);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLTENT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF16);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LOAD);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GDCALL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDCALL);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE12);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IEENT);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO32);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO64);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPMOD);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPOFF);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_TPOFF);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_20);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT20);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT20);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE20);
|
||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_IRELATIVE);
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
Result.append(res.begin(), res.end());
|
||||
return object_error::success;
|
||||
return Res;
|
||||
}
|
||||
|
||||
#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getRelocationTypeName(
|
||||
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
|
||||
const Elf_Shdr *sec = getSection(Rel.w.b);
|
||||
uint32_t type;
|
||||
switch (sec->sh_type) {
|
||||
default :
|
||||
return object_error::parse_failed;
|
||||
case ELF::SHT_REL : {
|
||||
type = getRel(Rel)->getType(isMips64EL());
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_RELA : {
|
||||
type = getRela(Rel)->getType(isMips64EL());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isMips64EL()) {
|
||||
StringRef Name = getRelocationTypeName(type);
|
||||
Result.append(Name.begin(), Name.end());
|
||||
} else {
|
||||
uint8_t Type1 = (type >> 0) & 0xFF;
|
||||
uint8_t Type2 = (type >> 8) & 0xFF;
|
||||
uint8_t Type3 = (type >> 16) & 0xFF;
|
||||
|
||||
// Concat all three relocation type names.
|
||||
StringRef Name = getRelocationTypeName(Type1);
|
||||
Result.append(Name.begin(), Name.end());
|
||||
|
||||
Name = getRelocationTypeName(Type2);
|
||||
Result.append(1, '/');
|
||||
Result.append(Name.begin(), Name.end());
|
||||
|
||||
Name = getRelocationTypeName(Type3);
|
||||
Result.append(1, '/');
|
||||
Result.append(Name.begin(), Name.end());
|
||||
}
|
||||
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
error_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo(
|
||||
DataRefImpl Rel, int64_t &Result) const {
|
||||
@ -2189,8 +2320,7 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
|
||||
: ObjectFile(getELFType(
|
||||
static_cast<endianness>(ELFT::TargetEndianness) == support::little,
|
||||
ELFT::Is64Bits),
|
||||
Object,
|
||||
ec)
|
||||
Object)
|
||||
, isDyldELFObject(false)
|
||||
, SectionHeaderTable(0)
|
||||
, dot_shstrtab_sec(0)
|
||||
@ -2566,6 +2696,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
|
||||
return "ELF64-aarch64";
|
||||
case ELF::EM_PPC64:
|
||||
return "ELF64-ppc64";
|
||||
case ELF::EM_S390:
|
||||
return "ELF64-s390";
|
||||
default:
|
||||
return "ELF64-unknown";
|
||||
}
|
||||
@ -2593,6 +2725,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
|
||||
Triple::mipsel : Triple::mips;
|
||||
case ELF::EM_PPC64:
|
||||
return Triple::ppc64;
|
||||
case ELF::EM_S390:
|
||||
return Triple::systemz;
|
||||
default:
|
||||
return Triple::UnknownArch;
|
||||
}
|
||||
|
@ -7,16 +7,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the MachOObjectFile class, which binds the MachOObject
|
||||
// class to the generic ObjectFile wrapper.
|
||||
// This file declares the MachOObjectFile class, which implement the ObjectFile
|
||||
// interface for MachO files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MACHO_H
|
||||
#define LLVM_OBJECT_MACHO_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Object/MachOObject.h"
|
||||
#include "llvm/Object/MachOFormat.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/MachO.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -24,46 +25,26 @@
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
typedef MachOObject::LoadCommandInfo LoadCommandInfo;
|
||||
|
||||
class MachOObjectFile : public ObjectFile {
|
||||
public:
|
||||
MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec);
|
||||
struct LoadCommandInfo {
|
||||
const char *Ptr; // Where in memory the load command is.
|
||||
macho::LoadCommand C; // The command itself.
|
||||
};
|
||||
|
||||
virtual symbol_iterator begin_symbols() const;
|
||||
virtual symbol_iterator end_symbols() const;
|
||||
virtual symbol_iterator begin_dynamic_symbols() const;
|
||||
virtual symbol_iterator end_dynamic_symbols() const;
|
||||
virtual library_iterator begin_libraries_needed() const;
|
||||
virtual library_iterator end_libraries_needed() const;
|
||||
virtual section_iterator begin_sections() const;
|
||||
virtual section_iterator end_sections() const;
|
||||
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
|
||||
error_code &ec);
|
||||
|
||||
virtual uint8_t getBytesInAddress() const;
|
||||
virtual StringRef getFileFormatName() const;
|
||||
virtual unsigned getArch() const;
|
||||
virtual StringRef getLoadName() const;
|
||||
|
||||
// In a MachO file, sections have a segment name. This is used in the .o
|
||||
// files. They have a single segment, but this field specifies which segment
|
||||
// a section should be put in in the final object.
|
||||
error_code getSectionFinalSegmentName(DataRefImpl Sec, StringRef &Res) const;
|
||||
|
||||
MachOObject *getObject() { return MachOObj.get(); }
|
||||
|
||||
static inline bool classof(const Binary *v) {
|
||||
return v->isMachO();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb,
|
||||
SymbolRef::Type &Res) const;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
|
||||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
|
||||
virtual error_code getSymbolSection(DataRefImpl Symb,
|
||||
section_iterator &Res) const;
|
||||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
|
||||
@ -82,21 +63,17 @@ class MachOObjectFile : public ObjectFile {
|
||||
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S,
|
||||
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
|
||||
bool &Result) const;
|
||||
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
|
||||
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
|
||||
|
||||
virtual error_code getRelocationNext(DataRefImpl Rel,
|
||||
RelocationRef &Res) const;
|
||||
virtual error_code getRelocationAddress(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationOffset(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationSymbol(DataRefImpl Rel,
|
||||
SymbolRef &Res) const;
|
||||
virtual error_code getRelocationType(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
|
||||
virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationTypeName(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
|
||||
@ -108,28 +85,98 @@ class MachOObjectFile : public ObjectFile {
|
||||
virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
|
||||
virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
|
||||
|
||||
// TODO: Would be useful to have an iterator based version
|
||||
// of the load command interface too.
|
||||
|
||||
virtual symbol_iterator begin_symbols() const;
|
||||
virtual symbol_iterator end_symbols() const;
|
||||
|
||||
virtual symbol_iterator begin_dynamic_symbols() const;
|
||||
virtual symbol_iterator end_dynamic_symbols() const;
|
||||
|
||||
virtual section_iterator begin_sections() const;
|
||||
virtual section_iterator end_sections() const;
|
||||
|
||||
virtual library_iterator begin_libraries_needed() const;
|
||||
virtual library_iterator end_libraries_needed() const;
|
||||
|
||||
virtual uint8_t getBytesInAddress() const;
|
||||
|
||||
virtual StringRef getFileFormatName() const;
|
||||
virtual unsigned getArch() const;
|
||||
|
||||
virtual StringRef getLoadName() const;
|
||||
|
||||
relocation_iterator getSectionRelBegin(unsigned Index) const;
|
||||
relocation_iterator getSectionRelEnd(unsigned Index) const;
|
||||
|
||||
// In a MachO file, sections have a segment name. This is used in the .o
|
||||
// files. They have a single segment, but this field specifies which segment
|
||||
// a section should be put in in the final object.
|
||||
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
|
||||
|
||||
// Names are stored as 16 bytes. These returns the raw 16 bytes without
|
||||
// interpreting them as a C string.
|
||||
ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
|
||||
ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
|
||||
|
||||
// MachO specific Info about relocations.
|
||||
bool isRelocationScattered(const macho::RelocationEntry &RE) const;
|
||||
unsigned getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const;
|
||||
bool getPlainRelocationExternal(const macho::RelocationEntry &RE) const;
|
||||
bool getScatteredRelocationScattered(const macho::RelocationEntry &RE) const;
|
||||
uint32_t getScatteredRelocationValue(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationAddress(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const;
|
||||
SectionRef getRelocationSection(const macho::RelocationEntry &RE) const;
|
||||
|
||||
// Walk load commands.
|
||||
LoadCommandInfo getFirstLoadCommandInfo() const;
|
||||
LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;
|
||||
|
||||
// MachO specific structures.
|
||||
macho::Section getSection(DataRefImpl DRI) const;
|
||||
macho::Section64 getSection64(DataRefImpl DRI) const;
|
||||
macho::Section getSection(const LoadCommandInfo &L, unsigned Index) const;
|
||||
macho::Section64 getSection64(const LoadCommandInfo &L, unsigned Index) const;
|
||||
macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;
|
||||
macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;
|
||||
|
||||
macho::LinkeditDataLoadCommand
|
||||
getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
|
||||
macho::SegmentLoadCommand
|
||||
getSegmentLoadCommand(const LoadCommandInfo &L) const;
|
||||
macho::Segment64LoadCommand
|
||||
getSegment64LoadCommand(const LoadCommandInfo &L) const;
|
||||
macho::LinkerOptionsLoadCommand
|
||||
getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
|
||||
|
||||
macho::RelocationEntry getRelocation(DataRefImpl Rel) const;
|
||||
macho::Header getHeader() const;
|
||||
macho::Header64Ext getHeader64Ext() const;
|
||||
macho::IndirectSymbolTableEntry
|
||||
getIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
|
||||
unsigned Index) const;
|
||||
macho::DataInCodeTableEntry getDataInCodeTableEntry(uint32_t DataOffset,
|
||||
unsigned Index) const;
|
||||
macho::SymtabLoadCommand getSymtabLoadCommand() const;
|
||||
macho::DysymtabLoadCommand getDysymtabLoadCommand() const;
|
||||
|
||||
StringRef getStringTableData() const;
|
||||
bool is64Bit() const;
|
||||
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
|
||||
|
||||
static bool classof(const Binary *v) {
|
||||
return v->isMachO();
|
||||
}
|
||||
|
||||
private:
|
||||
OwningPtr<MachOObject> MachOObj;
|
||||
mutable uint32_t RegisteredStringTable;
|
||||
typedef SmallVector<DataRefImpl, 1> SectionList;
|
||||
typedef SmallVector<const char*, 1> SectionList;
|
||||
SectionList Sections;
|
||||
|
||||
|
||||
void moveToNextSection(DataRefImpl &DRI) const;
|
||||
void getSymbolTableEntry(DataRefImpl DRI,
|
||||
InMemoryStruct<macho::SymbolTableEntry> &Res) const;
|
||||
void getSymbol64TableEntry(DataRefImpl DRI,
|
||||
InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
|
||||
void moveToNextSymbol(DataRefImpl &DRI) const;
|
||||
void getSection(DataRefImpl DRI, InMemoryStruct<macho::Section> &Res) const;
|
||||
void getSection64(DataRefImpl DRI,
|
||||
InMemoryStruct<macho::Section64> &Res) const;
|
||||
void getRelocation(DataRefImpl Rel,
|
||||
InMemoryStruct<macho::RelocationEntry> &Res) const;
|
||||
std::size_t getSectionIndex(DataRefImpl Sec) const;
|
||||
|
||||
void printRelocationTargetName(InMemoryStruct<macho::RelocationEntry>& RE,
|
||||
raw_string_ostream &fmt) const;
|
||||
const char *SymtabLoadCmd;
|
||||
const char *DysymtabLoadCmd;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,210 +0,0 @@
|
||||
//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MACHOOBJECT_H
|
||||
#define LLVM_OBJECT_MACHOOBJECT_H
|
||||
|
||||
#include "llvm/ADT/InMemoryStruct.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/MachOFormat.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
class raw_ostream;
|
||||
|
||||
namespace object {
|
||||
|
||||
/// \brief Wrapper object for manipulating Mach-O object files.
|
||||
///
|
||||
/// This class is designed to implement a full-featured, efficient, portable,
|
||||
/// and robust Mach-O interface to Mach-O object files. It does not attempt to
|
||||
/// smooth over rough edges in the Mach-O format or generalize access to object
|
||||
/// independent features.
|
||||
///
|
||||
/// The class is designed around accessing the Mach-O object which is expected
|
||||
/// to be fully loaded into memory.
|
||||
///
|
||||
/// This class is *not* suitable for concurrent use. For efficient operation,
|
||||
/// the class uses APIs which rely on the ability to cache the results of
|
||||
/// certain calls in internal objects which are not safe for concurrent
|
||||
/// access. This allows the API to be zero-copy on the common paths.
|
||||
//
|
||||
// FIXME: It would be cool if we supported a "paged" MemoryBuffer
|
||||
// implementation. This would allow us to implement a more sensible version of
|
||||
// MemoryObject which can work like a MemoryBuffer, but be more efficient for
|
||||
// objects which are in the current address space.
|
||||
class MachOObject {
|
||||
public:
|
||||
struct LoadCommandInfo {
|
||||
/// The load command information.
|
||||
macho::LoadCommand Command;
|
||||
|
||||
/// The offset to the start of the load command in memory.
|
||||
uint64_t Offset;
|
||||
};
|
||||
|
||||
private:
|
||||
OwningPtr<MemoryBuffer> Buffer;
|
||||
|
||||
/// Whether the object is little endian.
|
||||
bool IsLittleEndian;
|
||||
/// Whether the object is 64-bit.
|
||||
bool Is64Bit;
|
||||
/// Whether the object is swapped endianness from the host.
|
||||
bool IsSwappedEndian;
|
||||
/// Whether the string table has been registered.
|
||||
bool HasStringTable;
|
||||
|
||||
/// The cached information on the load commands.
|
||||
LoadCommandInfo *LoadCommands;
|
||||
mutable unsigned NumLoadedCommands;
|
||||
|
||||
/// The cached copy of the header.
|
||||
macho::Header Header;
|
||||
macho::Header64Ext Header64Ext;
|
||||
|
||||
/// Cache string table information.
|
||||
StringRef StringTable;
|
||||
|
||||
private:
|
||||
MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
|
||||
|
||||
public:
|
||||
~MachOObject();
|
||||
|
||||
/// \brief Load a Mach-O object from a MemoryBuffer object.
|
||||
///
|
||||
/// \param Buffer - The buffer to load the object from. This routine takes
|
||||
/// exclusive ownership of the buffer (which is passed to the returned object
|
||||
/// on success).
|
||||
/// \param ErrorStr [out] - If given, will be set to a user readable error
|
||||
/// message on failure.
|
||||
/// \returns The loaded object, or null on error.
|
||||
static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
|
||||
std::string *ErrorStr = 0);
|
||||
|
||||
/// @name File Information
|
||||
/// @{
|
||||
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
bool isSwappedEndian() const { return IsSwappedEndian; }
|
||||
bool is64Bit() const { return Is64Bit; }
|
||||
|
||||
unsigned getHeaderSize() const {
|
||||
return Is64Bit ? macho::Header64Size : macho::Header32Size;
|
||||
}
|
||||
|
||||
StringRef getData(size_t Offset, size_t Size) const;
|
||||
|
||||
/// @}
|
||||
/// @name String Table Data
|
||||
/// @{
|
||||
|
||||
StringRef getStringTableData() const {
|
||||
assert(HasStringTable && "String table has not been registered!");
|
||||
return StringTable;
|
||||
}
|
||||
|
||||
StringRef getStringAtIndex(unsigned Index) const {
|
||||
size_t End = getStringTableData().find('\0', Index);
|
||||
return getStringTableData().slice(Index, End);
|
||||
}
|
||||
|
||||
void RegisterStringTable(macho::SymtabLoadCommand &SLC);
|
||||
|
||||
/// @}
|
||||
/// @name Object Header Access
|
||||
/// @{
|
||||
|
||||
const macho::Header &getHeader() const { return Header; }
|
||||
const macho::Header64Ext &getHeader64Ext() const {
|
||||
assert(is64Bit() && "Invalid access!");
|
||||
return Header64Ext;
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Object Structure Access
|
||||
/// @{
|
||||
|
||||
/// \brief Retrieve the information for the given load command.
|
||||
const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
|
||||
|
||||
void ReadSegmentLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
|
||||
void ReadSegment64LoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
|
||||
void ReadSymtabLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
|
||||
void ReadDysymtabLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
|
||||
void ReadLinkeditDataLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
|
||||
void ReadLinkerOptionsLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
|
||||
void ReadIndirectSymbolTableEntry(
|
||||
const macho::DysymtabLoadCommand &DLC,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
|
||||
void ReadSection(
|
||||
const LoadCommandInfo &LCI,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::Section> &Res) const;
|
||||
void ReadSection64(
|
||||
const LoadCommandInfo &LCI,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::Section64> &Res) const;
|
||||
void ReadRelocationEntry(
|
||||
uint64_t RelocationTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::RelocationEntry> &Res) const;
|
||||
void ReadSymbolTableEntry(
|
||||
uint64_t SymbolTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::SymbolTableEntry> &Res) const;
|
||||
void ReadSymbol64TableEntry(
|
||||
uint64_t SymbolTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
|
||||
void ReadDataInCodeTableEntry(
|
||||
uint64_t TableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
|
||||
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Object Dump Facilities
|
||||
/// @{
|
||||
/// dump - Support for debugging, callable in GDB: V->dump()
|
||||
//
|
||||
void dump() const;
|
||||
void dumpHeader() const;
|
||||
|
||||
/// print - Implement operator<< on Value.
|
||||
///
|
||||
void print(raw_ostream &O) const;
|
||||
void printHeader(raw_ostream &O) const;
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
|
||||
V.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // end namespace object
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -217,6 +217,8 @@ class SymbolRef {
|
||||
/// mapped).
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getFileOffset(uint64_t &Result) const;
|
||||
/// @brief Get the alignment of this symbol as the actual value (not log 2).
|
||||
error_code getAlignment(uint32_t &Result) const;
|
||||
error_code getSize(uint64_t &Result) const;
|
||||
error_code getType(SymbolRef::Type &Result) const;
|
||||
|
||||
@ -227,9 +229,6 @@ class SymbolRef {
|
||||
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
|
||||
error_code getFlags(uint32_t &Result) const;
|
||||
|
||||
/// @brief Return true for common symbols such as uninitialized globals
|
||||
error_code isCommon(bool &Result) const;
|
||||
|
||||
/// @brief Get section this symbol is defined in reference to. Result is
|
||||
/// end_sections() if it is undefined or is an absolute symbol.
|
||||
error_code getSection(section_iterator &Result) const;
|
||||
@ -276,7 +275,7 @@ class ObjectFile : public Binary {
|
||||
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
protected:
|
||||
ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
|
||||
ObjectFile(unsigned int Type, MemoryBuffer *source);
|
||||
|
||||
const uint8_t *base() const {
|
||||
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
|
||||
@ -295,6 +294,7 @@ class ObjectFile : public Binary {
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
|
||||
virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb,
|
||||
SymbolRef::Type &Res) const = 0;
|
||||
@ -428,6 +428,10 @@ inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getAlignment(uint32_t &Result) const {
|
||||
return OwningObject->getSymbolAlignment(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getSize(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolSize(SymbolPimpl, Result);
|
||||
}
|
||||
|
@ -102,6 +102,16 @@ class RelocVisitor {
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-s390") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_390_32:
|
||||
return visitELF_390_32(R, Value);
|
||||
case llvm::ELF::R_390_64:
|
||||
return visitELF_390_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
}
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
@ -133,7 +143,7 @@ class RelocVisitor {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint64_t Address;
|
||||
R.getAddress(Address);
|
||||
R.getOffset(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
}
|
||||
|
||||
@ -151,7 +161,7 @@ class RelocVisitor {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint64_t Address;
|
||||
R.getAddress(Address);
|
||||
R.getOffset(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
|
||||
@ -202,6 +212,24 @@ class RelocVisitor {
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
|
||||
// SystemZ ELF
|
||||
RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
int64_t Res = Value + Addend;
|
||||
|
||||
// Overflow check allows for both signed and unsigned interpretation.
|
||||
if (Res < INT32_MIN || Res > UINT32_MAX)
|
||||
HasError = true;
|
||||
|
||||
return RelocToApply(static_cast<uint32_t>(Res), 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LLVM_PASSMANAGER_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -98,6 +99,9 @@ class FunctionPassManager : public PassManagerBase {
|
||||
Module *M;
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef)
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,8 @@
|
||||
#define LLVM_PASSREGISTRY_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -79,6 +81,9 @@ class PassRegistry {
|
||||
void removeRegistrationListener(PassRegistrationListener *L);
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
46
contrib/llvm/include/llvm/Support/CBindingWrapping.h
Normal file
46
contrib/llvm/include/llvm/Support/CBindingWrapping.h
Normal file
@ -0,0 +1,46 @@
|
||||
//===- llvm/Support/CBindingWrapph.h - C Interface Wrapping -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the wrapping macros for the C interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_C_BINDING_WRAPPING_H
|
||||
#define LLVM_C_BINDING_WRAPPING_H
|
||||
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
inline ty *unwrap(ref P) { \
|
||||
return reinterpret_cast<ty*>(P); \
|
||||
} \
|
||||
\
|
||||
inline ref wrap(const ty *P) { \
|
||||
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
|
||||
}
|
||||
|
||||
#define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
\
|
||||
template<typename T> \
|
||||
inline T *unwrap(ref P) { \
|
||||
return cast<T>(unwrap(P)); \
|
||||
}
|
||||
|
||||
#define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
|
||||
\
|
||||
template<typename T> \
|
||||
inline T *unwrap(ref P) { \
|
||||
T *Q = (T*)unwrap(P); \
|
||||
assert(Q && "Invalid cast!"); \
|
||||
return Q; \
|
||||
}
|
||||
|
||||
#endif
|
@ -15,6 +15,9 @@
|
||||
#ifndef LLVM_SUPPORT_CODEGEN_H
|
||||
#define LLVM_SUPPORT_CODEGEN_H
|
||||
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Relocation model types.
|
||||
@ -47,6 +50,42 @@ namespace llvm {
|
||||
};
|
||||
}
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
inline CodeModel::Model unwrap(LLVMCodeModel Model) {
|
||||
switch (Model) {
|
||||
case LLVMCodeModelDefault:
|
||||
return CodeModel::Default;
|
||||
case LLVMCodeModelJITDefault:
|
||||
return CodeModel::JITDefault;
|
||||
case LLVMCodeModelSmall:
|
||||
return CodeModel::Small;
|
||||
case LLVMCodeModelKernel:
|
||||
return CodeModel::Kernel;
|
||||
case LLVMCodeModelMedium:
|
||||
return CodeModel::Medium;
|
||||
case LLVMCodeModelLarge:
|
||||
return CodeModel::Large;
|
||||
}
|
||||
return CodeModel::Default;
|
||||
}
|
||||
|
||||
inline LLVMCodeModel wrap(CodeModel::Model Model) {
|
||||
switch (Model) {
|
||||
case CodeModel::Default:
|
||||
return LLVMCodeModelDefault;
|
||||
case CodeModel::JITDefault:
|
||||
return LLVMCodeModelJITDefault;
|
||||
case CodeModel::Small:
|
||||
return LLVMCodeModelSmall;
|
||||
case CodeModel::Kernel:
|
||||
return LLVMCodeModelKernel;
|
||||
case CodeModel::Medium:
|
||||
return LLVMCodeModelMedium;
|
||||
case CodeModel::Large:
|
||||
return LLVMCodeModelLarge;
|
||||
}
|
||||
llvm_unreachable("Bad CodeModel!");
|
||||
}
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
@ -137,7 +138,23 @@ enum MiscFlags { // Miscellaneous flags to adjust argument
|
||||
Sink = 0x04 // Should this cl::list eat all unknown options?
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Option Category class
|
||||
//
|
||||
class OptionCategory {
|
||||
private:
|
||||
const char *const Name;
|
||||
const char *const Description;
|
||||
void registerCategory();
|
||||
public:
|
||||
OptionCategory(const char *const Name, const char *const Description = 0)
|
||||
: Name(Name), Description(Description) { registerCategory(); }
|
||||
const char *getName() { return Name; }
|
||||
const char *getDescription() { return Description; }
|
||||
};
|
||||
|
||||
// The general Option Category (used as default category).
|
||||
extern OptionCategory GeneralCategory;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Option Base class
|
||||
@ -173,10 +190,12 @@ class Option {
|
||||
unsigned Position; // Position of last occurrence of the option
|
||||
unsigned AdditionalVals;// Greater than 0 for multi-valued option.
|
||||
Option *NextRegistered; // Singly linked list of registered options.
|
||||
|
||||
public:
|
||||
const char *ArgStr; // The argument string itself (ex: "help", "o")
|
||||
const char *HelpStr; // The descriptive text message for -help
|
||||
const char *ValueStr; // String describing what the value of this option is
|
||||
const char *ArgStr; // The argument string itself (ex: "help", "o")
|
||||
const char *HelpStr; // The descriptive text message for -help
|
||||
const char *ValueStr; // String describing what the value of this option is
|
||||
OptionCategory *Category; // The Category this option belongs to
|
||||
|
||||
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
|
||||
return (enum NumOccurrencesFlag)Occurrences;
|
||||
@ -214,13 +233,14 @@ class Option {
|
||||
void setFormattingFlag(enum FormattingFlags V) { Formatting = V; }
|
||||
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
|
||||
void setPosition(unsigned pos) { Position = pos; }
|
||||
void setCategory(OptionCategory &C) { Category = &C; }
|
||||
protected:
|
||||
explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
|
||||
enum OptionHidden Hidden)
|
||||
: NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
|
||||
HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
|
||||
Position(0), AdditionalVals(0), NextRegistered(0),
|
||||
ArgStr(""), HelpStr(""), ValueStr("") {
|
||||
ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) {
|
||||
}
|
||||
|
||||
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
|
||||
@ -312,6 +332,16 @@ struct LocationClass {
|
||||
template<class Ty>
|
||||
LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
|
||||
|
||||
// cat - Specifiy the Option category for the command line argument to belong
|
||||
// to.
|
||||
struct cat {
|
||||
OptionCategory &Category;
|
||||
cat(OptionCategory &c) : Category(c) {}
|
||||
|
||||
template<class Opt>
|
||||
void apply(Opt &O) const { O.setCategory(Category); }
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OptionValue class
|
||||
@ -1674,10 +1704,48 @@ struct extrahelp {
|
||||
};
|
||||
|
||||
void PrintVersionMessage();
|
||||
// This function just prints the help message, exactly the same way as if the
|
||||
// -help option had been given on the command line.
|
||||
// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
|
||||
void PrintHelpMessage();
|
||||
|
||||
/// This function just prints the help message, exactly the same way as if the
|
||||
/// -help or -help-hidden option had been given on the command line.
|
||||
///
|
||||
/// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
|
||||
///
|
||||
/// \param hidden if true will print hidden options
|
||||
/// \param categorized if true print options in categories
|
||||
void PrintHelpMessage(bool Hidden=false, bool Categorized=false);
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Public interface for accessing registered options.
|
||||
//
|
||||
|
||||
/// \brief Use this to get a StringMap to all registered named options
|
||||
/// (e.g. -help). Note \p Map Should be an empty StringMap.
|
||||
///
|
||||
/// \param [out] map will be filled with mappings where the key is the
|
||||
/// Option argument string (e.g. "help") and value is the corresponding
|
||||
/// Option*.
|
||||
///
|
||||
/// Access to unnamed arguments (i.e. positional) are not provided because
|
||||
/// it is expected that the client already has access to these.
|
||||
///
|
||||
/// Typical usage:
|
||||
/// \code
|
||||
/// main(int argc,char* argv[]) {
|
||||
/// StringMap<llvm::cl::Option*> opts;
|
||||
/// llvm::cl::getRegisteredOptions(opts);
|
||||
/// assert(opts.count("help") == 1)
|
||||
/// opts["help"]->setDescription("Show alphabetical help information")
|
||||
/// // More code
|
||||
/// llvm::cl::ParseCommandLineOptions(argc,argv);
|
||||
/// //More code
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// This interface is useful for modifying options in libraries that are out of
|
||||
/// the control of the client. The options should be modified before calling
|
||||
/// llvm::cl::ParseCommandLineOptions().
|
||||
void getRegisteredOptions(StringMap<Option*> &Map);
|
||||
|
||||
} // End namespace cl
|
||||
|
||||
|
58
contrib/llvm/include/llvm/Support/Compression.h
Normal file
58
contrib/llvm/include/llvm/Support/Compression.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===-- llvm/Support/Compression.h ---Compression----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains basic functions for compression/uncompression.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_COMPRESSION_H
|
||||
#define LLVM_SUPPORT_COMPRESSION_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
template<typename T> class OwningPtr;
|
||||
class StringRef;
|
||||
|
||||
namespace zlib {
|
||||
|
||||
enum CompressionLevel {
|
||||
NoCompression,
|
||||
DefaultCompression,
|
||||
BestSpeedCompression,
|
||||
BestSizeCompression
|
||||
};
|
||||
|
||||
enum Status {
|
||||
StatusOK,
|
||||
StatusUnsupported, // zlib is unavaliable
|
||||
StatusOutOfMemory, // there was not enough memory
|
||||
StatusBufferTooShort, // there was not enough room in the output buffer
|
||||
StatusInvalidArg, // invalid input parameter
|
||||
StatusInvalidData // data was corrupted or incomplete
|
||||
};
|
||||
|
||||
bool isAvailable();
|
||||
|
||||
Status compress(StringRef InputBuffer,
|
||||
OwningPtr<MemoryBuffer> &CompressedBuffer,
|
||||
CompressionLevel Level = DefaultCompression);
|
||||
|
||||
Status uncompress(StringRef InputBuffer,
|
||||
OwningPtr<MemoryBuffer> &UncompressedBuffer,
|
||||
size_t UncompressedSize);
|
||||
|
||||
} // End of namespace zlib
|
||||
|
||||
} // End of namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -466,6 +466,7 @@ enum {
|
||||
|
||||
// ELF Relocation types for PPC64
|
||||
enum {
|
||||
R_PPC64_NONE = 0,
|
||||
R_PPC64_ADDR32 = 1,
|
||||
R_PPC64_ADDR16_LO = 4,
|
||||
R_PPC64_ADDR16_HI = 5,
|
||||
@ -486,6 +487,7 @@ enum {
|
||||
R_PPC64_TOC16_LO_DS = 64,
|
||||
R_PPC64_TLS = 67,
|
||||
R_PPC64_TPREL16_LO = 70,
|
||||
R_PPC64_TPREL16_HA = 72,
|
||||
R_PPC64_DTPREL16_LO = 75,
|
||||
R_PPC64_DTPREL16_HA = 77,
|
||||
R_PPC64_GOT_TLSGD16_LO = 80,
|
||||
@ -944,6 +946,72 @@ enum {
|
||||
R_HEX_TPREL_11_X = 85
|
||||
};
|
||||
|
||||
// ELF Relocation types for S390/zSeries
|
||||
enum {
|
||||
R_390_NONE = 0,
|
||||
R_390_8 = 1,
|
||||
R_390_12 = 2,
|
||||
R_390_16 = 3,
|
||||
R_390_32 = 4,
|
||||
R_390_PC32 = 5,
|
||||
R_390_GOT12 = 6,
|
||||
R_390_GOT32 = 7,
|
||||
R_390_PLT32 = 8,
|
||||
R_390_COPY = 9,
|
||||
R_390_GLOB_DAT = 10,
|
||||
R_390_JMP_SLOT = 11,
|
||||
R_390_RELATIVE = 12,
|
||||
R_390_GOTOFF = 13,
|
||||
R_390_GOTPC = 14,
|
||||
R_390_GOT16 = 15,
|
||||
R_390_PC16 = 16,
|
||||
R_390_PC16DBL = 17,
|
||||
R_390_PLT16DBL = 18,
|
||||
R_390_PC32DBL = 19,
|
||||
R_390_PLT32DBL = 20,
|
||||
R_390_GOTPCDBL = 21,
|
||||
R_390_64 = 22,
|
||||
R_390_PC64 = 23,
|
||||
R_390_GOT64 = 24,
|
||||
R_390_PLT64 = 25,
|
||||
R_390_GOTENT = 26,
|
||||
R_390_GOTOFF16 = 27,
|
||||
R_390_GOTOFF64 = 28,
|
||||
R_390_GOTPLT12 = 29,
|
||||
R_390_GOTPLT16 = 30,
|
||||
R_390_GOTPLT32 = 31,
|
||||
R_390_GOTPLT64 = 32,
|
||||
R_390_GOTPLTENT = 33,
|
||||
R_390_PLTOFF16 = 34,
|
||||
R_390_PLTOFF32 = 35,
|
||||
R_390_PLTOFF64 = 36,
|
||||
R_390_TLS_LOAD = 37,
|
||||
R_390_TLS_GDCALL = 38,
|
||||
R_390_TLS_LDCALL = 39,
|
||||
R_390_TLS_GD32 = 40,
|
||||
R_390_TLS_GD64 = 41,
|
||||
R_390_TLS_GOTIE12 = 42,
|
||||
R_390_TLS_GOTIE32 = 43,
|
||||
R_390_TLS_GOTIE64 = 44,
|
||||
R_390_TLS_LDM32 = 45,
|
||||
R_390_TLS_LDM64 = 46,
|
||||
R_390_TLS_IE32 = 47,
|
||||
R_390_TLS_IE64 = 48,
|
||||
R_390_TLS_IEENT = 49,
|
||||
R_390_TLS_LE32 = 50,
|
||||
R_390_TLS_LE64 = 51,
|
||||
R_390_TLS_LDO32 = 52,
|
||||
R_390_TLS_LDO64 = 53,
|
||||
R_390_TLS_DTPMOD = 54,
|
||||
R_390_TLS_DTPOFF = 55,
|
||||
R_390_TLS_TPOFF = 56,
|
||||
R_390_20 = 57,
|
||||
R_390_GOT20 = 58,
|
||||
R_390_GOTPLT20 = 59,
|
||||
R_390_TLS_GOTIE20 = 60,
|
||||
R_390_IRELATIVE = 61
|
||||
};
|
||||
|
||||
// Section header.
|
||||
struct Elf32_Shdr {
|
||||
Elf32_Word sh_name; // Section name (index into string table)
|
||||
|
@ -37,7 +37,7 @@ namespace detail {
|
||||
namespace endian {
|
||||
template<typename value_type, endianness endian>
|
||||
inline value_type byte_swap(value_type value) {
|
||||
if (endian != native && sys::isBigEndianHost() != (endian == big))
|
||||
if (endian != native && sys::IsBigEndianHost != (endian == big))
|
||||
return sys::SwapByteOrder(value);
|
||||
return value;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user