aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h180
-rw-r--r--include/llvm-c/ExecutionEngine.h59
-rw-r--r--include/llvm-c/Object.h46
-rw-r--r--include/llvm-c/Target.h23
-rw-r--r--include/llvm-c/TargetMachine.h27
-rw-r--r--include/llvm-c/Transforms/PassManagerBuilder.h10
-rw-r--r--include/llvm-c/Transforms/Vectorize.h3
-rw-r--r--include/llvm/ADT/APSInt.h4
-rw-r--r--include/llvm/ADT/DenseMap.h2
-rw-r--r--include/llvm/ADT/Hashing.h4
-rw-r--r--include/llvm/ADT/InMemoryStruct.h77
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h4
-rw-r--r--include/llvm/ADT/Optional.h14
-rw-r--r--include/llvm/ADT/PointerIntPair.h52
-rw-r--r--include/llvm/ADT/PostOrderIterator.h2
-rw-r--r--include/llvm/ADT/SmallPtrSet.h31
-rw-r--r--include/llvm/ADT/SmallSet.h1
-rw-r--r--include/llvm/ADT/SmallVector.h4
-rw-r--r--include/llvm/ADT/StringRef.h20
-rw-r--r--include/llvm/ADT/Triple.h2
-rw-r--r--include/llvm/ADT/Twine.h2
-rw-r--r--include/llvm/ADT/ilist.h4
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h1
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h2
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h12
-rw-r--r--include/llvm/Analysis/RegionInfo.h18
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h4
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h11
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h36
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h2
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h6
-rw-r--r--include/llvm/CodeGen/FastISel.h22
-rw-r--r--include/llvm/CodeGen/GCs.h6
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h8
-rw-r--r--include/llvm/CodeGen/LinkAllAsmWriterComponents.h1
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h1
-rw-r--r--include/llvm/CodeGen/LiveInterval.h9
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h3
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h2
-rw-r--r--include/llvm/CodeGen/LiveVariables.h4
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h5
-rw-r--r--include/llvm/CodeGen/MachineBranchProbabilityInfo.h1
-rw-r--r--include/llvm/CodeGen/MachineFunction.h4
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h30
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h6
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h9
-rw-r--r--include/llvm/CodeGen/MachineTraceMetrics.h33
-rw-r--r--include/llvm/CodeGen/Passes.h67
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h19
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h79
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h30
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h7
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h31
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h3
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h18
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h49
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h6
-rw-r--r--include/llvm/CodeGen/ValueTypes.td4
-rw-r--r--include/llvm/Config/config.h.cmake12
-rw-r--r--include/llvm/Config/config.h.in20
-rw-r--r--include/llvm/DIBuilder.h118
-rw-r--r--include/llvm/DebugInfo.h131
-rw-r--r--include/llvm/DebugInfo/DWARFFormValue.h82
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h11
-rw-r--r--include/llvm/ExecutionEngine/GenericValue.h13
-rw-r--r--include/llvm/ExecutionEngine/ObjectCache.h54
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h4
-rw-r--r--include/llvm/IR/Argument.h4
-rw-r--r--include/llvm/IR/Attributes.h30
-rw-r--r--include/llvm/IR/BasicBlock.h4
-rw-r--r--include/llvm/IR/Constants.h19
-rw-r--r--include/llvm/IR/DataLayout.h63
-rw-r--r--include/llvm/IR/DerivedTypes.h2
-rw-r--r--include/llvm/IR/GlobalValue.h3
-rw-r--r--include/llvm/IR/IRBuilder.h25
-rw-r--r--include/llvm/IR/Intrinsics.h11
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td25
-rw-r--r--include/llvm/IR/IntrinsicsX86.td9
-rw-r--r--include/llvm/IR/LLVMContext.h15
-rw-r--r--include/llvm/IR/MDBuilder.h35
-rw-r--r--include/llvm/IR/Module.h11
-rw-r--r--include/llvm/IR/Type.h15
-rw-r--r--include/llvm/IR/Use.h13
-rw-r--r--include/llvm/IR/User.h20
-rw-r--r--include/llvm/IR/Value.h25
-rw-r--r--include/llvm/IRReader/IRReader.h55
-rw-r--r--include/llvm/InitializePasses.h2
-rw-r--r--include/llvm/LinkAllPasses.h1
-rw-r--r--include/llvm/Linker.h42
-rw-r--r--include/llvm/MC/MCAsmInfo.h12
-rw-r--r--include/llvm/MC/MCAssembler.h12
-rw-r--r--include/llvm/MC/MCAtom.h4
-rw-r--r--include/llvm/MC/MCELFStreamer.h3
-rw-r--r--include/llvm/MC/MCExpr.h4
-rw-r--r--include/llvm/MC/MCInst.h2
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h11
-rw-r--r--include/llvm/MC/MCObjectStreamer.h10
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h28
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h22
-rw-r--r--include/llvm/MC/MCSection.h4
-rw-r--r--include/llvm/MC/MCSectionCOFF.h3
-rw-r--r--include/llvm/MC/MCSectionELF.h3
-rw-r--r--include/llvm/MC/MCSectionMachO.h3
-rw-r--r--include/llvm/MC/MCStreamer.h48
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h14
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h6
-rw-r--r--include/llvm/MC/MachineLocation.h7
-rw-r--r--include/llvm/MC/SubtargetFeature.h4
-rw-r--r--include/llvm/Object/Binary.h20
-rw-r--r--include/llvm/Object/ELF.h614
-rw-r--r--include/llvm/Object/MachO.h171
-rw-r--r--include/llvm/Object/MachOObject.h210
-rw-r--r--include/llvm/Object/ObjectFile.h12
-rw-r--r--include/llvm/Object/RelocVisitor.h4
-rw-r--r--include/llvm/PassManager.h4
-rw-r--r--include/llvm/PassRegistry.h5
-rw-r--r--include/llvm/Support/CBindingWrapping.h46
-rw-r--r--include/llvm/Support/CFG.h16
-rw-r--r--include/llvm/Support/COFF.h3
-rw-r--r--include/llvm/Support/CallSite.h1
-rw-r--r--include/llvm/Support/Casting.h48
-rw-r--r--include/llvm/Support/CodeGen.h39
-rw-r--r--include/llvm/Support/Compiler.h10
-rw-r--r--include/llvm/Support/Compression.h58
-rw-r--r--include/llvm/Support/ELF.h4
-rw-r--r--include/llvm/Support/Endian.h2
-rw-r--r--include/llvm/Support/ErrorHandling.h15
-rw-r--r--include/llvm/Support/FEnv.h4
-rw-r--r--include/llvm/Support/FormattedStream.h234
-rw-r--r--include/llvm/Support/Host.h26
-rw-r--r--include/llvm/Support/IRReader.h112
-rw-r--r--include/llvm/Support/MemoryBuffer.h5
-rw-r--r--include/llvm/Support/Program.h8
-rw-r--r--include/llvm/Support/ValueHandle.h45
-rw-r--r--include/llvm/Support/Watchdog.h38
-rw-r--r--include/llvm/Support/Win64EH.h18
-rw-r--r--include/llvm/Support/type_traits.h20
-rw-r--r--include/llvm/TableGen/Error.h1
-rw-r--r--include/llvm/Target/Target.td16
-rw-r--r--include/llvm/Target/TargetCallingConv.h42
-rw-r--r--include/llvm/Target/TargetInstrInfo.h13
-rw-r--r--include/llvm/Target/TargetLowering.h68
-rw-r--r--include/llvm/Target/TargetMachine.h1
-rw-r--r--include/llvm/Target/TargetOptions.h1
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td3
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h3
-rw-r--r--include/llvm/Transforms/Utils/BlackList.h1
-rw-r--r--include/llvm/Transforms/Utils/Local.h4
-rw-r--r--include/llvm/Transforms/Vectorize.h6
150 files changed, 2402 insertions, 1745 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index e85fb97505..63e816effc 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -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;
+
/**
* @}
*/
@@ -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);
/**
* @}
@@ -1694,6 +1743,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.
*
* @see llvm::Function::getAttributes()
@@ -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) */
diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h
index cb77bb2e2e..8fae77def4 100644
--- a/include/llvm-c/ExecutionEngine.h
+++ b/include/llvm-c/ExecutionEngine.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
diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h
index e2dad62b4e..ecccfeed7f 100644
--- a/include/llvm-c/Object.h
+++ b/include/llvm-c/Object.h
@@ -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
diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h
index 57abfa0207..80fc3e5ad7 100644
--- a/include/llvm-c/Target.h
+++ b/include/llvm-c/Target.h
@@ -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
diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h
index 691abdfcb4..5e355959f6 100644
--- a/include/llvm-c/TargetMachine.h
+++ b/include/llvm-c/TargetMachine.h
@@ -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
diff --git a/include/llvm-c/Transforms/PassManagerBuilder.h b/include/llvm-c/Transforms/PassManagerBuilder.h
index 82e513d490..545f8aae8c 100644
--- a/include/llvm-c/Transforms/PassManagerBuilder.h
+++ b/include/llvm-c/Transforms/PassManagerBuilder.h
@@ -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
diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h
index 68a9bdd388..c9102da602 100644
--- a/include/llvm-c/Transforms/Vectorize.h
+++ b/include/llvm-c/Transforms/Vectorize.h
@@ -39,6 +39,9 @@ void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
/** See llvm::createLoopVectorizePass function. */
void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
+/** See llvm::createSLPVectorizerPass function. */
+void LLVMAddSLPVectorizePass(LLVMPassManagerRef PM);
+
/**
* @}
*/
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 42e123930d..11be4c513e 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -161,11 +161,11 @@ public:
}
APSInt& operator++() {
- static_cast<APInt&>(*this)++;
+ ++(static_cast<APInt&>(*this));
return *this;
}
APSInt& operator--() {
- static_cast<APInt&>(*this)--;
+ --(static_cast<APInt&>(*this));
return *this;
}
APSInt operator++(int) {
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index d410619964..31fd6d899d 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -618,7 +618,7 @@ public:
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();
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index cda31a261d..e434417da7 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -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;
}
diff --git a/include/llvm/ADT/InMemoryStruct.h b/include/llvm/ADT/InMemoryStruct.h
deleted file mode 100644
index a56084501a..0000000000
--- a/include/llvm/ADT/InMemoryStruct.h
+++ /dev/null
@@ -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
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 9e5ab021a5..b8b8861995 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -226,13 +226,13 @@ namespace llvm {
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
- static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+ static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
return Val.getPtr();
}
};
template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
- typedef T* SimpleType;
+ typedef /*const*/ T* SimpleType;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
return Val.getPtr();
}
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 81d73ed8b9..194e53fac2 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -128,20 +128,6 @@ public:
#endif
};
-template<typename T> struct simplify_type;
-
-template <typename T>
-struct simplify_type<const Optional<T> > {
- typedef const T* SimpleType;
- static SimpleType getSimplifiedValue(const Optional<T> &Val) {
- return Val.getPointer();
- }
-};
-
-template <typename T>
-struct simplify_type<Optional<T> >
- : public simplify_type<const Optional<T> > {};
-
template <typename T> struct isPodLike;
template <typename T> struct isPodLike<Optional<T> > {
// An Optional<T> is pod-like if T is.
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index cce2efb6ac..0299a83c44 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -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 @@ public:
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 {
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index 7f6350e444..59fa3f39c9 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -260,7 +260,7 @@ class ReversePostOrderTraversal {
typedef typename GT::NodeType NodeType;
std::vector<NodeType*> Blocks; // Block list in normal PO order
inline void Initialize(NodeType *BB) {
- copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
+ std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
}
public:
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 3bb883088c..8c7304197f 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -54,8 +54,6 @@ protected:
/// then the set is in 'small mode'.
const void **CurArray;
/// CurArraySize - The allocated size of CurArray, always a power of two.
- /// Note that CurArray points to an array that has CurArraySize+1 elements in
- /// it, so that the end iterator actually points to valid memory.
unsigned CurArraySize;
// If small, this is # elts allocated consecutively
@@ -68,9 +66,6 @@ protected:
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
"Initial size must be a power of two!");
- // The end pointer, always valid, is set to a valid element to help the
- // iterator.
- CurArray[SmallSize] = 0;
clear();
}
~SmallPtrSetImpl();
@@ -147,9 +142,11 @@ protected:
class SmallPtrSetIteratorImpl {
protected:
const void *const *Bucket;
+ const void *const *End;
public:
- explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
- AdvanceIfNotValid();
+ explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
+ : Bucket(BP), End(E) {
+ AdvanceIfNotValid();
}
bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
@@ -164,8 +161,10 @@ protected:
/// that is. This is guaranteed to stop because the end() bucket is marked
/// valid.
void AdvanceIfNotValid() {
- while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
- *Bucket == SmallPtrSetImpl::getTombstoneMarker())
+ assert(Bucket <= End);
+ while (Bucket != End &&
+ (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImpl::getTombstoneMarker()))
++Bucket;
}
};
@@ -182,12 +181,13 @@ public:
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
- explicit SmallPtrSetIterator(const void *const *BP)
- : SmallPtrSetIteratorImpl(BP) {}
+ explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
+ : SmallPtrSetIteratorImpl(BP, E) {}
// Most methods provided by baseclass.
const PtrTy operator*() const {
+ assert(Bucket < End);
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
}
@@ -236,9 +236,8 @@ template<class PtrType, unsigned SmallSize>
class SmallPtrSet : public SmallPtrSetImpl {
// Make sure that SmallSize is a power of two, round up if not.
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
- /// SmallStorage - Fixed size storage used in 'small mode'. The extra element
- /// ensures that the end iterator actually points to valid memory.
- const void *SmallStorage[SmallSizePowTwo+1];
+ /// SmallStorage - Fixed size storage used in 'small mode'.
+ const void *SmallStorage[SmallSizePowTwo];
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
public:
SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
@@ -275,10 +274,10 @@ public:
typedef SmallPtrSetIterator<PtrType> iterator;
typedef SmallPtrSetIterator<PtrType> const_iterator;
inline iterator begin() const {
- return iterator(CurArray);
+ return iterator(CurArray, CurArray+CurArraySize);
}
inline iterator end() const {
- return iterator(CurArray+CurArraySize);
+ return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
}
// Allow assignment from any smallptrset with the same element type even if it
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index 4eb7de895a..5dfe924f6d 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -55,6 +55,7 @@ public:
}
/// insert - Insert an element into the set if it isn't already there.
+ /// Returns true if the element is inserted (it was not in the set before).
bool insert(const T &V) {
if (!isSmall())
return Set.insert(V).second;
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 9167f87218..7ba0a714bf 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -16,6 +16,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
@@ -267,7 +268,8 @@ template <typename T, bool isPodLike>
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
size_t CurCapacity = this->capacity();
size_t CurSize = this->size();
- size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
+ // Always grow, even from zero.
+ size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
if (NewCapacity < MinSize)
NewCapacity = MinSize;
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 224855e3f8..d013d05623 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -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);
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 8fac222c13..75b562afdf 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -43,7 +43,7 @@ public:
enum ArchType {
UnknownArch,
- arm, // ARM; arm, armv.*, xscale
+ arm, // ARM: arm, armv.*, xscale
aarch64, // AArch64: aarch64
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index cc290d51d2..e16c6b4913 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -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.
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index aeb78484c6..71dab2ef55 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -274,12 +274,12 @@ template<typename From> struct simplify_type;
template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
typedef NodeTy* SimpleType;
- static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
return &*Node;
}
};
template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
- typedef NodeTy* SimpleType;
+ typedef /*const*/ NodeTy* SimpleType;
static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
return &*Node;
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
index 163331c262..da007072e5 100644
--- a/include/llvm/Analysis/AliasSetTracker.h
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
#include <vector>
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
index f220c58244..b3e2d18eb2 100644
--- a/include/llvm/Analysis/BlockFrequencyImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -271,7 +271,7 @@ class BlockFrequencyImpl {
BlockT *EntryBlock = fn->begin();
- copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
+ std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT));
unsigned RPOidx = 0;
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index 63262eb9a3..488338302a 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -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);
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 69cc293811..e87319516c 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -266,6 +266,24 @@ public:
/// @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.
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 42fd3927c8..306549fba4 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -338,6 +338,10 @@ namespace llvm {
/// getMax - Get the max backedge taken count for the loop.
const SCEV *getMax(ScalarEvolution *SE) const;
+ /// Return true if any backedge taken count expressions refer to the given
+ /// subexpression.
+ bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
+
/// clear - Invalidate this result and free associated memory.
void clear();
};
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index ccab19495f..a9d6725d86 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -263,6 +263,13 @@ public:
SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
};
+ /// \brief Additonal information about an operand's possible values.
+ enum OperandValueKind {
+ OK_AnyValue, // Operand can have any value.
+ OK_UniformValue, // Operand is uniform (splat of a value).
+ OK_UniformConstantValue // Operand is uniform constant.
+ };
+
/// \return The number of scalar or vector registers that the target has.
/// If 'Vectors' is true, it returns the number of vector registers. If it is
/// set to false, it returns the number of scalar registers.
@@ -277,7 +284,9 @@ public:
virtual unsigned getMaximumUnrollFactor() const;
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
- virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
+ virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
+ OperandValueKind Opd1Info = OK_AnyValue,
+ OperandValueKind Opd2Info = OK_AnyValue) const;
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
/// The index and subtype parameters are used by the subvector insertion and
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index 2d2976cde1..f3139739cd 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -126,7 +126,7 @@ public:
}
};
-
+
/// BitstreamEntry - When advancing through a bitstream cursor, each advance can
/// discover a few different kinds of entries:
/// Error - Malformed bitcode was found.
@@ -142,7 +142,7 @@ struct BitstreamEntry {
SubBlock,
Record
} Kind;
-
+
unsigned ID;
static BitstreamEntry getError() {
@@ -170,7 +170,7 @@ class BitstreamCursor {
BitstreamReader *BitStream;
size_t NextChar;
-
+
/// CurWord/word_t - This is the current data we have pulled from the stream
/// but have not returned to the client. This is specifically and
/// intentionally defined to follow the word size of the host machine for
@@ -199,7 +199,7 @@ class BitstreamCursor {
/// BlockScope - This tracks the codesize of parent blocks.
SmallVector<Block, 8> BlockScope;
-
+
public:
BitstreamCursor() : BitStream(0), NextChar(0) {
}
@@ -231,7 +231,7 @@ public:
void operator=(const BitstreamCursor &RHS);
void freeState();
-
+
bool isEndPos(size_t pos) {
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
}
@@ -278,7 +278,7 @@ public:
/// returned just like normal records.
AF_DontAutoprocessAbbrevs = 2
};
-
+
/// advance - Advance the current bitstream, returning the next entry in the
/// stream.
BitstreamEntry advance(unsigned Flags = 0) {
@@ -290,10 +290,10 @@ public:
return BitstreamEntry::getError();
return BitstreamEntry::getEndBlock();
}
-
+
if (Code == bitc::ENTER_SUBBLOCK)
return BitstreamEntry::getSubBlock(ReadSubBlockID());
-
+
if (Code == bitc::DEFINE_ABBREV &&
!(Flags & AF_DontAutoprocessAbbrevs)) {
// We read and accumulate abbrev's, the client can't do anything with
@@ -314,7 +314,7 @@ public:
BitstreamEntry Entry = advance(Flags);
if (Entry.Kind != BitstreamEntry::SubBlock)
return Entry;
-
+
// If we found a sub-block, just skip over it and check the next entry.
if (SkipBlock())
return BitstreamEntry::getError();
@@ -345,7 +345,7 @@ public:
uint32_t Read(unsigned NumBits) {
assert(NumBits && NumBits <= 32 &&
"Cannot return zero or more than 32 bits!");
-
+
// If the field is fully contained by CurWord, return it quickly.
if (BitsInCurWord >= NumBits) {
uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
@@ -365,15 +365,15 @@ public:
// Read the next word from the stream.
uint8_t Array[sizeof(word_t)] = {0};
-
+
BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array),
Array, NULL);
-
+
// Handle big-endian byte-swapping if necessary.
support::detail::packed_endian_specific_integral
<word_t, support::little, support::unaligned> EndianValue;
memcpy(&EndianValue, Array, sizeof(Array));
-
+
CurWord = EndianValue;
NextChar += sizeof(word_t);
@@ -450,7 +450,7 @@ private:
BitsInCurWord = 32;
return;
}
-
+
BitsInCurWord = 0;
CurWord = 0;
}
@@ -493,7 +493,7 @@ public:
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block has an error.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0);
-
+
bool ReadBlockEnd() {
if (BlockScope.empty()) return true;
@@ -529,7 +529,7 @@ private:
void readAbbreviatedField(const BitCodeAbbrevOp &Op,
SmallVectorImpl<uint64_t> &Vals);
void skipAbbreviatedField(const BitCodeAbbrevOp &Op);
-
+
public:
/// getAbbrev - Return the abbreviation for the specified AbbrevId.
@@ -541,7 +541,7 @@ public:
/// skipRecord - Read the current record and discard it.
void skipRecord(unsigned AbbrevID);
-
+
unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
StringRef *Blob = 0);
@@ -549,7 +549,7 @@ public:
// Abbrev Processing
//===--------------------------------------------------------------------===//
void ReadAbbrevRecord();
-
+
bool ReadBlockInfoBlock();
};
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index 7b68f8761a..a837211875 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -458,7 +458,7 @@ public:
template<typename uintty>
void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
const char *ArrayData, unsigned ArrayLen) {
- return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
+ return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
ArrayLen));
}
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index e0a6e3f402..c2fd6ce367 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -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);
};
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 705db7e643..471e9bfc40 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -123,12 +123,28 @@ public:
/// 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;
}
diff --git a/include/llvm/CodeGen/GCs.h b/include/llvm/CodeGen/GCs.h
index c407b61674..456d2dcb51 100644
--- a/include/llvm/CodeGen/GCs.h
+++ b/include/llvm/CodeGen/GCs.h
@@ -26,6 +26,12 @@ namespace llvm {
/// Creates an ocaml-compatible metadata printer.
void linkOcamlGCPrinter();
+
+ /// Creates an erlang-compatible garbage collector.
+ void linkErlangGC();
+
+ /// Creates an erlang-compatible metadata printer.
+ void linkErlangGCPrinter();
/// Creates a shadow stack garbage collector. This collector requires no code
/// generator support.
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 442729b5d7..0fd211b4a8 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -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.
diff --git a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index 4b941730a2..722b0de6f7 100644
--- a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -30,6 +30,7 @@ namespace {
return;
llvm::linkOcamlGCPrinter();
+ llvm::linkErlangGCPrinter();
}
} ForceAsmWriterLinking; // Force link by creating a global definition.
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 2145eb80bd..916c0f233e 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -37,6 +37,7 @@ namespace {
(void) llvm::createDefaultPBQPRegisterAllocator();
llvm::linkOcamlGC();
+ llvm::linkErlangGC();
llvm::linkShadowStackGC();
(void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 244be9c501..cb09a49666 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -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,
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 4632368157..7d72f37255 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -20,9 +20,7 @@
#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -36,6 +34,7 @@
namespace llvm {
class AliasAnalysis;
+ class BitVector;
class LiveRangeCalc;
class LiveVariables;
class MachineDominatorTree;
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index def7b00ce7..8a32a3c11a 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -83,7 +83,7 @@ private:
/// allUsesAvailableAt - Return true if all registers used by OrigMI at
/// OrigIdx are also available with the same value at UseIdx.
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
- SlotIndex UseIdx);
+ SlotIndex UseIdx) const;
/// foldAsLoad - If LI has a single use and a single def that can be folded as
/// a load, eliminate the register by folding the def into the use.
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index 3c5ed9297e..6628fd278e 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -29,21 +29,19 @@
#ifndef LLVM_CODEGEN_LIVEVARIABLES_H
#define LLVM_CODEGEN_LIVEVARIABLES_H
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseBitVector.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/TargetRegisterInfo.h"
namespace llvm {
+class MachineBasicBlock;
class MachineRegisterInfo;
-class TargetRegisterInfo;
class LiveVariables : public MachineFunctionPass {
public:
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 492a3ff49f..0f2f8746b3 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -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() {}
diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
index 1c9bdd954c..98dd03b45c 100644
--- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
+++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -1,4 +1,3 @@
-
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
//
// The LLVM Compiler Infrastructure
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 82c4cd6598..c886e256e0 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -352,8 +352,8 @@ public:
// 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);
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index ddb127120f..00a55b57f3 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -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 @@ public:
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 @@ public:
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 @@ public:
/// 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.
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 1db6252ef4..a3acec8095 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -295,7 +295,7 @@ public:
/// isUsedFunction - Return true if the functions in the llvm.used list. This
/// does not return true for things in llvm.compiler.used unless they are also
/// in llvm.used.
- bool isUsedFunction(const Function *F) {
+ bool isUsedFunction(const Function *F) const {
return UsedFunctions.count(F);
}
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 4b43cc1095..24ba7bb1ac 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -157,6 +157,12 @@ public:
// 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.
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 57febe7746..769e4b42a5 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -274,6 +274,10 @@ public:
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 @@ public:
/// 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 @@ protected:
void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure);
- void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
bool checkSchedLimit();
void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h
index eaaa70a67d..4e087fc62d 100644
--- a/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -107,6 +107,13 @@ public:
/// Get the fixed resource information about MBB. Compute it on demand.
const FixedBlockInfo *getResources(const MachineBasicBlock*);
+ /// Get the scaled number of cycles used per processor resource in MBB.
+ /// This is an array with SchedModel.getNumProcResourceKinds() entries.
+ /// The getResources() function above must have been called first.
+ ///
+ /// These numbers have already been scaled by SchedModel.getResourceFactor().
+ ArrayRef<unsigned> getProcResourceCycles(unsigned MBBNum) const;
+
/// A virtual register or regunit required by a basic block or its trace
/// successors.
struct LiveInReg {
@@ -253,9 +260,13 @@ public:
/// independent, exposing the maximum instruction-level parallelism.
///
/// Any blocks in Extrablocks are included as if they were part of the
- /// trace.
+ /// 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 =
- ArrayRef<const MachineBasicBlock*>()) const;
+ ArrayRef<const MachineBasicBlock*>(),
+ ArrayRef<const MCSchedClassDesc*> ExtraInstrs =
+ ArrayRef<const MCSchedClassDesc*>()) const;
/// Return the length of the (data dependency) critical path through the
/// trace.
@@ -284,6 +295,8 @@ public:
class Ensemble {
SmallVector<TraceBlockInfo, 4> BlockInfo;
DenseMap<const MachineInstr*, InstrCycles> Cycles;
+ SmallVector<unsigned, 0> ProcResourceDepths;
+ SmallVector<unsigned, 0> ProcResourceHeights;
friend class Trace;
void computeTrace(const MachineBasicBlock*);
@@ -303,6 +316,8 @@ public:
const MachineLoop *getLoopFor(const MachineBasicBlock*) const;
const TraceBlockInfo *getDepthResources(const MachineBasicBlock*) const;
const TraceBlockInfo *getHeightResources(const MachineBasicBlock*) const;
+ ArrayRef<unsigned> getProcResourceDepths(unsigned MBBNum) const;
+ ArrayRef<unsigned> getProcResourceHeights(unsigned MBBNum) const;
public:
virtual ~Ensemble();
@@ -343,8 +358,22 @@ private:
// One entry per basic block, indexed by block number.
SmallVector<FixedBlockInfo, 4> BlockInfo;
+ // Cycles consumed on each processor resource per block.
+ // The number of processor resource kinds is constant for a given subtarget,
+ // but it is not known at compile time. The number of cycles consumed by
+ // block B on processor resource R is at ProcResourceCycles[B*Kinds + R]
+ // where Kinds = SchedModel.getNumProcResourceKinds().
+ SmallVector<unsigned, 0> ProcResourceCycles;
+
// One ensemble per strategy.
Ensemble* Ensembles[TS_NumStrategies];
+
+ // Convert scaled resource usage to a cycle count that can be compared with
+ // latencies.
+ unsigned getCycles(unsigned Scaled) {
+ unsigned Factor = SchedModel.getLatencyFactor();
+ return (Scaled + Factor - 1) / Factor;
+ }
};
inline raw_ostream &operator<<(raw_ostream &OS,
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 4d559b5799..b02f63e70b 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -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 @@ public:
/// 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 @@ protected:
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
@@ -444,10 +477,6 @@ namespace llvm {
/// information.
extern char &MachineBlockPlacementStatsID;
- /// Code Placement - This pass optimize code placement and aligns loop
- /// headers to target specific alignment boundary.
- extern char &CodePlacementOptID;
-
/// GCLowering Pass - Performs target-independent LLVM IR transformations for
/// highly portable strategies.
///
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index b617c14558..8b8e3d90f7 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -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);
}
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 01199205b5..95bf29167c 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -40,21 +40,23 @@ class RegScavenger {
/// registers.
bool Tracking;
- /// ScavengingFrameIndex - Special spill slot used for scavenging a register
- /// post register allocation.
- int ScavengingFrameIndex;
+ /// Information on scavenged registers (held in a spill slot).
+ struct ScavengedInfo {
+ ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(NULL) {}
- /// ScavengedReg - If none zero, the specific register is currently being
- /// scavenged. That is, it is spilled to the special scavenging stack slot.
- unsigned ScavengedReg;
+ /// A spill slot used for scavenging a register post register allocation.
+ int FrameIndex;
- /// ScavengedRC - Register class of the scavenged register.
- ///
- const TargetRegisterClass *ScavengedRC;
+ /// If non-zero, the specific register is currently being
+ /// scavenged. That is, it is spilled to this scavenging stack slot.
+ unsigned Reg;
+
+ /// The instruction that restores the scavenged register from stack.
+ const MachineInstr *Restore;
+ };
- /// ScavengeRestore - Instruction that restores the scavenged register from
- /// stack.
- const MachineInstr *ScavengeRestore;
+ /// A vector of information on scavenged registers.
+ SmallVector<ScavengedInfo, 2> Scavenged;
/// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
///
@@ -71,8 +73,7 @@ class RegScavenger {
public:
RegScavenger()
- : MBB(NULL), NumPhysRegs(0), Tracking(false),
- ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {}
+ : MBB(NULL), NumPhysRegs(0), Tracking(false) {}
/// enterBasicBlock - Start tracking liveness from the begin of the specific
/// basic block.
@@ -92,9 +93,25 @@ public:
while (MBBI != I) forward();
}
+ /// Invert the behavior of forward() on the current instruction (undo the
+ /// changes to the available registers made by forward()).
+ void unprocess();
+
+ /// Unprocess instructions until you reach the provided iterator.
+ void unprocess(MachineBasicBlock::iterator I) {
+ while (MBBI != I) unprocess();
+ }
+
/// skipTo - Move the internal MBB iterator but do not update register states.
- ///
- void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
+ void skipTo(MachineBasicBlock::iterator I) {
+ if (I == MachineBasicBlock::iterator(NULL))
+ Tracking = false;
+ MBBI = I;
+ }
+
+ MachineBasicBlock::iterator getCurrentPosition() const {
+ return MBBI;
+ }
/// getRegsUsed - return all registers currently in use in used.
void getRegsUsed(BitVector &used, bool includeReserved);
@@ -107,10 +124,28 @@ public:
/// Return 0 if none is found.
unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
- /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
- /// ScavengingFrameIndex.
- void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
- int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
+ /// Add a scavenging frame index.
+ void addScavengingFrameIndex(int FI) {
+ Scavenged.push_back(ScavengedInfo(FI));
+ }
+
+ /// Query whether a frame index is a scavenging frame index.
+ bool isScavengingFrameIndex(int FI) const {
+ for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(),
+ IE = Scavenged.end(); I != IE; ++I)
+ if (I->FrameIndex == FI)
+ return true;
+
+ return false;
+ }
+
+ /// Get an array of scavenging frame indices.
+ void getScavengingFrameIndices(SmallVectorImpl<int> &A) const {
+ for (SmallVector<ScavengedInfo, 2>::const_iterator I = Scavenged.begin(),
+ IE = Scavenged.end(); I != IE; ++I)
+ if (I->FrameIndex >= 0)
+ A.push_back(I->FrameIndex);
+ }
/// scavengeRegister - Make a register of the specific register class
/// available and do the appropriate bookkeeping. SPAdj is the stack
@@ -149,6 +184,10 @@ private:
RegsAvailable |= Regs;
}
+ /// Processes the current instruction and fill the KillRegs and DefRegs bit
+ /// vectors.
+ void determineKillsAndDefs();
+
/// Add Reg and all its sub-registers to BV.
void addRegWithSubRegs(BitVector &BV, unsigned Reg);
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 8c959da696..7cff27e172 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -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.
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 2219520ca1..990cac6348 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -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; }
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index e5adf67249..8c064bf2d4 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -810,31 +810,32 @@ public:
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,
+ SDValue Op1, SDValue Op2);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ SDValue Op1, SDValue Op2, SDValue Op3);
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
- const SDValue *Ops, unsigned NumOps);
+ ArrayRef<SDValue> Ops);
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
- EVT VT3, SDValue Op1, SDValue Op2);
+ EVT VT3, SDValue Op1, SDValue Op2);
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
- EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3);
+ EVT VT3, SDValue Op1, SDValue Op2,
+ SDValue Op3);
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
- EVT VT3, const SDValue *Ops, unsigned NumOps);
+ EVT VT3, ArrayRef<SDValue> Ops);
MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
- EVT VT3, EVT VT4, const SDValue *Ops, unsigned NumOps);
+ 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.
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 5f503deff1..a4721db685 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -259,9 +259,6 @@ private:
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();
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 05f3b1494f..fef567f56b 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -196,14 +196,14 @@ template <> struct isPodLike<SDValue> { static const bool value = true; };
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDValue> {
typedef SDNode* SimpleType;
- static SimpleType getSimplifiedValue(const SDValue &Val) {
- return static_cast<SimpleType>(Val.getNode());
+ static SimpleType getSimplifiedValue(SDValue &Val) {
+ return Val.getNode();
}
};
template<> struct simplify_type<const SDValue> {
- typedef SDNode* SimpleType;
+ typedef /*const*/ SDNode* SimpleType;
static SimpleType getSimplifiedValue(const SDValue &Val) {
- return static_cast<SimpleType>(Val.getNode());
+ return Val.getNode();
}
};
@@ -295,14 +295,8 @@ private:
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDUse> {
typedef SDNode* SimpleType;
- static SimpleType getSimplifiedValue(const SDUse &Val) {
- return static_cast<SimpleType>(Val.getNode());
- }
-};
-template<> struct simplify_type<const SDUse> {
- typedef SDNode* SimpleType;
- static SimpleType getSimplifiedValue(const SDUse &Val) {
- return static_cast<SimpleType>(Val.getNode());
+ static SimpleType getSimplifiedValue(SDUse &Val) {
+ return Val.getNode();
}
};
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index a277080466..26d0433f3e 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -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
+ }
+
};
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index e7098e48bf..5b22c9c685 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -128,6 +128,12 @@ public:
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
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
index 76df6ac8e6..da26985949 100644
--- a/include/llvm/CodeGen/ValueTypes.td
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -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
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 0a26857397..93c2582ae2 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -69,6 +69,9 @@
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
+/* Define to 1 if you have the <cxxabi.h> header file. */
+#cmakedefine HAVE_CXXABI_H ${HAVE_CXXABI_H}
+
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
@@ -230,6 +233,9 @@
/* Define to 1 if you have the `udis86' library (-ludis86). */
#undef HAVE_LIBUDIS86
+/* Define to 1 if you have the 'z' library (-lz). */
+#cmakedefine HAVE_LIBZ ${HAVE_LIBZ}
+
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
@@ -498,6 +504,9 @@
/* Define if the xdot.py program is available */
#cmakedefine HAVE_XDOT_PY ${HAVE_XDOT_PY}
+/* Define to 1 if you have the <zlib.h> header file. */
+#cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
+
/* Have host's _alloca */
#cmakedefine HAVE__ALLOCA ${HAVE__ALLOCA}
@@ -570,6 +579,9 @@
/* Define if threads enabled */
#cmakedefine01 LLVM_ENABLE_THREADS
+/* Define if zlib compression is available */
+#cmakedefine01 LLVM_ENABLE_ZLIB
+
/* Installation directory for config files */
#cmakedefine LLVM_ETCDIR "${LLVM_ETCDIR}"
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 2f9e6ffe23..7fa00b8a03 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -78,6 +78,17 @@
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
+/* Define to 1 if you have the <cxxabi.h> header file. */
+#undef HAVE_CXXABI_H
+
+/* Define to 1 if you have the declaration of `FE_ALL_EXCEPT', and to 0 if you
+ don't. */
+#undef HAVE_DECL_FE_ALL_EXCEPT
+
+/* Define to 1 if you have the declaration of `FE_INEXACT', and to 0 if you
+ don't. */
+#undef HAVE_DECL_FE_INEXACT
+
/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
don't. */
#undef HAVE_DECL_STRERROR_S
@@ -218,6 +229,9 @@
/* Define to 1 if you have the `udis86' library (-ludis86). */
#undef HAVE_LIBUDIS86
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
@@ -495,6 +509,9 @@
/* Define if the xdot.py program is available */
#undef HAVE_XDOT_PY
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
/* Have host's _alloca */
#undef HAVE__ALLOCA
@@ -567,6 +584,9 @@
/* Define if threads enabled */
#undef LLVM_ENABLE_THREADS
+/* Define if zlib is enabled */
+#undef LLVM_ENABLE_ZLIB
+
/* Installation directory for config files */
#undef LLVM_ETCDIR
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index d59847558a..2c0f712a93 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -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,16 +265,17 @@ 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.
- DIType createClassType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, uint64_t OffsetInBits,
- unsigned Flags, DIType DerivedFrom,
- DIArray Elements, MDNode *VTableHolder = 0,
- MDNode *TemplateParms = 0);
+ DICompositeType createClassType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType DerivedFrom, DIArray Elements,
+ MDNode *VTableHolder = 0,
+ MDNode *TemplateParms = 0);
/// createStructType - Create debugging information entry for a struct.
/// @param Scope Scope in which this struct is defined.
@@ -345,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.
@@ -375,16 +383,12 @@ namespace llvm {
/// flag set.
DIType createObjectPointerType(DIType Ty);
- /// createTemporaryType - Create a temporary forward-declared type.
- DIType createTemporaryType();
- DIType createTemporaryType(DIFile F);
-
/// createForwardDecl - Create a temporary forward-declared type.
DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
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);
@@ -411,8 +415,21 @@ namespace llvm {
createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+ /// \brief Create a new descriptor for the specified global.
+ /// @param Name Name of the variable.
+ /// @param LinkageName Mangled variable name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type.
+ /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// externally visible or not.
+ /// @param Val llvm::Value of the variable.
+ DIGlobalVariable
+ createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File,
+ 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.
@@ -425,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.
@@ -508,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.
@@ -546,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.
@@ -556,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.
@@ -577,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);
};
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index a9d5a4b7b6..f9b58f4770 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -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;
@@ -177,6 +178,7 @@ namespace llvm {
if (DbgNode && !isFile())
DbgNode = 0;
}
+ MDNode *getFileNode() const;
bool Verify() const;
};
@@ -188,22 +190,17 @@ namespace llvm {
explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
unsigned getLanguage() const { return getUnsignedField(2); }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(3).getFilename();
- }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(3).getDirectory();
- }
- StringRef getProducer() const { return getStringField(4); }
+ StringRef getProducer() const { return getStringField(3); }
- bool isOptimized() const { return getUnsignedField(5) != 0; }
- StringRef getFlags() const { return getStringField(6); }
- unsigned getRunTimeVersion() const { return getUnsignedField(7); }
+ bool isOptimized() const { return getUnsignedField(4) != 0; }
+ StringRef getFlags() const { return getStringField(5); }
+ unsigned getRunTimeVersion() const { return getUnsignedField(6); }
DIArray getEnumTypes() const;
DIArray getRetainedTypes() const;
DIArray getSubprograms() const;
DIArray getGlobalVariables() const;
+ DIArray getImportedModules() const;
StringRef getSplitDebugFilename() const { return getStringField(12); }
@@ -241,9 +238,8 @@ namespace llvm {
explicit DIType(const MDNode *N);
explicit DIType() {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getName() const { return getStringField(2); }
- DIFile getFile() const { return getFieldAs<DIFile>(3); }
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
uint64_t getAlignInBits() const { return getUInt64Field(6); }
@@ -288,12 +284,6 @@ namespace llvm {
bool isValid() const {
return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
}
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(3).getDirectory();
- }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(3).getFilename();
- }
/// isUnsignedDIType - Return true if type encoding is unsigned.
bool isUnsignedDIType();
@@ -354,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;
@@ -366,10 +359,12 @@ namespace llvm {
}
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
+ void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
unsigned getRunTimeLang() const { return getUnsignedField(11); }
DICompositeType getContainingType() const {
return getFieldAs<DICompositeType>(12);
}
+ void setContainingType(DICompositeType ContainingType);
DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
/// Verify - Verify that a composite type descriptor is well formed.
@@ -426,78 +421,66 @@ namespace llvm {
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
- unsigned getLineNumber() const { return getUnsignedField(7); }
- DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
+ unsigned getLineNumber() const { return getUnsignedField(6); }
+ DICompositeType getType() const { return getFieldAs<DICompositeType>(7); }
/// getReturnTypeName - Subprogram return types are encoded either as
/// DIType or as DICompositeType.
StringRef getReturnTypeName() const {
- DICompositeType DCT(getFieldAs<DICompositeType>(8));
+ DICompositeType DCT(getFieldAs<DICompositeType>(7));
if (DCT.Verify()) {
DIArray A = DCT.getTypeArray();
DIType T(A.getElement(0));
return T.getName();
}
- DIType T(getFieldAs<DIType>(8));
+ DIType T(getFieldAs<DIType>(7));
return T.getName();
}
/// isLocalToUnit - Return true if this subprogram is local to the current
/// compile unit, like 'static' in C.
- unsigned isLocalToUnit() const { return getUnsignedField(9); }
- unsigned isDefinition() const { return getUnsignedField(10); }
+ unsigned isLocalToUnit() const { return getUnsignedField(8); }
+ unsigned isDefinition() const { return getUnsignedField(9); }
- unsigned getVirtuality() const { return getUnsignedField(11); }
- unsigned getVirtualIndex() const { return getUnsignedField(12); }
+ unsigned getVirtuality() const { return getUnsignedField(10); }
+ unsigned getVirtualIndex() const { return getUnsignedField(11); }
DICompositeType getContainingType() const {
- return getFieldAs<DICompositeType>(13);
+ return getFieldAs<DICompositeType>(12);
}
unsigned getFlags() const {
- return getUnsignedField(14);
+ return getUnsignedField(13);
}
unsigned isArtificial() const {
- return (getUnsignedField(14) & FlagArtificial) != 0;
+ return (getUnsignedField(13) & FlagArtificial) != 0;
}
/// isPrivate - Return true if this subprogram has "private"
/// access specifier.
bool isPrivate() const {
- return (getUnsignedField(14) & FlagPrivate) != 0;
+ return (getUnsignedField(13) & FlagPrivate) != 0;
}
/// isProtected - Return true if this subprogram has "protected"
/// access specifier.
bool isProtected() const {
- return (getUnsignedField(14) & FlagProtected) != 0;
+ return (getUnsignedField(13) & FlagProtected) != 0;
}
/// isExplicit - Return true if this subprogram is marked as explicit.
bool isExplicit() const {
- return (getUnsignedField(14) & FlagExplicit) != 0;
+ return (getUnsignedField(13) & FlagExplicit) != 0;
}
/// isPrototyped - Return true if this subprogram is prototyped.
bool isPrototyped() const {
- return (getUnsignedField(14) & FlagPrototyped) != 0;
+ return (getUnsignedField(13) & FlagPrototyped) != 0;
}
unsigned isOptimized() const;
- StringRef getFilename() const {
- return getFieldAs<DIFile>(6).getFilename();
- }
-
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(6).getDirectory();
- }
-
- DIFile getFile() const {
- return getFieldAs<DIFile>(6);
- }
-
/// getScopeLineNumber - Get the beginning of the scope of the
/// function, not necessarily where the name of the program
/// starts.
- unsigned getScopeLineNumber() const { return getUnsignedField(20); }
+ unsigned getScopeLineNumber() const { return getUnsignedField(19); }
/// Verify - Verify that a subprogram descriptor is well formed.
bool Verify() const;
@@ -506,11 +489,11 @@ namespace llvm {
/// information for the function F.
bool describes(const Function *F);
- Function *getFunction() const { return getFunctionField(16); }
- void replaceFunction(Function *F) { replaceFunctionField(16, F); }
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
+ Function *getFunction() const { return getFunctionField(15); }
+ void replaceFunction(Function *F) { replaceFunctionField(15, F); }
+ DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); }
DISubprogram getFunctionDeclaration() const {
- return getFieldAs<DISubprogram>(18);
+ return getFieldAs<DISubprogram>(17);
}
MDNode *getVariablesNodes() const;
DIArray getVariables() const;
@@ -614,15 +597,9 @@ namespace llvm {
class DILexicalBlock : public DIScope {
public:
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- unsigned getLineNumber() const { return getUnsignedField(2); }
- unsigned getColumnNumber() const { return getUnsignedField(3); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(4).getDirectory();
- }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(4).getFilename();
- }
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ unsigned getLineNumber() const { return getUnsignedField(3); }
+ unsigned getColumnNumber() const { return getUnsignedField(4); }
bool Verify() const;
};
@@ -634,28 +611,18 @@ namespace llvm {
DIScope getContext() const { if (getScope().isSubprogram()) return getScope(); return getScope().getContext(); }
unsigned getLineNumber() const { return getScope().getLineNumber(); }
unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(2).getDirectory();
- }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(2).getFilename();
- }
- DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
+ DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
bool Verify() const;
};
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
+ friend class DIDescriptor;
+ void printInternal(raw_ostream &OS) const;
public:
explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getName() const { return getStringField(2); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(3).getDirectory();
- }
- StringRef getFilename() const {
- return getFieldAs<DIFile>(3).getFilename();
- }
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
unsigned getLineNumber() const { return getUnsignedField(4); }
bool Verify() const;
};
@@ -716,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);
diff --git a/include/llvm/DebugInfo/DWARFFormValue.h b/include/llvm/DebugInfo/DWARFFormValue.h
new file mode 100644
index 0000000000..eaaccfb4f3
--- /dev/null
+++ b/include/llvm/DebugInfo/DWARFFormValue.h
@@ -0,0 +1,82 @@
+//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
+#define LLVM_DEBUGINFO_DWARFFORMVALUE_H
+
+#include "llvm/Support/DataExtractor.h"
+
+namespace llvm {
+
+class DWARFCompileUnit;
+class raw_ostream;
+
+class DWARFFormValue {
+public:
+ struct ValueType {
+ ValueType() : data(NULL) {
+ uval = 0;
+ }
+
+ union {
+ uint64_t uval;
+ int64_t sval;
+ const char* cstr;
+ };
+ const uint8_t* data;
+ };
+
+ enum {
+ eValueTypeInvalid = 0,
+ eValueTypeUnsigned,
+ eValueTypeSigned,
+ eValueTypeCStr,
+ eValueTypeBlock
+ };
+
+private:
+ uint16_t Form; // Form for this value.
+ ValueType Value; // Contains all data for the form.
+
+public:
+ DWARFFormValue(uint16_t form = 0) : Form(form) {}
+ uint16_t getForm() const { return Form; }
+ const ValueType& value() const { return Value; }
+ void dump(raw_ostream &OS, const DWARFCompileUnit* cu) const;
+ bool extractValue(DataExtractor data, uint32_t *offset_ptr,
+ const DWARFCompileUnit *cu);
+ bool isInlinedCStr() const {
+ return Value.data != NULL && Value.data == (const uint8_t*)Value.cstr;
+ }
+ const uint8_t *BlockData() const;
+ uint64_t getReference(const DWARFCompileUnit* cu) const;
+
+ /// Resolve any compile unit specific references so that we don't need
+ /// the compile unit at a later time in order to work with the form
+ /// value.
+ bool resolveCompileUnitReferences(const DWARFCompileUnit* cu);
+ uint64_t getUnsigned() const { return Value.uval; }
+ int64_t getSigned() const { return Value.sval; }
+ const char *getAsCString(const DataExtractor *debug_str_data_ptr) const;
+ const char *getIndirectCString(const DataExtractor *,
+ const DataExtractor *) const;
+ uint64_t getIndirectAddress(const DataExtractor *,
+ const DWARFCompileUnit *) const;
+ bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
+ const DWARFCompileUnit *cu) const;
+ static bool skipValue(uint16_t form, DataExtractor debug_info_data,
+ uint32_t *offset_ptr, const DWARFCompileUnit *cu);
+ static bool isBlockForm(uint16_t form);
+ static bool isDataForm(uint16_t form);
+ static const uint8_t *getFixedFormSizes(uint8_t AddrSize, uint16_t Version);
+};
+
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 3fd69e266b..bbaebc6f90 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -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 @@ public:
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 @@ public:
ExecutionEngine *create(TargetMachine *TM);
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
+
} // End llvm namespace
#endif
diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h
index 21b99421b3..0e92f79eba 100644
--- a/include/llvm/ExecutionEngine/GenericValue.h
+++ b/include/llvm/ExecutionEngine/GenericValue.h
@@ -35,14 +35,19 @@ struct GenericValue {
struct IntPair UIntPairVal;
unsigned char Untyped[8];
};
- APInt IntVal; // also used for long doubles
-
- GenericValue() : DoubleVal(0.0), IntVal(1,0) {}
+ APInt IntVal; // also used for long doubles.
+ // For aggregate data types.
+ std::vector<GenericValue> AggregateVal;
+
+ // to make code faster, set GenericValue to zero could be omitted, but it is
+ // potentially can cause problems, since GenericValue to store garbage
+ // instead of zero.
+ GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;}
explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
};
inline GenericValue PTOGV(void *P) { return GenericValue(P); }
inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
-} // End llvm namespace
+} // End llvm namespace.
#endif
diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h
new file mode 100644
index 0000000000..0bee86161b
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectCache.h
@@ -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
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
index ae5004e130..9ac8c92524 100644
--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -87,9 +87,7 @@ public:
/// 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:
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index ef4e4fc7aa..40d61ff685 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -78,6 +78,10 @@ public:
/// 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);
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 074b38779a..2c7da6485d 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -87,6 +87,7 @@ public:
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 @@ private:
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 @@ public:
/// \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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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);
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index ea5695a9e6..3bdc95d556 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -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 @@ private:
}
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
+
} // End llvm namespace
#endif
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index ad258f9aca..2f29f54594 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
/// 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:
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index 4d3016c72f..b0def6be3f 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -22,6 +22,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
@@ -169,13 +171,13 @@ public:
/// 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)
{ }
@@ -350,6 +352,10 @@ public:
/// type.
Type *getIntPtrType(Type *) const;
+ /// getSmallestLegalIntType - Return the smallest integer type with size at
+ /// least as big as Width bits.
+ Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const;
+
/// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr.
uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const;
@@ -420,9 +426,52 @@ public:
private:
friend class DataLayout; // Only DataLayout can create this class
- StructLayout(StructType *ST, const DataLayout &TD);
+ StructLayout(StructType *ST, const DataLayout &DL);
};
+
+// The implementation of this method is provided inline as it is particularly
+// well suited to constant folding when called on a specific Type subclass.
+inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
+ assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
+ switch (Ty->getTypeID()) {
+ case Type::LabelTyID:
+ return getPointerSizeInBits(0);
+ case Type::PointerTyID:
+ return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
+ case Type::ArrayTyID: {
+ ArrayType *ATy = cast<ArrayType>(Ty);
+ return ATy->getNumElements() *
+ getTypeAllocSizeInBits(ATy->getElementType());
+ }
+ case Type::StructTyID:
+ // Get the layout annotation... which is lazily created on demand.
+ return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
+ case Type::IntegerTyID:
+ return cast<IntegerType>(Ty)->getBitWidth();
+ case Type::HalfTyID:
+ return 16;
+ case Type::FloatTyID:
+ return 32;
+ case Type::DoubleTyID:
+ case Type::X86_MMXTyID:
+ return 64;
+ case Type::PPC_FP128TyID:
+ case Type::FP128TyID:
+ return 128;
+ // In memory objects this is always aligned to a higher boundary, but
+ // only 80 bits contain information.
+ case Type::X86_FP80TyID:
+ return 80;
+ case Type::VectorTyID: {
+ VectorType *VTy = cast<VectorType>(Ty);
+ return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType());
+ }
+ default:
+ llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
+ }
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index 6c00f596ba..e279e60e47 100644
--- a/include/llvm/IR/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -117,7 +117,7 @@ public:
/// 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;
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index f398bc1b87..260302a594 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -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 @@ public:
/// 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) {
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 1c71d0a901..f11d3b4e0b 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -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 @@ protected:
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 @@ public:
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 @@ public:
}
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
+
}
#endif
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index c97cd91d73..e69ddec1e3 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -63,14 +63,13 @@ 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.
+ /// 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 = ArrayRef<Type*>());
-
+
/// Map a GCC builtin name to an intrinsic ID.
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index cde39ccd3c..5664f79250 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -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">,
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index d2463c0efa..69e0ab4fa2 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -2550,7 +2550,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
-// RDRAND intrinsics. Return a random value and whether it is valid.
+// RDRAND intrinsics - Return a random value and whether it is valid.
+// RDSEED intrinsics - Return a NIST SP800-90B & C compliant random value and
+// whether it is valid.
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// These are declared side-effecting so they don't get eliminated by CSE or
@@ -2558,6 +2560,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_rdrand_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>;
def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>;
def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
+ def int_x86_rdseed_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>;
+ def int_x86_rdseed_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>;
+ def int_x86_rdseed_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
}
//===----------------------------------------------------------------------===//
@@ -2570,4 +2575,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[], [], []>;
def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">,
Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>;
+ def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">,
+ Intrinsic<[llvm_i32_ty], [], []>;
}
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index ae81e5b1c3..f25d820c2b 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -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 @@ private:
/// 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
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index 604051b90a..ce81b5498f 100644
--- a/include/llvm/IR/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -156,6 +156,41 @@ public:
return MDNode::get(Context, Vals);
}
+ /// \brief Return metadata for a TBAA struct node in the type DAG
+ /// with the given name, a list of pairs (offset, field type in the type DAG).
+ MDNode *createTBAAStructTypeNode(StringRef Name,
+ 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] = 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,
+ uint64_t Offset) {
+ Type *Int64 = IntegerType::get(Context, 64);
+ Value *Ops[3] = { BaseType, AccessType, ConstantInt::get(Int64, Offset) };
+ return MDNode::get(Context, Ops);
+ }
+
};
} // end namespace llvm
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 4460aa435b..cb500ffe7c 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -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
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index d89ae243f5..1bf8789d30 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -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
diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h
index 33a69c4686..efd8b48a0e 100644
--- a/include/llvm/IR/Use.h
+++ b/include/llvm/IR/Use.h
@@ -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>
@@ -149,14 +151,14 @@ private:
// casting operators.
template<> struct simplify_type<Use> {
typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const Use &Val) {
- return static_cast<SimpleType>(Val.get());
+ static SimpleType getSimplifiedValue(Use &Val) {
+ return Val.get();
}
};
template<> struct simplify_type<const Use> {
- typedef Value* SimpleType;
+ typedef /*const*/ Value* SimpleType;
static SimpleType getSimplifiedValue(const Use &Val) {
- return static_cast<SimpleType>(Val.get());
+ return Val.get();
}
};
@@ -214,6 +216,9 @@ public:
unsigned getOperandNo() const;
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
+
} // End llvm namespace
#endif
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index a4d0a5d7df..505bdeb178 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -183,27 +183,17 @@ public:
template<> struct simplify_type<User::op_iterator> {
typedef Value* SimpleType;
-
- static SimpleType getSimplifiedValue(const User::op_iterator &Val) {
- return static_cast<SimpleType>(Val->get());
+ static SimpleType getSimplifiedValue(User::op_iterator &Val) {
+ return Val->get();
}
};
-
-template<> struct simplify_type<const User::op_iterator>
- : public simplify_type<User::op_iterator> {};
-
template<> struct simplify_type<User::const_op_iterator> {
- typedef Value* SimpleType;
-
- static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) {
- return static_cast<SimpleType>(Val->get());
+ typedef /*const*/ Value* SimpleType;
+ static SimpleType getSimplifiedValue(User::const_op_iterator &Val) {
+ return Val->get();
}
};
-template<> struct simplify_type<const User::const_op_iterator>
- : public simplify_type<User::const_op_iterator> {};
-
-
// value_use_iterator::getOperandNo - Requires the definition of the User class.
template<typename UserTy>
unsigned value_use_iterator<UserTy>::getOperandNo() const {
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index a4f78627a8..fb61a2ac70 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -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 {
@@ -406,6 +408,29 @@ public:
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
diff --git a/include/llvm/IRReader/IRReader.h b/include/llvm/IRReader/IRReader.h
new file mode 100644
index 0000000000..e2ae5f7164
--- /dev/null
+++ b/include/llvm/IRReader/IRReader.h
@@ -0,0 +1,55 @@
+//===---- llvm/IRReader/IRReader.h - Reader for LLVM IR files ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines functions for reading LLVM IR. They support both
+// Bitcode and Assembly, automatically detecting the input format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IRREADER_IRREADER_H
+#define LLVM_IRREADER_IRREADER_H
+
+#include <string>
+
+namespace llvm {
+
+class Module;
+class MemoryBuffer;
+class SMDiagnostic;
+class LLVMContext;
+
+/// If the given MemoryBuffer holds a bitcode image, return a Module for it
+/// which does lazy deserialization of function bodies. Otherwise, attempt to
+/// parse it as LLVM Assembly and return a fully populated Module. This
+/// function *always* takes ownership of the given MemoryBuffer.
+Module *getLazyIRModule(MemoryBuffer *Buffer, SMDiagnostic &Err,
+ LLVMContext &Context);
+
+/// If the given file holds a bitcode image, return a Module
+/// for it which does lazy deserialization of function bodies. Otherwise,
+/// attempt to parse it as LLVM Assembly and return a fully populated
+/// Module.
+Module *getLazyIRFileModule(const std::string &Filename, SMDiagnostic &Err,
+ LLVMContext &Context);
+
+/// If the given MemoryBuffer holds a bitcode image, return a Module
+/// for it. Otherwise, attempt to parse it as LLVM Assembly and return
+/// a Module for it. This function *always* takes ownership of the given
+/// MemoryBuffer.
+Module *ParseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, LLVMContext &Context);
+
+/// If the given file holds a bitcode image, return a Module for it.
+/// Otherwise, attempt to parse it as LLVM Assembly and return a Module
+/// for it.
+Module *ParseIRFile(const std::string &Filename, SMDiagnostic &Err,
+ LLVMContext &Context);
+
+}
+
+#endif
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index a6dbb0c7d2..5b2cd603c3 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -91,7 +91,6 @@ void initializeCFGViewerPass(PassRegistry&);
void initializeCalculateSpillWeightsPass(PassRegistry&);
void initializeCallGraphAnalysisGroup(PassRegistry&);
void initializeCodeGenPreparePass(PassRegistry&);
-void initializeCodePlacementOptPass(PassRegistry&);
void initializeConstantMergePass(PassRegistry&);
void initializeConstantPropagationPass(PassRegistry&);
void initializeMachineCopyPropagationPass(PassRegistry&);
@@ -272,6 +271,7 @@ void initializeInstSimplifierPass(PassRegistry&);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeFinalizeMachineBundlesPass(PassRegistry&);
void initializeLoopVectorizePass(PassRegistry&);
+void initializeSLPVectorizerPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
}
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 1f017e471d..ca1c13924e 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -161,6 +161,7 @@ namespace {
(void) llvm::createMemDepPrinter();
(void) llvm::createInstructionSimplifierPass();
(void) llvm::createLoopVectorizePass();
+ (void) llvm::createSLPVectorizerPass();
(void) llvm::createBBVectorizePass();
(void)new llvm::IntervalPartition();
diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h
index 8bf9efa8e2..679638427d 100644
--- a/include/llvm/Linker.h
+++ b/include/llvm/Linker.h
@@ -6,10 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the interface to the module/file/archive linker.
-//
-//===----------------------------------------------------------------------===//
#ifndef LLVM_LINKER_H
#define LLVM_LINKER_H
@@ -19,7 +15,6 @@
#include <vector>
namespace llvm {
- namespace sys { class Path; }
class Module;
class LLVMContext;
@@ -31,8 +26,7 @@ class StringRef;
/// 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. It retains a set of search paths
-/// in which to find any libraries presented to it. By default, the linker
+/// 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
@@ -96,16 +90,10 @@ class Linker {
/// 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. The Linker's
- /// LibPaths and flags to be reset, and memory will be released.
+ /// subsequent linking as if the constructor had been called.
/// @brief Release the linked/composite module.
Module* releaseModule();
- /// This method gets the list of libraries that form the path that the
- /// Linker will search when it is presented with a library name.
- /// @brief Get the Linkers library path
- const std::vector<sys::Path>& getLibPaths() const { return LibPaths; }
-
/// 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
@@ -120,31 +108,6 @@ class Linker {
/// @name Mutators
/// @{
public:
- /// Add a path to the list of paths that the Linker will search. The Linker
- /// accumulates the set of libraries added
- /// library paths for the target platform. The standard libraries will
- /// always be searched last. The added libraries will be searched in the
- /// order added.
- /// @brief Add a path.
- void addPath(const sys::Path& path);
-
- /// Add a set of paths to the list of paths that the linker will search. The
- /// Linker accumulates the set of libraries added. The \p paths will be
- /// added to the end of the Linker's list. Order will be retained.
- /// @brief Add a set of paths.
- void addPaths(const std::vector<std::string>& paths);
-
- /// This method augments the Linker's list of library paths with the system
- /// paths of the host operating system, include LLVM_LIB_SEARCH_PATH.
- /// @brief Add the system paths.
- void addSystemPaths();
-
- /// Control optional linker behavior by setting a group of flags. The flags
- /// are defined in the ControlFlags enumeration.
- /// @see ControlFlags
- /// @brief Set control flags.
- void setFlags(unsigned flags) { Flags = flags; }
-
/// This method links the \p Src module into the Linker's Composite module
/// by calling LinkModules.
/// @see LinkModules
@@ -185,7 +148,6 @@ class Linker {
private:
LLVMContext& Context; ///< The context for global information
Module* Composite; ///< The composite module linked together
- std::vector<sys::Path> LibPaths; ///< The library search paths
unsigned Flags; ///< Flags to control optional behavior.
std::string Error; ///< Text of error that occurred.
std::string ProgramName; ///< Name of the program being linked
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 28256b3677..d020de3004 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -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;
}
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 6aeb8b8c3a..2c8c602b38 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -459,7 +459,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); }
@@ -495,7 +495,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); }
@@ -526,7 +526,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); }
@@ -598,6 +598,10 @@ private:
/// 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:
@@ -641,6 +645,8 @@ public:
bool empty() const { return Fragments.empty(); }
+ iterator getSubsectionInsertionPoint(unsigned Subsection);
+
bool isBundleLocked() const {
return BundleLockState != NotBundleLocked;
}
diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h
index 682cf7cd76..ae5bf0bc20 100644
--- a/include/llvm/MC/MCAtom.h
+++ b/include/llvm/MC/MCAtom.h
@@ -46,8 +46,8 @@ class MCAtom {
: Type(T), Parent(P), Begin(B), End(E) { }
public:
- bool isTextAtom() { return Type == TextAtom; }
- bool isDataAtom() { return Type == DataAtom; }
+ bool isTextAtom() const { return Type == TextAtom; }
+ bool isDataAtom() const { return Type == DataAtom; }
void addInst(const MCInst &I, uint64_t Address, unsigned Size);
void addData(const MCData &D);
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index 6fb2d22be2..55c05b0363 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -50,7 +50,8 @@ public:
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);
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index b5bfed18ec..a2c5bd3f76 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -216,7 +216,9 @@ public:
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:
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index e91c6a2e8e..4766815da5 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -171,7 +171,7 @@ public:
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) {
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index c8d748420e..a5853b602c 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -46,10 +46,15 @@ protected:
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 @@ public:
}
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; }
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index f06c49ff08..22a2839869 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -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 @@ protected:
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 @@ public:
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
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index d7e3902ac4..4ca5b9ae9e 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -33,15 +33,30 @@ 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) = 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.
@@ -151,6 +166,13 @@ public:
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.
///
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index c78cd976f2..818fbbd6c6 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -37,15 +37,8 @@ public:
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;
@@ -57,19 +50,12 @@ public:
/// isMem - Is this a memory operand?
virtual bool isMem() const = 0;
- virtual unsigned getMemSize() const { return 0; }
/// getStartLoc - Get the location of the first token of this operand.
virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
virtual SMLoc getEndLoc() const = 0;
- /// needAsmRewrite - AsmRewrites happen in both the target-independent and
- /// target-dependent parsers. The target-independent parser calls this
- /// function to determine if the target-dependent parser has already taken
- /// care of the rewrites. Only valid when parsing MS-style inline assembly.
- virtual bool needAsmRewrite() const { return true; }
-
/// needAddressOf - Do we need to emit code to get the address of the
/// variable/label? Only valid when parsing MS-style inline assembly.
virtual bool needAddressOf() const { return false; }
@@ -82,10 +68,6 @@ public:
/// getOffsetOfLoc - Get the location of the offset operator.
virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
- /// needSizeDirective - Do we need to emit a sizing directive for this
- /// operand? Only valid when parsing MS-style inline assembly.
- virtual bool needSizeDirective() const { return false; }
-
/// print - Print a debug representation of the operand to the given stream.
virtual void print(raw_ostream &OS) const = 0;
/// dump - Print to the debug stream.
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 5d6cac2b98..944bfcbf02 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -20,6 +20,7 @@
namespace llvm {
class MCAsmInfo;
+ class MCExpr;
class raw_ostream;
/// MCSection - Instances of this class represent a uniqued identifier for a
@@ -49,7 +50,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.
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 07c47144cb..50e33a5b04 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -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;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 4b8b849c79..59799158ad 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -70,7 +70,8 @@ public:
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;
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 898f571490..b68bd85968 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -175,7 +175,8 @@ public:
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;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index a069a2b0ca..2cab481c3d 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -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.
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 4c5b176125..6e878df3cb 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -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;
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index 11df5749d4..f13e7d5480 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -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.
diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h
index 5caad337f8..83c8b72ee4 100644
--- a/include/llvm/MC/MachineLocation.h
+++ b/include/llvm/MC/MachineLocation.h
@@ -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 @@ public:
};
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 @@ public:
}
// 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;
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 37ae03b45c..8862c8b762 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -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.
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index 8bbcd8b4d4..78fcf6feb8 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -41,11 +41,17 @@ protected:
// 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 @@ protected:
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 @@ public:
}
bool isMachO() const {
- return TypeID == ID_MachO;
+ return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
}
bool isCOFF() const {
@@ -87,7 +100,8 @@ public:
}
bool isLittleEndian() const {
- return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B);
+ return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
+ TypeID == ID_MachO32B || TypeID == ID_MachO64B);
}
};
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index d5ff6f9594..491a17eb94 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -83,9 +83,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
@@ -97,9 +96,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
@@ -111,27 +109,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;
-
-// This is required to get template types into a macro :(
-#define LLVM_ELF_COMMA ,
-
- // Section header.
+#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;
+
+#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
+ LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \
+ ELFT::Is64Bits)
+
+// 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_*)
@@ -144,11 +144,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_*)
@@ -177,11 +175,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
@@ -190,11 +186,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
@@ -222,7 +216,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)
};
@@ -233,7 +227,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_*)
@@ -253,7 +247,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)
};
@@ -262,7 +256,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)
@@ -274,7 +268,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
@@ -287,11 +281,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;
@@ -299,11 +291,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;
@@ -325,90 +315,129 @@ 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
+
+ uint32_t getRInfo(bool isMips64EL) const {
+ assert(!isMips64EL);
+ return r_info;
+ }
+ void setRInfo(uint32_t R) {
+ r_info = R;
+ }
};
-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
+
+ uint64_t getRInfo(bool isMips64EL) const {
+ uint64_t t = r_info;
+ if (!isMips64EL)
+ return t;
+ // Mip64 little endian has a "special" encoding of r_info. Instead of one
+ // 64 bit little endian number, it is a little ending 32 bit number followed
+ // by a 32 bit big endian number.
+ return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+ ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+ return r_info;
+ }
+ void setRInfo(uint64_t R) {
+ // FIXME: Add mips64el support.
+ r_info = R;
+ }
};
-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
+
+ uint32_t getRInfo(bool isMips64EL) const {
+ assert(!isMips64EL);
+ return r_info;
+ }
+ void setRInfo(uint32_t R) {
+ r_info = R;
+ }
};
-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.
+
+ uint64_t getRInfo(bool isMips64EL) const {
+ // Mip64 little endian has a "special" encoding of r_info. Instead of one
+ // 64 bit little endian number, it is a little ending 32 bit number followed
+ // by a 32 bit big endian number.
+ uint64_t t = r_info;
+ if (!isMips64EL)
+ return t;
+ return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+ ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+ }
+ void setRInfo(uint64_t R) {
+ // FIXME: Add mips64el support.
+ r_info = R;
+ }
};
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> {
- using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela>::r_info;
- 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:
- uint32_t getSymbol() const { return (uint32_t) (r_info >> 32); }
- uint32_t getType() const {
- return (uint32_t) (r_info & 0xffffffffL);
+ uint32_t getSymbol(bool isMips64EL) const {
+ return (uint32_t) (this->getRInfo(isMips64EL) >> 32);
+ }
+ uint32_t getType(bool isMips64EL) const {
+ return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL);
}
void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
void setSymbolAndType(uint32_t s, uint32_t t) {
- r_info = ((uint64_t)s << 32) + (t&0xffffffffL);
+ this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL));
}
};
-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> {
- using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela>::r_info;
- 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:
- uint32_t getSymbol() const { return (r_info >> 8); }
- unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+ uint32_t getSymbol(bool isMips64EL) const {
+ return this->getRInfo(isMips64EL) >> 8;
+ }
+ unsigned char getType(bool isMips64EL) const {
+ return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff);
+ }
void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
void setSymbolAndType(uint32_t s, unsigned char t) {
- r_info = (s << 8) + t;
+ this->setRInfo((s << 8) + t);
}
};
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_*)
@@ -434,11 +463,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
@@ -449,11 +476,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
@@ -466,7 +491,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.
@@ -584,6 +609,8 @@ private:
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> {
@@ -640,6 +667,7 @@ public:
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,
@@ -656,6 +684,7 @@ protected:
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;
@@ -705,6 +734,13 @@ protected:
public:
ELFObjectFile(MemoryBuffer *Object, error_code &ec);
+
+ bool isMips64EL() const {
+ return Header->e_machine == ELF::EM_MIPS &&
+ Header->getFileClass() == ELF::ELFCLASS64 &&
+ Header->getDataEncoding() == ELF::ELFDATA2LSB;
+ }
+
virtual symbol_iterator begin_symbols() const;
virtual symbol_iterator end_symbols() const;
@@ -792,6 +828,7 @@ public:
uint64_t getNumSections() const;
uint64_t getStringTableIndex() const;
ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
+ const Elf_Ehdr *getElfHeader() const;
const Elf_Shdr *getSection(const Elf_Sym *symb) const;
const Elf_Shdr *getElfSection(section_iterator &It) const;
const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
@@ -971,6 +1008,12 @@ ELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const {
}
template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Ehdr *
+ELFObjectFile<ELFT>::getElfHeader() const {
+ return Header;
+}
+
+template<class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Shdr *
ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const {
llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
@@ -1060,6 +1103,11 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
IsRelocatable = true;
}
Result = symb->st_value;
+
+ // Clear the ARM/Thumb indicator flag.
+ if (Header->e_machine == ELF::EM_ARM)
+ Result &= ~1;
+
if (IsRelocatable && Section != 0)
Result += Section->sh_addr;
return object_error::success;
@@ -1070,6 +1118,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 {
validateSymbol(Symb);
@@ -1375,8 +1438,16 @@ template<class ELFT>
error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
DataRefImpl Symb,
bool &Result) const {
- // FIXME: Unimplemented.
- Result = false;
+ validateSymbol(Symb);
+
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ const Elf_Sym *symb = getSymbol(Symb);
+
+ unsigned shndx = symb->st_shndx;
+ bool Reserved = shndx >= ELF::SHN_LORESERVE
+ && shndx <= ELF::SHN_HIRESERVE;
+
+ Result = !Reserved && (sec == getSection(symb->st_shndx));
return object_error::success;
}
@@ -1449,11 +1520,11 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
default :
report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL : {
- symbolIdx = getRel(Rel)->getSymbol();
+ symbolIdx = getRel(Rel)->getSymbol(isMips64EL());
break;
}
case ELF::SHT_RELA : {
- symbolIdx = getRela(Rel)->getSymbol();
+ symbolIdx = getRela(Rel)->getSymbol(isMips64EL());
break;
}
}
@@ -1470,45 +1541,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>
@@ -1519,11 +1577,11 @@ error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
default :
report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL : {
- Result = getRel(Rel)->getType();
+ Result = getRel(Rel)->getType(isMips64EL());
break;
}
case ELF::SHT_RELA : {
- Result = getRela(Rel)->getType();
+ Result = getRela(Rel)->getType(isMips64EL());
break;
}
}
@@ -1531,29 +1589,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();
- break;
- }
- case ELF::SHT_RELA : {
- type = getRela(Rel)->getType();
- 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);
@@ -1581,17 +1624,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);
@@ -1632,12 +1680,68 @@ 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) {
+ 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);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16);
+ 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);
+ 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);
@@ -1711,13 +1815,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);
@@ -1849,12 +1951,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);
@@ -1941,20 +2042,118 @@ 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;
+ 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 {
const Elf_Shdr *sec = getSection(Rel.w.b);
@@ -1984,14 +2183,14 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
default:
return object_error::parse_failed;
case ELF::SHT_REL: {
- type = getRel(Rel)->getType();
- symbol_index = getRel(Rel)->getSymbol();
+ type = getRel(Rel)->getType(isMips64EL());
+ symbol_index = getRel(Rel)->getSymbol(isMips64EL());
// TODO: Read implicit addend from section data.
break;
}
case ELF::SHT_RELA: {
- type = getRela(Rel)->getType();
- symbol_index = getRela(Rel)->getSymbol();
+ type = getRela(Rel)->getType(isMips64EL());
+ symbol_index = getRela(Rel)->getSymbol(isMips64EL());
addend = getRela(Rel)->r_addend;
break;
}
@@ -2056,8 +2255,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)
@@ -2305,8 +2503,9 @@ ELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
if (NULLEnd) {
Elf_Dyn_iterator Start = begin_dynamic_table();
- for (; Start != Ret && Start->getTag() != ELF::DT_NULL; ++Start)
- ;
+ while (Start != Ret && Start->getTag() != ELF::DT_NULL)
+ ++Start;
+
// Include the DT_NULL.
if (Start != Ret)
++Start;
@@ -2323,10 +2522,9 @@ StringRef ELFObjectFile<ELFT>::getLoadName() const {
// Find the DT_SONAME entry
Elf_Dyn_iterator it = begin_dynamic_table();
Elf_Dyn_iterator ie = end_dynamic_table();
- for (; it != ie; ++it) {
- if (it->getTag() == ELF::DT_SONAME)
- break;
- }
+ while (it != ie && it->getTag() != ELF::DT_SONAME)
+ ++it;
+
if (it != ie) {
if (dot_dynstr_sec == NULL)
report_fatal_error("Dynamic string table is missing");
@@ -2343,10 +2541,8 @@ library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
// Find the first DT_NEEDED entry
Elf_Dyn_iterator i = begin_dynamic_table();
Elf_Dyn_iterator e = end_dynamic_table();
- for (; i != e; ++i) {
- if (i->getTag() == ELF::DT_NEEDED)
- break;
- }
+ while (i != e && i->getTag() != ELF::DT_NEEDED)
+ ++i;
DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(i.get());
@@ -2361,11 +2557,10 @@ error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
reinterpret_cast<const char *>(Data.p));
Elf_Dyn_iterator e = end_dynamic_table();
- // Skip the current dynamic table entry.
- ++i;
-
- // Find the next DT_NEEDED entry.
- for (; i != e && i->getTag() != ELF::DT_NEEDED; ++i);
+ // Skip the current dynamic table entry and find the next DT_NEEDED entry.
+ do
+ ++i;
+ while (i != e && i->getTag() != ELF::DT_NEEDED);
DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(i.get());
@@ -2706,6 +2901,21 @@ static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
}
+/// This function returns the hash value for a symbol in the .dynsym section
+/// Name of the API remains consistent as specified in the libelf
+/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
+static inline unsigned elf_hash(StringRef &symbolName) {
+ unsigned h = 0, g;
+ for (unsigned i = 0, j = symbolName.size(); i < j; i++) {
+ h = (h << 4) + symbolName[i];
+ g = h & 0xf0000000L;
+ if (g != 0)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ return h;
+}
+
}
}
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index ed7aabd2c8..14cd4d767d 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -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);
-
- 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;
+ struct LoadCommandInfo {
+ const char *Ptr; // Where in memory the load command is.
+ macho::LoadCommand C; // The command itself.
+ };
- virtual uint8_t getBytesInAddress() const;
- virtual StringRef getFileFormatName() const;
- virtual unsigned getArch() const;
- virtual StringRef getLoadName() const;
+ MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
+ error_code &ec);
- // 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 @@ protected:
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 @@ protected:
virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
-private:
- OwningPtr<MachOObject> MachOObj;
- mutable uint32_t RegisteredStringTable;
- typedef SmallVector<DataRefImpl, 1> SectionList;
- SectionList Sections;
+ // 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;
- 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;
+ 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:
+ typedef SmallVector<const char*, 1> SectionList;
+ SectionList Sections;
+ const char *SymtabLoadCmd;
+ const char *DysymtabLoadCmd;
};
}
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
deleted file mode 100644
index 9e4ab199f5..0000000000
--- a/include/llvm/Object/MachOObject.h
+++ /dev/null
@@ -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
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 6a66653fe2..eb53cc0aab 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -217,6 +217,8 @@ public:
/// 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 @@ public:
/// 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 @@ protected:
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);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 2dcbdf9053..59d810763f 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -133,7 +133,7 @@ private:
int64_t Addend;
R.getAdditionalInfo(Addend);
uint64_t Address;
- R.getAddress(Address);
+ R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4);
}
@@ -151,7 +151,7 @@ private:
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) {
diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h
index ce5fda79f9..b6a8186a4e 100644
--- a/include/llvm/PassManager.h
+++ b/include/llvm/PassManager.h
@@ -18,6 +18,7 @@
#define LLVM_PASSMANAGER_H
#include "llvm/Pass.h"
+#include "llvm/Support/CBindingWrapping.h"
namespace llvm {
@@ -98,6 +99,9 @@ private:
Module *M;
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef)
+
} // End llvm namespace
#endif
diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h
index 5d89c49221..f49c953e44 100644
--- a/include/llvm/PassRegistry.h
+++ b/include/llvm/PassRegistry.h
@@ -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 @@ public:
void removeRegistrationListener(PassRegistrationListener *L);
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef)
+
}
#endif
diff --git a/include/llvm/Support/CBindingWrapping.h b/include/llvm/Support/CBindingWrapping.h
new file mode 100644
index 0000000000..51097b8202
--- /dev/null
+++ b/include/llvm/Support/CBindingWrapping.h
@@ -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
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index a9fb65cba9..265b886daf 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -27,8 +27,9 @@ namespace llvm {
template <class Ptr, class USE_iterator> // Predecessor Iterator
class PredIterator : public std::iterator<std::forward_iterator_tag,
- Ptr, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super;
+ Ptr, ptrdiff_t, Ptr*, Ptr*> {
+ typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
+ Ptr*> super;
typedef PredIterator<Ptr, USE_iterator> Self;
USE_iterator It;
@@ -40,6 +41,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
public:
typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
PredIterator() {}
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
@@ -50,7 +52,7 @@ public:
inline bool operator==(const Self& x) const { return It == x.It; }
inline bool operator!=(const Self& x) const { return !operator==(x); }
- inline pointer operator*() const {
+ inline reference operator*() const {
assert(!It.atEnd() && "pred_iterator out of range!");
return cast<TerminatorInst>(*It)->getParent();
}
@@ -100,10 +102,11 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) {
template <class Term_, class BB_> // Successor Iterator
class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
- BB_, ptrdiff_t> {
+ BB_, ptrdiff_t, BB_*, BB_*> {
const Term_ Term;
unsigned idx;
- typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super;
+ typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*,
+ BB_*> super;
typedef SuccIterator<Term_, BB_> Self;
inline bool index_is_valid(int idx) {
@@ -112,6 +115,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
public:
typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
// TODO: This can be random access iterator, only operator[] missing.
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
@@ -142,7 +146,7 @@ public:
inline bool operator==(const Self& x) const { return idx == x.idx; }
inline bool operator!=(const Self& x) const { return !operator==(x); }
- inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline reference operator*() const { return Term->getSuccessor(idx); }
inline pointer operator->() const { return operator*(); }
inline Self& operator++() { ++idx; return *this; } // Preincrement
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 02c44cdfad..823b43ad93 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -321,7 +321,8 @@ namespace COFF {
IMAGE_COMDAT_SELECT_SAME_SIZE,
IMAGE_COMDAT_SELECT_EXACT_MATCH,
IMAGE_COMDAT_SELECT_ASSOCIATIVE,
- IMAGE_COMDAT_SELECT_LARGEST
+ IMAGE_COMDAT_SELECT_LARGEST,
+ IMAGE_COMDAT_SELECT_NEWEST
};
// Auxiliary Symbol Formats
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 3ce0fef4a0..92107ac025 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -28,7 +28,6 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Instructions.h"
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 80f09db4f7..0d2d6c92fd 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -36,9 +36,13 @@ template<typename From> struct simplify_type {
};
template<typename From> struct simplify_type<const From> {
- typedef const From SimpleType;
- static SimpleType &getSimplifiedValue(const From &Val) {
- return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
+ typedef typename add_const_past_pointer<NonConstSimpleType>::type
+ SimpleType;
+ typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
+ RetType;
+ static RetType getSimplifiedValue(const From& Val) {
+ return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
}
};
@@ -81,6 +85,13 @@ template <typename To, typename From> struct isa_impl_cl<To, From*> {
}
};
+template <typename To, typename From> struct isa_impl_cl<To, From*const> {
+ static inline bool doit(const From *Val) {
+ assert(Val && "isa<> used on a null pointer");
+ return isa_impl<To, From>::doit(*Val);
+ }
+};
+
template <typename To, typename From> struct isa_impl_cl<To, const From*> {
static inline bool doit(const From *Val) {
assert(Val && "isa<> used on a null pointer");
@@ -102,7 +113,7 @@ struct isa_impl_wrap {
static bool doit(const From &Val) {
return isa_impl_wrap<To, SimpleFrom,
typename simplify_type<SimpleFrom>::SimpleType>::doit(
- simplify_type<From>::getSimplifiedValue(Val));
+ simplify_type<const From>::getSimplifiedValue(Val));
}
};
@@ -121,7 +132,8 @@ struct isa_impl_wrap<To, FromTy, FromTy> {
//
template <class X, class Y>
inline bool isa(const Y &Val) {
- return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
+ return isa_impl_wrap<X, const Y,
+ typename simplify_type<const Y>::SimpleType>::doit(Val);
}
//===----------------------------------------------------------------------===//
@@ -178,7 +190,7 @@ struct cast_retty {
//
template<class To, class From, class SimpleFrom> struct cast_convert_val {
// This is not a simple type, use the template to simplify it...
- static typename cast_retty<To, From>::ret_type doit(const From &Val) {
+ static typename cast_retty<To, From>::ret_type doit(From &Val) {
return cast_convert_val<To, SimpleFrom,
typename simplify_type<SimpleFrom>::SimpleType>::doit(
simplify_type<From>::getSimplifiedValue(Val));
@@ -204,20 +216,14 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename enable_if_c<
- !is_same<Y, typename simplify_type<Y>::SimpleType>::value,
- typename cast_retty<X, Y>::ret_type
->::type cast(const Y &Val) {
+inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
- return cast_convert_val<X, Y,
- typename simplify_type<Y>::SimpleType>::doit(Val);
+ return cast_convert_val<X, const Y,
+ typename simplify_type<const Y>::SimpleType>::doit(Val);
}
template <class X, class Y>
-inline typename enable_if<
- is_same<Y, typename simplify_type<Y>::SimpleType>,
- typename cast_retty<X, Y>::ret_type
->::type cast(Y &Val) {
+inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<X, Y,
typename simplify_type<Y>::SimpleType>::doit(Val);
@@ -253,18 +259,12 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename enable_if_c<
- !is_same<Y, typename simplify_type<Y>::SimpleType>::value,
- typename cast_retty<X, Y>::ret_type
->::type dyn_cast(const Y &Val) {
+inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
template <class X, class Y>
-inline typename enable_if<
- is_same<Y, typename simplify_type<Y>::SimpleType>,
- typename cast_retty<X, Y>::ret_type
->::type dyn_cast(Y &Val) {
+inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h
index 1b66c94389..240eba6c8a 100644
--- a/include/llvm/Support/CodeGen.h
+++ b/include/llvm/Support/CodeGen.h
@@ -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
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 25f42a98e7..13d057be04 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -351,4 +351,14 @@
#define LLVM_EXPLICIT
#endif
+/// \macro LLVM_STATIC_ASSERT
+/// \brief Expands to C/C++'s static_assert on compilers which support it.
+#if __has_feature(cxx_static_assert)
+# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
+#elif __has_feature(c_static_assert)
+# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
+#else
+# define LLVM_STATIC_ASSERT(expr, msg)
+#endif
+
#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
new file mode 100644
index 0000000000..9b1142d035
--- /dev/null
+++ b/include/llvm/Support/Compression.h
@@ -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
+
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index cc9151ef50..232aadc3e0 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -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,
@@ -480,10 +481,13 @@ enum {
R_PPC64_TOC16_LO = 48,
R_PPC64_TOC16_HA = 50,
R_PPC64_TOC = 51,
+ R_PPC64_ADDR16_DS = 56,
+ R_PPC64_ADDR16_LO_DS = 57,
R_PPC64_TOC16_DS = 63,
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,
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index d438facfa4..0d35849883 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -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;
}
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index ca5dec0173..b948d97bff 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -24,7 +24,8 @@ namespace llvm {
/// An error handler callback.
typedef void (*fatal_error_handler_t)(void *user_data,
- const std::string& reason);
+ const std::string& reason,
+ bool gen_crash_diag);
/// install_fatal_error_handler - Installs a new error handler to be used
/// whenever a serious (non-recoverable) error is encountered by LLVM.
@@ -73,10 +74,14 @@ namespace llvm {
/// standard error, followed by a newline.
/// After the error handler is called this function will call exit(1), it
/// does not return.
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason,
+ bool gen_crash_diag = true);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason,
+ bool gen_crash_diag = true);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason,
+ bool gen_crash_diag = true);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason,
+ bool gen_crash_diag = true);
/// This function calls abort(), and prints the optional message to stderr.
/// Use the llvm_unreachable macro (that adds location info), instead of
diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h
index d9cf7247a3..8560ee0a8a 100644
--- a/include/llvm/Support/FEnv.h
+++ b/include/llvm/Support/FEnv.h
@@ -32,7 +32,7 @@ namespace sys {
/// llvm_fenv_clearexcept - Clear the floating-point exception state.
static inline void llvm_fenv_clearexcept() {
-#ifdef HAVE_FENV_H
+#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;
@@ -43,7 +43,7 @@ static inline bool llvm_fenv_testexcept() {
int errno_val = errno;
if (errno_val == ERANGE || errno_val == EDOM)
return true;
-#ifdef HAVE_FENV_H
+#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
return true;
#endif
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 21635dcfb6..2e4bd5aeca 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -17,125 +17,125 @@
#include "llvm/Support/raw_ostream.h"
-namespace llvm
-{
- /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
- /// asm-specific constructs.
+namespace llvm {
+
+/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
+/// of column position, allowing padding out to specific column boundaries.
+///
+class formatted_raw_ostream : public raw_ostream {
+public:
+ /// DELETE_STREAM - Tell the destructor to delete the held stream.
///
- class formatted_raw_ostream : public raw_ostream {
- public:
- /// DELETE_STREAM - Tell the destructor to delete the held stream.
- ///
- static const bool DELETE_STREAM = true;
-
- /// PRESERVE_STREAM - Tell the destructor to not delete the held
- /// stream.
- ///
- static const bool PRESERVE_STREAM = false;
-
- private:
- /// TheStream - The real stream we output to. We set it to be
- /// unbuffered, since we're already doing our own buffering.
- ///
- raw_ostream *TheStream;
-
- /// DeleteStream - Do we need to delete TheStream in the
- /// destructor?
- ///
- bool DeleteStream;
-
- /// ColumnScanned - The current output column of the data that's
- /// been flushed and the portion of the buffer that's been
- /// scanned. The column scheme is zero-based.
- ///
- unsigned ColumnScanned;
-
- /// Scanned - This points to one past the last character in the
- /// buffer we've scanned.
- ///
- const char *Scanned;
-
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
-
- /// current_pos - Return the current position within the stream,
- /// not counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE {
- // Our current position in the stream is all the contents which have been
- // written to the underlying stream (*not* the current position of the
- // underlying stream).
- return TheStream->tell();
- }
-
- /// ComputeColumn - Examine the given output buffer and figure out which
- /// column we end up in after output.
- ///
- void ComputeColumn(const char *Ptr, size_t size);
-
- public:
- /// formatted_raw_ostream - Open the specified file for
- /// writing. If an error occurs, information about the error is
- /// put into ErrorInfo, and the stream should be immediately
- /// destroyed; the string will be empty if no error occurred.
- ///
- /// As a side effect, the given Stream is set to be Unbuffered.
- /// This is because formatted_raw_ostream does its own buffering,
- /// so it doesn't want another layer of buffering to be happening
- /// underneath it.
- ///
- formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
- : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
- setStream(Stream, Delete);
- }
- explicit formatted_raw_ostream()
- : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
- Scanned = 0;
- }
-
- ~formatted_raw_ostream() {
- flush();
- releaseStream();
- }
-
- void setStream(raw_ostream &Stream, bool Delete = false) {
- releaseStream();
-
- TheStream = &Stream;
- DeleteStream = Delete;
-
- // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
- // own buffering, and it doesn't need or want TheStream to do another
- // layer of buffering underneath. Resize the buffer to what TheStream
- // had been using, and tell TheStream not to do its own buffering.
- if (size_t BufferSize = TheStream->GetBufferSize())
- SetBufferSize(BufferSize);
- else
- SetUnbuffered();
- TheStream->SetUnbuffered();
+ static const bool DELETE_STREAM = true;
+
+ /// PRESERVE_STREAM - Tell the destructor to not delete the held
+ /// stream.
+ ///
+ static const bool PRESERVE_STREAM = false;
+
+private:
+ /// TheStream - The real stream we output to. We set it to be
+ /// unbuffered, since we're already doing our own buffering.
+ ///
+ raw_ostream *TheStream;
- Scanned = 0;
- }
-
- /// PadToColumn - Align the output to some column number. If the current
- /// column is already equal to or more than NewCol, PadToColumn inserts one
- /// space.
- ///
- /// \param NewCol - The column to move to.
- formatted_raw_ostream &PadToColumn(unsigned NewCol);
-
- private:
- void releaseStream() {
- // Delete the stream if needed. Otherwise, transfer the buffer
- // settings from this raw_ostream back to the underlying stream.
- if (!TheStream)
- return;
- if (DeleteStream)
- delete TheStream;
- else if (size_t BufferSize = GetBufferSize())
- TheStream->SetBufferSize(BufferSize);
- else
- TheStream->SetUnbuffered();
- }
- };
+ /// DeleteStream - Do we need to delete TheStream in the
+ /// destructor?
+ ///
+ bool DeleteStream;
+
+ /// ColumnScanned - The current output column of the data that's
+ /// been flushed and the portion of the buffer that's been
+ /// scanned. The column scheme is zero-based.
+ ///
+ unsigned ColumnScanned;
+
+ /// Scanned - This points to one past the last character in the
+ /// buffer we've scanned.
+ ///
+ const char *Scanned;
+
+ virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+
+ /// current_pos - Return the current position within the stream,
+ /// not counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() const LLVM_OVERRIDE {
+ // Our current position in the stream is all the contents which have been
+ // written to the underlying stream (*not* the current position of the
+ // underlying stream).
+ return TheStream->tell();
+ }
+
+ /// ComputeColumn - Examine the given output buffer and figure out which
+ /// column we end up in after output.
+ ///
+ void ComputeColumn(const char *Ptr, size_t size);
+
+public:
+ /// formatted_raw_ostream - Open the specified file for
+ /// writing. If an error occurs, information about the error is
+ /// put into ErrorInfo, and the stream should be immediately
+ /// destroyed; the string will be empty if no error occurred.
+ ///
+ /// As a side effect, the given Stream is set to be Unbuffered.
+ /// This is because formatted_raw_ostream does its own buffering,
+ /// so it doesn't want another layer of buffering to be happening
+ /// underneath it.
+ ///
+ formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ setStream(Stream, Delete);
+ }
+ explicit formatted_raw_ostream()
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ Scanned = 0;
+ }
+
+ ~formatted_raw_ostream() {
+ flush();
+ releaseStream();
+ }
+
+ void setStream(raw_ostream &Stream, bool Delete = false) {
+ releaseStream();
+
+ TheStream = &Stream;
+ DeleteStream = Delete;
+
+ // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+ // own buffering, and it doesn't need or want TheStream to do another
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = 0;
+ }
+
+ /// PadToColumn - Align the output to some column number. If the current
+ /// column is already equal to or more than NewCol, PadToColumn inserts one
+ /// space.
+ ///
+ /// \param NewCol - The column to move to.
+ formatted_raw_ostream &PadToColumn(unsigned NewCol);
+
+private:
+ void releaseStream() {
+ // Delete the stream if needed. Otherwise, transfer the buffer
+ // settings from this raw_ostream back to the underlying stream.
+ if (!TheStream)
+ return;
+ if (DeleteStream)
+ delete TheStream;
+ else if (size_t BufferSize = GetBufferSize())
+ TheStream->SetBufferSize(BufferSize);
+ else
+ TheStream->SetUnbuffered();
+ }
+};
/// fouts() - This returns a reference to a formatted_raw_ostream for
/// standard output. Use it like: fouts() << "foo" << "bar";
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index 3a44405739..9a4036a8af 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -15,23 +15,27 @@
#define LLVM_SUPPORT_HOST_H
#include "llvm/ADT/StringMap.h"
+
+#if defined(__linux__)
+#include <endian.h>
+#else
+#ifndef LLVM_ON_WIN32
+#include <machine/endian.h>
+#endif
+#endif
+
#include <string>
namespace llvm {
namespace sys {
- inline bool isLittleEndianHost() {
- union {
- int i;
- char c;
- };
- i = 1;
- return c;
- }
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+ static const bool IsBigEndianHost = true;
+#else
+ static const bool IsBigEndianHost = false;
+#endif
- inline bool isBigEndianHost() {
- return !isLittleEndianHost();
- }
+ static const bool IsLittleEndianHost = !IsBigEndianHost;
/// getDefaultTargetTriple() - Return the default target triple the compiler
/// has been configured to produce code for.
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
deleted file mode 100644
index 6d8a9b30ae..0000000000
--- a/include/llvm/Support/IRReader.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines functions for reading LLVM IR. They support both
-// Bitcode and Assembly, automatically detecting the input format.
-//
-// These functions must be defined in a header file in order to avoid
-// library dependencies, since they reference both Bitcode and Assembly
-// functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_IRREADER_H
-#define LLVM_SUPPORT_IRREADER_H
-
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Assembly/Parser.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/system_error.h"
-
-namespace llvm {
-
- /// If the given MemoryBuffer holds a bitcode image, return a Module for it
- /// which does lazy deserialization of function bodies. Otherwise, attempt to
- /// parse it as LLVM Assembly and return a fully populated Module. This
- /// function *always* takes ownership of the given MemoryBuffer.
- inline Module *getLazyIRModule(MemoryBuffer *Buffer,
- SMDiagnostic &Err,
- LLVMContext &Context) {
- if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
- (const unsigned char *)Buffer->getBufferEnd())) {
- std::string ErrMsg;
- Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
- if (M == 0) {
- Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
- ErrMsg);
- // ParseBitcodeFile does not take ownership of the Buffer in the
- // case of an error.
- delete Buffer;
- }
- return M;
- }
-
- return ParseAssembly(Buffer, 0, Err, Context);
- }
-
- /// If the given file holds a bitcode image, return a Module
- /// for it which does lazy deserialization of function bodies. Otherwise,
- /// attempt to parse it as LLVM Assembly and return a fully populated
- /// Module.
- inline Module *getLazyIRFileModule(const std::string &Filename,
- SMDiagnostic &Err,
- LLVMContext &Context) {
- OwningPtr<MemoryBuffer> File;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
- Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
- "Could not open input file: " + ec.message());
- return 0;
- }
-
- return getLazyIRModule(File.take(), Err, Context);
- }
-
- /// If the given MemoryBuffer holds a bitcode image, return a Module
- /// for it. Otherwise, attempt to parse it as LLVM Assembly and return
- /// a Module for it. This function *always* takes ownership of the given
- /// MemoryBuffer.
- inline Module *ParseIR(MemoryBuffer *Buffer,
- SMDiagnostic &Err,
- LLVMContext &Context) {
- if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
- (const unsigned char *)Buffer->getBufferEnd())) {
- std::string ErrMsg;
- Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
- if (M == 0)
- Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
- ErrMsg);
- // ParseBitcodeFile does not take ownership of the Buffer.
- delete Buffer;
- return M;
- }
-
- return ParseAssembly(Buffer, 0, Err, Context);
- }
-
- /// If the given file holds a bitcode image, return a Module for it.
- /// Otherwise, attempt to parse it as LLVM Assembly and return a Module
- /// for it.
- inline Module *ParseIRFile(const std::string &Filename,
- SMDiagnostic &Err,
- LLVMContext &Context) {
- OwningPtr<MemoryBuffer> File;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
- Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
- "Could not open input file: " + ec.message());
- return 0;
- }
-
- return ParseIR(File.take(), Err, Context);
- }
-
-}
-
-#endif
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 1f02907d9f..0cce726d48 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -15,8 +15,10 @@
#define LLVM_SUPPORT_MEMORYBUFFER_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm-c/Core.h"
namespace llvm {
@@ -137,6 +139,9 @@ public:
virtual BufferKind getBufferKind() const = 0;
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef)
+
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index a0cc27c024..fb177de97b 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_PROGRAM_H
#define LLVM_SUPPORT_PROGRAM_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Path.h"
namespace llvm {
@@ -125,7 +126,8 @@ namespace sys {
const sys::Path** redirects = 0,
unsigned secondsToWait = 0,
unsigned memoryLimit = 0,
- std::string* ErrMsg = 0);
+ std::string* ErrMsg = 0,
+ bool *ExecutionFailed = 0);
/// A convenience function equivalent to Program prg; prg.Execute(..);
/// @see Execute
@@ -139,6 +141,10 @@ namespace sys {
/// @}
};
+
+ // Return true if the given arguments fit within system-specific
+ // argument length limits.
+ bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args);
}
}
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index db44995d95..b49341c3ff 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -20,6 +20,7 @@
namespace llvm {
class ValueHandleBase;
+template<typename From> struct simplify_type;
// ValueHandleBase** is only 4-byte aligned.
template<>
@@ -162,14 +163,12 @@ public:
// Specialize simplify_type to allow WeakVH to participate in
// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const WeakVH> {
+template<> struct simplify_type<WeakVH> {
typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const WeakVH &WVH) {
- return static_cast<Value *>(WVH);
+ static SimpleType getSimplifiedValue(WeakVH &WVH) {
+ return WVH;
}
};
-template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {};
/// AssertingVH - This is a Value Handle that points to a value and asserts out
/// if the value is destroyed while the handle is still live. This is very
@@ -236,18 +235,6 @@ public:
ValueTy &operator*() const { return *getValPtr(); }
};
-// Specialize simplify_type to allow AssertingVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const AssertingVH<Value> > {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) {
- return static_cast<Value *>(AVH);
- }
-};
-template<> struct simplify_type<AssertingVH<Value> >
- : public simplify_type<const AssertingVH<Value> > {};
-
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
template<typename T>
struct DenseMapInfo<AssertingVH<T> > {
@@ -345,18 +332,6 @@ public:
ValueTy &operator*() const { return *getValPtr(); }
};
-// Specialize simplify_type to allow TrackingVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const TrackingVH<Value> > {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) {
- return static_cast<Value *>(AVH);
- }
-};
-template<> struct simplify_type<TrackingVH<Value> >
- : public simplify_type<const TrackingVH<Value> > {};
-
/// CallbackVH - This is a value handle that allows subclasses to define
/// callbacks that run when the underlying Value has RAUW called on it or is
/// destroyed. This class can be used as the key of a map, as long as the user
@@ -399,18 +374,6 @@ public:
virtual void allUsesReplacedWith(Value *);
};
-// Specialize simplify_type to allow CallbackVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const CallbackVH> {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const CallbackVH &CVH) {
- return static_cast<Value *>(CVH);
- }
-};
-template<> struct simplify_type<CallbackVH>
- : public simplify_type<const CallbackVH> {};
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/Watchdog.h b/include/llvm/Support/Watchdog.h
new file mode 100644
index 0000000000..b58496b2fb
--- /dev/null
+++ b/include/llvm/Support/Watchdog.h
@@ -0,0 +1,38 @@
+//===--- Watchdog.h - Watchdog timer ----------------------------*- 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 llvm::sys::Watchdog class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WATCHDOG_H
+#define LLVM_SUPPORT_WATCHDOG_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+ namespace sys {
+
+ /// This class provides an abstraction for a timeout around an operation
+ /// that must complete in a given amount of time. Failure to complete before
+ /// the timeout is an unrecoverable situation and no mechanisms to attempt
+ /// to handle it are provided.
+ class Watchdog {
+ public:
+ Watchdog(unsigned int seconds);
+ ~Watchdog();
+ private:
+ // Noncopyable.
+ Watchdog(const Watchdog &other) LLVM_DELETED_FUNCTION;
+ Watchdog &operator=(const Watchdog &other) LLVM_DELETED_FUNCTION;
+ };
+ }
+}
+
+#endif
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
index 164aca16bf..ecce713680 100644
--- a/include/llvm/Support/Win64EH.h
+++ b/include/llvm/Support/Win64EH.h
@@ -106,12 +106,17 @@ struct UnwindInfo {
return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
}
- /// \brief Return image-relativ offset of language-specific exception handler.
- uint32_t getLanguageSpecificHandlerOffset() {
- return *reinterpret_cast<uint32_t *>(getLanguageSpecificData());
+ /// \brief Return pointer to language specific data part of UnwindInfo.
+ const void *getLanguageSpecificData() const {
+ return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]);
+ }
+
+ /// \brief Return image-relative offset of language-specific exception handler.
+ uint32_t getLanguageSpecificHandlerOffset() const {
+ return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData());
}
- /// \brief Set image-relativ offset of language-specific exception handler.
+ /// \brief Set image-relative offset of language-specific exception handler.
void setLanguageSpecificHandlerOffset(uint32_t offset) {
*reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
}
@@ -126,6 +131,11 @@ struct UnwindInfo {
RuntimeFunction *getChainedFunctionEntry() {
return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
}
+
+ /// \brief Return pointer to chained unwind info.
+ const RuntimeFunction *getChainedFunctionEntry() const {
+ return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
+ }
};
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index db43ccfece..906e97c91f 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -209,6 +209,26 @@ template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
template <typename T> struct remove_pointer<T*const volatile> {
typedef T type; };
+// If T is a pointer, just return it. If it is not, return T&.
+template<typename T, typename Enable = void>
+struct add_lvalue_reference_if_not_pointer { typedef T &type; };
+
+template<typename T>
+struct add_lvalue_reference_if_not_pointer<T,
+ typename enable_if<is_pointer<T> >::type> {
+ typedef T type;
+};
+
+// If T is a pointer to X, return a pointer to const X. If it is not, return
+// const T.
+template<typename T, typename Enable = void>
+struct add_const_past_pointer { typedef const T type; };
+
+template<typename T>
+struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> {
+ typedef const typename remove_pointer<T>::type *type;
+};
+
template <bool, typename T, typename F>
struct conditional { typedef T type; };
diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h
index 2f6b7e625c..2d0a2b45a9 100644
--- a/include/llvm/TableGen/Error.h
+++ b/include/llvm/TableGen/Error.h
@@ -32,6 +32,7 @@ LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc,
const std::string &Msg);
extern SourceMgr SrcMgr;
+extern unsigned ErrorsPrinted;
} // end namespace "llvm"
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index deee2eb6de..7de8b384c3 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -790,8 +790,8 @@ class AsmParser {
// This can be used to perform target specific instruction post-processing.
string AsmParserInstCleanup = "";
- //ShouldEmitMatchRegisterName - Set to false if the target needs a hand
- //written register name matcher
+ // ShouldEmitMatchRegisterName - Set to false if the target needs a hand
+ // written register name matcher
bit ShouldEmitMatchRegisterName = 1;
}
def DefaultAsmParser : AsmParser;
@@ -807,6 +807,9 @@ class AsmParserVariant {
// assembly language.
int Variant = 0;
+ // Name - The AsmParser variant name (e.g., AT&T vs Intel).
+ string Name = "";
+
// CommentDelimiter - If given, the delimiter string used to recognize
// comments which are hard coded in the .td assembler strings for individual
// instructions.
@@ -860,9 +863,16 @@ class TokenAlias<string From, string To> {
/// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
/// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
///
-class MnemonicAlias<string From, string To> {
+/// Mnemonic aliases can also be constrained to specific variants, e.g.:
+///
+/// def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
+///
+/// If no variant (e.g., "att" or "intel") is specified then the alias is
+/// applied unconditionally.
+class MnemonicAlias<string From, string To, string VariantName = ""> {
string FromMnemonic = From;
string ToMnemonic = To;
+ string AsmVariantName = VariantName;
// Predicates - Predicates that must be true for this remapping to happen.
list<Predicate> Predicates = [];
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 2160e371bd..1fd0bd98b6 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -36,13 +36,15 @@ namespace ISD {
static const uint64_t ByValOffs = 4;
static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
static const uint64_t NestOffs = 5;
- static const uint64_t ByValAlign = 0xFULL << 6; ///< Struct alignment
- static const uint64_t ByValAlignOffs = 6;
- static const uint64_t Split = 1ULL << 10;
- static const uint64_t SplitOffs = 10;
+ static const uint64_t Returned = 1ULL<<6; ///< Always returned
+ static const uint64_t ReturnedOffs = 6;
+ static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment
+ static const uint64_t ByValAlignOffs = 7;
+ static const uint64_t Split = 1ULL<<11;
+ static const uint64_t SplitOffs = 11;
static const uint64_t OrigAlign = 0x1FULL<<27;
static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0xffffffffULL << 32; ///< Struct size
+ static const uint64_t ByValSize = 0xffffffffULL<<32; ///< Struct size
static const uint64_t ByValSizeOffs = 32;
static const uint64_t One = 1ULL; ///< 1 of this type, for shifts
@@ -51,23 +53,26 @@ namespace ISD {
public:
ArgFlagsTy() : Flags(0) { }
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
+ bool isZExt() const { return Flags & ZExt; }
+ void setZExt() { Flags |= One << ZExtOffs; }
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
+ bool isSExt() const { return Flags & SExt; }
+ void setSExt() { Flags |= One << SExtOffs; }
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
+ bool isInReg() const { return Flags & InReg; }
+ void setInReg() { Flags |= One << InRegOffs; }
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
+ bool isSRet() const { return Flags & SRet; }
+ void setSRet() { Flags |= One << SRetOffs; }
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
+ bool isByVal() const { return Flags & ByVal; }
+ void setByVal() { Flags |= One << ByValOffs; }
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
+ bool isNest() const { return Flags & Nest; }
+ void setNest() { Flags |= One << NestOffs; }
+
+ bool isReturned() const { return Flags & Returned; }
+ void setReturned() { Flags |= One << ReturnedOffs; }
unsigned getByValAlign() const {
return (unsigned)
@@ -97,9 +102,6 @@ namespace ISD {
Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
}
- /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
- std::string getArgFlagsString();
-
/// getRawBits - Represent the flags as a bunch of bits.
uint64_t getRawBits() const { return Flags; }
};
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index fb311d8508..d49ce1ce7f 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -364,11 +364,10 @@ public:
/// condition code in Cond.
///
/// When successful, also return the latency in cycles from TrueReg,
- /// FalseReg, and Cond to the destination register. The Cond latency should
- /// compensate for a conditional branch being removed. For example, if a
- /// conditional branch has a 3 cycle latency from the condition code read,
- /// and a cmov instruction has a 2 cycle latency from the condition code
- /// read, CondCycles should be returned as -1.
+ /// FalseReg, and Cond to the destination register. In most cases, a select
+ /// instruction will be 1 cycle, so CondCycles = TrueCycles = FalseCycles = 1
+ ///
+ /// Some x86 implementations have 2-cycle cmov instructions.
///
/// @param MBB Block where select instruction would be inserted.
/// @param Cond Condition returned by AnalyzeBranch.
@@ -775,6 +774,10 @@ public:
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
/// instruction, try to fold the immediate into the use instruction.
+ /// If MRI->hasOneNonDBGUse(Reg) is true, and this function returns true,
+ /// then the caller may assume that DefMI has been erased from its parent
+ /// block. The caller may assume that it will not be erased by this
+ /// function otherwise.
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
unsigned Reg, MachineRegisterInfo *MRI) const {
return false;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 5d74848b71..d5c9ebe0f2 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -135,6 +135,11 @@ public:
const TargetLoweringObjectFile *TLOF);
virtual ~TargetLoweringBase();
+protected:
+ /// \brief Initialize all of the actions to default values.
+ void initActions();
+
+public:
const TargetMachine &getTargetMachine() const { return TM; }
const DataLayout *getDataLayout() const { return TD; }
const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
@@ -694,13 +699,6 @@ public:
return false;
}
- /// This function returns true if the target would benefit from code placement
- /// optimization.
- /// @brief Determine if the target should perform code placement optimization.
- bool shouldOptimizeCodePlacement() const {
- return BenefitFromCodePlacementOpt;
- }
-
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
@@ -812,13 +810,6 @@ public:
return PrefLoopAlignment;
}
- /// getShouldFoldAtomicFences - return whether the combiner should fold
- /// fence MEMBARRIER instructions into the atomic intrinsic instructions.
- ///
- bool getShouldFoldAtomicFences() const {
- return ShouldFoldAtomicFences;
- }
-
/// getInsertFencesFor - return whether the DAG builder should automatically
/// insert fences and reduce ordering for atomics.
///
@@ -858,6 +849,9 @@ public:
// the derived class constructor to configure this object for the target.
//
+ /// \brief Reset the operation actions based on target options.
+ virtual void resetOperationActions() {}
+
protected:
/// setBooleanContents - Specify how the target extends the result of a
/// boolean value from i1 to a wider type. See getBooleanContents.
@@ -958,13 +952,17 @@ protected:
RegClassForVT[VT.SimpleTy] = RC;
}
- /// clearRegisterClasses - remove all register classes
+ /// clearRegisterClasses - Remove all register classes.
void clearRegisterClasses() {
- for (unsigned i = 0 ; i<array_lengthof(RegClassForVT); i++)
- RegClassForVT[i] = 0;
+ memset(RegClassForVT, 0,MVT::LAST_VALUETYPE * sizeof(TargetRegisterClass*));
+
AvailableRegClasses.clear();
}
+ /// \brief Remove all operation actions.
+ void clearOperationActions() {
+ }
+
/// findRepresentativeClass - Return the largest legal super-reg register class
/// of the register class for the specified type and its associated "cost".
virtual std::pair<const TargetRegisterClass*, uint8_t>
@@ -1096,12 +1094,6 @@ protected:
MinStackArgumentAlignment = Align;
}
- /// setShouldFoldAtomicFences - Set if the target's implementation of the
- /// atomic operation intrinsics includes locking. Default is false.
- void setShouldFoldAtomicFences(bool fold) {
- ShouldFoldAtomicFences = fold;
- }
-
/// setInsertFencesForAtomic - Set if the DAG builder should
/// automatically insert fences and reduce the order of atomic memory
/// operations to Monotonic.
@@ -1359,11 +1351,6 @@ private:
///
unsigned PrefLoopAlignment;
- /// ShouldFoldAtomicFences - Whether fencing MEMBARRIER instructions should
- /// be folded into the enclosed atomic intrinsic instruction by the
- /// combiner.
- bool ShouldFoldAtomicFences;
-
/// InsertFencesForAtomic - Whether the DAG builder should automatically
/// insert fences and reduce ordering for atomics. (This will be set for
/// for most architectures with weak memory ordering.)
@@ -1518,6 +1505,7 @@ public:
// or until the element integer type is too big. If a legal type was not
// found, fallback to the usual mechanism of widening/splitting the
// vector.
+ EVT OldEltVT = EltVT;
while (1) {
// Increase the bitwidth of the element to the next pow-of-two
// (which is greater than 8 bits).
@@ -1536,6 +1524,10 @@ public:
return LegalizeKind(TypePromoteInteger,
EVT::getVectorVT(Context, EltVT, NumElts));
}
+
+ // Reset the type to the unexpanded type if we did not find a legal vector
+ // type with a promoted vector element type.
+ EltVT = OldEltVT;
}
// Try to widen the vector until a legal type is found.
@@ -1644,10 +1636,6 @@ protected:
/// to memmove, used for functions with OpSize attribute.
unsigned MaxStoresPerMemmoveOptSize;
- /// This field specifies whether the target can benefit from code placement
- /// optimization.
- bool BenefitFromCodePlacementOpt;
-
/// PredictableSelectIsExpensive - Tells the code generator that select is
/// more expensive than a branch if the branch is usually predicted right.
bool PredictableSelectIsExpensive;
@@ -1904,16 +1892,18 @@ public:
struct ArgListEntry {
SDValue Node;
Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- bool isByVal : 1;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
+ bool isReturned : 1;
uint16_t Alignment;
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
+ isSRet(false), isNest(false), isByVal(false), isReturned(false),
+ Alignment(0) { }
};
typedef std::vector<ArgListEntry> ArgListTy;
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 66f3a3c71b..37a79fe852 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -32,6 +32,7 @@ class MCContext;
class PassManagerBase;
class Target;
class DataLayout;
+class TargetLibraryInfo;
class TargetFrameLowering;
class TargetInstrInfo;
class TargetIntrinsicInfo;
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index c31db24490..c763a595dd 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -208,6 +208,7 @@ namespace llvm {
/// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+ bool operator==(const TargetOptions &);
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 83bd7874df..d89a6e658e 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -414,9 +414,6 @@ def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf,
[SDNPHasChain, SDNPSideEffect]>;
-def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier,
- [SDNPHasChain, SDNPSideEffect]>;
-
def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence,
[SDNPHasChain, SDNPSideEffect]>;
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 209f68db6f..563721e128 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -103,7 +103,8 @@ public:
bool DisableSimplifyLibCalls;
bool DisableUnitAtATime;
bool DisableUnrollLoops;
- bool Vectorize;
+ bool BBVectorize;
+ bool SLPVectorize;
bool LoopVectorize;
private:
diff --git a/include/llvm/Transforms/Utils/BlackList.h b/include/llvm/Transforms/Utils/BlackList.h
index f19470e19d..316b364845 100644
--- a/include/llvm/Transforms/Utils/BlackList.h
+++ b/include/llvm/Transforms/Utils/BlackList.h
@@ -20,6 +20,7 @@
// global-init:*global_with_initialization_issues*
// global-init-type:*Namespace::ClassName*
// src:file_with_tricky_code.cc
+// global-init-src:ignore-global-initializers-issues.cc
// ---
// Note that the wild card is in fact an llvm::Regex, but * is automatically
// replaced with .*
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 687c9d517b..267825079e 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -234,12 +234,12 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
/// Dbg Intrinsic utilities
///
-/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
+/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
/// that has an associated llvm.dbg.decl intrinsic.
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
StoreInst *SI, DIBuilder &Builder);
-/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
+/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
/// that has an associated llvm.dbg.decl intrinsic.
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
LoadInst *LI, DIBuilder &Builder);
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index d205dbdede..8d0db16116 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -117,6 +117,12 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
Pass *createLoopVectorizePass();
//===----------------------------------------------------------------------===//
+//
+// SLPVectorizer - Create a bottom-up SLP vectorizer pass.
+//
+Pass *createSLPVectorizerPass();
+
+//===----------------------------------------------------------------------===//
/// @brief Vectorize the BasicBlock.
///
/// @param BB The BasicBlock to be vectorized