diff options
author | Shih-wei Liao <sliao@google.com> | 2012-04-24 11:26:46 -0700 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2012-04-24 11:26:46 -0700 |
commit | cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d (patch) | |
tree | 557137810ae9efc96147d672d372e4dabd0a2440 /include | |
parent | 4c8fab82874a29dcd2b242533af3ebe7f66bfd74 (diff) | |
parent | fc728fbdc2631ce8f343cf9b7292d218fde7419f (diff) | |
download | external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.zip external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.gz external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.bz2 |
Merge with LLVM upstream r155090.
Conflicts:
lib/Support/Unix/PathV2.inc
Change-Id: I7b89833849f6cbcfa958a33a971d0f7754c9cb2c
Diffstat (limited to 'include')
116 files changed, 2151 insertions, 1285 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 52b8b1c..7774606 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -2398,6 +2398,8 @@ LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str, const char *Name); LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str, const char *Name); +LLVMBool LLVMGetVolatile(LLVMValueRef MemoryAccessInst); +void LLVMSetVolatile(LLVMValueRef MemoryAccessInst, LLVMBool IsVolatile); /* Casts */ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val, diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index 258a2be..568e60d 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -58,16 +58,19 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef; #define LLVM_ASM_PRINTER(TargetName) \ void LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" +#undef LLVM_ASM_PRINTER /* Explicit undef to make SWIG happier */ /* Declare all of the available assembly parser initialization functions. */ #define LLVM_ASM_PARSER(TargetName) \ void LLVMInitialize##TargetName##AsmParser(); #include "llvm/Config/AsmParsers.def" +#undef LLVM_ASM_PARSER /* Explicit undef to make SWIG happier */ /* Declare all of the available disassembler initialization functions. */ #define LLVM_DISASSEMBLER(TargetName) \ void LLVMInitialize##TargetName##Disassembler(); #include "llvm/Config/Disassemblers.def" +#undef LLVM_DISASSEMBLER /* Explicit undef to make SWIG happier */ /** LLVMInitializeAllTargetInfos - The main program should call this function if it wants access to all available targets that LLVM is configured to diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h new file mode 100644 index 0000000..0d35d73 --- /dev/null +++ b/include/llvm-c/TargetMachine.h @@ -0,0 +1,142 @@ +/*===-- llvm-c/TargetMachine.h - Target Machine Library C Interface - C++ -*-=*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header declares the C interface to the Target and TargetMachine *| +|* classes, which can be used to generate assembly or object files. *| +|* *| +|* Many exotic languages can interoperate with C code but have a harder time *| +|* with C++ due to name mangling. So in addition to C, this interface enables *| +|* tools written in such languages. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_TARGETMACHINE_H +#define LLVM_C_TARGETMACHINE_H + +#include "llvm-c/Core.h" + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct LLVMTargetMachine *LLVMTargetMachineRef; +typedef struct LLVMTarget *LLVMTargetRef; + +typedef enum { + LLVMCodeGenLevelNone, + LLVMCodeGenLevelLess, + LLVMCodeGenLevelDefault, + LLVMCodeGenLevelAggressive +} LLVMCodeGenOptLevel; + +typedef enum { + LLVMRelocDefault, + LLVMRelocStatic, + LLVMRelocPIC, + LLVMRelocDynamicNoPic +} LLVMRelocMode; + +typedef enum { + LLVMCodeModelDefault, + LLVMCodeModelJITDefault, + LLVMCodeModelSmall, + LLVMCodeModelKernel, + LLVMCodeModelMedium, + LLVMCodeModelLarge +} LLVMCodeModel; + +typedef enum { + LLVMAssemblyFile, + LLVMObjectFile +} LLVMCodeGenFileType; + +/** Returns the first llvm::Target in the registered targets list. */ +LLVMTargetRef LLVMGetFirstTarget(); +/** Returns the next llvm::Target given a previous one (or null if there's none) */ +LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T); + +/*===-- Target ------------------------------------------------------------===*/ +/** Returns the name of a target. See llvm::Target::getName */ +const char *LLVMGetTargetName(LLVMTargetRef T); + +/** Returns the description of a target. See llvm::Target::getDescription */ +const char *LLVMGetTargetDescription(LLVMTargetRef T); + +/** Returns if the target has a JIT */ +LLVMBool LLVMTargetHasJIT(LLVMTargetRef T); + +/** Returns if the target has a TargetMachine associated */ +LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T); + +/** Returns if the target as an ASM backend (required for emitting output) */ +LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T); + +/*===-- Target Machine ----------------------------------------------------===*/ +/** Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine */ +LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char *Triple, + char *CPU, char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, + LLVMCodeModel CodeModel); + +/** Dispose the LLVMTargetMachineRef instance generated by + LLVMCreateTargetMachine. */ +void LLVMDisposeTargetMachine(LLVMTargetMachineRef T); + +/** Returns the Target used in a TargetMachine */ +LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T); + +/** Returns the triple used creating this target machine. See + llvm::TargetMachine::getTriple. The result needs to be disposed with + LLVMDisposeMessage. */ +char *LLVMGetTargetMachineTriple(LLVMTargetMachineRef T); + +/** Returns the cpu used creating this target machine. See + llvm::TargetMachine::getCPU. The result needs to be disposed with + LLVMDisposeMessage. */ +char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T); + +/** Returns the feature string used creating this target machine. See + llvm::TargetMachine::getFeatureString. The result needs to be disposed with + LLVMDisposeMessage. */ +char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T); + +/** Returns the llvm::TargetData used for this llvm:TargetMachine. */ +LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T); + +/** Emits an asm or object file for the given module to the filename. This + wraps several c++ only classes (among them a file stream). Returns any + error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */ +LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, + char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage); + + + + +#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/lto.h b/include/llvm-c/lto.h index 43ef9dc..f43d365 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -31,20 +31,20 @@ typedef enum { LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */ - LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0, - LTO_SYMBOL_PERMISSIONS_CODE = 0x000000A0, - LTO_SYMBOL_PERMISSIONS_DATA = 0x000000C0, - LTO_SYMBOL_PERMISSIONS_RODATA = 0x00000080, - LTO_SYMBOL_DEFINITION_MASK = 0x00000700, - LTO_SYMBOL_DEFINITION_REGULAR = 0x00000100, - LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200, - LTO_SYMBOL_DEFINITION_WEAK = 0x00000300, - LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400, + LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0, + LTO_SYMBOL_PERMISSIONS_CODE = 0x000000A0, + LTO_SYMBOL_PERMISSIONS_DATA = 0x000000C0, + LTO_SYMBOL_PERMISSIONS_RODATA = 0x00000080, + LTO_SYMBOL_DEFINITION_MASK = 0x00000700, + LTO_SYMBOL_DEFINITION_REGULAR = 0x00000100, + LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200, + LTO_SYMBOL_DEFINITION_WEAK = 0x00000300, + LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400, LTO_SYMBOL_DEFINITION_WEAKUNDEF = 0x00000500, - LTO_SYMBOL_SCOPE_MASK = 0x00003800, - LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800, - LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000, - LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000, + LTO_SYMBOL_SCOPE_MASK = 0x00003800, + LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800, + LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000, + LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000, LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800, LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800 } lto_symbol_attributes; @@ -95,7 +95,7 @@ lto_module_is_object_file(const char* path); * Checks if a file is a loadable object compiled for requested target. */ extern bool -lto_module_is_object_file_for_target(const char* path, +lto_module_is_object_file_for_target(const char* path, const char* target_triple_prefix); @@ -110,7 +110,7 @@ lto_module_is_object_file_in_memory(const void* mem, size_t length); * Checks if a buffer is a loadable object compiled for requested target. */ extern bool -lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length, +lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length, const char* target_triple_prefix); @@ -258,7 +258,6 @@ lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args, extern void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol); - /** * Writes a new object file at the specified path that contains the * merged contents of all modules added so far. @@ -267,11 +266,10 @@ lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol); extern bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path); - /** * Generates code for all added modules into one native object file. * On success returns a pointer to a generated mach-o/ELF buffer and - * length set to the buffer size. The buffer is owned by the + * length set to the buffer size. The buffer is owned by the * lto_code_gen_t and will be freed when lto_codegen_dispose() * is called, or lto_codegen_compile() is called again. * On failure, returns NULL (check lto_get_error_message() for details). @@ -292,6 +290,7 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); */ extern void lto_codegen_debug_options(lto_code_gen_t cg, const char *); + #ifdef __cplusplus } #endif diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index d40727d..2b466f9 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -320,6 +320,7 @@ namespace llvm { const fltSemantics &getSemantics() const { return *semantics; } bool isZero() const { return category == fcZero; } bool isNonZero() const { return category != fcZero; } + bool isNormal() const { return category == fcNormal; } bool isNaN() const { return category == fcNaN; } bool isInfinity() const { return category == fcInfinity; } bool isNegative() const { return sign; } diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 672147d..8d4a19d 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -30,12 +30,11 @@ namespace llvm { template<typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT>, bool IsConst = false> + bool IsConst = false> class DenseMapIterator; template<typename KeyT, typename ValueT, - typename KeyInfoT = DenseMapInfo<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT> > + typename KeyInfoT = DenseMapInfo<KeyT> > class DenseMap { typedef std::pair<KeyT, ValueT> BucketT; unsigned NumBuckets; @@ -80,7 +79,7 @@ public: typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator; typedef DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, true> const_iterator; + KeyInfoT, true> const_iterator; inline iterator begin() { // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). return empty() ? end() : iterator(Buckets, Buckets+NumBuckets); @@ -256,7 +255,7 @@ public: private: void CopyFrom(const DenseMap& other) { if (NumBuckets != 0 && - (!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) { + (!isPodLike<KeyT>::value || !isPodLike<ValueT>::value)) { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { if (!KeyInfoT::isEqual(P->first, EmptyKey) && @@ -285,7 +284,7 @@ private: Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets)); - if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value) + if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT)); else for (size_t i = 0; i < NumBuckets; ++i) { @@ -502,12 +501,12 @@ public: }; template<typename KeyT, typename ValueT, - typename KeyInfoT, typename ValueInfoT, bool IsConst> + typename KeyInfoT, bool IsConst> class DenseMapIterator { typedef std::pair<KeyT, ValueT> Bucket; typedef DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, true> ConstIterator; - friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, ValueInfoT, true>; + KeyInfoT, true> ConstIterator; + friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>; public: typedef ptrdiff_t difference_type; typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type; @@ -528,7 +527,7 @@ public: // const_iterator and the default copy constructor is used. // Otherwise this is a copy constructor for iterator. DenseMapIterator(const DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, false>& I) + KeyInfoT, false>& I) : Ptr(I.Ptr), End(I.End) {} reference operator*() const { @@ -566,9 +565,9 @@ private: } }; -template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename KeyInfoT> static inline size_t -capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) { +capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) { return X.getMemorySize(); } diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index d2e0b8f..7d7c777 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -193,12 +193,11 @@ protected: virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0; /// NodeEquals - Instantiations of the FoldingSet template implement /// this function to compare the given node with the given ID. - virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, + virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const=0; - /// NodeEquals - Instantiations of the FoldingSet template implement + /// ComputeNodeHash - Instantiations of the FoldingSet template implement /// this function to compute a hash value for the given node. - virtual unsigned ComputeNodeHash(Node *N, - FoldingSetNodeID &TempID) const = 0; + virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0; }; //===----------------------------------------------------------------------===// @@ -220,7 +219,7 @@ template<typename T> struct DefaultFoldingSetTrait { // to compute a temporary ID if necessary. The default implementation // just calls Profile and does a regular comparison. Implementations // can override this to provide more efficient implementations. - static inline bool Equals(T &X, const FoldingSetNodeID &ID, + static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID); // ComputeHash - Compute a hash value for X, using TempID to @@ -249,7 +248,7 @@ struct DefaultContextualFoldingSetTrait { static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) { X.Profile(ID, Context); } - static inline bool Equals(T &X, const FoldingSetNodeID &ID, + static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context); static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID, Ctx Context); @@ -344,7 +343,7 @@ template<class T> class FoldingSetBucketIterator; template<typename T> inline bool DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID, - FoldingSetNodeID &TempID) { + unsigned IDHash, FoldingSetNodeID &TempID) { FoldingSetTrait<T>::Profile(X, TempID); return TempID == ID; } @@ -358,6 +357,7 @@ template<typename T, typename Ctx> inline bool DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X, const FoldingSetNodeID &ID, + unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context) { ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context); @@ -387,15 +387,14 @@ private: } /// NodeEquals - Instantiations may optionally provide a way to compare a /// node with a specified ID. - virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, + virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); - return FoldingSetTrait<T>::Equals(*TN, ID, TempID); + return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID); } - /// NodeEquals - Instantiations may optionally provide a way to compute a + /// ComputeNodeHash - Instantiations may optionally provide a way to compute a /// hash value directly from a node. - virtual unsigned ComputeNodeHash(Node *N, - FoldingSetNodeID &TempID) const { + virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); return FoldingSetTrait<T>::ComputeHash(*TN, TempID); } @@ -465,10 +464,11 @@ private: ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context); } virtual bool NodeEquals(FoldingSetImpl::Node *N, - const FoldingSetNodeID &ID, + const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); - return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, TempID, Context); + return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID, + Context); } virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N, FoldingSetNodeID &TempID) const { diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 81a5117..53032ee 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -505,13 +505,10 @@ namespace detail { /// recursive combining of arguments used in hash_combine. It is particularly /// useful at minimizing the code in the recursive calls to ease the pain /// caused by a lack of variadic functions. -class hash_combine_recursive_helper { - const size_t seed; +struct hash_combine_recursive_helper { char buffer[64]; - char *const buffer_end; - char *buffer_ptr; - size_t length; hash_state state; + const size_t seed; public: /// \brief Construct a recursive hash combining helper. @@ -519,10 +516,7 @@ public: /// This sets up the state for a recursive hash combine, including getting /// the seed and buffer setup. hash_combine_recursive_helper() - : seed(get_execution_seed()), - buffer_end(buffer + array_lengthof(buffer)), - buffer_ptr(buffer), - length(0) {} + : seed(get_execution_seed()) {} /// \brief Combine one chunk of data into the current in-flight hash. /// @@ -530,7 +524,8 @@ public: /// the data. If the buffer is full, it hashes the buffer into its /// hash_state, empties it, and then merges the new chunk in. This also /// handles cases where the data straddles the end of the buffer. - template <typename T> void combine_data(T data) { + template <typename T> + char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) { if (!store_and_advance(buffer_ptr, buffer_end, data)) { // Check for skew which prevents the buffer from being packed, and do // a partial store into the buffer to fill it. This is only a concern @@ -561,6 +556,7 @@ public: partial_store_size)) abort(); } + return buffer_ptr; } #if defined(__has_feature) && __has_feature(__cxx_variadic_templates__) @@ -570,11 +566,12 @@ public: /// This function recurses through each argument, combining that argument /// into a single hash. template <typename T, typename ...Ts> - hash_code combine(const T &arg, const Ts &...args) { - combine_data( get_hashable_data(arg)); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T &arg, const Ts &...args) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg)); // Recurse to the next argument. - return combine(args...); + return combine(length, buffer_ptr, buffer_end, args...); } #else @@ -583,37 +580,43 @@ public: template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4, arg5, arg6); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6); } template <typename T1, typename T2, typename T3, typename T4, typename T5> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4, arg5); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5); } template <typename T1, typename T2, typename T3, typename T4> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4); } template <typename T1, typename T2, typename T3> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3); } template <typename T1, typename T2> - hash_code combine(const T1 &arg1, const T2 &arg2) { - combine_data(get_hashable_data(arg1)); - return combine(arg2); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2); } template <typename T1> - hash_code combine(const T1 &arg1) { - combine_data(get_hashable_data(arg1)); - return combine(); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end); } #endif @@ -623,7 +626,7 @@ public: /// The base case when combining arguments recursively is reached when all /// arguments have been handled. It flushes the remaining buffer and /// constructs a hash_code. - hash_code combine() { + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) { // Check whether the entire set of values fit in the buffer. If so, we'll // use the optimized short hashing routine and skip state entirely. if (length == 0) @@ -663,7 +666,7 @@ public: template <typename ...Ts> hash_code hash_combine(const Ts &...args) { // Recursively hash each argument using a helper class. ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(args...); + return helper.combine(0, helper.buffer, helper.buffer + 64, args...); } #else @@ -674,36 +677,39 @@ template <typename ...Ts> hash_code hash_combine(const Ts &...args) { template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4, const T5 &arg5, const T6 &arg6) { + const T4 &arg4, const T5 &arg5, const T6 &arg6) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4, arg5, arg6); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4, arg5, arg6); } template <typename T1, typename T2, typename T3, typename T4, typename T5> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4, const T5 &arg5) { + const T4 &arg4, const T5 &arg5) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4, arg5); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4, arg5); } template <typename T1, typename T2, typename T3, typename T4> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4) { + const T4 &arg4) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4); } template <typename T1, typename T2, typename T3> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3); } template <typename T1, typename T2> hash_code hash_combine(const T1 &arg1, const T2 &arg2) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2); } template <typename T1> hash_code hash_combine(const T1 &arg1) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1); } #endif diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 70693d5..498a034 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -126,9 +126,6 @@ protected: private: bool isSmall() const { return CurArray == SmallArray; } - unsigned Hash(const void *Ptr) const { - return static_cast<unsigned>(((uintptr_t)Ptr >> 4) & (CurArraySize-1)); - } const void * const *FindBucketFor(const void *Ptr) const; void shrink_and_clear(); diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 4e0e018..655d884 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -15,12 +15,7 @@ #define LLVM_ADT_STRINGEXTRAS_H #include "llvm/Support/DataTypes.h" -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/StringRef.h" -#include <cctype> -#include <cstdio> -#include <string> namespace llvm { template<typename T> class SmallVectorImpl; @@ -101,22 +96,6 @@ static inline std::string itostr(int64_t X) { return utostr(static_cast<uint64_t>(X)); } -static inline std::string ftostr(double V) { - char Buffer[200]; - sprintf(Buffer, "%20.6e", V); - char *B = Buffer; - while (*B == ' ') ++B; - return B; -} - -static inline std::string ftostr(const APFloat& V) { - if (&V.getSemantics() == &APFloat::IEEEdouble) - return ftostr(V.convertToDouble()); - else if (&V.getSemantics() == &APFloat::IEEEsingle) - return ftostr((double)V.convertToFloat()); - return "<unknown format in ftostr>"; // error -} - /// StrInStrNoCase - Portable version of strcasestr. Locates the first /// occurrence of string 's1' in string 's2', ignoring case. Returns /// the offset of s2 in s1 or npos if s2 cannot be found. diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 097418e..b4497a2 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -239,7 +239,7 @@ public: explicit StringMap(AllocatorTy A) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} - explicit StringMap(const StringMap &RHS) + StringMap(const StringMap &RHS) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { assert(RHS.empty() && "Copy ctor from non-empty stringmap not implemented yet!"); diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 102c95a..f5f99d0 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -72,7 +72,9 @@ public: Apple, PC, - SCEI + SCEI, + BGP, + BGQ }; enum OSType { UnknownOS, @@ -95,7 +97,8 @@ public: Haiku, Minix, RTEMS, - NativeClient + NativeClient, + CNK // BG/P Compute-Node Kernel }; enum EnvironmentType { UnknownEnvironment, diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h index d1f4e5a..707d07d 100644 --- a/include/llvm/ADT/ValueMap.h +++ b/include/llvm/ADT/ValueMap.h @@ -35,7 +35,7 @@ namespace llvm { -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename Config> class ValueMapCallbackVH; template<typename DenseMapT, typename KeyT> @@ -72,13 +72,11 @@ struct ValueMapConfig { }; /// See the file comment. -template<typename KeyT, typename ValueT, typename Config = ValueMapConfig<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT> > +template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> > class ValueMap { - friend class ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT>; - typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> ValueMapCVH; - typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>, - ValueInfoT> MapT; + friend class ValueMapCallbackVH<KeyT, ValueT, Config>; + typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH; + typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT; typedef typename Config::ExtraData ExtraData; MapT Map; ExtraData Data; @@ -190,11 +188,11 @@ private: // This CallbackVH updates its ValueMap when the contained Value changes, // according to the user's preferences expressed through the Config object. -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename Config> class ValueMapCallbackVH : public CallbackVH { - friend class ValueMap<KeyT, ValueT, Config, ValueInfoT>; + friend class ValueMap<KeyT, ValueT, Config>; friend struct DenseMapInfo<ValueMapCallbackVH>; - typedef ValueMap<KeyT, ValueT, Config, ValueInfoT> ValueMapT; + typedef ValueMap<KeyT, ValueT, Config> ValueMapT; typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT; ValueMapT *Map; @@ -244,9 +242,9 @@ public: } }; -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> -struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { - typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH; +template<typename KeyT, typename ValueT, typename Config> +struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > { + typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH; typedef DenseMapInfo<KeyT> PointerInfo; static inline VH getEmptyKey() { diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 033e19b..7116078 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -20,9 +20,13 @@ namespace llvm { class BasicBlock; class Function; + class Instruction; class TargetData; class Value; + /// \brief Check whether an instruction is likely to be "free" when lowered. + bool isInstructionFree(const Instruction *I, const TargetData *TD = 0); + /// \brief Check whether a call will lower to something small. /// /// This tests checks whether calls to this function will lower to something diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 5190f0a..2d109cd 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -211,13 +211,19 @@ namespace llvm { /// createObjCProperty - Create debugging information entry for Objective-C /// property. /// @param Name Property name. + /// @param File File where this property is defined. + /// @param LineNumber Line number. /// @param GetterName Name of the Objective C property getter selector. /// @param SetterName Name of the Objective C property setter selector. /// @param PropertyAttributes Objective C property attributes. - DIObjCProperty createObjCProperty(StringRef Name, StringRef GetterName, - StringRef SetterName, - unsigned PropertyAttributes); - + /// @param Ty Type. + DIObjCProperty createObjCProperty(StringRef Name, + DIFile File, unsigned LineNumber, + StringRef GetterName, + 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. @@ -439,6 +445,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 ScopeLine Set to the beginning of the scope this starts /// @param Flags e.g. is this function prototyped or not. /// This flags are used to emit dwarf attributes. /// @param isOptimized True if optimization is ON. @@ -449,6 +456,7 @@ namespace llvm { DIFile File, unsigned LineNo, DIType Ty, bool isLocalToUnit, bool isDefinition, + unsigned ScopeLine, unsigned Flags = 0, bool isOptimized = false, Function *Fn = 0, diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 1bbe8df..894c542 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -519,6 +519,7 @@ namespace llvm { DICompositeType getContainingType() const { return getFieldAs<DICompositeType>(13); } + unsigned isArtificial() const { if (getVersion() <= llvm::LLVMDebugVersion8) return getUnsignedField(14); @@ -567,6 +568,11 @@ namespace llvm { return getFieldAs<DIFile>(6).getDirectory(); } + /// 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); } + /// Verify - Verify that a subprogram descriptor is well formed. bool Verify() const; @@ -792,31 +798,36 @@ namespace llvm { explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { } StringRef getObjCPropertyName() const { return getStringField(1); } + DIFile getFile() const { return getFieldAs<DIFile>(2); } + unsigned getLineNumber() const { return getUnsignedField(3); } + StringRef getObjCPropertyGetterName() const { - return getStringField(2); + return getStringField(4); } StringRef getObjCPropertySetterName() const { - return getStringField(3); + return getStringField(5); } bool isReadOnlyObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; } bool isReadWriteObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; } bool isAssignObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_assign) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0; } bool isRetainObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_retain) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0; } bool isCopyObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_copy) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0; } bool isNonAtomicObjCProperty() { - return (getUnsignedField(4) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; + return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; } + DIType getType() const { return getFieldAs<DIType>(7); } + /// Verify - Verify that a derived type descriptor is well formed. bool Verify() const; diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index c384925..6e8e424 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -185,6 +185,18 @@ void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT, template<class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> { + bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, + const DomTreeNodeBase<NodeT> *B) const { + assert(A != B); + assert(isReachableFromEntry(B)); + assert(isReachableFromEntry(A)); + + const DomTreeNodeBase<NodeT> *IDom; + while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B) + B = IDom; // Walk up the tree + return IDom != 0; + } + protected: typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType; DomTreeNodeMapType DomTreeNodes; @@ -338,38 +350,26 @@ public: /// Note that this is not a constant time operation! /// bool properlyDominates(const DomTreeNodeBase<NodeT> *A, - const DomTreeNodeBase<NodeT> *B) const { - if (A == 0 || B == 0) return false; - return dominatedBySlowTreeWalk(A, B); - } - - inline bool properlyDominates(const NodeT *A, const NodeT *B) { + const DomTreeNodeBase<NodeT> *B) { + if (A == 0 || B == 0) + return false; if (A == B) return false; - - // Cast away the const qualifiers here. This is ok since - // this function doesn't actually return the values returned - // from getNode. - return properlyDominates(getNode(const_cast<NodeT *>(A)), - getNode(const_cast<NodeT *>(B))); - } - - bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, - const DomTreeNodeBase<NodeT> *B) const { - const DomTreeNodeBase<NodeT> *IDom; - if (A == 0 || B == 0) return false; - while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B) - B = IDom; // Walk up the tree - return IDom != 0; + return dominates(A, B); } + bool properlyDominates(const NodeT *A, const NodeT *B); /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. - bool isReachableFromEntry(const NodeT* A) { + bool isReachableFromEntry(const NodeT* A) const { assert(!this->isPostDominator() && "This is not implemented for post dominators"); - return dominates(&A->getParent()->front(), A); + return isReachableFromEntry(getNode(const_cast<NodeT *>(A))); + } + + inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const { + return A; } /// dominates - Returns true iff A dominates B. Note that this is not a @@ -377,10 +377,16 @@ public: /// inline bool dominates(const DomTreeNodeBase<NodeT> *A, const DomTreeNodeBase<NodeT> *B) { + // A node trivially dominates itself. if (B == A) - return true; // A node trivially dominates itself. + return true; - if (A == 0 || B == 0) + // An unreachable node is dominated by anything. + if (!isReachableFromEntry(B)) + return true; + + // And dominates nothing. + if (!isReachableFromEntry(A)) return false; // Compare the result of the tree walk and the dfs numbers, if expensive @@ -405,16 +411,7 @@ public: return dominatedBySlowTreeWalk(A, B); } - inline bool dominates(const NodeT *A, const NodeT *B) { - if (A == B) - return true; - - // Cast away the const qualifiers here. This is ok since - // this function doesn't actually return the values returned - // from getNode. - return dominates(getNode(const_cast<NodeT *>(A)), - getNode(const_cast<NodeT *>(B))); - } + bool dominates(const NodeT *A, const NodeT *B); NodeT *getRoot() const { assert(this->Roots.size() == 1 && "Should always have entry node!"); @@ -680,6 +677,32 @@ public: } }; +// These two functions are declared out of line as a workaround for building +// with old (< r147295) versions of clang because of pr11642. +template<class NodeT> +bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) { + if (A == B) + return true; + + // Cast away the const qualifiers here. This is ok since + // this function doesn't actually return the values returned + // from getNode. + return dominates(getNode(const_cast<NodeT *>(A)), + getNode(const_cast<NodeT *>(B))); +} +template<class NodeT> +bool +DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) { + if (A == B) + return false; + + // Cast away the const qualifiers here. This is ok since + // this function doesn't actually return the values returned + // from getNode. + return dominates(getNode(const_cast<NodeT *>(A)), + getNode(const_cast<NodeT *>(B))); +} + EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>); //===------------------------------------- @@ -752,6 +775,7 @@ public: // dominates - Return true if Def dominates a use in User. This performs // the special checks necessary if Def and User are in the same basic block. // Note that Def doesn't dominate a use in Def itself! + bool dominates(const Instruction *Def, const Use &U) const; bool dominates(const Instruction *Def, const Instruction *User) const; bool dominates(const Instruction *Def, const BasicBlock *BB) const; @@ -820,6 +844,8 @@ public: return DT->isReachableFromEntry(A); } + bool isReachableFromEntry(const Use &U) const; + virtual void releaseMemory() { DT->releaseMemory(); diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 11d2cf0..2bf79b9 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -145,8 +145,7 @@ public: /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. - bool AddUsersIfInteresting(Instruction *I, - SmallPtrSet<Loop*,16> &SimpleLoopNests); + bool AddUsersIfInteresting(Instruction *I); IVStrideUse &AddUser(Instruction *User, Value *Operand); @@ -175,6 +174,8 @@ public: /// dump - This method is used for debugging. void dump() const; +protected: + bool AddUsersImpl(Instruction *I, SmallPtrSet<Loop*,16> &SimpleLoopNests); }; Pass *createIVUsersPass(); diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index c804c46..691c2d1 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -16,6 +16,7 @@ #include "llvm/Function.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/ValueMap.h" #include "llvm/Analysis/CodeMetrics.h" #include <cassert> @@ -25,171 +26,106 @@ namespace llvm { class CallSite; - template<class PtrType, unsigned SmallSize> - class SmallPtrSet; class TargetData; namespace InlineConstants { // Various magic constants used to adjust heuristics. const int InstrCost = 5; - const int IndirectCallBonus = -100; + const int IndirectCallThreshold = 100; const int CallPenalty = 25; const int LastCallToStaticBonus = -15000; const int ColdccPenalty = 2000; const int NoreturnPenalty = 10000; } - /// InlineCost - Represent the cost of inlining a function. This - /// supports special values for functions which should "always" or - /// "never" be inlined. Otherwise, the cost represents a unitless - /// amount; smaller values increase the likelihood of the function - /// being inlined. + /// \brief Represents the cost of inlining a function. + /// + /// This supports special values for functions which should "always" or + /// "never" be inlined. Otherwise, the cost represents a unitless amount; + /// smaller values increase the likelihood of the function being inlined. + /// + /// Objects of this type also provide the adjusted threshold for inlining + /// based on the information available for a particular callsite. They can be + /// directly tested to determine if inlining should occur given the cost and + /// threshold for this cost metric. class InlineCost { - enum Kind { - Value, - Always, - Never + enum SentinelValues { + AlwaysInlineCost = INT_MIN, + NeverInlineCost = INT_MAX }; - // This is a do-it-yourself implementation of - // int Cost : 30; - // unsigned Type : 2; - // We used to use bitfields, but they were sometimes miscompiled (PR3822). - enum { TYPE_BITS = 2 }; - enum { COST_BITS = unsigned(sizeof(unsigned)) * CHAR_BIT - TYPE_BITS }; - unsigned TypedCost; // int Cost : COST_BITS; unsigned Type : TYPE_BITS; + /// \brief The estimated cost of inlining this callsite. + const int Cost; - Kind getType() const { - return Kind(TypedCost >> COST_BITS); - } + /// \brief The adjusted threshold against which this cost was computed. + const int Threshold; - int getCost() const { - // Sign-extend the bottom COST_BITS bits. - return (int(TypedCost << TYPE_BITS)) >> TYPE_BITS; + // Trivial constructor, interesting logic in the factory functions below. + InlineCost(int Cost, int Threshold) + : Cost(Cost), Threshold(Threshold) {} + + public: + static InlineCost get(int Cost, int Threshold) { + assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); + assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); + return InlineCost(Cost, Threshold); + } + static InlineCost getAlways() { + return InlineCost(AlwaysInlineCost, 0); + } + static InlineCost getNever() { + return InlineCost(NeverInlineCost, 0); } - InlineCost(int C, int T) { - TypedCost = (unsigned(C << TYPE_BITS) >> TYPE_BITS) | (T << COST_BITS); - assert(getCost() == C && "Cost exceeds InlineCost precision"); + /// \brief Test whether the inline cost is low enough for inlining. + operator bool() const { + return Cost < Threshold; } - public: - static InlineCost get(int Cost) { return InlineCost(Cost, Value); } - static InlineCost getAlways() { return InlineCost(0, Always); } - static InlineCost getNever() { return InlineCost(0, Never); } - - bool isVariable() const { return getType() == Value; } - bool isAlways() const { return getType() == Always; } - bool isNever() const { return getType() == Never; } - - /// getValue() - Return a "variable" inline cost's amount. It is - /// an error to call this on an "always" or "never" InlineCost. - int getValue() const { - assert(getType() == Value && "Invalid access of InlineCost"); - return getCost(); + + bool isAlways() const { return Cost == AlwaysInlineCost; } + bool isNever() const { return Cost == NeverInlineCost; } + bool isVariable() const { return !isAlways() && !isNever(); } + + /// \brief Get the inline cost estimate. + /// It is an error to call this on an "always" or "never" InlineCost. + int getCost() const { + assert(isVariable() && "Invalid access of InlineCost"); + return Cost; } + + /// \brief Get the cost delta from the threshold for inlining. + /// Only valid if the cost is of the variable kind. Returns a negative + /// value if the cost is too high to inline. + int getCostDelta() const { return Threshold - getCost(); } }; /// InlineCostAnalyzer - Cost analyzer used by inliner. class InlineCostAnalyzer { - struct ArgInfo { - public: - unsigned ConstantWeight; - unsigned AllocaWeight; - - ArgInfo(unsigned CWeight, unsigned AWeight) - : ConstantWeight(CWeight), AllocaWeight(AWeight) - {} - }; - - struct FunctionInfo { - CodeMetrics Metrics; - - /// ArgumentWeights - Each formal argument of the function is inspected to - /// see if it is used in any contexts where making it a constant or alloca - /// would reduce the code size. If so, we add some value to the argument - /// entry here. - std::vector<ArgInfo> ArgumentWeights; - - /// PointerArgPairWeights - Weights to use when giving an inline bonus to - /// a call site due to correlated pairs of pointers. - DenseMap<std::pair<unsigned, unsigned>, unsigned> PointerArgPairWeights; - - /// countCodeReductionForConstant - Figure out an approximation for how - /// many instructions will be constant folded if the specified value is - /// constant. - unsigned countCodeReductionForConstant(const CodeMetrics &Metrics, - Value *V); - - /// countCodeReductionForAlloca - Figure out an approximation of how much - /// smaller the function will be if it is inlined into a context where an - /// argument becomes an alloca. - unsigned countCodeReductionForAlloca(const CodeMetrics &Metrics, - Value *V); - - /// countCodeReductionForPointerPair - Count the bonus to apply to an - /// inline call site where a pair of arguments are pointers and one - /// argument is a constant offset from the other. The idea is to - /// recognize a common C++ idiom where a begin and end iterator are - /// actually pointers, and many operations on the pair of them will be - /// constants if the function is called with arguments that have - /// a constant offset. - void countCodeReductionForPointerPair( - const CodeMetrics &Metrics, - DenseMap<Value *, unsigned> &PointerArgs, - Value *V, unsigned ArgIdx); - - /// analyzeFunction - Add information about the specified function - /// to the current structure. - void analyzeFunction(Function *F, const TargetData *TD); - - /// NeverInline - Returns true if the function should never be - /// inlined into any caller. - bool NeverInline(); - }; - - // The Function* for a function can be changed (by ArgumentPromotion); - // the ValueMap will update itself when this happens. - ValueMap<const Function *, FunctionInfo> CachedFunctionInfo; - // TargetData if available, or null. const TargetData *TD; - int CountBonusForConstant(Value *V, Constant *C = NULL); - int ConstantFunctionBonus(CallSite CS, Constant *C); - int getInlineSize(CallSite CS, Function *Callee); - int getInlineBonuses(CallSite CS, Function *Callee); public: InlineCostAnalyzer(): TD(0) {} void setTargetData(const TargetData *TData) { TD = TData; } - /// getInlineCost - The heuristic used to determine if we should inline the - /// function call or not. + /// \brief Get an InlineCost object representing the cost of inlining this + /// callsite. /// - InlineCost getInlineCost(CallSite CS); + /// Note that threshold is passed into this function. Only costs below the + /// threshold are computed with any accuracy. The threshold can be used to + /// bound the computation necessary to determine whether the cost is + /// sufficiently low to warrant inlining. + InlineCost getInlineCost(CallSite CS, int Threshold); /// getCalledFunction - The heuristic used to determine if we should inline /// the function call or not. The callee is explicitly specified, to allow - /// you to calculate the cost of inlining a function via a pointer. The - /// result assumes that the inlined version will always be used. You should - /// weight it yourself in cases where this callee will not always be called. - InlineCost getInlineCost(CallSite CS, Function *Callee); - - /// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a - /// higher threshold to determine if the function call should be inlined. - float getInlineFudgeFactor(CallSite CS); - - /// resetCachedFunctionInfo - erase any cached cost info for this function. - void resetCachedCostInfo(Function* Caller) { - CachedFunctionInfo[Caller] = FunctionInfo(); - } - - /// growCachedCostInfo - update the cached cost info for Caller after Callee - /// has been inlined. If Callee is NULL it means a dead call has been - /// eliminated. - void growCachedCostInfo(Function* Caller, Function* Callee); - - /// clear - empty the cache of inline costs - void clear(); + /// you to calculate the cost of inlining a function via a pointer. This + /// behaves exactly as the version with no explicit callee parameter in all + /// other respects. + // + // Note: This is used by out-of-tree passes, please do not remove without + // adding a replacement API. + InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); }; /// callIsSmall - If a call is likely to lower to a single target instruction, diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index fb07b03..152e885 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -189,16 +189,29 @@ namespace llvm { const DominatorTree *DT = 0); - /// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then - /// delete the From instruction. In addition to a basic RAUW, this does a - /// recursive simplification of the updated instructions. This catches - /// things where one simplification exposes other opportunities. This only - /// simplifies and deletes scalar operations, it does not change the CFG. + /// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses + /// recursively. /// - void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, - const TargetData *TD = 0, - const TargetLibraryInfo *TLI = 0, - const DominatorTree *DT = 0); + /// This first performs a normal RAUW of I with SimpleV. It then recursively + /// attempts to simplify those users updated by the operation. The 'I' + /// instruction must not be equal to the simplified value 'SimpleV'. + /// + /// The function returns true if any simplifications were performed. + bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, + const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + + /// \brief Recursively attempt to simplify an instruction. + /// + /// This routine uses SimplifyInstruction to simplify 'I', and if successful + /// replaces uses of 'I' with the simplified value. It then recurses on each + /// of the users impacted. It returns true if any simplifications were + /// performed. + bool recursivelySimplifyInstruction(Instruction *I, + const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); } // end namespace llvm #endif diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index f807d48..91feaaa 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -594,6 +594,9 @@ public: /// normal form. bool isLoopSimplifyForm() const; + /// isSafeToClone - Return true if the loop body is safe to clone in practice. + bool isSafeToClone() const; + /// hasDedicatedExits - Return true if no exit block for the loop /// has a predecessor that is outside the loop. bool hasDedicatedExits() const; @@ -762,7 +765,8 @@ public: InvBlockTraits::child_begin(BB), E = InvBlockTraits::child_end(BB); I != E; ++I) { typename InvBlockTraits::NodeType *N = *I; - if (DT.dominates(BB, N)) // If BB dominates its predecessor... + // If BB dominates its predecessor... + if (DT.dominates(BB, N) && DT.isReachableFromEntry(N)) TodoStack.push_back(N); } @@ -772,14 +776,12 @@ public: LoopT *L = new LoopT(BB); BBMap[BB] = L; - BlockT *EntryBlock = BB->getParent()->begin(); - while (!TodoStack.empty()) { // Process all the nodes in the loop BlockT *X = TodoStack.back(); TodoStack.pop_back(); if (!L->contains(X) && // As of yet unprocessed?? - DT.dominates(EntryBlock, X)) { // X is reachable from entry block? + DT.isReachableFromEntry(X)) { // Check to see if this block already belongs to a loop. If this occurs // then we have a case where a loop that is supposed to be a child of // the current loop was processed before the current loop. When this diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 727bf1b..72408f7 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -140,7 +140,7 @@ namespace llvm { ID = X.FastID; } static bool Equals(const SCEV &X, const FoldingSetNodeID &ID, - FoldingSetNodeID &TempID) { + unsigned IDHash, FoldingSetNodeID &TempID) { return ID == X.FastID; } static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) { diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index dfd774b..f2f9db4 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -24,7 +24,8 @@ namespace llvm { class APInt; class TargetData; class StringRef; - + class MDNode; + /// ComputeMaskedBits - Determine which of the bits specified in Mask are /// known to be either zero or one and return them in the KnownZero/KnownOne /// bit sets. This code only analyzes bits in Mask, in order to short-circuit @@ -35,10 +36,10 @@ namespace llvm { /// where V is a vector, the mask, known zero, and known one values are the /// same width as the vector element, and the bit is set only if it is true /// for all of the elements in the vector. - void ComputeMaskedBits(Value *V, const APInt &Mask, APInt &KnownZero, - APInt &KnownOne, const TargetData *TD = 0, - unsigned Depth = 0); - + void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne, + const TargetData *TD = 0, unsigned Depth = 0); + void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero); + /// ComputeSignBit - Determine whether the sign bit is known to be zero or /// one. Convenience wrapper around ComputeMaskedBits. void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, diff --git a/include/llvm/Assembly/AssemblyAnnotationWriter.h b/include/llvm/Assembly/AssemblyAnnotationWriter.h index fa8cdde..37b47c3 100644 --- a/include/llvm/Assembly/AssemblyAnnotationWriter.h +++ b/include/llvm/Assembly/AssemblyAnnotationWriter.h @@ -23,7 +23,6 @@ class Function; class BasicBlock; class Instruction; class Value; -class raw_ostream; class formatted_raw_ostream; class AssemblyAnnotationWriter { diff --git a/include/llvm/Assembly/Parser.h b/include/llvm/Assembly/Parser.h index 82ec6d8..b971c53 100644 --- a/include/llvm/Assembly/Parser.h +++ b/include/llvm/Assembly/Parser.h @@ -21,7 +21,6 @@ namespace llvm { class Module; class MemoryBuffer; class SMDiagnostic; -class raw_ostream; class LLVMContext; /// This function is the main interface to the LLVM Assembly Parser. It parses diff --git a/include/llvm/Assembly/Writer.h b/include/llvm/Assembly/Writer.h index 8d8befd..6b89ae0 100644 --- a/include/llvm/Assembly/Writer.h +++ b/include/llvm/Assembly/Writer.h @@ -19,7 +19,6 @@ namespace llvm { -class Type; class Module; class Value; class raw_ostream; diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index fda801c..0b609ed 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -27,6 +27,7 @@ namespace llvm { class GlobalVariable; class TargetLowering; class SDNode; +class SDValue; class SelectionDAG; /// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence @@ -89,7 +90,7 @@ bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr, const TargetLowering &TLI); bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, - const TargetLowering &TLI); + SDValue &Chain, const TargetLowering &TLI); } // End llvm namespace diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index 6cb5c9e..eb01f66 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -209,7 +209,7 @@ public: Parent->closeInsnRange(NewScope); } - /// dominates - Return true if current scope dominsates given lexical scope. + /// dominates - Return true if current scope dominates given lexical scope. bool dominates(const LexicalScope *S) const { if (S == this) return true; diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h new file mode 100644 index 0000000..57a6193 --- /dev/null +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -0,0 +1,207 @@ +//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeEdit class represents changes done to a virtual register when it +// is spilled or split. +// +// The parent register is never changed. Instead, a number of new virtual +// registers are created and added to the newRegs vector. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H +#define LLVM_CODEGEN_LIVERANGEEDIT_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class AliasAnalysis; +class LiveIntervals; +class MachineLoopInfo; +class MachineRegisterInfo; +class VirtRegMap; + +class LiveRangeEdit { +public: + /// Callback methods for LiveRangeEdit owners. + class Delegate { + virtual void anchor(); + public: + /// Called immediately before erasing a dead machine instruction. + virtual void LRE_WillEraseInstruction(MachineInstr *MI) {} + + /// Called when a virtual register is no longer used. Return false to defer + /// its deletion from LiveIntervals. + virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } + + /// Called before shrinking the live range of a virtual register. + virtual void LRE_WillShrinkVirtReg(unsigned) {} + + /// Called after cloning a virtual register. + /// This is used for new registers representing connected components of Old. + virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {} + + virtual ~Delegate() {} + }; + +private: + LiveInterval &parent_; + SmallVectorImpl<LiveInterval*> &newRegs_; + MachineRegisterInfo &MRI; + LiveIntervals &LIS; + VirtRegMap *VRM; + const TargetInstrInfo &TII; + Delegate *const delegate_; + + /// firstNew_ - Index of the first register added to newRegs_. + const unsigned firstNew_; + + /// scannedRemattable_ - true when remattable values have been identified. + bool scannedRemattable_; + + /// remattable_ - Values defined by remattable instructions as identified by + /// tii.isTriviallyReMaterializable(). + SmallPtrSet<const VNInfo*,4> remattable_; + + /// rematted_ - Values that were actually rematted, and so need to have their + /// live range trimmed or entirely removed. + SmallPtrSet<const VNInfo*,4> rematted_; + + /// scanRemattable - Identify the parent_ values that may rematerialize. + void scanRemattable(AliasAnalysis *aa); + + /// 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); + + /// 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. + bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead); + +public: + /// Create a LiveRangeEdit for breaking down parent into smaller pieces. + /// @param parent The register being spilled or split. + /// @param newRegs List to receive any new registers created. This needn't be + /// empty initially, any existing registers are ignored. + /// @param MF The MachineFunction the live range edit is taking place in. + /// @param lis The collection of all live intervals in this function. + /// @param vrm Map of virtual registers to physical registers for this + /// function. If NULL, no virtual register map updates will + /// be done. This could be the case if called before Regalloc. + LiveRangeEdit(LiveInterval &parent, + SmallVectorImpl<LiveInterval*> &newRegs, + MachineFunction &MF, + LiveIntervals &lis, + VirtRegMap *vrm, + Delegate *delegate = 0) + : parent_(parent), newRegs_(newRegs), + MRI(MF.getRegInfo()), LIS(lis), VRM(vrm), + TII(*MF.getTarget().getInstrInfo()), + delegate_(delegate), + firstNew_(newRegs.size()), + scannedRemattable_(false) {} + + LiveInterval &getParent() const { return parent_; } + unsigned getReg() const { return parent_.reg; } + + /// Iterator for accessing the new registers added by this edit. + typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator; + iterator begin() const { return newRegs_.begin()+firstNew_; } + iterator end() const { return newRegs_.end(); } + unsigned size() const { return newRegs_.size()-firstNew_; } + bool empty() const { return size() == 0; } + LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } + + ArrayRef<LiveInterval*> regs() const { + return makeArrayRef(newRegs_).slice(firstNew_); + } + + /// createFrom - Create a new virtual register based on OldReg. + LiveInterval &createFrom(unsigned OldReg); + + /// create - Create a new register with the same class and original slot as + /// parent. + LiveInterval &create() { + return createFrom(getReg()); + } + + /// anyRematerializable - Return true if any parent values may be + /// rematerializable. + /// This function must be called before any rematerialization is attempted. + bool anyRematerializable(AliasAnalysis*); + + /// checkRematerializable - Manually add VNI to the list of rematerializable + /// values if DefMI may be rematerializable. + bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, + AliasAnalysis*); + + /// Remat - Information needed to rematerialize at a specific location. + struct Remat { + VNInfo *ParentVNI; // parent_'s value at the remat location. + MachineInstr *OrigMI; // Instruction defining ParentVNI. + explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {} + }; + + /// canRematerializeAt - Determine if ParentVNI can be rematerialized at + /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI. + /// When cheapAsAMove is set, only cheap remats are allowed. + bool canRematerializeAt(Remat &RM, + SlotIndex UseIdx, + bool cheapAsAMove); + + /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an + /// instruction into MBB before MI. The new instruction is mapped, but + /// liveness is not updated. + /// Return the SlotIndex of the new instruction. + SlotIndex rematerializeAt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const Remat &RM, + const TargetRegisterInfo&, + bool Late = false); + + /// markRematerialized - explicitly mark a value as rematerialized after doing + /// it manually. + void markRematerialized(const VNInfo *ParentVNI) { + rematted_.insert(ParentVNI); + } + + /// didRematerialize - Return true if ParentVNI was rematerialized anywhere. + bool didRematerialize(const VNInfo *ParentVNI) const { + return rematted_.count(ParentVNI); + } + + /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try + /// to erase it from LIS. + void eraseVirtReg(unsigned Reg); + + /// eliminateDeadDefs - Try to delete machine instructions that are now dead + /// (allDefsAreDead returns true). This may cause live intervals to be trimmed + /// and further dead efs to be eliminated. + /// RegsBeingSpilled lists registers currently being spilled by the register + /// allocator. These registers should not be split into new intervals + /// as currently those new intervals are not guaranteed to spill. + void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, + ArrayRef<unsigned> RegsBeingSpilled + = ArrayRef<unsigned>()); + + /// calculateRegClassAndHint - Recompute register class and hint for each new + /// register. + void calculateRegClassAndHint(MachineFunction&, + const MachineLoopInfo&); +}; + +} + +#endif diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index fd4cac8..dda2dc7 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -380,7 +380,8 @@ public: MachineMemOperand *getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, - const MDNode *TBAAInfo = 0); + const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); /// getMachineMemOperand - Allocate a new MachineMemOperand by copying /// an existing one, adjusting by an offset and using the given size. diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index eed4a76..1ac9080 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -84,6 +84,7 @@ class MachineMemOperand { uint64_t Size; unsigned Flags; const MDNode *TBAAInfo; + const MDNode *Ranges; public: /// Flags values. These may be or'd together. @@ -105,7 +106,8 @@ public: /// MachineMemOperand - Construct an MachineMemOperand object with the /// specified PtrInfo, flags, size, and base alignment. MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s, - unsigned base_alignment, const MDNode *TBAAInfo = 0); + unsigned base_alignment, const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); const MachinePointerInfo &getPointerInfo() const { return PtrInfo; } @@ -140,6 +142,9 @@ public: /// getTBAAInfo - Return the TBAA tag for the memory reference. const MDNode *getTBAAInfo() const { return TBAAInfo; } + /// getRanges - Return the range tag for the memory reference. + const MDNode *getRanges() const { return Ranges; } + bool isLoad() const { return Flags & MOLoad; } bool isStore() const { return Flags & MOStore; } bool isVolatile() const { return Flags & MOVolatile; } diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index c41e8e2..90ee7f4 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -26,7 +26,7 @@ namespace llvm { typedef void *(*MachinePassCtor)(); -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistryListener - Listener to adds and removals of nodes in /// registration list. @@ -42,7 +42,7 @@ public: }; -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistryNode - Machine pass node stored in registration list. /// @@ -55,7 +55,7 @@ private: const char *Name; // Name of function pass. const char *Description; // Description string. MachinePassCtor Ctor; // Function pass creator. - + public: MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C) @@ -72,11 +72,11 @@ public: const char *getDescription() const { return Description; } MachinePassCtor getCtor() const { return Ctor; } void setNext(MachinePassRegistryNode *N) { Next = N; } - + }; -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistry - Track the registration of machine passes. /// @@ -88,7 +88,7 @@ private: MachinePassRegistryNode *List; // List of registry nodes. MachinePassCtor Default; // Default function pass creator. MachinePassRegistryListener* Listener;// Listener for list adds are removes. - + public: // NO CONSTRUCTOR - we don't want static constructor ordering to mess @@ -99,6 +99,7 @@ public: MachinePassRegistryNode *getList() { return List; } MachinePassCtor getDefault() { return Default; } void setDefault(MachinePassCtor C) { Default = C; } + void setDefault(StringRef Name); void setListener(MachinePassRegistryListener *L) { Listener = L; } /// Add - Adds a function pass to the registration list. @@ -126,7 +127,7 @@ public: void initialize(cl::Option &O) { cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O); - + // Add existing passes to option. for (RegistryClass *Node = RegistryClass::getList(); Node; Node = Node->getNext()) { @@ -134,7 +135,7 @@ public: (typename RegistryClass::FunctionPassCtor)Node->getCtor(), Node->getDescription()); } - + // Make sure we listen for list changes. RegistryClass::setListener(this); } diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 69ce588..3272fbd 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -32,6 +32,11 @@ class MachineRegisterInfo { /// registers have a single def. bool IsSSA; + /// TracksLiveness - True while register liveness is being tracked accurately. + /// Basic block live-in lists, kill flags, and implicit defs may not be + /// accurate when after this flag is cleared. + bool TracksLiveness; + /// VRegInfo - Information we keep for each virtual register. /// /// Each element in this list contains the register class of the vreg and the @@ -103,6 +108,23 @@ public: // leaveSSA - Indicates that the machine function is no longer in SSA form. void leaveSSA() { IsSSA = false; } + /// tracksLiveness - Returns true when tracking register liveness accurately. + /// + /// While this flag is true, register liveness information in basic block + /// live-in lists and machine instruction operands is accurate. This means it + /// can be used to change the code in ways that affect the values in + /// registers, for example by the register scavenger. + /// + /// When this flag is false, liveness is no longer reliable. + bool tracksLiveness() const { return TracksLiveness; } + + /// invalidateLiveness - Indicates that register liveness is no longer being + /// tracked accurately. + /// + /// This should be called by late passes that invalidate the liveness + /// information. + void invalidateLiveness() { TracksLiveness = false; } + //===--------------------------------------------------------------------===// // Register Info //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index e852009..474c95d 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -81,6 +81,9 @@ public: static void setDefault(ScheduleDAGCtor C) { Registry.setDefault((MachinePassCtor)C); } + static void setDefault(StringRef Name) { + Registry.setDefault(Name); + } static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index 5240729..a5d8b0d 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -350,6 +350,43 @@ namespace PBQP { numNodes = numEdges = 0; } + /// \brief Dump a graph to an output stream. + template <typename OStream> + void dump(OStream &os) { + os << getNumNodes() << " " << getNumEdges() << "\n"; + + for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd(); + nodeItr != nodeEnd; ++nodeItr) { + const Vector& v = getNodeCosts(nodeItr); + os << "\n" << v.getLength() << "\n"; + assert(v.getLength() != 0 && "Empty vector in graph."); + os << v[0]; + for (unsigned i = 1; i < v.getLength(); ++i) { + os << " " << v[i]; + } + os << "\n"; + } + + for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd(); + edgeItr != edgeEnd; ++edgeItr) { + unsigned n1 = std::distance(nodesBegin(), getEdgeNode1(edgeItr)); + unsigned n2 = std::distance(nodesBegin(), getEdgeNode2(edgeItr)); + assert(n1 != n2 && "PBQP graphs shound not have self-edges."); + const Matrix& m = getEdgeCosts(edgeItr); + os << "\n" << n1 << " " << n2 << "\n" + << m.getRows() << " " << m.getCols() << "\n"; + assert(m.getRows() != 0 && "No rows in matrix."); + assert(m.getCols() != 0 && "No cols in matrix."); + for (unsigned i = 0; i < m.getRows(); ++i) { + os << m[i][0]; + for (unsigned j = 1; j < m.getCols(); ++j) { + os << " " << m[i][j]; + } + os << "\n"; + } + } + } + /// \brief Print a representation of this graph in DOT format. /// @param os Output stream to print on. template <typename OStream> diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index e96c4cb..a859e58 100644 --- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -418,6 +418,12 @@ namespace PBQP { unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; nd.numDenied = 0; + const Vector& nCosts = getGraph().getNodeCosts(nItr); + for (unsigned i = 1; i < nCosts.getLength(); ++i) { + if (nCosts[i] == std::numeric_limits<PBQPNum>::infinity()) + ++nd.numDenied; + } + nd.numSafe = numRegs; nd.unsafeDegrees.resize(numRegs, 0); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index d6ca148e..3b38199 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -223,11 +223,6 @@ protected: /// regalloc pass. FunctionPass *createRegAllocPass(bool Optimized); - /// printNoVerify - Add a pass to dump the machine function, if debugging is - /// enabled. - /// - void printNoVerify(const char *Banner) const; - /// printAndVerify - Add a pass to dump then verify the machine function, if /// those steps are enabled. /// diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index a08f6cc..4fee108 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -181,6 +181,13 @@ namespace llvm { /// the def-side latency only. bool UnitLatencies; + /// The standard DAG builder does not normally include terminators as DAG + /// nodes because it does not create the necessary dependencies to prevent + /// reordering. A specialized scheduler can overide + /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate + /// it has taken responsibility for scheduling the terminator correctly. + bool CanHandleTerminators; + /// State specific to the current scheduling region. /// ------------------------------------------------ @@ -296,6 +303,10 @@ namespace llvm { /// overriding enterRegion() or exitRegion(). virtual void schedule() = 0; + /// finalizeSchedule - Allow targets to perform final scheduling actions at + /// the level of the whole MachineFunction. By default does nothing. + virtual void finalizeSchedule() {} + virtual void dumpNode(const SUnit *SU) const; /// Return a label for a DAG node that points to an instruction. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index f921ca2..6a7a87e 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -654,7 +654,7 @@ public: SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, - const MDNode *TBAAInfo = 0); + const MDNode *TBAAInfo = 0, const MDNode *Ranges = 0); SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, bool isVolatile, @@ -667,7 +667,8 @@ public: SDValue Chain, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT MemVT, bool isVolatile, bool isNonTemporal, bool isInvariant, - unsigned Alignment, const MDNode *TBAAInfo = 0); + unsigned Alignment, const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, SDValue Offset, @@ -979,8 +980,8 @@ public: /// bitsets. This code only analyzes bits in Mask, in order to short-circuit /// processing. Targets can implement the computeMaskedBitsForTargetNode /// method in the TargetLowering class to allow target nodes to be understood. - void ComputeMaskedBits(SDValue Op, const APInt &Mask, APInt &KnownZero, - APInt &KnownOne, unsigned Depth = 0) const; + void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, + unsigned Depth = 0) const; /// ComputeNumSignBits - Return the number of times the sign bit of the /// register is replicated into the other bits. We know that at least 1 bit diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index da3ea2a..f8248b8 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -933,6 +933,9 @@ public: /// Returns the TBAAInfo that describes the dereference. const MDNode *getTBAAInfo() const { return MMO->getTBAAInfo(); } + /// Returns the Ranges that describes the dereference. + const MDNode *getRanges() const { return MMO->getRanges(); } + /// getMemoryVT - Return the type of the in-memory value. EVT getMemoryVT() const { return MemoryVT; } diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index d868cb8..dfea0ac 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/ilist.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" @@ -33,8 +34,7 @@ namespace llvm { /// SlotIndexes pass. It should not be used directly. See the /// SlotIndex & SlotIndexes classes for the public interface to this /// information. - class IndexListEntry { - IndexListEntry *next, *prev; + class IndexListEntry : public ilist_node<IndexListEntry> { MachineInstr *mi; unsigned index; @@ -51,23 +51,31 @@ namespace llvm { void setIndex(unsigned index) { this->index = index; } - - IndexListEntry* getNext() { return next; } - const IndexListEntry* getNext() const { return next; } - void setNext(IndexListEntry *next) { - this->next = next; - } - IndexListEntry* getPrev() { return prev; } - const IndexListEntry* getPrev() const { return prev; } - void setPrev(IndexListEntry *prev) { - this->prev = prev; + }; + + template <> + struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> { + private: + mutable ilist_half_node<IndexListEntry> Sentinel; + public: + IndexListEntry *createSentinel() const { + return static_cast<IndexListEntry*>(&Sentinel); } + void destroySentinel(IndexListEntry *) const {} + + IndexListEntry *provideInitialHead() const { return createSentinel(); } + IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); } + static void noteHead(IndexListEntry*, IndexListEntry*) {} + void deleteNode(IndexListEntry *N) {} + + private: + void createNode(const IndexListEntry &); }; // Specialize PointerLikeTypeTraits for IndexListEntry. template <> - class PointerLikeTypeTraits<IndexListEntry*> { + class PointerLikeTypeTraits<IndexListEntry*> { public: static inline void* getAsVoidPointer(IndexListEntry *p) { return p; @@ -112,13 +120,13 @@ namespace llvm { SlotIndex(IndexListEntry *entry, unsigned slot) : lie(entry, slot) {} - IndexListEntry& entry() const { + IndexListEntry* listEntry() const { assert(isValid() && "Attempt to compare reserved index."); - return *lie.getPointer(); + return lie.getPointer(); } int getIndex() const { - return entry().getIndex() | getSlot(); + return listEntry()->getIndex() | getSlot(); } /// Returns the slot for this SlotIndex. @@ -150,8 +158,7 @@ namespace llvm { SlotIndex() : lie(0, 0) {} // Construct a new slot index from the given one, and set the slot. - SlotIndex(const SlotIndex &li, Slot s) - : lie(&li.entry(), unsigned(s)) { + SlotIndex(const SlotIndex &li, Slot s) : lie(li.listEntry(), unsigned(s)) { assert(lie.getPointer() != 0 && "Attempt to construct index with 0 pointer."); } @@ -179,7 +186,7 @@ namespace llvm { bool operator!=(SlotIndex other) const { return lie != other.lie; } - + /// Compare two SlotIndex objects. Return true if the first index /// is strictly lower than the second. bool operator<(SlotIndex other) const { @@ -211,7 +218,7 @@ namespace llvm { /// isEarlierInstr - Return true if A refers to an instruction earlier than /// B. This is equivalent to A < B && !isSameInstr(A, B). static bool isEarlierInstr(SlotIndex A, SlotIndex B) { - return A.entry().getIndex() < B.entry().getIndex(); + return A.listEntry()->getIndex() < B.listEntry()->getIndex(); } /// Return the distance from this index to the given one. @@ -236,25 +243,25 @@ namespace llvm { /// is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBaseIndex() const { - return SlotIndex(&entry(), Slot_Block); + return SlotIndex(listEntry(), Slot_Block); } /// Returns the boundary index for associated with this index. The boundary /// index is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBoundaryIndex() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the register use/def slot in the current instruction for a /// normal or early-clobber def. SlotIndex getRegSlot(bool EC = false) const { - return SlotIndex(&entry(), EC ? Slot_EarlyClobber : Slot_Register); + return SlotIndex(listEntry(), EC ? Slot_EarlyClobber : Slot_Register); } /// Returns the dead def kill slot for the current instruction. SlotIndex getDeadSlot() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the next slot in the index list. This could be either the @@ -266,15 +273,15 @@ namespace llvm { SlotIndex getNextSlot() const { Slot s = getSlot(); if (s == Slot_Dead) { - return SlotIndex(entry().getNext(), Slot_Block); + return SlotIndex(listEntry()->getNextNode(), Slot_Block); } - return SlotIndex(&entry(), s + 1); + return SlotIndex(listEntry(), s + 1); } /// Returns the next index. This is the index corresponding to the this /// index's slot, but for the next instruction. SlotIndex getNextIndex() const { - return SlotIndex(entry().getNext(), getSlot()); + return SlotIndex(listEntry()->getNextNode(), getSlot()); } /// Returns the previous slot in the index list. This could be either the @@ -286,15 +293,15 @@ namespace llvm { SlotIndex getPrevSlot() const { Slot s = getSlot(); if (s == Slot_Block) { - return SlotIndex(entry().getPrev(), Slot_Dead); + return SlotIndex(listEntry()->getPrevNode(), Slot_Dead); } - return SlotIndex(&entry(), s - 1); + return SlotIndex(listEntry(), s - 1); } /// Returns the previous index. This is the index corresponding to this /// index's slot, but for the previous instruction. SlotIndex getPrevIndex() const { - return SlotIndex(entry().getPrev(), getSlot()); + return SlotIndex(listEntry()->getPrevNode(), getSlot()); } }; @@ -315,7 +322,7 @@ namespace llvm { return (LHS == RHS); } }; - + template <> struct isPodLike<SlotIndex> { static const bool value = true; }; @@ -346,8 +353,10 @@ namespace llvm { class SlotIndexes : public MachineFunctionPass { private: + typedef ilist<IndexListEntry> IndexList; + IndexList indexList; + MachineFunction *mf; - IndexListEntry *indexListHead; unsigned functionSize; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; @@ -374,84 +383,18 @@ namespace llvm { return entry; } - void initList() { - assert(indexListHead == 0 && "Zero entry non-null at initialisation."); - indexListHead = createEntry(0, ~0U); - indexListHead->setNext(0); - indexListHead->setPrev(indexListHead); - } - - void clearList() { - indexListHead = 0; - ileAllocator.Reset(); - } - - IndexListEntry* getTail() { - assert(indexListHead != 0 && "Call to getTail on uninitialized list."); - return indexListHead->getPrev(); - } - - const IndexListEntry* getTail() const { - assert(indexListHead != 0 && "Call to getTail on uninitialized list."); - return indexListHead->getPrev(); - } - - // Returns true if the index list is empty. - bool empty() const { return (indexListHead == getTail()); } - - IndexListEntry* front() { - assert(!empty() && "front() called on empty index list."); - return indexListHead; - } - - const IndexListEntry* front() const { - assert(!empty() && "front() called on empty index list."); - return indexListHead; - } - - IndexListEntry* back() { - assert(!empty() && "back() called on empty index list."); - return getTail()->getPrev(); - } - - const IndexListEntry* back() const { - assert(!empty() && "back() called on empty index list."); - return getTail()->getPrev(); - } - - /// Insert a new entry before itr. - void insert(IndexListEntry *itr, IndexListEntry *val) { - assert(itr != 0 && "itr should not be null."); - IndexListEntry *prev = itr->getPrev(); - val->setNext(itr); - val->setPrev(prev); - - if (itr != indexListHead) { - prev->setNext(val); - } - else { - indexListHead = val; - } - itr->setPrev(val); - } - - /// Push a new entry on to the end of the list. - void push_back(IndexListEntry *val) { - insert(getTail(), val); - } - - /// Renumber locally after inserting newEntry. - void renumberIndexes(IndexListEntry *newEntry); + /// Renumber locally after inserting curItr. + void renumberIndexes(IndexList::iterator curItr); public: static char ID; - SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) { + SlotIndexes() : MachineFunctionPass(ID) { initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); } virtual void getAnalysisUsage(AnalysisUsage &au) const; - virtual void releaseMemory(); + virtual void releaseMemory(); virtual bool runOnMachineFunction(MachineFunction &fn); @@ -463,22 +406,21 @@ namespace llvm { /// Returns the zero index for this analysis. SlotIndex getZeroIndex() { - assert(front()->getIndex() == 0 && "First index is not 0?"); - return SlotIndex(front(), 0); + assert(indexList.front().getIndex() == 0 && "First index is not 0?"); + return SlotIndex(&indexList.front(), 0); } /// Returns the base index of the last slot in this analysis. SlotIndex getLastIndex() { - return SlotIndex(back(), 0); + return SlotIndex(&indexList.back(), 0); } /// Returns the distance between the highest and lowest indexes allocated /// so far. unsigned getIndexesLength() const { - assert(front()->getIndex() == 0 && + assert(indexList.front().getIndex() == 0 && "Initial index isn't zero?"); - - return back()->getIndex(); + return indexList.back().getIndex(); } /// Returns the number of instructions in the function. @@ -503,19 +445,15 @@ namespace llvm { /// Returns the instruction for the given index, or null if the given /// index has no instruction associated with it. MachineInstr* getInstructionFromIndex(SlotIndex index) const { - return index.isValid() ? index.entry().getInstr() : 0; + return index.isValid() ? index.listEntry()->getInstr() : 0; } /// Returns the next non-null index. SlotIndex getNextNonNullIndex(SlotIndex index) { - SlotIndex nextNonNull = index.getNextIndex(); - - while (&nextNonNull.entry() != getTail() && - getInstructionFromIndex(nextNonNull) == 0) { - nextNonNull = nextNonNull.getNextIndex(); - } - - return nextNonNull; + IndexList::iterator itr(index.listEntry()); + ++itr; + while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; } + return SlotIndex(itr, index.getSlot()); } /// getIndexBefore - Returns the index of the last indexed instruction @@ -659,31 +597,31 @@ namespace llvm { assert(mi->getParent() != 0 && "Instr must be added to function."); // Get the entries where mi should be inserted. - IndexListEntry *prevEntry, *nextEntry; + IndexList::iterator prevItr, nextItr; if (Late) { // Insert mi's index immediately before the following instruction. - nextEntry = &getIndexAfter(mi).entry(); - prevEntry = nextEntry->getPrev(); + nextItr = getIndexAfter(mi).listEntry(); + prevItr = prior(nextItr); } else { // Insert mi's index immediately after the preceeding instruction. - prevEntry = &getIndexBefore(mi).entry(); - nextEntry = prevEntry->getNext(); + prevItr = getIndexBefore(mi).listEntry(); + nextItr = llvm::next(prevItr); } // Get a number for the new instr, or 0 if there's no room currently. // In the latter case we'll force a renumber later. - unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u; - unsigned newNumber = prevEntry->getIndex() + dist; + unsigned dist = ((nextItr->getIndex() - prevItr->getIndex())/2) & ~3u; + unsigned newNumber = prevItr->getIndex() + dist; // Insert a new list entry for mi. - IndexListEntry *newEntry = createEntry(mi, newNumber); - insert(nextEntry, newEntry); + IndexList::iterator newItr = + indexList.insert(nextItr, createEntry(mi, newNumber)); // Renumber locally if we need to. if (dist == 0) - renumberIndexes(newEntry); + renumberIndexes(newItr); - SlotIndex newIndex(newEntry, SlotIndex::Slot_Block); + SlotIndex newIndex(&*newItr, SlotIndex::Slot_Block); mi2iMap.insert(std::make_pair(mi, newIndex)); return newIndex; } @@ -694,7 +632,7 @@ namespace llvm { // MachineInstr -> index mappings Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi); if (mi2iItr != mi2iMap.end()) { - IndexListEntry *miEntry(&mi2iItr->second.entry()); + IndexListEntry *miEntry(mi2iItr->second.listEntry()); assert(miEntry->getInstr() == mi && "Instruction indexes broken."); // FIXME: Eventually we want to actually delete these indexes. miEntry->setInstr(0); @@ -709,7 +647,7 @@ namespace llvm { if (mi2iItr == mi2iMap.end()) return; SlotIndex replaceBaseIndex = mi2iItr->second; - IndexListEntry *miEntry(&replaceBaseIndex.entry()); + IndexListEntry *miEntry(replaceBaseIndex.listEntry()); assert(miEntry->getInstr() == mi && "Mismatched instruction in index tables."); miEntry->setInstr(newMI); @@ -726,13 +664,13 @@ namespace llvm { IndexListEntry *nextEntry = 0; if (nextMBB == mbb->getParent()->end()) { - nextEntry = getTail(); + nextEntry = indexList.end(); } else { - nextEntry = &getMBBStartIdx(nextMBB).entry(); + nextEntry = getMBBStartIdx(nextMBB).listEntry(); } - insert(nextEntry, startEntry); - insert(nextEntry, stopEntry); + indexList.insert(nextEntry, startEntry); + indexList.insert(nextEntry, stopEntry); SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block); @@ -766,4 +704,4 @@ namespace llvm { } -#endif // LLVM_CODEGEN_LIVEINDEX_H +#endif // LLVM_CODEGEN_SLOTINDEXES_H diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index e50bff5..95c4d6c 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -11,9 +11,6 @@ /* Relative directory for resource files */ #define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" -/* Directory wherelibstdc++ is installed. */ -#define GCC_INSTALL_PREFIX "${GCC_INSTALL_PREFIX}" - /* Directories clang will search for headers */ #define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}" @@ -572,6 +569,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter +/* LLVM name for the native Disassembler init function, if available */ +#cmakedefine LLVM_NATIVE_DISASSEMBLER LLVMInitialize${LLVM_NATIVE_ARCH}Disassembler + /* LLVM name for the native Target init function, if available */ #cmakedefine LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 723a5f6..677bf2e 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -12,8 +12,8 @@ /* Directories clang will search for headers */ #undef C_INCLUDE_DIRS -/* Define if CBE is enabled for printf %a output */ -#undef ENABLE_CBE_PRINTF_A +/* Default <path> to all compiler invocations for --sysroot=<path>. */ +#undef DEFAULT_SYSROOT /* Define if position independent code is enabled */ #undef ENABLE_PIC @@ -570,6 +570,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER +/* LLVM name for the native Disassembler init function, if available */ +#undef LLVM_NATIVE_DISASSEMBLER + /* LLVM name for the native Target init function, if available */ #undef LLVM_NATIVE_TARGET diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index 3a55e6b..85d28fe 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -61,6 +61,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter +/* LLVM name for the native Disassembler init function, if available */ +#cmakedefine LLVM_NATIVE_DISASSEMBLER LLVMInitialize${LLVM_NATIVE_ARCH}Disassembler + /* LLVM name for the native Target init function, if available */ #cmakedefine LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in index 2613366..973652f 100644 --- a/include/llvm/Config/llvm-config.h.in +++ b/include/llvm/Config/llvm-config.h.in @@ -61,6 +61,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER +/* LLVM name for the native Disassembler init function, if available */ +#undef LLVM_NATIVE_DISASSEMBLER + /* LLVM name for the native Target init function, if available */ #undef LLVM_NATIVE_TARGET diff --git a/include/llvm/DebugInfoProbe.h b/include/llvm/DebugInfoProbe.h deleted file mode 100644 index 78d00df..0000000 --- a/include/llvm/DebugInfoProbe.h +++ /dev/null @@ -1,67 +0,0 @@ -//===-- DebugInfoProbe.h - DebugInfo Probe ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a probe, DebugInfoProbe, that can be used by pass -// manager to analyze how optimizer is treating debugging information. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H -#define LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H - -#include "llvm/ADT/StringMap.h" - -namespace llvm { - class Function; - class Pass; - class DebugInfoProbeImpl; - - /// DebugInfoProbe - This class provides a interface to monitor - /// how an optimization pass is preserving debugging information. - class DebugInfoProbe { - public: - DebugInfoProbe(); - ~DebugInfoProbe(); - - /// initialize - Collect information before running an optimization pass. - void initialize(StringRef PName, Function &F); - - /// finalize - Collect information after running an optimization pass. This - /// must be used after initialization. - void finalize(Function &F); - - /// report - Report findings. This should be invoked after finalize. - void report(); - - private: - DebugInfoProbeImpl *pImpl; - }; - - /// DebugInfoProbeInfo - This class provides an interface that a pass manager - /// can use to manage debug info probes. - class DebugInfoProbeInfo { - StringMap<DebugInfoProbe *> Probes; - public: - DebugInfoProbeInfo() {} - - /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting - /// them. - ~DebugInfoProbeInfo(); - - /// initialize - Collect information before running an optimization pass. - void initialize(Pass *P, Function &F); - - /// finalize - Collect information after running an optimization pass. This - /// must be used after initialization. - void finalize(Pass *P, Function &F); - }; - -} // End llvm namespace - -#endif diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 9f56ed1..e920e98 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -602,19 +602,20 @@ public: return *this; } + TargetMachine *selectTarget(); + /// selectTarget - Pick a target either via -march or by guessing the native /// arch. Add any CPU features specified via -mcpu or -mattr. - static TargetMachine *selectTarget(const Triple &TargetTriple, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs, - const TargetOptions &Options, - Reloc::Model RM, - CodeModel::Model CM, - CodeGenOpt::Level OL, - std::string *Err); - - ExecutionEngine *create(); + TargetMachine *selectTarget(const Triple &TargetTriple, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs); + + ExecutionEngine *create() { + return create(selectTarget()); + } + + ExecutionEngine *create(TargetMachine *TM); }; } // End llvm namespace diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 3587e38..4c75b6a 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -48,8 +48,8 @@ public: virtual void setPoisonMemory(bool poison) = 0; /// getPointerToNamedFunction - This method returns the address of the - /// specified function by using the dlsym function call. As such it is only - /// useful for resolving library symbols, not code generated symbols. + /// specified function. As such it is only useful for resolving library + /// symbols, not code generated symbols. /// /// If AbortOnFailure is false and no function with the given name is /// found, this function silently returns a null pointer. Otherwise, diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index aabfd03..54c28f3 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -47,7 +47,6 @@ public: virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; - }; class RuntimeDyld { diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index de5ce4e..37aa18b 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -17,6 +17,7 @@ #define LLVM_INLINEASM_H #include "llvm/Value.h" +#include "llvm/ADT/StringRef.h" #include <vector> namespace llvm { diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index e3676fe..f6eaf04 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -2507,7 +2507,8 @@ public: /// Resolves successor for current case. BasicBlockTy *getCaseSuccessor() { - assert((Index < SI->getNumCases() || DefaultPseudoIndex) && + assert((Index < SI->getNumCases() || + Index == DefaultPseudoIndex) && "Index out the number of cases."); return SI->getSuccessor(getSuccessorIndex()); } diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index f4abba9..cb7b3ea 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -904,13 +904,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Test instruction with bitwise comparison. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse41_ptestz : GCCBuiltin<"__builtin_ia32_ptestz128">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_x86_sse41_ptestc : GCCBuiltin<"__builtin_ia32_ptestc128">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; def int_x86_sse41_ptestnzc : GCCBuiltin<"__builtin_ia32_ptestnzc128">, - Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; } @@ -1091,20 +1091,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". GCCBuiltin<"__builtin_ia32_vperm2f128_si256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx_vpermil_pd : - Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps : - Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx_vpermil_pd_256 : - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps_256 : - Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, - llvm_i8_ty], [IntrNoMem]>; } // Vector blend @@ -1659,15 +1645,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_permd : GCCBuiltin<"__builtin_ia32_permvarsi256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty], [IntrNoMem]>; - def int_x86_avx2_permq : GCCBuiltin<"__builtin_ia32_permdi256">, - Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_i8_ty], - [IntrNoMem]>; def int_x86_avx2_permps : GCCBuiltin<"__builtin_ia32_permvarsf256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>; - def int_x86_avx2_permpd : GCCBuiltin<"__builtin_ia32_permdf256">, - Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i8_ty], - [IntrNoMem]>; def int_x86_avx2_vperm2i128 : GCCBuiltin<"__builtin_ia32_permti256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>; diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 47d2eaa..a8306a9 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -42,7 +42,8 @@ public: MD_dbg = 0, // "dbg" MD_tbaa = 1, // "tbaa" MD_prof = 2, // "prof" - MD_fpaccuracy = 3 // "fpaccuracy" + MD_fpmath = 3, // "fpmath" + MD_range = 4 // "range" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h index 88908fb..1ebcd6b 100644 --- a/include/llvm/Linker.h +++ b/include/llvm/Linker.h @@ -15,14 +15,15 @@ #define LLVM_LINKER_H #include <memory> +#include <string> #include <vector> -#include "llvm/ADT/StringRef.h" namespace llvm { namespace sys { class Path; } class Module; class LLVMContext; +class StringRef; /// This class provides the core functionality of linking in LLVM. It retains a /// Module object which is the composite of the modules and libraries linked diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 641ded5..05e6286 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -12,7 +12,6 @@ #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -20,15 +19,13 @@ namespace llvm { class MCAsmLayout; class MCAssembler; class MCELFObjectTargetWriter; -class MCFixup; +struct MCFixupKindInfo; class MCFragment; class MCInst; class MCInstFragment; class MCObjectWriter; class MCSection; class MCValue; -template<typename T> -class SmallVectorImpl; class raw_ostream; /// MCAsmBackend - Generic interface to target specific assembler backends. diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 095ca14..0f67c99 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -143,6 +143,10 @@ namespace llvm { /// symbol names. This defaults to true. bool AllowPeriodsInName; + /// AllowUTF8 - This is true if the assembler accepts UTF-8 input. + // FIXME: Make this a more general encoding setting? + bool AllowUTF8; + //===--- Data Emission Directives -------------------------------------===// /// ZeroDirective - this should be set to the directive used to get some @@ -485,6 +489,9 @@ namespace llvm { bool doesAllowPeriodsInName() const { return AllowPeriodsInName; } + bool doesAllowUTF8() const { + return AllowUTF8; + } const char *getZeroDirective() const { return ZeroDirective; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 915645f..498bfe1 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -29,7 +29,6 @@ namespace llvm { class raw_ostream; class MCAsmLayout; class MCAssembler; -class MCBinaryExpr; class MCContext; class MCCodeEmitter; class MCExpr; diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index bc63241..934ef69 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -10,12 +10,8 @@ #ifndef LLVM_MC_MCCODEEMITTER_H #define LLVM_MC_MCCODEEMITTER_H -#include "llvm/MC/MCFixup.h" - -#include <cassert> - namespace llvm { -class MCExpr; +class MCFixup; class MCInst; class raw_ostream; template<typename T> class SmallVectorImpl; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 8b4e296..b586319 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -16,7 +16,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/SMLoc.h" #include "llvm/Support/raw_ostream.h" #include <vector> // FIXME: Shouldn't be needed. @@ -31,6 +30,7 @@ namespace llvm { class MCObjectFileInfo; class MCRegisterInfo; class MCLineSection; + class SMLoc; class StringRef; class Twine; class MCSectionMachO; diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index a0fc9e5..fdb7ab2 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -17,20 +17,16 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MachineLocation.h" -#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" #include <vector> namespace llvm { class MCContext; - class MCExpr; + class MCObjectWriter; class MCSection; - class MCSectionData; class MCStreamer; class MCSymbol; - class MCObjectStreamer; - class raw_ostream; class SourceMgr; class SMLoc; diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 6e9f5d8..f153cb0 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -10,11 +10,45 @@ #ifndef LLVM_MC_MCELFOBJECTWRITER_H #define LLVM_MC_MCELFOBJECTWRITER_H -#include "llvm/MC/MCObjectWriter.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" +#include <vector> namespace llvm { +class MCAssembler; +class MCFixup; +class MCFragment; +class MCObjectWriter; +class MCSymbol; +class MCValue; + +/// @name Relocation Data +/// @{ + +struct ELFRelocationEntry { + // Make these big enough for both 32-bit and 64-bit + uint64_t r_offset; + int Index; + unsigned Type; + const MCSymbol *Symbol; + uint64_t r_addend; + const MCFixup *Fixup; + + ELFRelocationEntry() + : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} + + ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, + const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup) + : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), + r_addend(Addend), Fixup(&Fixup) {} + + // Support lexicographic sorting. + bool operator<(const ELFRelocationEntry &RE) const { + return RE.r_offset < r_offset; + } +}; + class MCELFObjectTargetWriter { const uint8_t OSABI; const uint16_t EMachine; @@ -52,6 +86,8 @@ public: virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); + virtual void sortRelocs(const MCAssembler &Asm, + std::vector<ELFRelocationEntry> &Relocs); /// @name Accessors /// @{ diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 2ae1e84..ff33641 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -15,7 +15,6 @@ #include "llvm/Support/DataTypes.h" namespace llvm { -class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 4d2adfa..3c4f28b 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -14,6 +14,7 @@ namespace llvm { class MCInst; class raw_ostream; class MCAsmInfo; +class MCInstrInfo; class MCRegisterInfo; class StringRef; @@ -26,6 +27,7 @@ protected: /// assembly emission is disable. raw_ostream *CommentStream; const MCAsmInfo &MAI; + const MCInstrInfo &MII; const MCRegisterInfo &MRI; /// The current set of available features. @@ -34,8 +36,9 @@ protected: /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: - MCInstPrinter(const MCAsmInfo &mai, const MCRegisterInfo &mri) - : CommentStream(0), MAI(mai), MRI(mri), AvailableFeatures(0) {} + MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, + const MCRegisterInfo &mri) + : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {} virtual ~MCInstPrinter(); @@ -49,7 +52,7 @@ public: /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. - virtual StringRef getOpcodeName(unsigned Opcode) const; + StringRef getOpcodeName(unsigned Opcode) const; /// printRegName - Print the assembler register name. virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 5d5801f..aea4b41 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -14,13 +14,12 @@ #ifndef LLVM_MC_MCBJECTFILEINFO_H #define LLVM_MC_MCBJECTFILEINFO_H -#include "llvm/MC/MCCodeGenInfo.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/MC/SectionKind.h" +#include "llvm/Support/CodeGen.h" namespace llvm { class MCContext; class MCSection; + class StringRef; class Triple; class MCObjectFileInfo { @@ -48,6 +47,7 @@ protected: unsigned FDECFIEncoding; unsigned TTypeEncoding; // Section flags for eh_frame + unsigned EHSectionType; unsigned EHSectionFlags; /// TextSection - Section directive for standard text. diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index f6a566a..6e44e6c 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,7 +10,6 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/DataTypes.h" #include <cassert> @@ -20,11 +19,9 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; -class MCSymbol; class MCSymbolData; class MCSymbolRefExpr; class MCValue; -class raw_ostream; /// MCObjectWriter - Defines the object file and target independent interfaces /// used by the assembler backend to write native file format object files. diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index dcecfb6..9a8735f 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -16,14 +16,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/MCAsmLexer.h" -#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/DataTypes.h" #include <string> -#include <cassert> namespace llvm { class MemoryBuffer; -class SMLoc; class MCAsmInfo; /// AsmLexer - Lexer class for assembly files. diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index ac04483..5e29ad4 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -15,8 +15,6 @@ #include "llvm/Support/SMLoc.h" namespace llvm { -class MCAsmLexer; -class MCInst; /// AsmToken - Target independent representation for an assembler token. class AsmToken { @@ -53,6 +51,7 @@ public: Greater, GreaterEqual, GreaterGreater, At }; +private: TokenKind Kind; /// A reference to the entire token contents; this is always a pointer into diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 1937fdc..27acf2f 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -127,22 +127,34 @@ struct MCRegisterDesc { class MCRegisterInfo { public: typedef const MCRegisterClass *regclass_iterator; + + /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be + /// performed with a binary search. + struct DwarfLLVMRegPair { + unsigned FromReg; + unsigned ToReg; + + bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; } + }; private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array unsigned RAReg; // Return address register const MCRegisterClass *Classes; // Pointer to the regclass array unsigned NumClasses; // Number of entries in the array - const uint16_t *Overlaps; // Pointer to the overlaps array - const uint16_t *SubRegs; // Pointer to the subregs array - const uint16_t *SuperRegs; // Pointer to the superregs array + const uint16_t *RegLists; // Pointer to the reglists array const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. unsigned NumSubRegIndices; // Number of subreg indices. - DenseMap<unsigned, int> L2DwarfRegs; // LLVM to Dwarf regs mapping - DenseMap<unsigned, int> EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH - DenseMap<unsigned, unsigned> Dwarf2LRegs; // Dwarf to LLVM regs mapping - DenseMap<unsigned, unsigned> EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH + + unsigned L2DwarfRegsSize; + unsigned EHL2DwarfRegsSize; + unsigned Dwarf2LRegsSize; + unsigned EHDwarf2LRegsSize; + const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping + const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH + const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping + const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping public: @@ -150,40 +162,45 @@ public: /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, const MCRegisterClass *C, unsigned NC, - const uint16_t *O, const uint16_t *Sub, - const uint16_t *Super, + const uint16_t *RL, const uint16_t *SubIndices, unsigned NumIndices) { Desc = D; NumRegs = NR; RAReg = RA; Classes = C; - Overlaps = O; - SubRegs = Sub; - SuperRegs = Super; + RegLists = RL; NumClasses = NC; SubRegIndices = SubIndices; NumSubRegIndices = NumIndices; } - /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf + /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. - void mapLLVMRegToDwarfReg(unsigned LLVMReg, int DwarfReg, bool isEH) { - if (isEH) - EHL2DwarfRegs[LLVMReg] = DwarfReg; - else - L2DwarfRegs[LLVMReg] = DwarfReg; + void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, + bool isEH) { + if (isEH) { + EHL2DwarfRegs = Map; + EHL2DwarfRegsSize = Size; + } else { + L2DwarfRegs = Map; + L2DwarfRegsSize = Size; + } } - /// mapDwarfRegToLLVMReg - Used to initialize Dwarf register to LLVM + /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. - void mapDwarfRegToLLVMReg(unsigned DwarfReg, unsigned LLVMReg, bool isEH) { - if (isEH) - EHDwarf2LRegs[DwarfReg] = LLVMReg; - else - Dwarf2LRegs[DwarfReg] = LLVMReg; + void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, + bool isEH) { + if (isEH) { + EHDwarf2LRegs = Map; + EHDwarf2LRegsSize = Size; + } else { + Dwarf2LRegs = Map; + Dwarf2LRegsSize = Size; + } } /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register @@ -220,7 +237,7 @@ public: /// const uint16_t *getAliasSet(unsigned RegNo) const { // The Overlaps set always begins with Reg itself. - return Overlaps + get(RegNo).Overlaps + 1; + return RegLists + get(RegNo).Overlaps + 1; } /// getOverlaps - Return a list of registers that overlap Reg, including @@ -229,7 +246,7 @@ public: /// These are exactly the registers in { x | regsOverlap(x, Reg) }. /// const uint16_t *getOverlaps(unsigned RegNo) const { - return Overlaps + get(RegNo).Overlaps; + return RegLists + get(RegNo).Overlaps; } /// getSubRegisters - Return the list of registers that are sub-registers of @@ -238,7 +255,7 @@ public: /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. /// const uint16_t *getSubRegisters(unsigned RegNo) const { - return SubRegs + get(RegNo).SubRegs; + return RegLists + get(RegNo).SubRegs; } /// getSubReg - Returns the physical register number of sub-register "Index" @@ -274,7 +291,7 @@ public: /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX. /// const uint16_t *getSuperRegisters(unsigned RegNo) const { - return SuperRegs + get(RegNo).SuperRegs; + return RegLists + get(RegNo).SuperRegs; } /// getName - Return the human-readable symbolic target-specific name for the @@ -294,21 +311,26 @@ public: /// parameter allows targets to use different numberings for EH info and /// debugging info. int getDwarfRegNum(unsigned RegNum, bool isEH) const { - const DenseMap<unsigned, int> &M = isEH ? EHL2DwarfRegs : L2DwarfRegs; - const DenseMap<unsigned, int>::const_iterator I = M.find(RegNum); - if (I == M.end()) return -1; - return I->second; + const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs; + unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize; + + DwarfLLVMRegPair Key = { RegNum, 0 }; + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key); + if (I == M+Size || I->FromReg != RegNum) + return -1; + return I->ToReg; } /// getLLVMRegNum - Map a dwarf register back to a target register. /// int getLLVMRegNum(unsigned RegNum, bool isEH) const { - const DenseMap<unsigned, unsigned> &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; - const DenseMap<unsigned, unsigned>::const_iterator I = M.find(RegNum); - if (I == M.end()) { - llvm_unreachable("Invalid RegNum"); - } - return I->second; + const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; + unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize; + + DwarfLLVMRegPair Key = { RegNum, 0 }; + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key); + assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum"); + return I->ToReg; } /// getSEHRegNum - Map a target register to an equivalent SEH register diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index e366522..a708edc 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -14,12 +14,10 @@ #ifndef LLVM_MC_MCSECTION_H #define LLVM_MC_MCSECTION_H -#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Casting.h" namespace llvm { - class MCContext; class MCAsmInfo; class raw_ostream; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index b154cf5..7eacde5 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -15,8 +15,8 @@ #define LLVM_MC_MCSECTIONCOFF_H #include "llvm/MC/MCSection.h" - #include "llvm/Support/COFF.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index c82de71..7321ca8 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -16,6 +16,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/Support/ELF.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index bdb17e90..15eb4f4 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSECTIONMACHO_H #include "llvm/MC/MCSection.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 9932306..2595600 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -23,7 +23,6 @@ namespace llvm { class MCAsmBackend; - class MCAsmInfo; class MCCodeEmitter; class MCContext; class MCExpr; @@ -32,7 +31,6 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; - class TargetLoweringObjectFile; class Twine; class raw_ostream; class formatted_raw_ostream; diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 29458ef..7357986 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -39,28 +39,24 @@ class MDString : public Value { virtual void anchor(); MDString(const MDString &); // DO NOT IMPLEMENT - StringRef Str; - explicit MDString(LLVMContext &C, StringRef S); - + explicit MDString(LLVMContext &C); public: static MDString *get(LLVMContext &Context, StringRef Str); static MDString *get(LLVMContext &Context, const char *Str) { return get(Context, Str ? StringRef(Str) : StringRef()); } - StringRef getString() const { return Str; } + StringRef getString() const { return getName(); } - unsigned getLength() const { return (unsigned)Str.size(); } + unsigned getLength() const { return (unsigned)getName().size(); } typedef StringRef::iterator iterator; /// begin() - Pointer to the first byte of the string. - /// - iterator begin() const { return Str.begin(); } + iterator begin() const { return getName().begin(); } /// end() - Pointer to one byte past the end of the string. - /// - iterator end() const { return Str.end(); } + iterator end() const { return getName().end(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MDString *) { return true; } @@ -79,6 +75,10 @@ class MDNode : public Value, public FoldingSetNode { void operator=(const MDNode &); // DO NOT IMPLEMENT friend class MDNodeOperand; friend class LLVMContextImpl; + friend struct FoldingSetTrait<MDNode>; + + /// Hash - If the MDNode is uniqued cache the hash to speed up lookup. + unsigned Hash; /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the /// end of this MDNode. diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 4ca8fde..b9c9881 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -30,8 +30,7 @@ class GVMaterializer; class LLVMContext; class StructType; template<typename T> struct DenseMapInfo; -template<typename KeyT, typename ValueT, - typename KeyInfoT, typename ValueInfoT> class DenseMap; +template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap; template<> struct ilist_traits<Function> : public SymbolTableListTraits<Function, Module> { @@ -299,8 +298,8 @@ public: void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; - typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*>, - DenseMapInfo<unsigned> > NumeredTypesMapTy; + typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*> > + NumeredTypesMapTy; /// findUsedStructTypes - Walk the entire module and find all of the /// struct types that are in use, returning them in a vector. diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 91971bb..68b5ca1 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -126,6 +126,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index d33f317..e493f5b 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -33,6 +33,15 @@ namespace llvm { namespace object { +// Subclasses of ELFObjectFile may need this for template instantiation +inline std::pair<unsigned char, unsigned char> +getElfArchType(MemoryBuffer *Object) { + if (Object->getBufferSize() < ELF::EI_NIDENT) + return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); + return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] + , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); +} + // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. template<support::endianness target_endianness> struct ELFDataTypeTypedefHelperCommon { @@ -290,9 +299,7 @@ class DynRefImpl { const OwningType *OwningObject; public: - DynRefImpl() : OwningObject(NULL) { - std::memset(&DynPimpl, 0, sizeof(DynPimpl)); - } + DynRefImpl() : OwningObject(NULL) { } DynRefImpl(DataRefImpl DynP, const OwningType *Owner); @@ -542,6 +549,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; @@ -1096,6 +1107,43 @@ error_code ELFObjectFile<target_endianness, is64Bits> template<support::endianness target_endianness, bool is64Bits> error_code ELFObjectFile<target_endianness, is64Bits> + ::isSectionRequiredForExecution(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); + if (sec->sh_flags & ELF::SHF_ALLOC) + Result = true; + else + Result = false; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> + ::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); + if (sec->sh_type == ELF::SHT_NOBITS) + Result = true; + else + Result = false; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits>::isSectionZeroInit(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); + // For ELF, all zero-init sections are virtual (that is, they occupy no space + // in the object image) and vice versa. + if (sec->sh_flags & ELF::SHT_NOBITS) + Result = true; + else + Result = false; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> ::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const { @@ -1108,7 +1156,6 @@ template<support::endianness target_endianness, bool is64Bits> relocation_iterator ELFObjectFile<target_endianness, is64Bits> ::getSectionRelBegin(DataRefImpl Sec) const { DataRefImpl RelData; - memset(&RelData, 0, sizeof(RelData)); const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); if (sec != 0 && ittr != SectionRelocMap.end()) { @@ -1123,7 +1170,6 @@ template<support::endianness target_endianness, bool is64Bits> relocation_iterator ELFObjectFile<target_endianness, is64Bits> ::getSectionRelEnd(DataRefImpl Sec) const { DataRefImpl RelData; - memset(&RelData, 0, sizeof(RelData)); const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); if (sec != 0 && ittr != SectionRelocMap.end()) { @@ -1626,7 +1672,6 @@ template<support::endianness target_endianness, bool is64Bits> symbol_iterator ELFObjectFile<target_endianness, is64Bits> ::begin_symbols() const { DataRefImpl SymbolData; - memset(&SymbolData, 0, sizeof(SymbolData)); if (SymbolTableSections.size() <= 1) { SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); @@ -1641,7 +1686,6 @@ template<support::endianness target_endianness, bool is64Bits> symbol_iterator ELFObjectFile<target_endianness, is64Bits> ::end_symbols() const { DataRefImpl SymbolData; - memset(&SymbolData, 0, sizeof(SymbolData)); SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); return symbol_iterator(SymbolRef(SymbolData, this)); @@ -1651,7 +1695,6 @@ template<support::endianness target_endianness, bool is64Bits> symbol_iterator ELFObjectFile<target_endianness, is64Bits> ::begin_dynamic_symbols() const { DataRefImpl SymbolData; - memset(&SymbolData, 0, sizeof(SymbolData)); if (SymbolTableSections[0] == NULL) { SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); @@ -1666,7 +1709,6 @@ template<support::endianness target_endianness, bool is64Bits> symbol_iterator ELFObjectFile<target_endianness, is64Bits> ::end_dynamic_symbols() const { DataRefImpl SymbolData; - memset(&SymbolData, 0, sizeof(SymbolData)); SymbolData.d.a = std::numeric_limits<uint32_t>::max(); SymbolData.d.b = std::numeric_limits<uint32_t>::max(); return symbol_iterator(SymbolRef(SymbolData, this)); @@ -1676,7 +1718,6 @@ template<support::endianness target_endianness, bool is64Bits> section_iterator ELFObjectFile<target_endianness, is64Bits> ::begin_sections() const { DataRefImpl ret; - memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); return section_iterator(SectionRef(ret, this)); } @@ -1685,7 +1726,6 @@ template<support::endianness target_endianness, bool is64Bits> section_iterator ELFObjectFile<target_endianness, is64Bits> ::end_sections() const { DataRefImpl ret; - memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff + (Header->e_shentsize*getNumSections())); @@ -1696,7 +1736,6 @@ template<support::endianness target_endianness, bool is64Bits> typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const { DataRefImpl DynData; - memset(&DynData, 0, sizeof(DynData)); if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) { DynData.d.a = std::numeric_limits<uint32_t>::max(); } else { @@ -1710,7 +1749,6 @@ typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator ELFObjectFile<target_endianness, is64Bits> ::end_dynamic_table() const { DataRefImpl DynData; - memset(&DynData, 0, sizeof(DynData)); DynData.d.a = std::numeric_limits<uint32_t>::max(); return dyn_iterator(DynRef(DynData, this)); } diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1e409b2..0b73f94 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -72,6 +72,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 09eb7fc..4dd7fb5 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -38,6 +38,9 @@ union DataRefImpl { uint32_t a, b; } d; uintptr_t p; + DataRefImpl() { + std::memset(this, 0, sizeof(DataRefImpl)); + } }; template<class content_type> @@ -94,9 +97,7 @@ class RelocationRef { const ObjectFile *OwningObject; public: - RelocationRef() : OwningObject(NULL) { - std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); - } + RelocationRef() : OwningObject(NULL) { } RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); @@ -136,9 +137,7 @@ class SectionRef { const ObjectFile *OwningObject; public: - SectionRef() : OwningObject(NULL) { - std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); - } + SectionRef() : OwningObject(NULL) { } SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); @@ -159,11 +158,16 @@ public: error_code isText(bool &Result) const; error_code isData(bool &Result) const; error_code isBSS(bool &Result) const; + error_code isRequiredForExecution(bool &Result) const; + error_code isVirtual(bool &Result) const; + error_code isZeroInit(bool &Result) const; error_code containsSymbol(SymbolRef S, bool &Result) const; relocation_iterator begin_relocations() const; relocation_iterator end_relocations() const; + + DataRefImpl getRawDataRefImpl() const; }; typedef content_iterator<SectionRef> section_iterator; @@ -175,9 +179,7 @@ class SymbolRef { const ObjectFile *OwningObject; public: - SymbolRef() : OwningObject(NULL) { - std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); - } + SymbolRef() : OwningObject(NULL) { } enum Type { ST_Unknown, // Type not specified @@ -220,6 +222,9 @@ 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; @@ -236,9 +241,7 @@ class LibraryRef { const ObjectFile *OwningObject; public: - LibraryRef() : OwningObject(NULL) { - std::memset(&LibraryPimpl, 0, sizeof(LibraryPimpl)); - } + LibraryRef() : OwningObject(NULL) { } LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner); @@ -304,6 +307,11 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const = 0; + // A section is 'virtual' if its contents aren't present in the object image. + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const = 0; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; @@ -486,6 +494,18 @@ inline error_code SectionRef::isBSS(bool &Result) const { return OwningObject->isSectionBSS(SectionPimpl, Result); } +inline error_code SectionRef::isRequiredForExecution(bool &Result) const { + return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result); +} + +inline error_code SectionRef::isVirtual(bool &Result) const { + return OwningObject->isSectionVirtual(SectionPimpl, Result); +} + +inline error_code SectionRef::isZeroInit(bool &Result) const { + return OwningObject->isSectionZeroInit(SectionPimpl, Result); +} + inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, Result); @@ -499,6 +519,9 @@ inline relocation_iterator SectionRef::end_relocations() const { return OwningObject->getSectionRelEnd(SectionPimpl); } +inline DataRefImpl SectionRef::getRawDataRefImpl() const { + return SectionPimpl; +} /// RelocationRef inline RelocationRef::RelocationRef(DataRefImpl RelocationP, diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index abd6a19..1e86980 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -15,8 +15,9 @@ #ifndef LLVM_OPERATOR_H #define LLVM_OPERATOR_H -#include "llvm/Instruction.h" #include "llvm/Constants.h" +#include "llvm/Instruction.h" +#include "llvm/Type.h" namespace llvm { @@ -129,14 +130,15 @@ public: IsExact = (1 << 0) }; +private: + ~PossiblyExactOperator(); // do not implement + friend class BinaryOperator; friend class ConstantExpr; void setIsExact(bool B) { SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); } -private: - ~PossiblyExactOperator(); // do not implement public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. @@ -161,7 +163,28 @@ public: (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; - + +/// FPMathOperator - Utility class for floating point operations which can have +/// information about relaxed accuracy requirements attached to them. +class FPMathOperator : public Operator { +private: + ~FPMathOperator(); // do not implement + +public: + + /// \brief Get the maximum error permitted by this operation in ULPs. An + /// accuracy of 0.0 means that the operation should be performed with the + /// default precision. + float getFPAccuracy() const; + + static inline bool classof(const FPMathOperator *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getType()->isFPOrFPVectorTy(); + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; /// ConcreteOperator - A helper template for defining operators for individual diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h index 3a76cc7..1b66c94 100644 --- a/include/llvm/Support/CodeGen.h +++ b/include/llvm/Support/CodeGen.h @@ -27,6 +27,16 @@ namespace llvm { enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; } + // TLS models. + namespace TLSModel { + enum Model { + GeneralDynamic, + LocalDynamic, + InitialExec, + LocalExec + }; + } + // Code generation optimization level. namespace CodeGenOpt { enum Level { diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index 8651fc1..e723272 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -35,14 +35,14 @@ class raw_ostream; #ifndef DEBUG_TYPE #define DEBUG_TYPE "" #endif - + #ifndef NDEBUG /// DebugFlag - This boolean is set to true if the '-debug' command line option /// is specified. This should probably not be referenced directly, instead, use /// the DEBUG macro below. /// extern bool DebugFlag; - + /// isCurrentDebugType - Return true if the specified string is the debug type /// specified on the command line, or if none was specified on the command line /// with the -debug-only=X option. @@ -54,7 +54,7 @@ bool isCurrentDebugType(const char *Type); /// debug output to be produced. /// void SetCurrentDebugType(const char *Type); - + /// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug /// information. In the '-debug' option is specified on the commandline, and if /// this is a debug build, then the code specified as the option to the macro diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index e57fbf7..8f18a99 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -131,7 +131,7 @@ enum dwarf_constants { DW_TAG_GNU_template_parameter_pack = 0x4107, DW_TAG_GNU_formal_parameter_pack = 0x4108, DW_TAG_lo_user = 0x4080, - DW_TAG_APPLE_Property = 0x4200, + DW_TAG_APPLE_property = 0x4200, DW_TAG_hi_user = 0xffff, // Children flag diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 5c5e4a1..fdd889b 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -609,8 +609,10 @@ enum { EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set EF_MIPS_ARCH_4 = 0x30000000, // MIPS4 instruction set EF_MIPS_ARCH_5 = 0x40000000, // MIPS5 instruction set - EF_MIPS_ARCH_32 = 0x60000000, // MIPS32 instruction set + EF_MIPS_ARCH_32 = 0x50000000, // MIPS32 instruction set per linux not elf.h + EF_MIPS_ARCH_64 = 0x60000000, // MIPS64 instruction set per linux not elf.h EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2 + EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2 EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant }; diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 7828001..ef00e8e 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/BasicBlock.h" +#include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" @@ -331,49 +332,63 @@ template<bool preserveNames = true, typename T = ConstantFolder, typename Inserter = IRBuilderDefaultInserter<preserveNames> > class IRBuilder : public IRBuilderBase, public Inserter { T Folder; + MDNode *DefaultFPMathTag; public: - IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) - : IRBuilderBase(C), Inserter(I), Folder(F) { + IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(), + MDNode *FPMathTag = 0) + : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) { } - explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder() { + explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C), + Folder(), DefaultFPMathTag(FPMathTag) { } - explicit IRBuilder(BasicBlock *TheBB, const T &F) - : IRBuilderBase(TheBB->getContext()), Folder(F) { + explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(F), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB); } - explicit IRBuilder(BasicBlock *TheBB) - : IRBuilderBase(TheBB->getContext()), Folder() { + explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB); } - explicit IRBuilder(Instruction *IP) - : IRBuilderBase(IP->getContext()), Folder() { + explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0) + : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { SetInsertPoint(IP); SetCurrentDebugLocation(IP->getDebugLoc()); } - explicit IRBuilder(Use &U) - : IRBuilderBase(U->getContext()), Folder() { + explicit IRBuilder(Use &U, MDNode *FPMathTag = 0) + : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) { SetInsertPoint(U); SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc()); } - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) - : IRBuilderBase(TheBB->getContext()), Folder(F) { + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F, + MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(F), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB, IP); } - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : IRBuilderBase(TheBB->getContext()), Folder() { + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0) + : IRBuilderBase(TheBB->getContext()), Folder(), + DefaultFPMathTag(FPMathTag) { SetInsertPoint(TheBB, IP); } /// getFolder - Get the constant folder being used. const T &getFolder() { return Folder; } + /// getDefaultFPMathTag - Get the floating point math metadata being used. + MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; } + + /// SetDefaultFPMathTag - Set the floating point math metadata to be used. + void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; } + /// isNamePreserving - Return true if this builder is configured to actually /// add the requested names to IR created through it. bool isNamePreserving() const { return preserveNames; } @@ -496,6 +511,14 @@ private: if (HasNSW) BO->setHasNoSignedWrap(); return BO; } + + Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const { + if (!FPMathTag) + FPMathTag = DefaultFPMathTag; + if (FPMathTag) + I->setMetadata(LLVMContext::MD_fpmath, FPMathTag); + return I; + } public: Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -511,11 +534,13 @@ public: Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateAdd(LHS, RHS, Name, true, false); } - Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFAdd(LC, RC), Name); - return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS), + FPMathTag), Name); } Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -531,11 +556,13 @@ public: Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSub(LHS, RHS, Name, true, false); } - Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFSub(LC, RC), Name); - return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS), + FPMathTag), Name); } Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "", bool HasNUW = false, bool HasNSW = false) { @@ -551,11 +578,13 @@ public: Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateMul(LHS, RHS, Name, true, false); } - Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFMul(LC, RC), Name); - return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS), + FPMathTag), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", bool isExact = false) { @@ -581,11 +610,13 @@ public: Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSDiv(LHS, RHS, Name, true); } - Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFDiv(LC, RC), Name); - return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS), + FPMathTag), Name); } Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast<Constant>(LHS)) @@ -599,11 +630,13 @@ public: return Insert(Folder.CreateSRem(LC, RC), Name); return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); } - Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = 0) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFRem(LC, RC), Name); - return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS), + FPMathTag), Name); } Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "", @@ -729,10 +762,10 @@ public: Value *CreateNUWNeg(Value *V, const Twine &Name = "") { return CreateNeg(V, Name, true, false); } - Value *CreateFNeg(Value *V, const Twine &Name = "") { + Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) { if (Constant *VC = dyn_cast<Constant>(V)) return Insert(Folder.CreateFNeg(VC), Name); - return Insert(BinaryOperator::CreateFNeg(V), Name); + return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name); } Value *CreateNot(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast<Constant>(V)) diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 2001456..52de8f6 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -14,6 +14,7 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -161,7 +162,6 @@ public: RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);} RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} - RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} @@ -187,7 +187,6 @@ public: RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);} RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);} RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);} - RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction);} RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);} RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);} @@ -196,6 +195,15 @@ public: RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } + // Call and Invoke are slightly different as they delegate first through + // a generic CallSite visitor. + RetTy visitCallInst(CallInst &I) { + return static_cast<SubClass*>(this)->visitCallSite(&I); + } + RetTy visitInvokeInst(InvokeInst &I) { + return static_cast<SubClass*>(this)->visitCallSite(&I); + } + // Next level propagators: If the user does not overload a specific // instruction type, they can overload one of these to get the whole class // of instructions... @@ -206,6 +214,19 @@ public: RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction);} RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);} + // Provide a special visitor for a 'callsite' that visits both calls and + // invokes. When unimplemented, properly delegates to either the terminator or + // regular instruction visitor. + RetTy visitCallSite(CallSite CS) { + assert(CS); + Instruction &I = *CS.getInstruction(); + if (CS.isCall()) + DELEGATE(Instruction); + + assert(CS.isInvoke()); + DELEGATE(TerminatorInst); + } + // If the user wants a 'default' case, they can choose to override this // function. If this function is not overloaded in the user's subclass, then // this instruction just gets ignored. diff --git a/include/llvm/Support/JSONParser.h b/include/llvm/Support/JSONParser.h deleted file mode 100644 index 11149f1..0000000 --- a/include/llvm/Support/JSONParser.h +++ /dev/null @@ -1,448 +0,0 @@ -//===--- JSONParser.h - Simple JSON parser ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements a JSON parser. -// -// See http://www.json.org/ for an overview. -// See http://www.ietf.org/rfc/rfc4627.txt for the full standard. -// -// FIXME: Currently this supports a subset of JSON. Specifically, support -// for numbers, booleans and null for values is missing. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_JSON_PARSER_H -#define LLVM_SUPPORT_JSON_PARSER_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SourceMgr.h" - -namespace llvm { - -class JSONContainer; -class JSONString; -class JSONValue; -class JSONKeyValuePair; - -/// \brief Base class for a parsable JSON atom. -/// -/// This class has no semantics other than being a unit of JSON data which can -/// be parsed out of a JSON document. -class JSONAtom { -public: - /// \brief Possible types of JSON objects. - enum Kind { JK_KeyValuePair, JK_Array, JK_Object, JK_String }; - - /// \brief Returns the type of this value. - Kind getKind() const { return MyKind; } - - static bool classof(const JSONAtom *Atom) { return true; } - -protected: - JSONAtom(Kind MyKind) : MyKind(MyKind) {} - -private: - Kind MyKind; -}; - -/// \brief A parser for JSON text. -/// -/// Use an object of JSONParser to iterate over the values of a JSON text. -/// All objects are parsed during the iteration, so you can only iterate once -/// over the JSON text, but the cost of partial iteration is minimized. -/// Create a new JSONParser if you want to iterate multiple times. -class JSONParser { -public: - /// \brief Create a JSONParser for the given input. - /// - /// Parsing is started via parseRoot(). Access to the object returned from - /// parseRoot() will parse the input lazily. - JSONParser(StringRef Input, SourceMgr *SM); - - /// \brief Returns the outermost JSON value (either an array or an object). - /// - /// Can return NULL if the input does not start with an array or an object. - /// The object is not parsed yet - the caller must iterate over the - /// returned object to trigger parsing. - /// - /// A JSONValue can be either a JSONString, JSONObject or JSONArray. - JSONValue *parseRoot(); - - /// \brief Parses the JSON text and returns whether it is valid JSON. - /// - /// In case validate() return false, failed() will return true and - /// getErrorMessage() will return the parsing error. - bool validate(); - - /// \brief Returns true if an error occurs during parsing. - /// - /// If there was an error while parsing an object that was created by - /// iterating over the result of 'parseRoot', 'failed' will return true. - bool failed() const; - -private: - /// \brief These methods manage the implementation details of parsing new JSON - /// atoms. - /// @{ - JSONString *parseString(); - JSONValue *parseValue(); - JSONKeyValuePair *parseKeyValuePair(); - /// @} - - /// \brief Helpers to parse the elements out of both forms of containers. - /// @{ - const JSONAtom *parseElement(JSONAtom::Kind ContainerKind); - StringRef::iterator parseFirstElement(JSONAtom::Kind ContainerKind, - char StartChar, char EndChar, - const JSONAtom *&Element); - StringRef::iterator parseNextElement(JSONAtom::Kind ContainerKind, - char EndChar, - const JSONAtom *&Element); - /// @} - - /// \brief Whitespace parsing. - /// @{ - void nextNonWhitespace(); - bool isWhitespace(); - /// @} - - /// \brief These methods are used for error handling. - /// { - void setExpectedError(StringRef Expected, StringRef Found); - void setExpectedError(StringRef Expected, char Found); - bool errorIfAtEndOfFile(StringRef Message); - bool errorIfNotAt(char C, StringRef Message); - /// } - - /// \brief Skips all elements in the given container. - bool skipContainer(const JSONContainer &Container); - - /// \brief Skips to the next position behind the given JSON atom. - bool skip(const JSONAtom &Atom); - - /// All nodes are allocated by the parser and will be deallocated when the - /// parser is destroyed. - BumpPtrAllocator ValueAllocator; - - /// \brief The original input to the parser. - MemoryBuffer *InputBuffer; - - /// \brief The source manager used for diagnostics and buffer management. - SourceMgr *SM; - - /// \brief The current position in the parse stream. - StringRef::iterator Position; - - /// \brief The end position for fast EOF checks without introducing - /// unnecessary dereferences. - StringRef::iterator End; - - /// \brief If true, an error has occurred. - bool Failed; - - friend class JSONContainer; -}; - - -/// \brief Base class for JSON value objects. -/// -/// This object represents an abstract JSON value. It is the root node behind -/// the group of JSON entities that can represent top-level values in a JSON -/// document. It has no API, and is just a placeholder in the type hierarchy of -/// nodes. -class JSONValue : public JSONAtom { -protected: - JSONValue(Kind MyKind) : JSONAtom(MyKind) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - switch (Atom->getKind()) { - case JK_Array: - case JK_Object: - case JK_String: - return true; - case JK_KeyValuePair: - return false; - } - llvm_unreachable("Invalid JSONAtom kind"); - } - static bool classof(const JSONValue *Value) { return true; } - ///@} -}; - -/// \brief Gives access to the text of a JSON string. -/// -/// FIXME: Implement a method to return the unescaped text. -class JSONString : public JSONValue { -public: - /// \brief Returns the underlying parsed text of the string. - /// - /// This is the unescaped content of the JSON text. - /// See http://www.ietf.org/rfc/rfc4627.txt for details. - StringRef getRawText() const { return RawText; } - -private: - JSONString(StringRef RawText) : JSONValue(JK_String), RawText(RawText) {} - - StringRef RawText; - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JK_String; - } - static bool classof(const JSONString *String) { return true; } - ///@} -}; - -/// \brief A (key, value) tuple of type (JSONString *, JSONValue *). -/// -/// Note that JSONKeyValuePair is not a JSONValue, it is a bare JSONAtom. -/// JSONKeyValuePairs can be elements of a JSONObject, but not of a JSONArray. -/// They are not viable as top-level values either. -class JSONKeyValuePair : public JSONAtom { -public: - const JSONString * const Key; - const JSONValue * const Value; - -private: - JSONKeyValuePair(const JSONString *Key, const JSONValue *Value) - : JSONAtom(JK_KeyValuePair), Key(Key), Value(Value) {} - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JK_KeyValuePair; - } - static bool classof(const JSONKeyValuePair *KeyValuePair) { return true; } - ///@} -}; - -/// \brief Implementation of JSON containers (arrays and objects). -/// -/// JSONContainers drive the lazy parsing of JSON arrays and objects via -/// forward iterators. -class JSONContainer : public JSONValue { -private: - /// \brief An iterator that parses the underlying container during iteration. - /// - /// Iterators on the same collection use shared state, so when multiple copies - /// of an iterator exist, only one is allowed to be used for iteration; - /// iterating multiple copies of an iterator of the same collection will lead - /// to undefined behavior. - class AtomIterator { - public: - AtomIterator(const AtomIterator &I) : Container(I.Container) {} - - /// \brief Iterator interface. - ///@{ - bool operator==(const AtomIterator &I) const { - if (isEnd() || I.isEnd()) - return isEnd() == I.isEnd(); - return Container->Position == I.Container->Position; - } - bool operator!=(const AtomIterator &I) const { - return !(*this == I); - } - AtomIterator &operator++() { - Container->parseNextElement(); - return *this; - } - const JSONAtom *operator*() { - return Container->Current; - } - ///@} - - private: - /// \brief Create an iterator for which 'isEnd' returns true. - AtomIterator() : Container(0) {} - - /// \brief Create an iterator for the given container. - AtomIterator(const JSONContainer *Container) : Container(Container) {} - - bool isEnd() const { - return Container == 0 || Container->Position == StringRef::iterator(); - } - - const JSONContainer * const Container; - - friend class JSONContainer; - }; - -protected: - /// \brief An iterator for the specified AtomT. - /// - /// Used for the implementation of iterators for JSONArray and JSONObject. - template <typename AtomT> - class IteratorTemplate : public std::iterator<std::forward_iterator_tag, - const AtomT*> { - public: - explicit IteratorTemplate(const AtomIterator& AtomI) - : AtomI(AtomI) {} - - bool operator==(const IteratorTemplate &I) const { - return AtomI == I.AtomI; - } - bool operator!=(const IteratorTemplate &I) const { return !(*this == I); } - - IteratorTemplate &operator++() { - ++AtomI; - return *this; - } - - const AtomT *operator*() { return dyn_cast<AtomT>(*AtomI); } - - private: - AtomIterator AtomI; - }; - - JSONContainer(JSONParser *Parser, char StartChar, char EndChar, - JSONAtom::Kind ContainerKind) - : JSONValue(ContainerKind), Parser(Parser), - Position(), Current(0), Started(false), - StartChar(StartChar), EndChar(EndChar) {} - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - AtomIterator atom_begin() const { - if (Started) - report_fatal_error("Cannot parse container twice."); - Started = true; - // Set up the position and current element when we begin iterating over the - // container. - Position = Parser->parseFirstElement(getKind(), StartChar, EndChar, Current); - return AtomIterator(this); - } - AtomIterator atom_end() const { - return AtomIterator(); - } - -private: - AtomIterator atom_current() const { - if (!Started) - return atom_begin(); - - return AtomIterator(this); - } - - /// \brief Parse the next element in the container into the Current element. - /// - /// This routine is called as an iterator into this container walks through - /// its elements. It mutates the container's internal current node to point to - /// the next atom of the container. - void parseNextElement() const { - Parser->skip(*Current); - Position = Parser->parseNextElement(getKind(), EndChar, Current); - } - - // For parsing, JSONContainers call back into the JSONParser. - JSONParser * const Parser; - - // 'Position', 'Current' and 'Started' store the state of the parse stream - // for iterators on the container, they don't change the container's elements - // and are thus marked as mutable. - mutable StringRef::iterator Position; - mutable const JSONAtom *Current; - mutable bool Started; - - const char StartChar; - const char EndChar; - - friend class JSONParser; - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - switch (Atom->getKind()) { - case JK_Array: - case JK_Object: - return true; - case JK_KeyValuePair: - case JK_String: - return false; - } - llvm_unreachable("Invalid JSONAtom kind"); - } - static bool classof(const JSONContainer *Container) { return true; } - ///@} -}; - -/// \brief A simple JSON array. -class JSONArray : public JSONContainer { -public: - typedef IteratorTemplate<JSONValue> const_iterator; - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - const_iterator begin() const { return const_iterator(atom_begin()); } - const_iterator end() const { return const_iterator(atom_end()); } - -private: - JSONArray(JSONParser *Parser) - : JSONContainer(Parser, '[', ']', JSONAtom::JK_Array) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JSONAtom::JK_Array; - } - static bool classof(const JSONArray *Array) { return true; } - ///@} - - friend class JSONParser; -}; - -/// \brief A JSON object: an iterable list of JSON key-value pairs. -class JSONObject : public JSONContainer { -public: - typedef IteratorTemplate<JSONKeyValuePair> const_iterator; - - /// \brief Returns a lazy parsing iterator over the container. - /// - /// As the iterator drives the parse stream, begin() must only be called - /// once per container. - const_iterator begin() const { return const_iterator(atom_begin()); } - const_iterator end() const { return const_iterator(atom_end()); } - -private: - JSONObject(JSONParser *Parser) - : JSONContainer(Parser, '{', '}', JSONAtom::JK_Object) {} - -public: - /// \brief dyn_cast helpers - ///@{ - static bool classof(const JSONAtom *Atom) { - return Atom->getKind() == JSONAtom::JK_Object; - } - static bool classof(const JSONObject *Object) { return true; } - ///@} - - friend class JSONParser; -}; - -} // end namespace llvm - -#endif // LLVM_SUPPORT_JSON_PARSER_H diff --git a/include/llvm/Support/Locale.h b/include/llvm/Support/Locale.h new file mode 100644 index 0000000..b0f1295 --- /dev/null +++ b/include/llvm/Support/Locale.h @@ -0,0 +1,17 @@ +#ifndef LLVM_SUPPORT_LOCALE +#define LLVM_SUPPORT_LOCALE + +#include "llvm/ADT/StringRef.h" + +namespace llvm { +namespace sys { +namespace locale { + +int columnWidth(StringRef s); +bool isPrint(int c); + +} +} +} + +#endif // LLVM_SUPPORT_LOCALE diff --git a/include/llvm/Support/MDBuilder.h b/include/llvm/Support/MDBuilder.h new file mode 100644 index 0000000..40f028a --- /dev/null +++ b/include/llvm/Support/MDBuilder.h @@ -0,0 +1,118 @@ +//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- 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 the MDBuilder class, which is used as a convenient way to +// create LLVM metadata with a consistent and simplified interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MDBUILDER_H +#define LLVM_SUPPORT_MDBUILDER_H + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" +#include "llvm/ADT/APInt.h" + +namespace llvm { + + class MDBuilder { + LLVMContext &Context; + + public: + MDBuilder(LLVMContext &context) : Context(context) {} + + /// \brief Return the given string as metadata. + MDString *createString(StringRef Str) { + return MDString::get(Context, Str); + } + + //===------------------------------------------------------------------===// + // FPMath metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata with the given settings. The special value 0.0 + /// for the Accuracy parameter indicates the default (maximal precision) + /// setting. + MDNode *createFPMath(float Accuracy) { + if (Accuracy == 0.0) + return 0; + assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); + Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); + return MDNode::get(Context, Op); + } + + + //===------------------------------------------------------------------===// + // Range metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata describing the range [Lo, Hi). + MDNode *createRange(const APInt &Lo, const APInt &Hi) { + assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); + // If the range is everything then it is useless. + if (Hi == Lo) + return 0; + + // Return the range [Lo, Hi). + Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); + Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; + return MDNode::get(Context, Range); + } + + + //===------------------------------------------------------------------===// + // TBAA metadata. + //===------------------------------------------------------------------===// + + /// \brief Return metadata appropriate for a TBAA root node. Each returned + /// node is distinct from all other metadata and will never be identified + /// (uniqued) with anything else. + MDNode *createAnonymousTBAARoot() { + // To ensure uniqueness the root node is self-referential. + MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); + MDNode *Root = MDNode::get(Context, Dummy); + // At this point we have + // !0 = metadata !{} <- dummy + // !1 = metadata !{metadata !0} <- root + // Replace the dummy operand with the root node itself and delete the dummy. + Root->replaceOperandWith(0, Root); + MDNode::deleteTemporary(Dummy); + // We now have + // !1 = metadata !{metadata !1} <- self-referential root + return Root; + } + + /// \brief Return metadata appropriate for a TBAA root node with the given + /// name. This may be identified (uniqued) with other roots with the same + /// name. + MDNode *createTBAARoot(StringRef Name) { + return MDNode::get(Context, createString(Name)); + } + + /// \brief Return metadata for a non-root TBAA node with the given name, + /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. + MDNode *createTBAANode(StringRef Name, MDNode *Parent, + bool isConstant = false) { + if (isConstant) { + Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); + Value *Ops[3] = { createString(Name), Parent, Flags }; + return MDNode::get(Context, Ops); + } else { + Value *Ops[2] = { createString(Name), Parent }; + return MDNode::get(Context, Ops); + } + } + + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 3379922..d796b79 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -136,6 +136,10 @@ namespace sys { /// Same as OutputColor, but only enables the bold attribute. static const char *OutputBold(bool bg); + /// This function returns the escape sequence to reverse forground and + /// background colors. + static const char *OutputReverse(); + /// Resets the terminals colors, or returns an escape sequence to do so. static const char *ResetColor(); /// @} diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 58b8fab..76967db 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -128,8 +128,11 @@ public: /// PrintMessage - Emit a message about the specified location with the /// specified string. /// + /// @param ShowColors - Display colored messages if output is a terminal and + /// the default error handler is used. void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, - ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const; + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + bool ShowColors = true) const; /// GetMessage - Return an SMDiagnostic at the specified location with the @@ -188,7 +191,7 @@ public: const std::vector<std::pair<unsigned, unsigned> > &getRanges() const { return Ranges; } - void print(const char *ProgName, raw_ostream &S) const; + void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const; }; } // end llvm namespace diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 93bdbca..8808130 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -104,6 +104,7 @@ namespace llvm { typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, + const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI); typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, @@ -393,11 +394,12 @@ namespace llvm { MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, const MCAsmInfo &MAI, + const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MRI, STI); + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI); } diff --git a/include/llvm/Support/TargetSelect.h b/include/llvm/Support/TargetSelect.h index 83ff68c..a86e953 100644 --- a/include/llvm/Support/TargetSelect.h +++ b/include/llvm/Support/TargetSelect.h @@ -149,6 +149,18 @@ namespace llvm { #endif } + /// InitializeNativeTargetDisassembler - The main program should call + /// this function to initialize the native target disassembler. + inline bool InitializeNativeTargetDisassembler() { + // If we have a native target, initialize the corresponding disassembler. +#ifdef LLVM_NATIVE_DISASSEMBLER + LLVM_NATIVE_DISASSEMBLER(); + return false; +#else + return true; +#endif + } + } #endif diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index c0cdc35..b7210b2 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -49,52 +49,61 @@ protected: Tracking, Weak }; -private: +private: PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; ValueHandleBase *Next; - Value *VP; + + // A subclass may want to store some information along with the value + // pointer. Allow them to do this by making the value pointer a pointer-int + // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this + // access. + PointerIntPair<Value*, 2> VP; explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT. public: explicit ValueHandleBase(HandleBaseKind Kind) - : PrevPair(0, Kind), Next(0), VP(0) {} + : PrevPair(0, Kind), Next(0), VP(0, 0) {} ValueHandleBase(HandleBaseKind Kind, Value *V) - : PrevPair(0, Kind), Next(0), VP(V) { - if (isValid(VP)) + : PrevPair(0, Kind), Next(0), VP(V, 0) { + if (isValid(VP.getPointer())) AddToUseList(); } ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) : PrevPair(0, Kind), Next(0), VP(RHS.VP) { - if (isValid(VP)) + if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr()); } ~ValueHandleBase() { - if (isValid(VP)) + if (isValid(VP.getPointer())) RemoveFromUseList(); } Value *operator=(Value *RHS) { - if (VP == RHS) return RHS; - if (isValid(VP)) RemoveFromUseList(); - VP = RHS; - if (isValid(VP)) AddToUseList(); + if (VP.getPointer() == RHS) return RHS; + if (isValid(VP.getPointer())) RemoveFromUseList(); + VP.setPointer(RHS); + if (isValid(VP.getPointer())) AddToUseList(); return RHS; } Value *operator=(const ValueHandleBase &RHS) { - if (VP == RHS.VP) return RHS.VP; - if (isValid(VP)) RemoveFromUseList(); - VP = RHS.VP; - if (isValid(VP)) AddToExistingUseList(RHS.getPrevPtr()); - return VP; + if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer(); + if (isValid(VP.getPointer())) RemoveFromUseList(); + VP.setPointer(RHS.VP.getPointer()); + if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr()); + return VP.getPointer(); } Value *operator->() const { return getValPtr(); } Value &operator*() const { return *getValPtr(); } protected: - Value *getValPtr() const { return VP; } + Value *getValPtr() const { return VP.getPointer(); } + + void setValPtrInt(unsigned K) { VP.setInt(K); } + unsigned getValPtrInt() const { return VP.getInt(); } + static bool isValid(Value *V) { return V && V != DenseMapInfo<Value *>::getEmptyKey() && diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h new file mode 100644 index 0000000..47206b3 --- /dev/null +++ b/include/llvm/Support/YAMLParser.h @@ -0,0 +1,552 @@ +//===--- YAMLParser.h - Simple YAML parser --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a YAML 1.2 parser. +// +// See http://www.yaml.org/spec/1.2/spec.html for the full standard. +// +// This currently does not implement the following: +// * Multi-line literal folding. +// * Tag resolution. +// * UTF-16. +// * BOMs anywhere other than the first Unicode scalar value in the file. +// +// The most important class here is Stream. This represents a YAML stream with +// 0, 1, or many documents. +// +// SourceMgr sm; +// StringRef input = getInput(); +// yaml::Stream stream(input, sm); +// +// for (yaml::document_iterator di = stream.begin(), de = stream.end(); +// di != de; ++di) { +// yaml::Node *n = di->getRoot(); +// if (n) { +// // Do something with n... +// } else +// break; +// } +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_YAML_PARSER_H +#define LLVM_SUPPORT_YAML_PARSER_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/SMLoc.h" + +#include <limits> +#include <utility> + +namespace llvm { +class MemoryBuffer; +class SourceMgr; +class raw_ostream; +class Twine; + +namespace yaml { + +class document_iterator; +class Document; +class Node; +class Scanner; +struct Token; + +/// @brief Dump all the tokens in this stream to OS. +/// @returns true if there was an error, false otherwise. +bool dumpTokens(StringRef Input, raw_ostream &); + +/// @brief Scans all tokens in input without outputting anything. This is used +/// for benchmarking the tokenizer. +/// @returns true if there was an error, false otherwise. +bool scanTokens(StringRef Input); + +/// @brief Escape \a Input for a double quoted scalar. +std::string escape(StringRef Input); + +/// @brief This class represents a YAML stream potentially containing multiple +/// documents. +class Stream { +public: + Stream(StringRef Input, SourceMgr &); + ~Stream(); + + document_iterator begin(); + document_iterator end(); + void skip(); + bool failed(); + bool validate() { + skip(); + return !failed(); + } + + void printError(Node *N, const Twine &Msg); + +private: + OwningPtr<Scanner> scanner; + OwningPtr<Document> CurrentDoc; + + friend class Document; + + /// @brief Validate a %YAML x.x directive. + void handleYAMLDirective(const Token &); +}; + +/// @brief Abstract base class for all Nodes. +class Node { +public: + enum NodeKind { + NK_Null, + NK_Scalar, + NK_KeyValue, + NK_Mapping, + NK_Sequence, + NK_Alias + }; + + Node(unsigned int Type, OwningPtr<Document>&, StringRef Anchor); + + /// @brief Get the value of the anchor attached to this node. If it does not + /// have one, getAnchor().size() will be 0. + StringRef getAnchor() const { return Anchor; } + + SMRange getSourceRange() const { return SourceRange; } + void setSourceRange(SMRange SR) { SourceRange = SR; } + + // These functions forward to Document and Scanner. + Token &peekNext(); + Token getNext(); + Node *parseBlockNode(); + BumpPtrAllocator &getAllocator(); + void setError(const Twine &Message, Token &Location) const; + bool failed() const; + + virtual void skip() {}; + + unsigned int getType() const { return TypeID; } + static inline bool classof(const Node *) { return true; } + + void *operator new ( size_t Size + , BumpPtrAllocator &Alloc + , size_t Alignment = 16) throw() { + return Alloc.Allocate(Size, Alignment); + } + + void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() { + Alloc.Deallocate(Ptr); + } + +protected: + OwningPtr<Document> &Doc; + SMRange SourceRange; + + void operator delete(void *) throw() {} + + virtual ~Node() {} + +private: + unsigned int TypeID; + StringRef Anchor; +}; + +/// @brief A null value. +/// +/// Example: +/// !!null null +class NullNode : public Node { +public: + NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {} + + static inline bool classof(const NullNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_Null; + } +}; + +/// @brief A scalar node is an opaque datum that can be presented as a +/// series of zero or more Unicode scalar values. +/// +/// Example: +/// Adena +class ScalarNode : public Node { +public: + ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val) + : Node(NK_Scalar, D, Anchor) + , Value(Val) { + SMLoc Start = SMLoc::getFromPointer(Val.begin()); + SMLoc End = SMLoc::getFromPointer(Val.end() - 1); + SourceRange = SMRange(Start, End); + } + + // Return Value without any escaping or folding or other fun YAML stuff. This + // is the exact bytes that are contained in the file (after conversion to + // utf8). + StringRef getRawValue() const { return Value; } + + /// @brief Gets the value of this node as a StringRef. + /// + /// @param Storage is used to store the content of the returned StringRef iff + /// it requires any modification from how it appeared in the source. + /// This happens with escaped characters and multi-line literals. + StringRef getValue(SmallVectorImpl<char> &Storage) const; + + static inline bool classof(const ScalarNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_Scalar; + } + +private: + StringRef Value; + + StringRef unescapeDoubleQuoted( StringRef UnquotedValue + , StringRef::size_type Start + , SmallVectorImpl<char> &Storage) const; +}; + +/// @brief A key and value pair. While not technically a Node under the YAML +/// representation graph, it is easier to treat them this way. +/// +/// TODO: Consider making this not a child of Node. +/// +/// Example: +/// Section: .text +class KeyValueNode : public Node { +public: + KeyValueNode(OwningPtr<Document> &D) + : Node(NK_KeyValue, D, StringRef()) + , Key(0) + , Value(0) + {} + + /// @brief Parse and return the key. + /// + /// This may be called multiple times. + /// + /// @returns The key, or nullptr if failed() == true. + Node *getKey(); + + /// @brief Parse and return the value. + /// + /// This may be called multiple times. + /// + /// @returns The value, or nullptr if failed() == true. + Node *getValue(); + + virtual void skip() { + getKey()->skip(); + getValue()->skip(); + } + + static inline bool classof(const KeyValueNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_KeyValue; + } + +private: + Node *Key; + Node *Value; +}; + +/// @brief This is an iterator abstraction over YAML collections shared by both +/// sequences and maps. +/// +/// BaseT must have a ValueT* member named CurrentEntry and a member function +/// increment() which must set CurrentEntry to 0 to create an end iterator. +template <class BaseT, class ValueT> +class basic_collection_iterator + : public std::iterator<std::forward_iterator_tag, ValueT> { +public: + basic_collection_iterator() : Base(0) {} + basic_collection_iterator(BaseT *B) : Base(B) {} + + ValueT *operator ->() const { + assert(Base && Base->CurrentEntry && "Attempted to access end iterator!"); + return Base->CurrentEntry; + } + + ValueT &operator *() const { + assert(Base && Base->CurrentEntry && + "Attempted to dereference end iterator!"); + return *Base->CurrentEntry; + } + + operator ValueT*() const { + assert(Base && Base->CurrentEntry && "Attempted to access end iterator!"); + return Base->CurrentEntry; + } + + bool operator !=(const basic_collection_iterator &Other) const { + if(Base != Other.Base) + return true; + return (Base && Other.Base) && Base->CurrentEntry + != Other.Base->CurrentEntry; + } + + basic_collection_iterator &operator++() { + assert(Base && "Attempted to advance iterator past end!"); + Base->increment(); + // Create an end iterator. + if (Base->CurrentEntry == 0) + Base = 0; + return *this; + } + +private: + BaseT *Base; +}; + +// The following two templates are used for both MappingNode and Sequence Node. +template <class CollectionType> +typename CollectionType::iterator begin(CollectionType &C) { + assert(C.IsAtBeginning && "You may only iterate over a collection once!"); + C.IsAtBeginning = false; + typename CollectionType::iterator ret(&C); + ++ret; + return ret; +} + +template <class CollectionType> +void skip(CollectionType &C) { + // TODO: support skipping from the middle of a parsed collection ;/ + assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!"); + if (C.IsAtBeginning) + for (typename CollectionType::iterator i = begin(C), e = C.end(); + i != e; ++i) + i->skip(); +} + +/// @brief Represents a YAML map created from either a block map for a flow map. +/// +/// This parses the YAML stream as increment() is called. +/// +/// Example: +/// Name: _main +/// Scope: Global +class MappingNode : public Node { +public: + enum MappingType { + MT_Block, + MT_Flow, + MT_Inline //< An inline mapping node is used for "[key: value]". + }; + + MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT) + : Node(NK_Mapping, D, Anchor) + , Type(MT) + , IsAtBeginning(true) + , IsAtEnd(false) + , CurrentEntry(0) + {} + + friend class basic_collection_iterator<MappingNode, KeyValueNode>; + typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator; + template <class T> friend typename T::iterator yaml::begin(T &); + template <class T> friend void yaml::skip(T &); + + iterator begin() { + return yaml::begin(*this); + } + + iterator end() { return iterator(); } + + virtual void skip() { + yaml::skip(*this); + } + + static inline bool classof(const MappingNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_Mapping; + } + +private: + MappingType Type; + bool IsAtBeginning; + bool IsAtEnd; + KeyValueNode *CurrentEntry; + + void increment(); +}; + +/// @brief Represents a YAML sequence created from either a block sequence for a +/// flow sequence. +/// +/// This parses the YAML stream as increment() is called. +/// +/// Example: +/// - Hello +/// - World +class SequenceNode : public Node { +public: + enum SequenceType { + ST_Block, + ST_Flow, + // Use for: + // + // key: + // - val1 + // - val2 + // + // As a BlockMappingEntry and BlockEnd are not created in this case. + ST_Indentless + }; + + SequenceNode(OwningPtr<Document> &D, StringRef Anchor, SequenceType ST) + : Node(NK_Sequence, D, Anchor) + , SeqType(ST) + , IsAtBeginning(true) + , IsAtEnd(false) + , WasPreviousTokenFlowEntry(true) // Start with an imaginary ','. + , CurrentEntry(0) + {} + + friend class basic_collection_iterator<SequenceNode, Node>; + typedef basic_collection_iterator<SequenceNode, Node> iterator; + template <class T> friend typename T::iterator yaml::begin(T &); + template <class T> friend void yaml::skip(T &); + + void increment(); + + iterator begin() { + return yaml::begin(*this); + } + + iterator end() { return iterator(); } + + virtual void skip() { + yaml::skip(*this); + } + + static inline bool classof(const SequenceNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_Sequence; + } + +private: + SequenceType SeqType; + bool IsAtBeginning; + bool IsAtEnd; + bool WasPreviousTokenFlowEntry; + Node *CurrentEntry; +}; + +/// @brief Represents an alias to a Node with an anchor. +/// +/// Example: +/// *AnchorName +class AliasNode : public Node { +public: + AliasNode(OwningPtr<Document> &D, StringRef Val) + : Node(NK_Alias, D, StringRef()), Name(Val) {} + + StringRef getName() const { return Name; } + Node *getTarget(); + + static inline bool classof(const ScalarNode *) { return true; } + static inline bool classof(const Node *N) { + return N->getType() == NK_Alias; + } + +private: + StringRef Name; +}; + +/// @brief A YAML Stream is a sequence of Documents. A document contains a root +/// node. +class Document { +public: + /// @brief Root for parsing a node. Returns a single node. + Node *parseBlockNode(); + + Document(Stream &ParentStream); + + /// @brief Finish parsing the current document and return true if there are + /// more. Return false otherwise. + bool skip(); + + /// @brief Parse and return the root level node. + Node *getRoot() { + if (Root) + return Root; + return Root = parseBlockNode(); + } + +private: + friend class Node; + friend class document_iterator; + + /// @brief Stream to read tokens from. + Stream &stream; + + /// @brief Used to allocate nodes to. All are destroyed without calling their + /// destructor when the document is destroyed. + BumpPtrAllocator NodeAllocator; + + /// @brief The root node. Used to support skipping a partially parsed + /// document. + Node *Root; + + Token &peekNext(); + Token getNext(); + void setError(const Twine &Message, Token &Location) const; + bool failed() const; + + void handleTagDirective(const Token &Tag) { + // TODO: Track tags. + } + + /// @brief Parse %BLAH directives and return true if any were encountered. + bool parseDirectives(); + + /// @brief Consume the next token and error if it is not \a TK. + bool expectToken(int TK); +}; + +/// @brief Iterator abstraction for Documents over a Stream. +class document_iterator { +public: + document_iterator() : Doc(NullDoc) {} + document_iterator(OwningPtr<Document> &D) : Doc(D) {} + + bool operator ==(const document_iterator &Other) { + return Doc == Other.Doc; + } + bool operator !=(const document_iterator &Other) { + return !(*this == Other); + } + + document_iterator operator ++() { + if (!Doc->skip()) { + Doc.reset(0); + } else { + Stream &S = Doc->stream; + Doc.reset(new Document(S)); + } + return *this; + } + + Document &operator *() { + return *Doc; + } + + OwningPtr<Document> &operator ->() { + return Doc; + } + +private: + static OwningPtr<Document> NullDoc; + OwningPtr<Document> &Doc; +}; + +} +} + +#endif diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 6bfae5e..6c5d478 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -222,6 +222,9 @@ public: /// outputting colored text, or before program exit. virtual raw_ostream &resetColor() { return *this; } + /// Reverses the forground and background colors. + virtual raw_ostream &reverseColor() { return *this; } + /// This function determines if this stream is connected to a "tty" or /// "console" window. That is, the output would be displayed to the user /// rather than being put on a pipe or stored in a file. @@ -379,6 +382,8 @@ public: bool bg=false); virtual raw_ostream &resetColor(); + virtual raw_ostream &reverseColor(); + virtual bool is_displayed() const; /// has_error - Return the value of the flag in this raw_fd_ostream indicating diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 0cb8e97..a3a551f 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -66,7 +66,7 @@ struct isPodLike { // std::pair's are pod-like if their elements are. template<typename T, typename U> struct isPodLike<std::pair<T, U> > { - static const bool value = isPodLike<T>::value & isPodLike<U>::value; + static const bool value = isPodLike<T>::value && isPodLike<U>::value; }; diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h index c01b32b..fd5f805 100644 --- a/include/llvm/TableGen/Error.h +++ b/include/llvm/TableGen/Error.h @@ -29,6 +29,11 @@ public: const std::string &getMessage() const { return Message; } }; +void PrintWarning(SMLoc WarningLoc, const Twine &Msg); +void PrintWarning(const char *Loc, const Twine &Msg); +void PrintWarning(const Twine &Msg); +void PrintWarning(const TGError &Warning); + void PrintError(SMLoc ErrorLoc, const Twine &Msg); void PrintError(const char *Loc, const Twine &Msg); void PrintError(const Twine &Msg); diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 5e68c10..3aea1ae 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -454,7 +454,7 @@ public: /// without adding quote markers. This primaruly affects /// StringInits where we will not surround the string value with /// quotes. - virtual std::string getAsUnquotedString() const { return getAsString(); } + virtual std::string getAsUnquotedString() const { return getAsString(); } /// dump - Debugging method that may be called through a debugger, just /// invokes print on stderr. @@ -1529,7 +1529,7 @@ struct MultiClass { void dump() const; - MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : + MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : Rec(Name, Loc, Records) {} }; diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h index c1c118b..d5e165e 100644 --- a/include/llvm/Target/Mangler.h +++ b/include/llvm/Target/Mangler.h @@ -17,11 +17,9 @@ #include "llvm/ADT/DenseMap.h" namespace llvm { -class StringRef; class Twine; -class Value; class GlobalValue; -template <typename T> class SmallVectorImpl; +template <typename T> class SmallVectorImpl; class MCContext; class MCSymbol; class TargetData; diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h index b97f3e2..114295e 100644 --- a/include/llvm/Target/TargetELFWriterInfo.h +++ b/include/llvm/Target/TargetELFWriterInfo.h @@ -15,9 +15,6 @@ #define LLVM_TARGET_TARGETELFWRITERINFO_H namespace llvm { - class Function; - class TargetData; - class TargetMachine; //===--------------------------------------------------------------------===// // TargetELFWriterInfo diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 4c759b2..d56db7b 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -15,8 +15,6 @@ #define LLVM_TARGET_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/MC/MCDwarf.h" -#include "llvm/ADT/ArrayRef.h" #include <utility> #include <vector> @@ -24,8 +22,6 @@ namespace llvm { class CalleeSavedInfo; class MachineFunction; - class MachineBasicBlock; - class MachineMove; class RegScavenger; /// Information about stack frame layout on the target. It holds the direction diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h index 80b78f8..044afd9 100644 --- a/include/llvm/Target/TargetJITInfo.h +++ b/include/llvm/Target/TargetJITInfo.h @@ -17,9 +17,9 @@ #ifndef LLVM_TARGET_TARGETJITINFO_H #define LLVM_TARGET_TARGETJITINFO_H -#include <cassert> #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DataTypes.h" +#include <cassert> namespace llvm { class Function; diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index 70e26bf..c8cacf2 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -83,7 +83,7 @@ namespace llvm { /// long double expm1l(long double x); expm1l, /// float expm1f(float x); - expl1f, + expm1f, /// double fabs(double x); fabs, /// long double fabsl(long double x); @@ -159,8 +159,14 @@ namespace llvm { rint, /// float rintf(float x); rintf, - /// long dobule rintl(long double x); + /// long double rintl(long double x); rintl, + /// double round(double x); + round, + /// float roundf(float x); + roundf, + /// long double roundl(long double x); + roundl, /// double sin(double x); sin, /// long double sinl(long double x); diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 793b080..720c9df 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -25,7 +25,6 @@ #include "llvm/CallingConv.h" #include "llvm/InlineAsm.h" #include "llvm/Attributes.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/Support/DebugLoc.h" @@ -65,17 +64,6 @@ namespace llvm { }; } - // FIXME: should this be here? - namespace TLSModel { - enum Model { - GeneralDynamic, - LocalDynamic, - InitialExec, - LocalExec - }; - } - TLSModel::Model getTLSModel(const GlobalValue *GV, Reloc::Model reloc); - //===----------------------------------------------------------------------===// /// TargetLowering - This class defines information used to lower LLVM code to @@ -874,7 +862,6 @@ public: /// Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. virtual void computeMaskedBitsForTargetNode(const SDValue Op, - const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, @@ -1287,9 +1274,11 @@ public: } /// isUsedByReturnOnly - Return true if result of the specified node is used - /// by a return node only. This is used to determine whether it is possible + /// by a return node only. It also compute and return the input chain for the + /// tail call. + /// This is used to determine whether it is possible /// to codegen a libcall as tail call at legalization time. - virtual bool isUsedByReturnOnly(SDNode *) const { + virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const { return false; } @@ -1601,6 +1590,18 @@ public: return false; } + /// isFNegFree - Return true if an fneg operation is free to the point where + /// it is never worthwhile to replace it with a bitwise operation. + virtual bool isFNegFree(EVT) const { + return false; + } + + /// isFAbsFree - Return true if an fneg operation is free to the point where + /// it is never worthwhile to replace it with a bitwise operation. + virtual bool isFAbsFree(EVT) const { + return false; + } + /// isNarrowingProfitable - Return true if it's profitable to narrow /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow /// from i32 to i8 but not from i32 to i16. diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 88f28a6..d631f58 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -19,19 +19,15 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/SectionKind.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" namespace llvm { class MachineModuleInfo; class Mangler; - class MCAsmInfo; class MCContext; class MCExpr; class MCSection; - class MCSectionMachO; class MCSymbol; class MCStreamer; - class NamedMDNode; class GlobalValue; class TargetMachine; diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index d4535db..1a05604 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,8 +14,8 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H +#include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/ADT/StringRef.h" #include <cassert> #include <string> @@ -24,11 +24,10 @@ namespace llvm { class InstrItineraryData; class JITCodeEmitter; +class GlobalValue; class MCAsmInfo; class MCCodeGenInfo; class MCContext; -class Pass; -class PassManager; class PassManagerBase; class Target; class TargetData; @@ -197,6 +196,10 @@ public: /// medium, large, and target default. CodeModel::Model getCodeModel() const; + /// getTLSModel - Returns the TLS model which should be used for the given + /// global variable. + TLSModel::Model getTLSModel(const GlobalValue *GV) const; + /// getOptLevel - Returns the optimization level: None, Less, /// Default, or Aggressive. CodeGenOpt::Level getOptLevel() const; diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 7730ab9..12a2757 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -24,7 +24,7 @@ namespace llvm { // Possible float ABI settings. Used with FloatABIType in TargetOptions.h. namespace FloatABI { enum ABIType { - Default, // Target-specific (either soft of hard depending on triple, etc). + Default, // Target-specific (either soft or hard depending on triple, etc). Soft, // Soft float. Hard // Hard float. }; @@ -42,8 +42,8 @@ namespace llvm { GuaranteedTailCallOpt(false), DisableTailCalls(false), StackAlignmentOverride(0), RealignStack(true), DisableJumpTables(false), EnableFastISel(false), - EnableSegmentedStacks(false), TrapFuncName(""), - FloatABIType(FloatABI::Default) + PositionIndependentExecutable(false), EnableSegmentedStacks(false), + TrapFuncName(""), FloatABIType(FloatABI::Default) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -164,6 +164,12 @@ namespace llvm { /// compile time. unsigned EnableFastISel : 1; + /// PositionIndependentExecutable - This flag indicates whether the code + /// will eventually be linked into a single executable, despite the PIC + /// relocation model being in use. It's value is undefined (and irrelevant) + /// if the relocation model is anything other than PIC. + unsigned PositionIndependentExecutable : 1; + unsigned EnableSegmentedStacks : 1; /// getTrapFunctionName - If this returns a non-empty string, this means diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index c6e3086..6ddd364 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -202,6 +202,13 @@ struct TargetRegisterInfoDesc { bool inAllocatableClass; // Register belongs to an allocatable regclass. }; +/// Each TargetRegisterClass has a per register weight, and weight +/// limit which must be less than the limits of its pressure sets. +struct RegClassWeight { + unsigned RegWeight; + unsigned WeightLimit; +}; + /// TargetRegisterInfo base class - We assume that the target defines a static /// array of TargetRegisterDesc objects that represent all of the machine /// registers that the target has. As such, we simply have to track a pointer @@ -500,11 +507,30 @@ public: /// getRegPressureLimit - Return the register pressure "high water mark" for /// the specific register class. The scheduler is in high register pressure /// mode (for the specific register class) if it goes over the limit. + /// + /// Note: this is the old register pressure model that relies on a manually + /// specified representative register class per value type. virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const { return 0; } + /// Get the weight in units of pressure for this register class. + virtual const RegClassWeight &getRegClassWeight( + const TargetRegisterClass *RC) const = 0; + + /// Get the number of dimensions of register pressure. + virtual unsigned getNumRegPressureSets() const = 0; + + /// Get the register unit pressure limit for this dimension. + /// This limit must be adjusted dynamically for reserved registers. + virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0; + + /// Get the dimensions of register pressure impacted by this register class. + /// Returns a -1 terminated array of pressure set IDs. + virtual const int *getRegClassPressureSets( + const TargetRegisterClass *RC) const = 0; + /// getRawAllocationOrder - Returns the register allocation order for a /// specified register class with a target-dependent hint. The returned list /// may contain reserved registers that cannot be allocated. diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index d9d8ce4..fc23b2c 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -15,7 +15,7 @@ #define LLVM_TARGET_TARGETSUBTARGETINFO_H #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/CodeGen.h" namespace llvm { diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h index f59479d..7c3cfc8 100644 --- a/include/llvm/Transforms/IPO/InlinerPass.h +++ b/include/llvm/Transforms/IPO/InlinerPass.h @@ -65,20 +65,6 @@ struct Inliner : public CallGraphSCCPass { /// virtual InlineCost getInlineCost(CallSite CS) = 0; - // getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a - // higher threshold to determine if the function call should be inlined. - /// - virtual float getInlineFudgeFactor(CallSite CS) = 0; - - /// resetCachedCostInfo - erase any cached cost data from the derived class. - /// If the derived class has no such data this can be empty. - /// - virtual void resetCachedCostInfo(Function* Caller) = 0; - - /// growCachedCostInfo - update the cached cost info for Caller after Callee - /// has been inlined. - virtual void growCachedCostInfo(Function *Caller, Function *Callee) = 0; - /// removeDeadFunctions - Remove dead functions. /// /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index a1b4f5c..47ce902 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -73,6 +73,10 @@ public: /// cleanup-ish optimizations. EP_ScalarOptimizerLate, + /// EP_OptimizerLast -- This extension point allows adding passes that + /// run after everything else. + EP_OptimizerLast, + /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that /// should not be disabled by O0 optimization level. The passes will be /// inserted after the inlining pass. @@ -127,8 +131,9 @@ public: /// populateModulePassManager - This sets up the primary pass manager. void populateModulePassManager(PassManagerBase &MPM); void populateLTOPassManager(PassManagerBase &PM, bool Internalize, - bool RunInliner); + bool RunInliner, bool DisableGVNLoadPRE = false); }; + /// Registers a function for adding a standard set of passes. This should be /// used by optimizer plugins to allow all front ends to transparently use /// them. Create a static instance of this class in your plugin, providing a @@ -139,5 +144,6 @@ struct RegisterStandardPasses { PassManagerBuilder::addGlobalExtension(Ty, Fn); } }; + } // end namespace llvm #endif diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h index c9bd916..2632d18 100644 --- a/include/llvm/Transforms/Utils/SimplifyIndVar.h +++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -49,12 +49,6 @@ bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM, bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, LPPassManager *LPM, SmallVectorImpl<WeakVH> &Dead); -/// simplifyIVUsers - Simplify instructions recorded by the IVUsers pass. -/// This is a legacy implementation to reproduce the behavior of the -/// IndVarSimplify pass prior to DisableIVRewrite. -bool simplifyIVUsers(IVUsers *IU, ScalarEvolution *SE, LPPassManager *LPM, - SmallVectorImpl<WeakVH> &Dead); - } // namespace llvm #endif diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 0384656..8594707 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -20,7 +20,7 @@ namespace llvm { class Value; class Instruction; - typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy; + typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy; /// ValueMapTypeRemapper - This is a class that can be implemented by clients /// to remap types when cloning constants and instructions. diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h index dfc099d..652916c 100644 --- a/include/llvm/Transforms/Vectorize.h +++ b/include/llvm/Transforms/Vectorize.h @@ -16,14 +16,99 @@ #define LLVM_TRANSFORMS_VECTORIZE_H namespace llvm { - +class BasicBlock; class BasicBlockPass; //===----------------------------------------------------------------------===// +/// @brief Vectorize configuration. +struct VectorizeConfig { + //===--------------------------------------------------------------------===// + // Target architecture related parameters + + /// @brief The size of the native vector registers. + unsigned VectorBits; + + /// @brief Vectorize integer values. + bool VectorizeInts; + + /// @brief Vectorize floating-point values. + bool VectorizeFloats; + + /// @brief Vectorize pointer values. + bool VectorizePointers; + + /// @brief Vectorize casting (conversion) operations. + bool VectorizeCasts; + + /// @brief Vectorize floating-point math intrinsics. + bool VectorizeMath; + + /// @brief Vectorize the fused-multiply-add intrinsic. + bool VectorizeFMA; + + /// @brief Vectorize select instructions. + bool VectorizeSelect; + + /// @brief Vectorize getelementptr instructions. + bool VectorizeGEP; + + /// @brief Vectorize loads and stores. + bool VectorizeMemOps; + + /// @brief Only generate aligned loads and stores. + bool AlignedOnly; + + //===--------------------------------------------------------------------===// + // Misc parameters + + /// @brief The required chain depth for vectorization. + unsigned ReqChainDepth; + + /// @brief The maximum search distance for instruction pairs. + unsigned SearchLimit; + + /// @brief The maximum number of candidate pairs with which to use a full + /// cycle check. + unsigned MaxCandPairsForCycleCheck; + + /// @brief Replicating one element to a pair breaks the chain. + bool SplatBreaksChain; + + /// @brief The maximum number of pairable instructions per group. + unsigned MaxInsts; + + /// @brief The maximum number of pairing iterations. + unsigned MaxIter; + + /// @brief Don't boost the chain-depth contribution of loads and stores. + bool NoMemOpBoost; + + /// @brief Use a fast instruction dependency analysis. + bool FastDep; + + /// @brief Initialize the VectorizeConfig from command line options. + VectorizeConfig(); +}; + +//===----------------------------------------------------------------------===// // // BBVectorize - A basic-block vectorization pass. // -BasicBlockPass *createBBVectorizePass(); +BasicBlockPass * +createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); + +//===----------------------------------------------------------------------===// +/// @brief Vectorize the BasicBlock. +/// +/// @param BB The BasicBlock to be vectorized +/// @param P The current running pass, should require AliasAnalysis and +/// ScalarEvolution. After the vectorization, AliasAnalysis, +/// ScalarEvolution and CFG are preserved. +/// +/// @return True if the BB is changed, false otherwise. +/// +bool vectorizeBasicBlock(Pass *P, BasicBlock &BB, + const VectorizeConfig &C = VectorizeConfig()); } // End llvm namespace diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 380af0b..a82ac45 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -15,7 +15,6 @@ #define LLVM_VALUE_H #include "llvm/Use.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" namespace llvm { @@ -31,8 +30,6 @@ class GlobalAlias; class InlineAsm; class ValueSymbolTable; template<typename ValueTy> class StringMapEntry; -template <typename ValueTy = Value> -class AssertingVH; typedef StringMapEntry<Value*> ValueName; class raw_ostream; class AssemblyAnnotationWriter; @@ -41,6 +38,7 @@ class LLVMContext; class Twine; class MDNode; class Type; +class StringRef; //===----------------------------------------------------------------------===// // Value Class @@ -109,9 +107,10 @@ public: /// All values hold a context through their type. LLVMContext &getContext() const; - // All values can potentially be named... - bool hasName() const { return Name != 0; } + // All values can potentially be named. + bool hasName() const { return Name != 0 && SubclassID != MDStringVal; } ValueName *getValueName() const { return Name; } + void setValueName(ValueName *VN) { Name = VN; } /// getName() - Return a constant reference to the value's name. This is cheap /// and guaranteed to return the same reference as long as the value is not |