diff options
author | dim <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 |
commit | ece02cd5829cea836e9365b0845a8ef042d17b0a (patch) | |
tree | b3032e51d630e8070e9e08d6641648f195316a80 /include | |
parent | 2b066988909948dc3d53d01760bc2d71d32f3feb (diff) | |
download | FreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.zip FreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.tar.gz |
Vendor import of llvm trunk r132879:
http://llvm.org/svn/llvm-project/llvm/trunk@132879
Diffstat (limited to 'include')
80 files changed, 1860 insertions, 621 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 39c3cb4..2eccc11 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -282,6 +282,8 @@ typedef enum { LLVMRealPredicateTrue /**< Always true (always folded) */ } LLVMRealPredicate; +void LLVMInitializeCore(LLVMPassRegistryRef R); + /*===-- Error handling ----------------------------------------------------===*/ @@ -1164,6 +1166,7 @@ namespace llvm { for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I) cast<T>(*I); #endif + (void)Length; return reinterpret_cast<T**>(Vals); } diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index 9f10973..3a3eb23 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -7,16 +7,16 @@ |* *| |*===----------------------------------------------------------------------===*| |* *| -|* This header provides public interface to a disassembler library. *| +|* This header provides a public interface to a disassembler library. *| |* LLVM provides an implementation of this interface. *| |* *| \*===----------------------------------------------------------------------===*/ #ifndef LLVM_C_DISASSEMBLER_H -#define LLVM_C_DISASSEMBLER_H 1 +#define LLVM_C_DISASSEMBLER_H -#include <stddef.h> #include "llvm/Support/DataTypes.h" +#include <stddef.h> /** * An opaque reference to a disassembler context. @@ -38,14 +38,11 @@ typedef void *LLVMDisasmContextRef; * will be the instruction width. The information is returned in TagBuf and is * Triple specific with its specific information defined by the value of * TagType for that Triple. If symbolic information is returned the function - * returns 1 else it returns 0. + * returns 1, otherwise it returns 0. */ -typedef int (*LLVMOpInfoCallback)(void *DisInfo, - uint64_t PC, - uint64_t Offset, - uint64_t Size, - int TagType, - void *TagBuf); +typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, + uint64_t Offset, uint64_t Size, + int TagType, void *TagBuf); /** * The initial support in LLVM MC for the most general form of a relocatable @@ -68,10 +65,11 @@ typedef int (*LLVMOpInfoCallback)(void *DisInfo, * operands like "_foo@GOT", ":lower16:_foo", etc. */ struct LLVMOpInfoSymbol1 { - uint64_t Present; /* 1 if this symbol is present */ - char *Name; /* symbol name if not NULL */ - uint64_t Value; /* symbol value if name is NULL */ + uint64_t Present; /* 1 if this symbol is present */ + char *Name; /* symbol name if not NULL */ + uint64_t Value; /* symbol value if name is NULL */ }; + struct LLVMOpInfo1 { struct LLVMOpInfoSymbol1 AddSymbol; struct LLVMOpInfoSymbol1 SubtractSymbol; @@ -92,11 +90,11 @@ struct LLVMOpInfo1 { /** * The type for the symbol lookup function. This may be called by the - * disassembler for such things like adding a comment for a PC plus a constant + * disassembler for things like adding a comment for a PC plus a constant * offset load instruction to use a symbol name instead of a load address value. * It is passed the block information is saved when the disassembler context is * created and a value of a symbol to look up. If no symbol is found NULL is - * to be returned. + * returned. */ typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo, uint64_t SymbolValue); @@ -107,40 +105,33 @@ extern "C" { /** * Create a disassembler for the TripleName. Symbolic disassembly is supported - * by passing a block of information in the DisInfo parameter and specifing the - * TagType and call back functions as described above. These can all be passed - * as NULL. If successful this returns a disassembler context if not it + * by passing a block of information in the DisInfo parameter and specifying the + * TagType and callback functions as described above. These can all be passed + * as NULL. If successful, this returns a disassembler context. If not, it * returns NULL. */ -extern LLVMDisasmContextRef -LLVMCreateDisasm(const char *TripleName, - void *DisInfo, - int TagType, - LLVMOpInfoCallback GetOpInfo, - LLVMSymbolLookupCallback SymbolLookUp); +LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, + int TagType, LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); /** * Dispose of a disassembler context. */ -extern void -LLVMDisasmDispose(LLVMDisasmContextRef DC); +void LLVMDisasmDispose(LLVMDisasmContextRef DC); /** - * Disassmble a single instruction using the disassembler context specified in - * the parameter DC. The bytes of the instruction are specified in the parameter - * Bytes, and contains at least BytesSize number of bytes. The instruction is - * at the address specified by the PC parameter. If a valid instruction can be - * disassembled its string is returned indirectly in OutString which whos size - * is specified in the parameter OutStringSize. This function returns the - * number of bytes in the instruction or zero if there was no valid instruction. + * Disassemble a single instruction using the disassembler context specified in + * the parameter DC. The bytes of the instruction are specified in the + * parameter Bytes, and contains at least BytesSize number of bytes. The + * instruction is at the address specified by the PC parameter. If a valid + * instruction can be disassembled, its string is returned indirectly in + * OutString whose size is specified in the parameter OutStringSize. This + * function returns the number of bytes in the instruction or zero if there was + * no valid instruction. */ -extern size_t -LLVMDisasmInstruction(LLVMDisasmContextRef DC, - uint8_t *Bytes, - uint64_t BytesSize, - uint64_t PC, - char *OutString, - size_t OutStringSize); +size_t LLVMDisasmInstruction(LLVMDisasmContextRef DC, uint8_t *Bytes, + uint64_t BytesSize, uint64_t PC, + char *OutString, size_t OutStringSize); #ifdef __cplusplus } diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 52e0434..d2e0b8f 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -671,17 +671,10 @@ public: // Partial specializations of FoldingSetTrait. template<typename T> struct FoldingSetTrait<T*> { - static inline void Profile(const T *X, FoldingSetNodeID &ID) { + static inline void Profile(T *X, FoldingSetNodeID &ID) { ID.AddPointer(X); } }; - -template<typename T> struct FoldingSetTrait<const T*> { - static inline void Profile(const T *X, FoldingSetNodeID &ID) { - ID.AddPointer(X); - } -}; - } // End of namespace llvm. #endif diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h new file mode 100644 index 0000000..272322a --- /dev/null +++ b/include/llvm/ADT/PackedVector.h @@ -0,0 +1,158 @@ +//===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the PackedVector class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_PACKEDVECTOR_H +#define LLVM_ADT_PACKEDVECTOR_H + +#include "llvm/ADT/BitVector.h" +#include <limits> + +namespace llvm { + +template <typename T, unsigned BitNum, bool isSigned> +class PackedVectorBase; + +// This won't be necessary if we can specialize members without specializing +// the parent template. +template <typename T, unsigned BitNum> +class PackedVectorBase<T, BitNum, false> { +protected: + static T getValue(const llvm::BitVector &Bits, unsigned Idx) { + T val = T(); + for (unsigned i = 0; i != BitNum; ++i) + val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i)); + return val; + } + + static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) { + assert((val >> BitNum) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum; ++i) + Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i); + } +}; + +template <typename T, unsigned BitNum> +class PackedVectorBase<T, BitNum, true> { +protected: + static T getValue(const llvm::BitVector &Bits, unsigned Idx) { + T val = T(); + for (unsigned i = 0; i != BitNum-1; ++i) + val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i)); + if (Bits[(Idx << (BitNum-1)) + BitNum-1]) + val = ~val; + return val; + } + + static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) { + if (val < 0) { + val = ~val; + Bits.set((Idx << (BitNum-1)) + BitNum-1); + } + assert((val >> (BitNum-1)) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum-1; ++i) + Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i); + } +}; + +/// \brief Store a vector of values using a specific number of bits for each +/// value. Both signed and unsigned types can be used, e.g +/// @code +/// PackedVector<signed, 2> vec; +/// @endcode +/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit +/// an assertion. +template <typename T, unsigned BitNum> +class PackedVector : public PackedVectorBase<T, BitNum, + std::numeric_limits<T>::is_signed> { + llvm::BitVector Bits; + typedef PackedVectorBase<T, BitNum, std::numeric_limits<T>::is_signed> base; + +public: + class reference { + PackedVector &Vec; + const unsigned Idx; + + reference(); // Undefined + public: + reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { } + + reference &operator=(T val) { + Vec.setValue(Vec.Bits, Idx, val); + return *this; + } + operator T() { + return Vec.getValue(Vec.Bits, Idx); + } + }; + + PackedVector() { } + explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { } + + bool empty() const { return Bits.empty(); } + + unsigned size() const { return Bits.size() >> (BitNum-1); } + + void clear() { Bits.clear(); } + + void resize(unsigned N) { Bits.resize(N << (BitNum-1)); } + + void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); } + + PackedVector &reset() { + Bits.reset(); + return *this; + } + + void push_back(T val) { + resize(size()+1); + (*this)[size()-1] = val; + } + + reference operator[](unsigned Idx) { + return reference(*this, Idx); + } + + T operator[](unsigned Idx) const { + return base::getValue(Bits, Idx); + } + + bool operator==(const PackedVector &RHS) const { + return Bits == RHS.Bits; + } + + bool operator!=(const PackedVector &RHS) const { + return Bits != RHS.Bits; + } + + const PackedVector &operator=(const PackedVector &RHS) { + Bits = RHS.Bits; + return *this; + } + + PackedVector &operator|=(const PackedVector &RHS) { + Bits |= RHS.Bits; + return *this; + } + + void swap(PackedVector &RHS) { + Bits.swap(RHS.Bits); + } +}; + +// Leave BitNum=0 undefined. +template <typename T> +class PackedVector<T, 0>; + +} // end llvm namespace + +#endif diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 1766d2b..8396921 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -46,7 +46,14 @@ namespace llvm { // integer works around this bug. static size_t min(size_t a, size_t b) { return a < b ? a : b; } static size_t max(size_t a, size_t b) { return a > b ? a : b; } - + + // Workaround memcmp issue with null pointers (undefined behavior) + // by providing a specialized version + static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { + if (Length == 0) { return 0; } + return ::memcmp(Lhs,Rhs,Length); + } + public: /// @name Constructors /// @{ @@ -56,11 +63,17 @@ namespace llvm { /// Construct a string ref from a cstring. /*implicit*/ StringRef(const char *Str) - : Data(Str), Length(::strlen(Str)) {} + : Data(Str) { + assert(Str && "StringRef cannot be built from a NULL argument"); + Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior + } /// Construct a string ref from a pointer and length. /*implicit*/ StringRef(const char *data, size_t length) - : Data(data), Length(length) {} + : Data(data), Length(length) { + assert((data || length == 0) && + "StringRef cannot be built from a NULL argument with non-null length"); + } /// Construct a string ref from an std::string. /*implicit*/ StringRef(const std::string &Str) @@ -104,7 +117,7 @@ namespace llvm { /// compare() when the relative ordering of inequal strings isn't needed. bool equals(StringRef RHS) const { return (Length == RHS.Length && - memcmp(Data, RHS.Data, RHS.Length) == 0); + compareMemory(Data, RHS.Data, RHS.Length) == 0); } /// equals_lower - Check for string equality, ignoring case. @@ -116,7 +129,7 @@ namespace llvm { /// is lexicographically less than, equal to, or greater than the \arg RHS. int compare(StringRef RHS) const { // Check the prefix for a mismatch. - if (int Res = memcmp(Data, RHS.Data, min(Length, RHS.Length))) + if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length))) return Res < 0 ? -1 : 1; // Otherwise the prefixes match, so we only need to check the lengths. @@ -183,13 +196,13 @@ namespace llvm { /// startswith - Check if this string starts with the given \arg Prefix. bool startswith(StringRef Prefix) const { return Length >= Prefix.Length && - memcmp(Data, Prefix.Data, Prefix.Length) == 0; + compareMemory(Data, Prefix.Data, Prefix.Length) == 0; } /// endswith - Check if this string ends with the given \arg Suffix. bool endswith(StringRef Suffix) const { return Length >= Suffix.Length && - memcmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; + compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; } /// @} @@ -447,6 +460,10 @@ namespace llvm { return LHS.compare(RHS) != -1; } + inline std::string &operator+=(std::string &buffer, llvm::StringRef string) { + return buffer.append(string.data(), string.size()); + } + /// @} // StringRefs can be treated like a POD type. diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 2659bce..078033d 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -225,7 +225,7 @@ public: /// if the environment component is present). StringRef getOSAndEnvironmentName() const; - /// getOSNumber - Parse the version number from the OS name component of the + /// getOSVersion - Parse the version number from the OS name component of the /// triple, if present. /// /// For example, "fooos1.2.3" would return (1, 2, 3). diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 8f9708b..5d8edd1 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -38,6 +38,7 @@ #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H #include "llvm/Support/CallSite.h" +#include "llvm/ADT/DenseMap.h" namespace llvm { @@ -488,6 +489,32 @@ public: } }; +// Specialize DenseMapInfo for Location. +template<> +struct DenseMapInfo<AliasAnalysis::Location> { + static inline AliasAnalysis::Location getEmptyKey() { + return + AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(), + 0, 0); + } + static inline AliasAnalysis::Location getTombstoneKey() { + return + AliasAnalysis::Location(DenseMapInfo<const Value *>::getTombstoneKey(), + 0, 0); + } + static unsigned getHashValue(const AliasAnalysis::Location &Val) { + return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^ + DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^ + DenseMapInfo<const MDNode *>::getHashValue(Val.TBAATag); + } + static bool isEqual(const AliasAnalysis::Location &LHS, + const AliasAnalysis::Location &RHS) { + return LHS.Ptr == RHS.Ptr && + LHS.Size == RHS.Size && + LHS.TBAATag == RHS.TBAATag; + } +}; + /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool isNoAliasCall(const Value *V); diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h new file mode 100644 index 0000000..91f289d --- /dev/null +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -0,0 +1,78 @@ +//===--- BranchProbabilityInfo.h - Branch Probability Analysis --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass is used to evaluate branch probabilties. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H +#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H + +#include "llvm/InitializePasses.h" +#include "llvm/Support/BranchProbability.h" +#include "llvm/Analysis/LoopInfo.h" + +namespace llvm { + +class raw_ostream; + +class BranchProbabilityInfo : public FunctionPass { + + // Default weight value. Used when we don't have information about the edge. + static const uint32_t DEFAULT_WEIGHT = 16; + + typedef std::pair<BasicBlock *, BasicBlock *> Edge; + + DenseMap<Edge, uint32_t> Weights; + + // Get sum of the block successors' weights. + uint32_t getSumForBlock(BasicBlock *BB) const; + +public: + static char ID; + + BranchProbabilityInfo() : FunctionPass(ID) { + initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<LoopInfo>(); + AU.setPreservesAll(); + } + + bool runOnFunction(Function &F); + + // Returned value is between 1 and UINT32_MAX. Look at + // BranchProbabilityInfo.cpp for details. + uint32_t getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const; + + // Look at BranchProbabilityInfo.cpp for details. Use it with caution! + void setEdgeWeight(BasicBlock *Src, BasicBlock *Dst, uint32_t Weight); + + // A 'Hot' edge is an edge which probability is >= 80%. + bool isEdgeHot(BasicBlock *Src, BasicBlock *Dst) const; + + // Return a hot successor for the block BB or null if there isn't one. + BasicBlock *getHotSucc(BasicBlock *BB) const; + + // Return a probability as a fraction between 0 (0% probability) and + // 1 (100% probability), however the value is never equal to 0, and can be 1 + // only iff SRC block has only one successor. + BranchProbability getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const; + + // Print value between 0 (0% probability) and 1 (100% probability), + // however the value is never equal to 0, and can be 1 only iff SRC block + // has only one successor. + raw_ostream &printEdgeProbability(raw_ostream &OS, BasicBlock *Src, + BasicBlock *Dst) const; +}; + +} + +#endif diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 089f322..fb77da7 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -259,6 +259,9 @@ public: /// addCalledFunction - Add a function to the list of functions called by this /// one. void addCalledFunction(CallSite CS, CallGraphNode *M) { + assert(!CS.getInstruction() || + !CS.getCalledFunction() || + !CS.getCalledFunction()->isIntrinsic()); CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M)); M->AddRef(); } diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 5846dbf..96c6587 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -117,8 +117,9 @@ namespace llvm { /// @param Name Typedef name. /// @param File File where this type is defined. /// @param LineNo Line number. + /// @param Context The surrounding context for the typedef. DIType createTypedef(DIType Ty, StringRef Name, DIFile File, - unsigned LineNo); + unsigned LineNo, DIDescriptor Context); /// createFriend - Create debugging information entry for a 'friend'. DIType createFriend(DIType Ty, DIType FriendTy); diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index c6cc8f7..fbee5a6 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -49,15 +49,16 @@ namespace llvm { class DIDescriptor { public: enum { - FlagPrivate = 1 << 0, - FlagProtected = 1 << 1, - FlagFwdDecl = 1 << 2, - FlagAppleBlock = 1 << 3, - FlagBlockByrefStruct = 1 << 4, - FlagVirtual = 1 << 5, - FlagArtificial = 1 << 6, - FlagExplicit = 1 << 7, - FlagPrototyped = 1 << 8 + FlagPrivate = 1 << 0, + FlagProtected = 1 << 1, + FlagFwdDecl = 1 << 2, + FlagAppleBlock = 1 << 3, + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5, + FlagArtificial = 1 << 6, + FlagExplicit = 1 << 7, + FlagPrototyped = 1 << 8, + FlagObjcClassComplete = 1 << 9 }; protected: const MDNode *DbgNode; @@ -271,6 +272,9 @@ namespace llvm { bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; } + bool isObjcClassComplete() const { + return (getFlags() & FlagObjcClassComplete) != 0; + } bool isValid() const { return DbgNode && (isBasicType() || isDerivedType() || isCompositeType()); } diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h index fc57e1a..3e5da57 100644 --- a/include/llvm/Analysis/FindUsedTypes.h +++ b/include/llvm/Analysis/FindUsedTypes.h @@ -14,8 +14,8 @@ #ifndef LLVM_ANALYSIS_FINDUSEDTYPES_H #define LLVM_ANALYSIS_FINDUSEDTYPES_H +#include "llvm/ADT/SetVector.h" #include "llvm/Pass.h" -#include <set> namespace llvm { @@ -23,7 +23,7 @@ class Type; class Value; class FindUsedTypes : public ModulePass { - std::set<const Type *> UsedTypes; + SetVector<const Type *> UsedTypes; public: static char ID; // Pass identification, replacement for typeid FindUsedTypes() : ModulePass(ID) { @@ -33,7 +33,7 @@ public: /// getTypes - After the pass has been run, return the set containing all of /// the types used in the module. /// - const std::set<const Type *> &getTypes() const { return UsedTypes; } + const SetVector<const Type *> &getTypes() const { return UsedTypes; } /// Print the types found in the module. If the optional Module parameter is /// passed in, then the types are printed symbolically if possible, using the diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index e56d24d..1b78fe4 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -37,8 +37,8 @@ class TargetData; class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { friend class IVUsers; public: - IVStrideUse(IVUsers *P, Instruction* U, Value *O) - : CallbackVH(U), Parent(P), OperandValToReplace(O) { + IVStrideUse(IVUsers *P, Instruction* U, Value *O, Value *PN) + : CallbackVH(U), Parent(P), OperandValToReplace(O), Phi(PN) { } /// getUser - Return the user instruction for this use. @@ -51,6 +51,11 @@ public: setValPtr(NewUser); } + /// getPhi - Return the phi node that represents this IV. + PHINode *getPhi() const { + return cast<PHINode>(Phi); + } + /// getOperandValToReplace - Return the Value of the operand in the user /// instruction that this IVStrideUse is representing. Value *getOperandValToReplace() const { @@ -81,6 +86,9 @@ private: /// that this IVStrideUse is representing. WeakVH OperandValToReplace; + /// Phi - The loop header phi that represents this IV. + WeakVH Phi; + /// PostIncLoops - The set of loops for which Expr has been adjusted to /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. PostIncLoopSet PostIncLoops; @@ -143,9 +151,9 @@ public: /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. - bool AddUsersIfInteresting(Instruction *I); + bool AddUsersIfInteresting(Instruction *I, PHINode *Phi); - IVStrideUse &AddUser(Instruction *User, Value *Operand); + IVStrideUse &AddUser(Instruction *User, Value *Operand, PHINode *Phi); /// getReplacementExpr - Return a SCEV expression which computes the /// value of the OperandValToReplace of the given IVStrideUse. diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index 5403e09..1a93859 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -109,7 +109,7 @@ public: /// @brief Print passes managed by this manager. void dumpPassStructure(unsigned Offset); - /// @brief Print passes contained by this manager. + /// @brief Get passes contained by this manager. Pass *getContainedPass(unsigned N) { assert(N < PassVector.size() && "Pass number out of range!"); Pass *FP = static_cast<Pass *>(PassVector[N]); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index a62f6a8..554524a 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -270,30 +270,30 @@ namespace llvm { /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for /// this function as they are computed. - std::map<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; + DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; /// ConstantEvolutionLoopExitValue - This map contains entries for all of /// the PHI instructions that we attempt to compute constant evolutions for. /// This allows us to avoid potentially expensive recomputation of these /// properties. An instruction maps to null if we are unable to compute its /// exit value. - std::map<PHINode*, Constant*> ConstantEvolutionLoopExitValue; + DenseMap<PHINode*, Constant*> ConstantEvolutionLoopExitValue; /// ValuesAtScopes - This map contains entries for all the expressions /// that we attempt to compute getSCEVAtScope information for, which can /// be expensive in extreme cases. - std::map<const SCEV *, + DenseMap<const SCEV *, std::map<const Loop *, const SCEV *> > ValuesAtScopes; /// LoopDispositions - Memoized computeLoopDisposition results. - std::map<const SCEV *, + DenseMap<const SCEV *, std::map<const Loop *, LoopDisposition> > LoopDispositions; /// computeLoopDisposition - Compute a LoopDisposition value. LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L); /// BlockDispositions - Memoized computeBlockDisposition results. - std::map<const SCEV *, + DenseMap<const SCEV *, std::map<const BasicBlock *, BlockDisposition> > BlockDispositions; /// computeBlockDisposition - Compute a BlockDisposition value. diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index 71c001f..ff86378 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -51,6 +51,9 @@ public: /// hasByValAttr - Return true if this argument has the byval attribute on it /// in its containing function. bool hasByValAttr() const; + + /// getParamAlignment - If this is a byval argument, return its alignment. + unsigned getParamAlignment() const; /// hasNestAttr - Return true if this argument has the nest attribute on /// it in its containing function. diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index da6188b..8b69d6e 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -67,6 +67,20 @@ const Attributes StackAlignment = 7<<26; ///< Alignment of stack for ///alignstack(1)) const Attributes Hotpatch = 1<<29; ///< Function should have special ///'hotpatch' sequence in prologue +const Attributes UWTable = 1<<30; ///< Function must be in a unwind + ///table + +/// Note that uwtable is about the ABI or the user mandating an entry in the +/// unwind table. The nounwind attribute is about an exception passing by the +/// function. +/// In a theoretical system that uses tables for profiling and sjlj for +/// exceptions, they would be fully independent. In a normal system that +/// uses tables for both, the semantics are: +/// nil = Needs an entry because an exception might pass by. +/// nounwind = No need for an entry +/// uwtable = Needs an entry because the ABI says so and because +/// an exception might pass by. +/// uwtable + nounwind = Needs an entry because the ABI says so. /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -76,7 +90,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | - Hotpatch; + Hotpatch | UWTable; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 58395ba..5eea099 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -185,7 +185,14 @@ namespace llvm { void emitPrologLabel(const MachineInstr &MI); - bool needsCFIMoves(); + enum CFIMoveType { + CFI_M_None, + CFI_M_EH, + CFI_M_Debug + }; + CFIMoveType needsCFIMoves(); + + bool needsSEHMoves(); /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is @@ -381,10 +388,6 @@ namespace llvm { /// operands. virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; - /// getDwarfRegOpSize - get size required to emit given machine location - /// using dwarf encoding. - virtual unsigned getDwarfRegOpSize(const MachineLocation &MLoc) const; - /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa /// encoding specified. virtual unsigned getISAEncoding() { return 0; } @@ -396,12 +399,9 @@ namespace llvm { // Dwarf Lowering Routines //===------------------------------------------------------------------===// - /// EmitFrameMoves - Emit frame instructions to describe the layout of the + /// EmitCFIFrameMove - Emit frame instruction to describe the layout of the /// frame. - void EmitFrameMoves(const std::vector<MachineMove> &Moves, - MCSymbol *BaseLabel, bool isEH) const; void EmitCFIFrameMove(const MachineMove &Move) const; - void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const; //===------------------------------------------------------------------===// // Inline Asm Support diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 9018ea3..77dc644 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -16,6 +16,7 @@ #define LLVM_CODEGEN_CALLINGCONVLOWER_H #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Target/TargetCallingConv.h" #include "llvm/CallingConv.h" @@ -141,14 +142,19 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); -typedef enum { Invalid, Prologue, Call } ParmContext; +/// ParmContext - This enum tracks whether calling convention lowering is in +/// the context of prologue or call generation. Not all backends make use of +/// this information. +typedef enum { Unknown, Prologue, Call } ParmContext; /// CCState - This class holds information needed while lowering arguments and /// return values. It captures which registers are already assigned and which /// stack slots are used. It provides accessors to allocate these values. class CCState { +private: CallingConv::ID CallingConv; bool IsVarArg; + MachineFunction &MF; const TargetMachine &TM; const TargetRegisterInfo &TRI; SmallVector<CCValAssign, 16> &Locs; @@ -158,10 +164,14 @@ class CCState { SmallVector<uint32_t, 16> UsedRegs; unsigned FirstByValReg; bool FirstByValRegValid; + +protected: ParmContext CallOrPrologue; + public: - CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, - SmallVector<CCValAssign, 16> &locs, LLVMContext &C); + CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, + const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, + LLVMContext &C); void addLoc(const CCValAssign &V) { Locs.push_back(V); @@ -169,6 +179,7 @@ public: LLVMContext &getContext() const { return Context; } const TargetMachine &getTarget() const { return TM; } + MachineFunction &getMachineFunction() const { return MF; } CallingConv::ID getCallingConv() const { return CallingConv; } bool isVarArg() const { return IsVarArg; } @@ -301,7 +312,6 @@ public: bool isFirstByValRegValid() { return FirstByValRegValid; } ParmContext getCallOrPrologue() { return CallOrPrologue; } - void setCallOrPrologue(ParmContext pc) { CallOrPrologue = pc; } private: /// MarkAllocated - Mark a register and all of its aliases as allocated. diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 10c4c33d..962a4e2 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -241,6 +241,15 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); + /// FastEmitInst_rrr - Emit a MachineInstr with three register operands + /// and a result register in the given register class. + /// + unsigned FastEmitInst_rrr(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill, + unsigned Op2, bool Op2IsKill); + /// FastEmitInst_ri - Emit a MachineInstr with a register operand, /// an immediate, and a result register in the given register class. /// @@ -301,7 +310,7 @@ protected: /// the CFG. void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL); - unsigned UpdateValueMap(const Value* I, unsigned Reg); + void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1); unsigned createResultReg(const TargetRegisterClass *RC); @@ -334,6 +343,8 @@ private: bool SelectCast(const User *I, unsigned Opcode); + bool SelectExtractValue(const User *I); + /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. /// Emit code to ensure constants are copied into registers when needed. /// Remember the virtual registers that need to be added to the Machine PHI diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index f0de936..e765cad 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -107,11 +107,11 @@ namespace ISD { // and returns an outchain. EH_SJLJ_LONGJMP, - // OUTCHAIN = EH_SJLJ_DISPATCHSETUP(INCHAIN, context) + // OUTCHAIN = EH_SJLJ_DISPATCHSETUP(INCHAIN, setjmpval) // This corresponds to the eh.sjlj.dispatchsetup intrinsic. It takes an - // input chain and a pointer to the sjlj function context as inputs and - // returns an outchain. By default, this does nothing. Targets can lower - // this to unwind setup code if needed. + // input chain and the value returning from setjmp as inputs and returns an + // outchain. By default, this does nothing. Targets can lower this to unwind + // setup code if needed. EH_SJLJ_DISPATCHSETUP, // TargetConstant* - Like Constant*, but the DAG does not do any folding, diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index c5285ce..5fd4d3d 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -492,9 +492,10 @@ namespace llvm { /// Returns true if the live interval is zero length, i.e. no live ranges /// span instructions. It doesn't pay to spill such an interval. - bool isZeroLength() const { + bool isZeroLength(SlotIndexes *Indexes) const { for (const_iterator i = begin(), e = end(); i != e; ++i) - if (i->end.getPrevIndex() > i->start) + if (Indexes->getNextNonNullIndex(i->start).getBaseIndex() < + i->end.getBaseIndex()) return false; return true; } diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 2724689..c36dd69 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -229,6 +229,7 @@ public: enum MICheckType { CheckDefs, // Check all operands for equality + CheckKillDead, // Check all operands including kill / dead markers IgnoreDefs, // Ignore all definitions IgnoreVRegDefs // Ignore virtual register definitions }; diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 967e019..c8183a3 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -88,7 +88,7 @@ public: return *this; } - const MachineInstrBuilder &addFrameIndex(unsigned Idx) const { + const MachineInstrBuilder &addFrameIndex(int Idx) const { MI->addOperand(MachineOperand::CreateFI(Idx)); return *this; } diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 6bc80b0..fa185c4 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -52,27 +52,13 @@ namespace llvm { class Constant; class GlobalVariable; class MDNode; +class MMIAddrLabelMap; class MachineBasicBlock; class MachineFunction; class Module; class PointerType; class StructType; -/// MachineModuleInfoImpl - This class can be derived from and used by targets -/// to hold private target-specific information for each Module. Objects of -/// type are accessed/created with MMI::getInfo and destroyed when the -/// MachineModuleInfo is destroyed. -class MachineModuleInfoImpl { -public: - typedef PointerIntPair<MCSymbol*, 1, bool> StubValueTy; - virtual ~MachineModuleInfoImpl(); - typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy; -protected: - static SymbolListTy GetSortedStubs(const DenseMap<MCSymbol*, StubValueTy>&); -}; - - - //===----------------------------------------------------------------------===// /// LandingPadInfo - This structure is used to retain landing pad info for /// the current function. @@ -89,7 +75,20 @@ struct LandingPadInfo { : LandingPadBlock(MBB), LandingPadLabel(0), Personality(0) {} }; -class MMIAddrLabelMap; +//===----------------------------------------------------------------------===// +/// MachineModuleInfoImpl - This class can be derived from and used by targets +/// to hold private target-specific information for each Module. Objects of +/// type are accessed/created with MMI::getInfo and destroyed when the +/// MachineModuleInfo is destroyed. +/// +class MachineModuleInfoImpl { +public: + typedef PointerIntPair<MCSymbol*, 1, bool> StubValueTy; + virtual ~MachineModuleInfoImpl(); + typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy; +protected: + static SymbolListTy GetSortedStubs(const DenseMap<MCSymbol*, StubValueTy>&); +}; //===----------------------------------------------------------------------===// /// MachineModuleInfo - This class contains meta information specific to a diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 8acc949..140c6e8 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -94,8 +94,8 @@ private: /// not a real instruction. Such uses should be ignored during codegen. bool IsDebug : 1; - /// SmallContents - Thisreally should be part of the Contents union, but lives - /// out here so we can get a better packed struct. + /// SmallContents - This really should be part of the Contents union, but + /// lives out here so we can get a better packed struct. /// MO_Register: Register number. /// OffsetedInfo: Low bits of offset. union { @@ -473,7 +473,7 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateFI(unsigned Idx) { + static MachineOperand CreateFI(int Idx) { MachineOperand Op(MachineOperand::MO_FrameIndex); Op.setIndex(Idx); return Op; diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index bace631..7dab4f9 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -21,7 +21,7 @@ namespace llvm { class raw_ostream; /// PseudoSourceValue - Special value supplied for machine level alias - /// analysis. It indicates that the a memory access references the functions + /// analysis. It indicates that a memory access references the functions /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument /// space), or constant pool. class PseudoSourceValue : public Value { diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index 7e8745e..8139c65 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -94,7 +94,7 @@ namespace llvm { typedef std::map<PBQP::Graph::ConstNodeItr, unsigned, PBQP::NodeItrComparator> Node2VReg; typedef DenseMap<unsigned, PBQP::Graph::NodeItr> VReg2Node; - typedef std::map<unsigned, AllowedSet> AllowedSetMap; + typedef DenseMap<unsigned, AllowedSet> AllowedSetMap; PBQP::Graph graph; Node2VReg node2VReg; diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 2eb3db3..2f01948 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -265,7 +265,6 @@ namespace llvm { bool isCloned : 1; // True if this node has been cloned. Sched::Preference SchedulingPref; // Scheduling preference. - SmallVector<MachineInstr*, 4> DbgInstrList; // dbg_values referencing this. private: bool isDepthCurrent : 1; // True if Depth is current. bool isHeightCurrent : 1; // True if Height is current. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 92fd0c9..1c42bef 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -284,7 +284,7 @@ public: /// /// Note that this is an involved process that may invalidate pointers into /// the graph. - void Legalize(CodeGenOpt::Level OptLevel); + void Legalize(); /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG /// that only uses vector math operations supported by the target. This is @@ -985,10 +985,6 @@ public: /// other positive zero. bool isEqualTo(SDValue A, SDValue B) const; - /// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has - /// been verified as a debug information descriptor. - bool isVerifiedDebugInfoDesc(SDValue Op) const; - /// UnrollVectorOp - Utility function used by legalize and lowering to /// "unroll" a vector operation by splitting out the scalars and operating /// on each element individually. If the ResNE is 0, fully unroll the vector diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 829f580..54e5751 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -58,6 +58,10 @@ public: virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual const MCSection *getEHFrameSection() const; + virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { + return NULL; + } + virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, @@ -133,6 +137,10 @@ public: virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual const MCSection *getEHFrameSection() const; + virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { + return NULL; + } + virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, @@ -196,6 +204,8 @@ public: class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { const MCSection *DrectveSection; + const MCSection *PDataSection; + const MCSection *XDataSection; public: TargetLoweringObjectFileCOFF() {} ~TargetLoweringObjectFileCOFF() {} @@ -203,6 +213,8 @@ public: virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); virtual const MCSection *getEHFrameSection() const; + virtual const MCSection *getWin64EHFuncTableSection(StringRef) const; + virtual const MCSection *getWin64EHTableSection(StringRef) const; virtual const MCSection *getDrectveSection() const { return DrectveSection; } diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td index 84e8783..6ba30aa 100644 --- a/include/llvm/CompilerDriver/Common.td +++ b/include/llvm/CompilerDriver/Common.td @@ -56,8 +56,11 @@ def forward_not_split; def case; // Boolean constants. -def true; -def false; +class Bool<bit val> { + bit Value = val; +} +def true : Bool<1>; +def false : Bool<0>; // Boolean operators. def and; diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index 9a9cb3b..ee81f7a 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -95,7 +95,7 @@ #cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}" /* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */ -#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT.PY}" +#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT_PY}" /* Installation prefix directory */ #cmakedefine LLVM_PREFIX "${LLVM_PREFIX}" diff --git a/include/llvm/DefaultPasses.h b/include/llvm/DefaultPasses.h new file mode 100644 index 0000000..e2e58a5b --- /dev/null +++ b/include/llvm/DefaultPasses.h @@ -0,0 +1,167 @@ +//===- llvm/DefaultPasses.h - Default Pass Support code --------*- 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 infrastructure for registering the standard pass list. +// This defines sets of standard optimizations that plugins can modify and +// front ends can use. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEFAULT_PASS_SUPPORT_H +#define LLVM_DEFAULT_PASS_SUPPORT_H + +namespace llvm { + +class PassManagerBase; + +/// Unique identifiers for the default standard passes. The addresses of +/// these symbols are used to uniquely identify passes from the default list. +namespace DefaultStandardPasses { +extern unsigned char AggressiveDCEID; +extern unsigned char ArgumentPromotionID; +extern unsigned char BasicAliasAnalysisID; +extern unsigned char CFGSimplificationID; +extern unsigned char ConstantMergeID; +extern unsigned char CorrelatedValuePropagationID; +extern unsigned char DeadArgEliminationID; +extern unsigned char DeadStoreEliminationID; +extern unsigned char DeadTypeEliminationID; +extern unsigned char EarlyCSEID; +extern unsigned char FunctionAttrsID; +extern unsigned char FunctionInliningID; +extern unsigned char GVNID; +extern unsigned char GlobalDCEID; +extern unsigned char GlobalOptimizerID; +extern unsigned char GlobalsModRefID; +extern unsigned char IPSCCPID; +extern unsigned char IndVarSimplifyID; +extern unsigned char InlinerPlaceholderID; +extern unsigned char InstructionCombiningID; +extern unsigned char JumpThreadingID; +extern unsigned char LICMID; +extern unsigned char LoopDeletionID; +extern unsigned char LoopIdiomID; +extern unsigned char LoopRotateID; +extern unsigned char LoopUnrollID; +extern unsigned char LoopUnswitchID; +extern unsigned char MemCpyOptID; +extern unsigned char PruneEHID; +extern unsigned char ReassociateID; +extern unsigned char SCCPID; +extern unsigned char ScalarReplAggregatesID; +extern unsigned char SimplifyLibCallsID; +extern unsigned char StripDeadPrototypesID; +extern unsigned char TailCallEliminationID; +extern unsigned char TypeBasedAliasAnalysisID; +} + +/// StandardPass - The class responsible for maintaining the lists of standard +class StandardPass { + friend class RegisterStandardPassLists; + public: + /// Predefined standard sets of passes + enum StandardSet { + AliasAnalysis, + Function, + Module, + LTO + }; + /// Flags to specify whether a pass should be enabled. Passes registered + /// with the standard sets may specify a minimum optimization level and one + /// or more flags that must be set when constructing the set for the pass to + /// be used. + enum OptimizationFlags { + /// Optimize for size was requested. + OptimizeSize = 1<<0, + /// Allow passes which may make global module changes. + UnitAtATime = 1<<1, + /// UnrollLoops - Allow loop unrolling. + UnrollLoops = 1<<2, + /// Allow library calls to be simplified. + SimplifyLibCalls = 1<<3, + /// Whether the module may have code using exceptions. + HaveExceptions = 1<<4, + // Run an inliner pass as part of this set. + RunInliner = 1<<5 + }; + enum OptimizationFlagComponents { + /// The low bits are used to store the optimization level. When requesting + /// passes, this should store the requested optimisation level. When + /// setting passes, this should set the minimum optimization level at which + /// the pass will run. + OptimizationLevelMask=0xf, + /// The maximum optimisation level at which the pass is run. + MaxOptimizationLevelMask=0xf0, + // Flags that must be set + RequiredFlagMask=0xff00, + // Flags that may not be set. + DisallowedFlagMask=0xff0000, + MaxOptimizationLevelShift=4, + RequiredFlagShift=8, + DisallowedFlagShift=16 + }; + /// Returns the optimisation level from a set of flags. + static unsigned OptimizationLevel(unsigned flags) { + return flags & OptimizationLevelMask; + } + /// Returns the maximum optimization level for this set of flags + static unsigned MaxOptimizationLevel(unsigned flags) { + return (flags & MaxOptimizationLevelMask) >> 4; + } + /// Constructs a set of flags from the specified minimum and maximum + /// optimisation level + static unsigned OptimzationFlags(unsigned minLevel=0, unsigned maxLevel=0xf, + unsigned requiredFlags=0, unsigned disallowedFlags=0) { + return ((minLevel & OptimizationLevelMask) | + ((maxLevel<<MaxOptimizationLevelShift) & MaxOptimizationLevelMask) + | ((requiredFlags<<RequiredFlagShift) & RequiredFlagMask) + | ((disallowedFlags<<DisallowedFlagShift) & DisallowedFlagMask)); + } + /// Returns the flags that must be set for this to match + static unsigned RequiredFlags(unsigned flags) { + return (flags & RequiredFlagMask) >> RequiredFlagShift; + } + /// Returns the flags that must not be set for this to match + static unsigned DisallowedFlags(unsigned flags) { + return (flags & DisallowedFlagMask) >> DisallowedFlagShift; + } + /// Register a standard pass in the specified set. If flags is non-zero, + /// then the pass will only be returned when the specified flags are set. + template<typename passName> + class RegisterStandardPass { + public: + RegisterStandardPass(StandardSet set, unsigned char *runBefore=0, + unsigned flags=0, unsigned char *ID=0) { + // Use the pass's ID if one is not specified + RegisterDefaultPass(PassInfo::NormalCtor_t(callDefaultCtor<passName>), + ID ? ID : (unsigned char*)&passName::ID, runBefore, set, flags); + } + }; + /// Adds the passes from the specified set to the provided pass manager + static void AddPassesFromSet(PassManagerBase *PM, + StandardSet set, + unsigned flags=0, + bool VerifyEach=false, + Pass *inliner=0); + private: + /// Registers the default passes. This is set by RegisterStandardPassLists + /// and is called lazily. + static void (*RegisterDefaultPasses)(void); + /// Creates the verifier pass that is inserted when a VerifyEach is passed to + /// AddPassesFromSet() + static Pass* (*CreateVerifierPass)(void); + /// Registers the pass + static void RegisterDefaultPass(PassInfo::NormalCtor_t constructor, + unsigned char *newPass, + unsigned char *oldPass, + StandardSet set, + unsigned flags=0); +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index a01ad3a..88b21cd 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -135,20 +135,14 @@ protected: JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs); + TargetMachine *TM); static ExecutionEngine *(*MCJITCtor)( Module *M, std::string *ErrorStr, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs); + TargetMachine *TM); static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); @@ -569,6 +563,14 @@ public: return *this; } + /// 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(Module *M, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs, + std::string *Err); + ExecutionEngine *create(); }; diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 9a0825a..1edc176 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -253,6 +253,23 @@ public: else removeFnAttr(Attribute::NoUnwind); } + /// @brief True if the ABI mandates (or the user requested) that this + /// function be in a unwind table. + bool hasUWTable() const { + return hasFnAttr(Attribute::UWTable); + } + void setHasUWTable(bool HasUWTable = true) { + if (HasUWTable) + addFnAttr(Attribute::UWTable); + else + removeFnAttr(Attribute::UWTable); + } + + /// @brief True if this function needs an unwind table. + bool needsUnwindTableEntry() const { + return hasUWTable() || !doesNotThrow(); + } + /// @brief Determine if the function returns a structure through first /// pointer argument. bool hasStructRetAttr() const { @@ -414,6 +431,10 @@ public: /// bool hasAddressTaken(const User** = 0) const; + /// callsFunctionThatReturnsTwice - Return true if the function has a call to + /// setjmp or other function that gcc recognizes as "returning twice". + bool callsFunctionThatReturnsTwice() const; + private: // Shadow Value::setValueSubclassData with a private forwarding method so that // subclasses cannot accidentally use it. diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index cca0194..372eaba 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -66,6 +66,7 @@ void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); +void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); void initializeCFGOnlyPrinterPass(PassRegistry&); void initializeCFGOnlyViewerPass(PassRegistry&); diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 74c30fb..24e5fe7 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -139,7 +139,7 @@ namespace llvm { return !getVolatileCst()->isZero(); } - unsigned getAddressSpace() const { + unsigned getDestAddressSpace() const { return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); } @@ -227,6 +227,10 @@ namespace llvm { /// value is guaranteed to be a pointer. Value *getSource() const { return getRawSource()->stripPointerCasts(); } + unsigned getSourceAddressSpace() const { + return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); + } + void setSource(Value *Ptr) { assert(getRawSource()->getType() == Ptr->getType() && "setSource called with pointer of wrong type!"); diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index a63cd6a..d8f249a 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -47,6 +47,9 @@ def IntrReadWriteArgMem : IntrinsicProperty; // Commutative - This intrinsic is commutative: X op Y == Y op X. def Commutative : IntrinsicProperty; +// Throws - This intrinsic can throw. +def Throws : IntrinsicProperty; + // NoCapture - The specified argument pointer is not captured by the intrinsic. class NoCapture<int argNo> : IntrinsicProperty { int ArgNo = argNo; @@ -292,6 +295,7 @@ let Properties = [IntrNoMem] in { def int_eh_exception : Intrinsic<[llvm_ptr_ty], [], [IntrReadMem]>; def int_eh_selector : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty]>; +def int_eh_resume : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [Throws]>; def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; @@ -307,7 +311,7 @@ let Properties = [IntrNoMem] in { def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_dispatch_setup : Intrinsic<[], []>; +def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty], [IntrReadMem]>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td index 03e9261..fa8034e 100644 --- a/include/llvm/IntrinsicsARM.td +++ b/include/llvm/IntrinsicsARM.td @@ -36,6 +36,16 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". } //===----------------------------------------------------------------------===// +// Load and Store exclusive doubleword + +let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". + def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, + llvm_ptr_ty], [IntrReadWriteArgMem]>; + def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty], + [IntrReadArgMem]>; +} + +//===----------------------------------------------------------------------===// // VFP let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". @@ -50,6 +60,43 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". } //===----------------------------------------------------------------------===// +// Coprocessor + +let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". + // Move to coprocessor + def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + + // Move from coprocessor + def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; + def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; + + // Coprocessor data processing + def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + + // Move from two registers to coprocessor + def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; + def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">, + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, + llvm_i32_ty, llvm_i32_ty], []>; +} + +//===----------------------------------------------------------------------===// // Advanced SIMD (NEON) let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index b44101a..d445a01 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -224,9 +224,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Cacheability support ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse_movnt_ps : GCCBuiltin<"__builtin_ia32_movntps">, - Intrinsic<[], [llvm_ptr_ty, - llvm_v4f32_ty], []>; def int_x86_sse_sfence : GCCBuiltin<"__builtin_ia32_sfence">, Intrinsic<[], [], []>; } @@ -536,19 +533,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_v4i32_ty], []>; } -// Cacheability support ops -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse2_movnt_dq : GCCBuiltin<"__builtin_ia32_movntdq">, - Intrinsic<[], [llvm_ptr_ty, - llvm_v2i64_ty], []>; - def int_x86_sse2_movnt_pd : GCCBuiltin<"__builtin_ia32_movntpd">, - Intrinsic<[], [llvm_ptr_ty, - llvm_v2f64_ty], []>; - def int_x86_sse2_movnt_i : GCCBuiltin<"__builtin_ia32_movnti">, - Intrinsic<[], [llvm_ptr_ty, - llvm_i32_ty], []>; -} - // Misc. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128">, @@ -964,19 +948,19 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Miscellaneous // CRC Instruction let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse42_crc32_8 : GCCBuiltin<"__builtin_ia32_crc32qi">, + def int_x86_sse42_crc32_32_8 : GCCBuiltin<"__builtin_ia32_crc32qi">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_sse42_crc32_16 : GCCBuiltin<"__builtin_ia32_crc32hi">, + def int_x86_sse42_crc32_32_16 : GCCBuiltin<"__builtin_ia32_crc32hi">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i16_ty], [IntrNoMem]>; - def int_x86_sse42_crc32_32 : GCCBuiltin<"__builtin_ia32_crc32si">, + def int_x86_sse42_crc32_32_32 : GCCBuiltin<"__builtin_ia32_crc32si">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_sse42_crc64_8 : + def int_x86_sse42_crc32_64_8 : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_sse42_crc64_64 : GCCBuiltin<"__builtin_ia32_crc32di">, + def int_x86_sse42_crc32_64_64 : GCCBuiltin<"__builtin_ia32_crc32di">, Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; } diff --git a/include/llvm/IntrinsicsXCore.td b/include/llvm/IntrinsicsXCore.td index e633af0..a062fc4 100644 --- a/include/llvm/IntrinsicsXCore.td +++ b/include/llvm/IntrinsicsXCore.td @@ -11,6 +11,12 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". // Miscellaneous instructions. def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>; + def int_xcore_crc8 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], + [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; + def int_xcore_crc32 : Intrinsic<[llvm_i32_ty], + [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], + [IntrNoMem]>; def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>; def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>; def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>; diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 88ee65a..c02e161 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -70,7 +70,7 @@ namespace { (void) llvm::createEdgeProfilerPass(); (void) llvm::createOptimalEdgeProfilerPass(); (void) llvm::createPathProfilerPass(); - (void) llvm::createGCOVProfilerPass(true, true); + (void) llvm::createGCOVProfilerPass(true, true, false); (void) llvm::createFunctionInliningPass(); (void) llvm::createAlwaysInlinerPass(); (void) llvm::createGlobalDCEPass(); diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 8733161..775d22b 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -26,12 +26,12 @@ namespace llvm { class MCSymbol; class MCContext; - /// MCAsmInfo - This class is intended to be used as a base class for asm - /// properties and features specific to the target. namespace ExceptionHandling { - enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj, ARM }; + enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 }; } + /// MCAsmInfo - This class is intended to be used as a base class for asm + /// properties and features specific to the target. class MCAsmInfo { protected: //===------------------------------------------------------------------===// @@ -269,9 +269,6 @@ namespace llvm { /// SupportsExceptionHandling - True if target supports exception handling. ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None - /// RequiresFrameSection - true if the Dwarf2 output needs a frame section - bool DwarfRequiresFrameSection; // Defaults to true. - /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to /// encode inline subroutine information. bool DwarfUsesInlineInfoSection; // Defaults to false. @@ -279,9 +276,9 @@ namespace llvm { /// DwarfSectionOffsetDirective - Special section offset directive. const char* DwarfSectionOffsetDirective; // Defaults to NULL - /// DwarfUsesAbsoluteLabelForStmtList - True if DW_AT_stmt_list needs - /// absolute label instead of offset. - bool DwarfUsesAbsoluteLabelForStmtList; // Defaults to true; + /// DwarfRequiresRelocationForSectionOffset - True if we need to produce a + // relocation when we want a section offset in dwarf. + bool DwarfRequiresRelocationForSectionOffset; // Defaults to true; // DwarfUsesLabelOffsetDifference - True if Dwarf2 output can // use EmitLabelOffsetDifference. @@ -462,13 +459,9 @@ namespace llvm { } bool isExceptionHandlingDwarf() const { return - (ExceptionsType == ExceptionHandling::DwarfTable || - ExceptionsType == ExceptionHandling::DwarfCFI || - ExceptionsType == ExceptionHandling::ARM); - } - - bool doesDwarfRequireFrameSection() const { - return DwarfRequiresFrameSection; + (ExceptionsType == ExceptionHandling::DwarfCFI || + ExceptionsType == ExceptionHandling::ARM || + ExceptionsType == ExceptionHandling::Win64); } bool doesDwarfUsesInlineInfoSection() const { return DwarfUsesInlineInfoSection; @@ -476,8 +469,8 @@ namespace llvm { const char *getDwarfSectionOffsetDirective() const { return DwarfSectionOffsetDirective; } - bool doesDwarfUsesAbsoluteLabelForStmtList() const { - return DwarfUsesAbsoluteLabelForStmtList; + bool doesDwarfRequireRelocationForSectionOffset() const { + return DwarfRequiresRelocationForSectionOffset; } bool doesDwarfUsesLabelOffsetForRanges() const { return DwarfUsesLabelOffsetForRanges; diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 3bbcf3e..90c3728 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -281,11 +281,10 @@ namespace llvm { // // This emits the frame info section. // - static void Emit(MCStreamer &streamer, bool usingCFI); - static void EmitDarwin(MCStreamer &streamer, bool usingCFI); + static void Emit(MCStreamer &streamer, bool usingCFI, + bool isEH); static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); - static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS, - const TargetAsmInfo &AsmInfo); + static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); }; } // end namespace llvm diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h index d798fb0..2225ea0 100644 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ b/include/llvm/MC/MCELFSymbolFlags.h @@ -49,7 +49,8 @@ namespace llvm { ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift), - ELF_Other_Weakref = (1 << ELF_Other_Shift) + ELF_Other_Weakref = (1 << ELF_Other_Shift), + ELF_Other_ThumbFunc = (2 << ELF_Other_Shift) }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 521fde6..0f28599 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -171,8 +171,10 @@ public: VK_ARM_GOTTPOFF, VK_PPC_TOC, - VK_PPC_HA16, // ha16(symbol) - VK_PPC_LO16 // lo16(symbol) + VK_PPC_DARWIN_HA16, // ha16(symbol) + VK_PPC_DARWIN_LO16, // lo16(symbol) + VK_PPC_GAS_HA16, // symbol@ha + VK_PPC_GAS_LO16 // symbol@l }; private: diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 0669558..39002da 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -45,8 +45,8 @@ public: /// "MOV32ri") or empty if we can't resolve it. virtual StringRef getOpcodeName(unsigned Opcode) const; - /// getRegName - Return the assembler register name. - virtual StringRef getRegName(unsigned RegNo) const; + /// printRegName - Print the assembler register name. + virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 606725a..47c580f 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -44,6 +44,7 @@ public: Colon, Plus, Minus, Tilde, Slash, // '/' + BackSlash, // '\' LParen, RParen, LBrac, RBrac, LCurly, RCurly, Star, Dot, Comma, Dollar, Equal, EqualEqual, diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 54979d9..7376693 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -71,7 +71,9 @@ public: /// Warning - Emit a warning at the location \arg L, with the message \arg /// Msg. - virtual void Warning(SMLoc L, const Twine &Msg) = 0; + /// + /// \return The return value is true, if warnings are fatal. + virtual bool Warning(SMLoc L, const Twine &Msg) = 0; /// Error - Emit an error at the location \arg L, with the message \arg /// Msg. diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index ceb57f5..4e2aee9 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -56,7 +56,7 @@ public: MCAsmParser &getParser() { return *Parser; } SourceMgr &getSourceManager() { return getParser().getSourceManager(); } MCStreamer &getStreamer() { return getParser().getStreamer(); } - void Warning(SMLoc L, const Twine &Msg) { + bool Warning(SMLoc L, const Twine &Msg) { return getParser().Warning(L, Msg); } bool Error(SMLoc L, const Twine &Msg) { diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index b005c8b..c05a925 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -18,6 +18,7 @@ #include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCWin64EH.h" namespace llvm { class MCAsmInfo; @@ -50,10 +51,18 @@ namespace llvm { MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT + bool EmitEHFrame; + bool EmitDebugFrame; + std::vector<MCDwarfFrameInfo> FrameInfos; MCDwarfFrameInfo *getCurrentFrameInfo(); void EnsureValidFrame(); + std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; + MCWin64EHUnwindInfo *CurrentW64UnwindInfo; + void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); + void EnsureValidW64UnwindInfo(); + const MCSymbol* LastNonPrivate; /// SectionStack - This is stack of current and previous section @@ -67,8 +76,12 @@ namespace llvm { const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, const MCSymbol *B); - const MCExpr *ForceExpAbs(MCStreamer *Streamer, MCContext &Context, - const MCExpr* Expr); + const MCExpr *ForceExpAbs(const MCExpr* Expr); + + void EmitFrames(bool usingCFI); + + MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;} + void EmitW64Tables(); public: virtual ~MCStreamer(); @@ -83,6 +96,14 @@ namespace llvm { return FrameInfos[i]; } + unsigned getNumW64UnwindInfos() { + return W64UnwindInfos.size(); + } + + MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) { + return *W64UnwindInfos[i]; + } + /// @name Assembly File Formatting. /// @{ @@ -174,6 +195,17 @@ namespace llvm { } } + /// SwitchSectionNoChange - Set the current section where code is being + /// emitted to @p Section. This is required to update CurSection. This + /// version does not call ChangeSection. + void SwitchSectionNoChange(const MCSection *Section) { + assert(Section && "Cannot switch to a null section!"); + const MCSection *curSection = SectionStack.back().first; + SectionStack.back().second = curSection; + if (Section != curSection) + SectionStack.back().first = Section; + } + /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; @@ -288,6 +320,7 @@ namespace llvm { /// if non-zero. This must be a power of 2 on some targets. virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) = 0; + /// @} /// @name Generating Data /// @{ @@ -436,6 +469,7 @@ namespace llvm { void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); + virtual void EmitCFISections(bool EH, bool Debug); virtual void EmitCFIStartProc(); virtual void EmitCFIEndProc(); virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); @@ -450,6 +484,21 @@ namespace llvm { virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); + virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); + virtual void EmitWin64EHEndProc(); + virtual void EmitWin64EHStartChained(); + virtual void EmitWin64EHEndChained(); + virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except); + virtual void EmitWin64EHHandlerData(); + virtual void EmitWin64EHPushReg(unsigned Register); + virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); + virtual void EmitWin64EHAllocStack(unsigned Size); + virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); + virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); + virtual void EmitWin64EHPushFrame(bool Code); + virtual void EmitWin64EHEndProlog(); + /// EmitInstruction - Emit the given @p Instruction into the current /// section. virtual void EmitInstruction(const MCInst &Inst) = 0; diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h new file mode 100644 index 0000000..eb4665a --- /dev/null +++ b/include/llvm/MC/MCWin64EH.h @@ -0,0 +1,93 @@ +//===- MCWin64EH.h - Machine Code Win64 EH support --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains declarations to support the Win64 Exception Handling +// scheme in MC. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCWIN64EH_H +#define LLVM_MC_MCWIN64EH_H + +#include "llvm/Support/Win64EH.h" +#include <cassert> +#include <vector> + +namespace llvm { + class StringRef; + class MCStreamer; + class MCSymbol; + + class MCWin64EHInstruction { + public: + typedef Win64EH::UnwindOpcodes OpType; + private: + OpType Operation; + MCSymbol *Label; + unsigned Offset; + unsigned Register; + public: + MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg) + : Operation(Op), Label(L), Offset(0), Register(Reg) { + assert(Op == Win64EH::UOP_PushNonVol); + } + MCWin64EHInstruction(MCSymbol *L, unsigned Size) + : Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall), + Label(L), Offset(Size) { } + MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off) + : Operation(Op), Label(L), Offset(Off), Register(Reg) { + assert(Op == Win64EH::UOP_SetFPReg || + Op == Win64EH::UOP_SaveNonVol || + Op == Win64EH::UOP_SaveNonVolBig || + Op == Win64EH::UOP_SaveXMM128 || + Op == Win64EH::UOP_SaveXMM128Big); + } + MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code) + : Operation(Op), Label(L), Offset(Code ? 1 : 0) { + assert(Op == Win64EH::UOP_PushMachFrame); + } + OpType getOperation() const { return Operation; } + MCSymbol *getLabel() const { return Label; } + unsigned getOffset() const { return Offset; } + unsigned getSize() const { return Offset; } + unsigned getRegister() const { return Register; } + bool isPushCodeFrame() const { return Offset == 1; } + }; + + struct MCWin64EHUnwindInfo { + MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0), + Function(0), PrologEnd(0), Symbol(0), + HandlesUnwind(false), HandlesExceptions(false), + LastFrameInst(-1), ChainedParent(0), + Instructions() {} + MCSymbol *Begin; + MCSymbol *End; + const MCSymbol *ExceptionHandler; + const MCSymbol *Function; + MCSymbol *PrologEnd; + MCSymbol *Symbol; + bool HandlesUnwind; + bool HandlesExceptions; + int LastFrameInst; + MCWin64EHUnwindInfo *ChainedParent; + std::vector<MCWin64EHInstruction> Instructions; + }; + + class MCWin64EHUnwindEmitter { + public: + static StringRef GetSectionSuffix(const MCSymbol *func); + // + // This emits the unwind info sections (.pdata and .xdata in PE/COFF). + // + static void Emit(MCStreamer &streamer); + static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info); + }; +} // end namespace llvm + +#endif diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index c323025..887e33c 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -34,7 +34,7 @@ template<typename ValueSubClass, typename ItemParentClass> //===----------------------------------------------------------------------===// /// MDString - a single uniqued string. /// These are used to efficiently contain a byte sequence for metadata. -/// MDString is always unnamd. +/// MDString is always unnamed. class MDString : public Value { MDString(const MDString &); // DO NOT IMPLEMENT diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index ff2a0ad..e9aa499 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -186,28 +186,46 @@ public: }; class AddOperator - : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {}; + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { + ~AddOperator(); // DO NOT IMPLEMENT +}; class SubOperator - : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {}; + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { + ~SubOperator(); // DO NOT IMPLEMENT +}; class MulOperator - : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {}; + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { + ~MulOperator(); // DO NOT IMPLEMENT +}; class ShlOperator - : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {}; + : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { + ~ShlOperator(); // DO NOT IMPLEMENT +}; class SDivOperator - : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {}; + : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { + ~SDivOperator(); // DO NOT IMPLEMENT +}; class UDivOperator - : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {}; + : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { + ~UDivOperator(); // DO NOT IMPLEMENT +}; class AShrOperator - : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {}; + : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { + ~AShrOperator(); // DO NOT IMPLEMENT +}; class LShrOperator - : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {}; + : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { + ~LShrOperator(); // DO NOT IMPLEMENT +}; class GEPOperator : public ConcreteOperator<Operator, Instruction::GetElementPtr> { + ~GEPOperator(); // DO NOT IMPLEMENT + enum { IsInBounds = (1 << 0) }; diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h new file mode 100644 index 0000000..7ba6491 --- /dev/null +++ b/include/llvm/Support/BranchProbability.h @@ -0,0 +1,50 @@ +//===- BranchProbability.h - Branch Probability Analysis --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of BranchProbability shared by IR and Machine Instructions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_BRANCHPROBABILITY_H +#define LLVM_SUPPORT_BRANCHPROBABILITY_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class raw_ostream; +class BranchProbabilityInfo; +class MachineBranchProbabilityInfo; +class MachineBasicBlock; + +// This class represents Branch Probability as a non-negative fraction. +class BranchProbability { + friend class BranchProbabilityInfo; + friend class MachineBranchProbabilityInfo; + friend class MachineBasicBlock; + + // Numerator + uint32_t N; + + // Denominator + uint32_t D; + + BranchProbability(uint32_t n, uint32_t d); + +public: + raw_ostream &print(raw_ostream &OS) const; + + void dump() const; +}; + +raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob); + +} + +#endif diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index abb5a9a..3aab436 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -23,8 +23,6 @@ namespace llvm { // isa<x> Support Templates //===----------------------------------------------------------------------===// -template<typename FromCl> struct isa_impl_cl; - // Define a template that can be specialized by smart pointers to reflect the // fact that they are automatically dereferenced, and are not involved with the // template selection process... the default implementation is a noop. @@ -43,12 +41,9 @@ template<typename From> struct simplify_type<const From> { } }; - -// isa<X> - Return true if the parameter to the template is an instance of the -// template type argument. Used like this: -// -// if (isa<Type*>(myVal)) { ... } -// +// The core of the implementation of isa<X> is here; To and From should be +// the names of classes. This template can be specialized to customize the +// implementation of isa<> without rewriting it from scratch. template <typename To, typename From> struct isa_impl { static inline bool doit(const From &Val) { @@ -56,66 +51,63 @@ struct isa_impl { } }; -template<typename To, typename From, typename SimpleType> -struct isa_impl_wrap { - // When From != SimplifiedType, we can simplify the type some more by using - // the simplify_type template. - static bool doit(const From &Val) { - return isa_impl_cl<const SimpleType>::template - isa<To>(simplify_type<const From>::getSimplifiedValue(Val)); +template <typename To, typename From> struct isa_impl_cl { + static inline bool doit(const From &Val) { + return isa_impl<To, From>::doit(Val); } }; -template<typename To, typename FromTy> -struct isa_impl_wrap<To, const FromTy, const FromTy> { - // When From == SimpleType, we are as simple as we are going to get. - static bool doit(const FromTy &Val) { - return isa_impl<To,FromTy>::doit(Val); +template <typename To, typename From> struct isa_impl_cl<To, const From> { + static inline bool doit(const From &Val) { + return isa_impl<To, From>::doit(Val); } }; -// isa_impl_cl - Use class partial specialization to transform types to a single -// canonical form for isa_impl. -// -template<typename FromCl> -struct isa_impl_cl { - template<class ToCl> - static bool isa(const FromCl &Val) { - return isa_impl_wrap<ToCl,const FromCl, - typename simplify_type<const FromCl>::SimpleType>::doit(Val); +template <typename To, typename From> struct isa_impl_cl<To, From*> { + static inline bool doit(const From *Val) { + return isa_impl<To, From>::doit(*Val); } }; -// Specialization used to strip const qualifiers off of the FromCl type... -template<typename FromCl> -struct isa_impl_cl<const FromCl> { - template<class ToCl> - static bool isa(const FromCl &Val) { - return isa_impl_cl<FromCl>::template isa<ToCl>(Val); +template <typename To, typename From> struct isa_impl_cl<To, const From*> { + static inline bool doit(const From *Val) { + return isa_impl<To, From>::doit(*Val); } }; -// Define pointer traits in terms of base traits... -template<class FromCl> -struct isa_impl_cl<FromCl*> { - template<class ToCl> - static bool isa(FromCl *Val) { - return isa_impl_cl<FromCl>::template isa<ToCl>(*Val); +template <typename To, typename From> struct isa_impl_cl<To, const From*const> { + static inline bool doit(const From *Val) { + return isa_impl<To, From>::doit(*Val); } }; -// Define reference traits in terms of base traits... -template<class FromCl> -struct isa_impl_cl<FromCl&> { - template<class ToCl> - static bool isa(FromCl &Val) { - return isa_impl_cl<FromCl>::template isa<ToCl>(&Val); +template<typename To, typename From, typename SimpleFrom> +struct isa_impl_wrap { + // When From != SimplifiedType, we can simplify the type some more by using + // the simplify_type template. + static bool doit(const From &Val) { + return isa_impl_wrap<To, SimpleFrom, + typename simplify_type<SimpleFrom>::SimpleType>::doit( + simplify_type<From>::getSimplifiedValue(Val)); + } +}; + +template<typename To, typename FromTy> +struct isa_impl_wrap<To, FromTy, FromTy> { + // When From == SimpleType, we are as simple as we are going to get. + static bool doit(const FromTy &Val) { + return isa_impl_cl<To,FromTy>::doit(Val); } }; +// isa<X> - Return true if the parameter to the template is an instance of the +// template type argument. Used like this: +// +// if (isa<Type>(myVal)) { ... } +// template <class X, class Y> inline bool isa(const Y &Val) { - return isa_impl_cl<Y>::template isa<X>(Val); + return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val); } //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index db835e8..4c0a5e2 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -186,8 +186,13 @@ public: } ~CrashRecoveryContextCleanupRegistrar() { + unregister(); + } + + void unregister() { if (cleanup && !cleanup->cleanupFired) - cleanup->getContext()->unregisterCleanup(cleanup); + cleanup->getContext()->unregisterCleanup(cleanup); + cleanup = 0; } }; } diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index f6d680b..70bac0c 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -235,6 +235,7 @@ enum dwarf_constants { DW_AT_APPLE_property_getter = 0x3fe9, DW_AT_APPLE_property_setter = 0x3fea, DW_AT_APPLE_property_attribute = 0x3feb, + DW_AT_APPLE_objc_complete_type = 0x3fec, // Attribute form encodings DW_FORM_addr = 0x01, diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 3878e79..6a7c277 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -80,6 +80,7 @@ public: void SetInsertPoint(Instruction *I) { BB = I->getParent(); InsertPt = I; + SetCurrentDebugLocation(I->getDebugLoc()); } /// SetInsertPoint - This specifies that created instructions should be @@ -106,6 +107,10 @@ public: I->setDebugLoc(CurDbgLocation); } + /// getCurrentFunctionReturnType - Get the return type of the current function + /// that we're emitting into. + const Type *getCurrentFunctionReturnType() const; + /// InsertPoint - A saved insertion point. class InsertPoint { BasicBlock *Block; @@ -194,6 +199,7 @@ public: return ConstantInt::get(getInt64Ty(), C); } + /// getInt - Get a constant integer value. ConstantInt *getInt(const APInt &AI) { return ConstantInt::get(Context, AI); } @@ -246,10 +252,10 @@ public: return Type::getInt8PtrTy(Context, AddrSpace); } - /// getCurrentFunctionReturnType - Get the return type of the current function - /// that we're emitting into. - const Type *getCurrentFunctionReturnType() const; - + //===--------------------------------------------------------------------===// + // Intrinsic creation methods + //===--------------------------------------------------------------------===// + /// CreateMemSet - Create and insert a memset to the specified pointer and the /// specified value. If the pointer isn't an i8*, it will be converted. If a /// TBAA tag is specified, it will be added to the instruction. @@ -282,6 +288,15 @@ public: CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, bool isVolatile = false, MDNode *TBAATag = 0); + + /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer + /// isn't i8* it will be converted. + CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0); + + /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't + /// i8* it will be converted. + CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0); + private: Value *getCastedInt8PtrValue(Value *Ptr); }; @@ -324,6 +339,7 @@ public: explicit IRBuilder(Instruction *IP) : IRBuilderBase(IP->getContext()), Folder() { SetInsertPoint(IP); + SetCurrentDebugLocation(IP->getDebugLoc()); } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index d912e86..5e55bd9 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -81,7 +81,7 @@ public: bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note - /// that InputData must be null terminated. + /// that InputData must be null terminated if RequiresNullTerminator is true. static MemoryBuffer *getMemBuffer(StringRef InputData, StringRef BufferName = "", bool RequiresNullTerminator = true); diff --git a/include/llvm/Support/PassManagerBuilder.h b/include/llvm/Support/PassManagerBuilder.h new file mode 100644 index 0000000..513bb88 --- /dev/null +++ b/include/llvm/Support/PassManagerBuilder.h @@ -0,0 +1,322 @@ +//===-- llvm/Support/PassManagerBuilder.h - Build Standard Pass -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PassManagerBuilder class, which is used to set up a +// "standard" optimization sequence suitable for languages like C and C++. +// +// These are implemented as inline functions so that we do not have to worry +// about link issues. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H +#define LLVM_SUPPORT_PASSMANAGERBUILDER_H + +#include "llvm/PassManager.h" +#include "llvm/DefaultPasses.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Target/TargetLibraryInfo.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/IPO.h" + +namespace llvm { + +/// PassManagerBuilder - This class is used to set up a standard optimization +/// sequence for languages like C and C++, allowing some APIs to customize the +/// pass sequence in various ways. A simple example of using it would be: +/// +/// PassManagerBuilder Builder; +/// Builder.OptLevel = 2; +/// Builder.populateFunctionPassManager(FPM); +/// Builder.populateModulePassManager(MPM); +/// +/// In addition to setting up the basic passes, PassManagerBuilder allows +/// frontends to vend a plugin API, where plugins are allowed to add extensions +/// to the default pass manager. They do this by specifying where in the pass +/// pipeline they want to be added, along with a callback function that adds +/// the pass(es). For example, a plugin that wanted to add a loop optimization +/// could do something like this: +/// +/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) { +/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0) +/// PM.add(createMyAwesomePass()); +/// } +/// ... +/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, +/// addMyLoopPass); +/// ... +class PassManagerBuilder { +public: + + /// Extensions are passed the builder itself (so they can see how it is + /// configured) as well as the pass manager to add stuff to. + typedef void (*ExtensionFn)(const PassManagerBuilder &Builder, + PassManagerBase &PM); + enum ExtensionPointTy { + /// EP_EarlyAsPossible - This extension point allows adding passes before + /// any other transformations, allowing them to see the code as it is coming + /// out of the frontend. + EP_EarlyAsPossible, + + /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to + /// the end of the loop optimizer. + EP_LoopOptimizerEnd + }; + + /// The Optimization Level - Specify the basic optimization level. + /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 + unsigned OptLevel; + + /// SizeLevel - How much we're optimizing for size. + /// 0 = none, 1 = -Os, 2 = -Oz + unsigned SizeLevel; + + /// LibraryInfo - Specifies information about the runtime library for the + /// optimizer. If this is non-null, it is added to both the function and + /// per-module pass pipeline. + TargetLibraryInfo *LibraryInfo; + + /// Inliner - Specifies the inliner to use. If this is non-null, it is + /// added to the per-module passes. + Pass *Inliner; + + bool DisableSimplifyLibCalls; + bool DisableUnitAtATime; + bool DisableUnrollLoops; + +private: + /// ExtensionList - This is list of all of the extensions that are registered. + std::vector<std::pair<ExtensionPointTy, ExtensionFn> > Extensions; + +public: + PassManagerBuilder() { + OptLevel = 2; + SizeLevel = 0; + LibraryInfo = 0; + Inliner = 0; + DisableSimplifyLibCalls = false; + DisableUnitAtATime = false; + DisableUnrollLoops = false; + } + + ~PassManagerBuilder() { + delete LibraryInfo; + delete Inliner; + } + + void addExtension(ExtensionPointTy Ty, ExtensionFn Fn) { + Extensions.push_back(std::make_pair(Ty, Fn)); + } + +private: + void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const { + for (unsigned i = 0, e = Extensions.size(); i != e; ++i) + if (Extensions[i].first == ETy) + Extensions[i].second(*this, PM); + } + + void addInitialAliasAnalysisPasses(PassManagerBase &PM) const { + // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that + // BasicAliasAnalysis wins if they disagree. This is intended to help + // support "obvious" type-punning idioms. + PM.add(createTypeBasedAliasAnalysisPass()); + PM.add(createBasicAliasAnalysisPass()); + } +public: + + /// populateFunctionPassManager - This fills in the function pass manager, + /// which is expected to be run on each function immediately as it is + /// generated. The idea is to reduce the size of the IR in memory. + void populateFunctionPassManager(FunctionPassManager &FPM) { + addExtensionsToPM(EP_EarlyAsPossible, FPM); + + // Add LibraryInfo if we have some. + if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); + + if (OptLevel == 0) return; + + addInitialAliasAnalysisPasses(FPM); + + FPM.add(createCFGSimplificationPass()); + FPM.add(createScalarReplAggregatesPass()); + FPM.add(createEarlyCSEPass()); + } + + /// populateModulePassManager - This sets up the primary pass manager. + void populateModulePassManager(PassManagerBase &MPM) { + // If all optimizations are disabled, just run the always-inline pass. + if (OptLevel == 0) { + if (Inliner) { + MPM.add(Inliner); + Inliner = 0; + } + return; + } + + // Add LibraryInfo if we have some. + if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo)); + + addInitialAliasAnalysisPasses(MPM); + + if (!DisableUnitAtATime) { + MPM.add(createGlobalOptimizerPass()); // Optimize out global vars + + MPM.add(createIPSCCPPass()); // IP SCCP + MPM.add(createDeadArgEliminationPass()); // Dead argument elimination + + MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE + MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + } + + // Start of CallGraph SCC passes. + if (!DisableUnitAtATime) + MPM.add(createPruneEHPass()); // Remove dead EH info + if (Inliner) { + MPM.add(Inliner); + Inliner = 0; + } + if (!DisableUnitAtATime) + MPM.add(createFunctionAttrsPass()); // Set readonly/readnone attrs + if (OptLevel > 2) + MPM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args + + // Start of function pass. + // Break up aggregate allocas, using SSAUpdater. + MPM.add(createScalarReplAggregatesPass(-1, false)); + MPM.add(createEarlyCSEPass()); // Catch trivial redundancies + if (!DisableSimplifyLibCalls) + MPM.add(createSimplifyLibCallsPass()); // Library Call Optimizations + MPM.add(createJumpThreadingPass()); // Thread jumps. + MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs + MPM.add(createInstructionCombiningPass()); // Combine silly seq's + + MPM.add(createTailCallEliminationPass()); // Eliminate tail calls + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs + MPM.add(createReassociatePass()); // Reassociate expressions + MPM.add(createLoopRotatePass()); // Rotate Loop + MPM.add(createLICMPass()); // Hoist loop invariants + MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); + MPM.add(createInstructionCombiningPass()); + MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars + MPM.add(createLoopIdiomPass()); // Recognize idioms like memset. + MPM.add(createLoopDeletionPass()); // Delete dead loops + if (!DisableUnrollLoops) + MPM.add(createLoopUnrollPass()); // Unroll small loops + addExtensionsToPM(EP_LoopOptimizerEnd, MPM); + + if (OptLevel > 1) + MPM.add(createGVNPass()); // Remove redundancies + MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset + MPM.add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + MPM.add(createInstructionCombiningPass()); + MPM.add(createJumpThreadingPass()); // Thread jumps + MPM.add(createCorrelatedValuePropagationPass()); + MPM.add(createDeadStoreEliminationPass()); // Delete dead stores + MPM.add(createAggressiveDCEPass()); // Delete dead instructions + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs + MPM.add(createInstructionCombiningPass()); // Clean up after everything. + + if (!DisableUnitAtATime) { + MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes + MPM.add(createDeadTypeEliminationPass()); // Eliminate dead types + + // GlobalOpt already deletes dead functions and globals, at -O3 try a + // late pass of GlobalDCE. It is capable of deleting dead cycles. + if (OptLevel > 2) + MPM.add(createGlobalDCEPass()); // Remove dead fns and globals. + + if (OptLevel > 1) + MPM.add(createConstantMergePass()); // Merge dup global constants + } + } + + void populateLTOPassManager(PassManagerBase &PM, bool Internalize, + bool RunInliner) { + // Provide AliasAnalysis services for optimizations. + addInitialAliasAnalysisPasses(PM); + + // Now that composite has been compiled, scan through the module, looking + // for a main function. If main is defined, mark all other functions + // internal. + if (Internalize) + PM.add(createInternalizePass(true)); + + // Propagate constants at call sites into the functions they call. This + // opens opportunities for globalopt (and inlining) by substituting function + // pointers passed as arguments to direct uses of functions. + PM.add(createIPSCCPPass()); + + // Now that we internalized some globals, see if we can hack on them! + PM.add(createGlobalOptimizerPass()); + + // Linking modules together can lead to duplicated global constants, only + // keep one copy of each constant. + PM.add(createConstantMergePass()); + + // Remove unused arguments from functions. + PM.add(createDeadArgEliminationPass()); + + // Reduce the code after globalopt and ipsccp. Both can open up significant + // simplification opportunities, and both can propagate functions through + // function pointers. When this happens, we often have to resolve varargs + // calls, etc, so let instcombine do this. + PM.add(createInstructionCombiningPass()); + + // Inline small functions + if (RunInliner) + PM.add(createFunctionInliningPass()); + + PM.add(createPruneEHPass()); // Remove dead EH info. + + // Optimize globals again if we ran the inliner. + if (RunInliner) + PM.add(createGlobalOptimizerPass()); + PM.add(createGlobalDCEPass()); // Remove dead functions. + + // If we didn't decide to inline a function, check to see if we can + // transform it to pass arguments by value instead of by reference. + PM.add(createArgumentPromotionPass()); + + // The IPO passes may leave cruft around. Clean up after them. + PM.add(createInstructionCombiningPass()); + PM.add(createJumpThreadingPass()); + // Break up allocas + PM.add(createScalarReplAggregatesPass()); + + // Run a few AA driven optimizations here and now, to cleanup the code. + PM.add(createFunctionAttrsPass()); // Add nocapture. + PM.add(createGlobalsModRefPass()); // IP alias analysis. + + PM.add(createLICMPass()); // Hoist loop invariants. + PM.add(createGVNPass()); // Remove redundancies. + PM.add(createMemCpyOptPass()); // Remove dead memcpys. + // Nuke dead stores. + PM.add(createDeadStoreEliminationPass()); + + // Cleanup and simplify the code after the scalar optimizations. + PM.add(createInstructionCombiningPass()); + + PM.add(createJumpThreadingPass()); + + // Delete basic blocks, which optimization passes may have killed. + PM.add(createCFGSimplificationPass()); + + // Now that we have optimized the program, discard unreachable functions. + PM.add(createGlobalDCEPass()); + } +}; + + +} // end namespace llvm +#endif diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 172480e..f0fb516 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -694,6 +694,99 @@ inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) { return brc_match<Cond_t>(C, T, F); } + +//===----------------------------------------------------------------------===// +// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). +// + +template<typename LHS_t, typename RHS_t, typename Pred_t> +struct MaxMin_match { + LHS_t L; + RHS_t R; + + MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) + : L(LHS), R(RHS) {} + + template<typename OpTy> + bool match(OpTy *V) { + // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". + SelectInst *SI = dyn_cast<SelectInst>(V); + if (!SI) + return false; + ICmpInst *Cmp = dyn_cast<ICmpInst>(SI->getCondition()); + if (!Cmp) + return false; + // At this point we have a select conditioned on a comparison. Check that + // it is the values returned by the select that are being compared. + Value *TrueVal = SI->getTrueValue(); + Value *FalseVal = SI->getFalseValue(); + Value *LHS = Cmp->getOperand(0); + Value *RHS = Cmp->getOperand(1); + if ((TrueVal != LHS || FalseVal != RHS) && + (TrueVal != RHS || FalseVal != LHS)) + return false; + ICmpInst::Predicate Pred = LHS == TrueVal ? + Cmp->getPredicate() : Cmp->getSwappedPredicate(); + // Does "(x pred y) ? x : y" represent the desired max/min operation? + if (!Pred_t::match(Pred)) + return false; + // It does! Bind the operands. + return L.match(LHS) && R.match(RHS); + } +}; + +/// smax_pred_ty - Helper class for identifying signed max predicates. +struct smax_pred_ty { + static bool match(ICmpInst::Predicate Pred) { + return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE; + } +}; + +/// smin_pred_ty - Helper class for identifying signed min predicates. +struct smin_pred_ty { + static bool match(ICmpInst::Predicate Pred) { + return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE; + } +}; + +/// umax_pred_ty - Helper class for identifying unsigned max predicates. +struct umax_pred_ty { + static bool match(ICmpInst::Predicate Pred) { + return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE; + } +}; + +/// umin_pred_ty - Helper class for identifying unsigned min predicates. +struct umin_pred_ty { + static bool match(ICmpInst::Predicate Pred) { + return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; + } +}; + +template<typename LHS, typename RHS> +inline MaxMin_match<LHS, RHS, smax_pred_ty> +m_SMax(const LHS &L, const RHS &R) { + return MaxMin_match<LHS, RHS, smax_pred_ty>(L, R); +} + +template<typename LHS, typename RHS> +inline MaxMin_match<LHS, RHS, smin_pred_ty> +m_SMin(const LHS &L, const RHS &R) { + return MaxMin_match<LHS, RHS, smin_pred_ty>(L, R); +} + +template<typename LHS, typename RHS> +inline MaxMin_match<LHS, RHS, umax_pred_ty> +m_UMax(const LHS &L, const RHS &R) { + return MaxMin_match<LHS, RHS, umax_pred_ty>(L, R); +} + +template<typename LHS, typename RHS> +inline MaxMin_match<LHS, RHS, umin_pred_ty> +m_UMin(const LHS &L, const RHS &R) { + return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R); +} + } // end namespace PatternMatch } // end namespace llvm diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 96b3566..a502657 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -85,8 +85,9 @@ namespace sys { /// This function waits for the program to exit. This function will block /// the current program until the invoked program exits. /// @returns an integer result code indicating the status of the program. - /// A zero or positive value indicates the result code of the program. A - /// negative value is the signal number on which it terminated. + /// A zero or positive value indicates the result code of the program. + /// -1 indicates failure to execute + /// -2 indicates a crash during execution or timeout /// @see Execute /// @brief Waits for the program to exit. int Wait diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 2a712e4..030db8f 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -106,7 +106,9 @@ public: /// AddIncludeFile - Search for a file with the specified name in the current /// directory or in one of the IncludeDirs. If no file is found, this returns /// ~0, otherwise it returns the buffer ID of the stacked file. - unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc); + /// The full path to the included file can be found in IncludedFile. + unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, + std::string &IncludedFile); /// FindBufferContainingLoc - Return the ID of the buffer containing the /// specified location, returning -1 if not found. diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h deleted file mode 100644 index 8dfd6f9..0000000 --- a/include/llvm/Support/StandardPasses.h +++ /dev/null @@ -1,244 +0,0 @@ -//===-- llvm/Support/StandardPasses.h - Standard pass lists -----*- 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 utility functions for creating a "standard" set of -// optimization passes, so that compilers and tools which use optimization -// passes use the same set of standard passes. -// -// These are implemented as inline functions so that we do not have to worry -// about link issues. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_STANDARDPASSES_H -#define LLVM_SUPPORT_STANDARDPASSES_H - -#include "llvm/PassManager.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/IPO.h" - -namespace llvm { - - static inline void createStandardAliasAnalysisPasses(PassManagerBase *PM) { - // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that - // BasicAliasAnalysis wins if they disagree. This is intended to help - // support "obvious" type-punning idioms. - PM->add(createTypeBasedAliasAnalysisPass()); - PM->add(createBasicAliasAnalysisPass()); - } - - /// createStandardFunctionPasses - Add the standard list of function passes to - /// the provided pass manager. - /// - /// \arg OptimizationLevel - The optimization level, corresponding to -O0, - /// -O1, etc. - static inline void createStandardFunctionPasses(PassManagerBase *PM, - unsigned OptimizationLevel) { - if (OptimizationLevel > 0) { - createStandardAliasAnalysisPasses(PM); - PM->add(createCFGSimplificationPass()); - PM->add(createScalarReplAggregatesPass()); - PM->add(createEarlyCSEPass()); - } - } - - /// createStandardModulePasses - Add the standard list of module passes to the - /// provided pass manager. - /// - /// \arg OptimizationLevel - The optimization level, corresponding to -O0, - /// -O1, etc. - /// \arg OptimizeSize - Whether the transformations should optimize for size. - /// \arg UnitAtATime - Allow passes which may make global module changes. - /// \arg UnrollLoops - Allow loop unrolling. - /// \arg SimplifyLibCalls - Allow library calls to be simplified. - /// \arg HaveExceptions - Whether the module may have code using exceptions. - /// \arg InliningPass - The inlining pass to use, if any, or null. This will - /// always be added, even at -O0.a - static inline void createStandardModulePasses(PassManagerBase *PM, - unsigned OptimizationLevel, - bool OptimizeSize, - bool UnitAtATime, - bool UnrollLoops, - bool SimplifyLibCalls, - bool HaveExceptions, - Pass *InliningPass) { - createStandardAliasAnalysisPasses(PM); - - // If all optimizations are disabled, just run the always-inline pass. - if (OptimizationLevel == 0) { - if (InliningPass) - PM->add(InliningPass); - return; - } - - if (UnitAtATime) { - PM->add(createGlobalOptimizerPass()); // Optimize out global vars - - PM->add(createIPSCCPPass()); // IP SCCP - PM->add(createDeadArgEliminationPass()); // Dead argument elimination - - PM->add(createInstructionCombiningPass());// Clean up after IPCP & DAE - PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - } - - // Start of CallGraph SCC passes. - if (UnitAtATime && HaveExceptions) - PM->add(createPruneEHPass()); // Remove dead EH info - if (InliningPass) - PM->add(InliningPass); - if (UnitAtATime) - PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs - if (OptimizationLevel > 2) - PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - // Start of function pass. - // Break up aggregate allocas, using SSAUpdater. - PM->add(createScalarReplAggregatesPass(-1, false)); - PM->add(createEarlyCSEPass()); // Catch trivial redundancies - if (SimplifyLibCalls) - PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM->add(createJumpThreadingPass()); // Thread jumps. - PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createInstructionCombiningPass()); // Combine silly seq's - - PM->add(createTailCallEliminationPass()); // Eliminate tail calls - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createReassociatePass()); // Reassociate expressions - PM->add(createLoopRotatePass()); // Rotate Loop - PM->add(createLICMPass()); // Hoist loop invariants - PM->add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel < 3)); - PM->add(createInstructionCombiningPass()); - PM->add(createIndVarSimplifyPass()); // Canonicalize indvars - PM->add(createLoopIdiomPass()); // Recognize idioms like memset. - PM->add(createLoopDeletionPass()); // Delete dead loops - if (UnrollLoops) - PM->add(createLoopUnrollPass()); // Unroll small loops - if (OptimizationLevel > 1) - PM->add(createGVNPass()); // Remove redundancies - PM->add(createMemCpyOptPass()); // Remove memcpy / form memset - PM->add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM->add(createInstructionCombiningPass()); - PM->add(createJumpThreadingPass()); // Thread jumps - PM->add(createCorrelatedValuePropagationPass()); - PM->add(createDeadStoreEliminationPass()); // Delete dead stores - PM->add(createAggressiveDCEPass()); // Delete dead instructions - PM->add(createCFGSimplificationPass()); // Merge & remove BBs - PM->add(createInstructionCombiningPass()); // Clean up after everything. - - if (UnitAtATime) { - PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - PM->add(createDeadTypeEliminationPass()); // Eliminate dead types - - // GlobalOpt already deletes dead functions and globals, at -O3 try a - // late pass of GlobalDCE. It is capable of deleting dead cycles. - if (OptimizationLevel > 2) - PM->add(createGlobalDCEPass()); // Remove dead fns and globals. - - if (OptimizationLevel > 1) - PM->add(createConstantMergePass()); // Merge dup global constants - } - } - - static inline void addOnePass(PassManagerBase *PM, Pass *P, bool AndVerify) { - PM->add(P); - - if (AndVerify) - PM->add(createVerifierPass()); - } - - /// createStandardLTOPasses - Add the standard list of module passes suitable - /// for link time optimization. - /// - /// Internalize - Run the internalize pass. - /// RunInliner - Use a function inlining pass. - /// VerifyEach - Run the verifier after each pass. - static inline void createStandardLTOPasses(PassManagerBase *PM, - bool Internalize, - bool RunInliner, - bool VerifyEach) { - // Provide AliasAnalysis services for optimizations. - createStandardAliasAnalysisPasses(PM); - - // Now that composite has been compiled, scan through the module, looking - // for a main function. If main is defined, mark all other functions - // internal. - if (Internalize) - addOnePass(PM, createInternalizePass(true), VerifyEach); - - // Propagate constants at call sites into the functions they call. This - // opens opportunities for globalopt (and inlining) by substituting function - // pointers passed as arguments to direct uses of functions. - addOnePass(PM, createIPSCCPPass(), VerifyEach); - - // Now that we internalized some globals, see if we can hack on them! - addOnePass(PM, createGlobalOptimizerPass(), VerifyEach); - - // Linking modules together can lead to duplicated global constants, only - // keep one copy of each constant... - addOnePass(PM, createConstantMergePass(), VerifyEach); - - // Remove unused arguments from functions... - addOnePass(PM, createDeadArgEliminationPass(), VerifyEach); - - // Reduce the code after globalopt and ipsccp. Both can open up significant - // simplification opportunities, and both can propagate functions through - // function pointers. When this happens, we often have to resolve varargs - // calls, etc, so let instcombine do this. - addOnePass(PM, createInstructionCombiningPass(), VerifyEach); - - // Inline small functions - if (RunInliner) - addOnePass(PM, createFunctionInliningPass(), VerifyEach); - - addOnePass(PM, createPruneEHPass(), VerifyEach); // Remove dead EH info. - // Optimize globals again if we ran the inliner. - if (RunInliner) - addOnePass(PM, createGlobalOptimizerPass(), VerifyEach); - addOnePass(PM, createGlobalDCEPass(), VerifyEach); // Remove dead functions. - - // If we didn't decide to inline a function, check to see if we can - // transform it to pass arguments by value instead of by reference. - addOnePass(PM, createArgumentPromotionPass(), VerifyEach); - - // The IPO passes may leave cruft around. Clean up after them. - addOnePass(PM, createInstructionCombiningPass(), VerifyEach); - addOnePass(PM, createJumpThreadingPass(), VerifyEach); - // Break up allocas - addOnePass(PM, createScalarReplAggregatesPass(), VerifyEach); - - // Run a few AA driven optimizations here and now, to cleanup the code. - addOnePass(PM, createFunctionAttrsPass(), VerifyEach); // Add nocapture. - addOnePass(PM, createGlobalsModRefPass(), VerifyEach); // IP alias analysis. - - addOnePass(PM, createLICMPass(), VerifyEach); // Hoist loop invariants. - addOnePass(PM, createGVNPass(), VerifyEach); // Remove redundancies. - addOnePass(PM, createMemCpyOptPass(), VerifyEach); // Remove dead memcpys. - // Nuke dead stores. - addOnePass(PM, createDeadStoreEliminationPass(), VerifyEach); - - // Cleanup and simplify the code after the scalar optimizations. - addOnePass(PM, createInstructionCombiningPass(), VerifyEach); - - addOnePass(PM, createJumpThreadingPass(), VerifyEach); - - // Delete basic blocks, which optimization passes may have killed. - addOnePass(PM, createCFGSimplificationPass(), VerifyEach); - - // Now that we have optimized the program, discard unreachable functions. - addOnePass(PM, createGlobalDCEPass(), VerifyEach); - } -} - -#endif diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h new file mode 100644 index 0000000..8d74e10 --- /dev/null +++ b/include/llvm/Support/Win64EH.h @@ -0,0 +1,100 @@ +//===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains constants and structures used for implementing +// exception handling on Win64 platforms. For more information, see +// http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_WIN64EH_H +#define LLVM_SUPPORT_WIN64EH_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { +namespace Win64EH { + +/// UnwindOpcodes - Enumeration whose values specify a single operation in +/// the prolog of a function. +enum UnwindOpcodes { + UOP_PushNonVol = 0, + UOP_AllocLarge, + UOP_AllocSmall, + UOP_SetFPReg, + UOP_SaveNonVol, + UOP_SaveNonVolBig, + UOP_SaveXMM128 = 8, + UOP_SaveXMM128Big, + UOP_PushMachFrame +}; + +/// UnwindCode - This union describes a single operation in a function prolog, +/// or part thereof. +union UnwindCode { + struct { + uint8_t codeOffset; + uint8_t unwindOp:4, + opInfo:4; + } u; + uint16_t frameOffset; +}; + +enum { + /// UNW_ExceptionHandler - Specifies that this function has an exception + /// handler. + UNW_ExceptionHandler = 0x01, + /// UNW_TerminateHandler - Specifies that this function has a termination + /// handler. + UNW_TerminateHandler = 0x02, + /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to + /// another one. + UNW_ChainInfo = 0x04 +}; + +/// RuntimeFunction - An entry in the table of functions with unwind info. +struct RuntimeFunction { + uint64_t startAddress; + uint64_t endAddress; + uint64_t unwindInfoOffset; +}; + +/// UnwindInfo - An entry in the exception table. +struct UnwindInfo { + uint8_t version:3, + flags:5; + uint8_t prologSize; + uint8_t numCodes; + uint8_t frameRegister:4, + frameOffset:4; + UnwindCode unwindCodes[1]; + + void *getLanguageSpecificData() { + return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]); + } + uint64_t getLanguageSpecificHandlerOffset() { + return *reinterpret_cast<uint64_t *>(getLanguageSpecificData()); + } + void setLanguageSpecificHandlerOffset(uint64_t offset) { + *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset; + } + RuntimeFunction *getChainedFunctionEntry() { + return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); + } + void *getExceptionData() { + return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>( + getLanguageSpecificData())+1); + } +}; + + +} // End of namespace Win64EH +} // End of namespace llvm + +#endif diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 68f0515..ab6a4e2 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -128,6 +128,11 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, // dags: (RegClass SubRegIndex, SubRegindex, ...) list<dag> SubRegClasses = []; + // isAllocatable - Specify that the register class can be used for virtual + // registers and register allocation. Some register classes are only used to + // model instruction operand constraints, and should have isAllocatable = 0. + bit isAllocatable = 1; + // MethodProtos/MethodBodies - These members can be used to insert arbitrary // code into a generated register class. The normal usage of this is to // overload virtual methods. @@ -151,6 +156,14 @@ class DwarfRegNum<list<int> Numbers> { list<int> DwarfNumbers = Numbers; } +// DwarfRegAlias - This class declares that a given register uses the same dwarf +// numbers as another one. This is useful for making it clear that the two +// registers do have the same number. It also lets us build a mapping +// from dwarf register number to llvm register. +class DwarfRegAlias<Register reg> { + Register DwarfAlias = reg; +} + //===----------------------------------------------------------------------===// // Pull in the common support for scheduling // diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 0271b67..743a2d4 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -22,6 +22,7 @@ namespace llvm { class MCSection; class MCContext; + class MachineFunction; class TargetMachine; class TargetLoweringObjectFile; @@ -58,6 +59,18 @@ public: return TLOF->getEHFrameSection(); } + const MCSection *getDwarfFrameSection() const { + return TLOF->getDwarfFrameSection(); + } + + const MCSection *getWin64EHFuncTableSection(StringRef Suffix) const { + return TLOF->getWin64EHFuncTableSection(Suffix); + } + + const MCSection *getWin64EHTableSection(StringRef Suffix) const { + return TLOF->getWin64EHTableSection(Suffix); + } + unsigned getFDEEncoding(bool CFI) const { return TLOF->getFDEEncoding(CFI); } @@ -66,6 +79,10 @@ public: return TLOF->isFunctionEHFrameSymbolPrivate(); } + const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { + return TRI->getCalleeSavedRegs(MF); + } + unsigned getDwarfRARegNum(bool isEH) const { return TRI->getDwarfRegNum(TRI->getRARegister(), isEH); } @@ -77,6 +94,14 @@ public: int getDwarfRegNum(unsigned RegNum, bool isEH) const { return TRI->getDwarfRegNum(RegNum, isEH); } + + int getLLVMRegNum(unsigned DwarfRegNum, bool isEH) const { + return TRI->getLLVMRegNum(DwarfRegNum, isEH); + } + + int getSEHRegNum(unsigned RegNum) const { + return TRI->getSEHRegNum(RegNum); + } }; } diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h index 198d585..6011402 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/Target/TargetInstrItineraries.h @@ -122,7 +122,8 @@ public: InstrItineraryData(const InstrStage *S, const unsigned *OS, const unsigned *F, const InstrItinerary *I) - : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {} + : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I), + IssueWidth(0) {} /// isEmpty - Returns true if there are no itineraries. /// diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index 0914b5d..02a1a3c 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -51,6 +51,7 @@ public: static char ID; TargetLibraryInfo(); TargetLibraryInfo(const Triple &T); + explicit TargetLibraryInfo(const TargetLibraryInfo &TLI); /// has - This function is used by optimizations that want to match on or form /// a given library function. diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 17d761c..3e36fb7 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -94,6 +94,19 @@ public: Custom // Use the LowerOperation hook to implement custom lowering. }; + /// LegalizeAction - This enum indicates whether a types are legal for a + /// target, and if not, what action should be used to make them valid. + enum LegalizeTypeAction { + TypeLegal, // The target natively supports this type. + TypePromoteInteger, // Replace this integer with a larger one. + TypeExpandInteger, // Split this integer into two of half the size. + TypeSoftenFloat, // Convert this float to a same size integer type. + TypeExpandFloat, // Split this float into two of half the size. + TypeScalarizeVector, // Replace this one-element vector with its element. + TypeSplitVector, // Split this vector into two of half the size. + TypeWidenVector // This vector should be widened into a larger vector. + }; + enum BooleanContent { // How the target represents true/false values. UndefinedBooleanContent, // Only bit 0 counts, the rest can hold garbage. ZeroOrOneBooleanContent, // All bits zero except for bit 0. @@ -200,71 +213,20 @@ public: } class ValueTypeActionImpl { - /// ValueTypeActions - For each value type, keep a LegalizeAction enum + /// ValueTypeActions - For each value type, keep a LegalizeTypeAction enum /// that indicates how instruction selection should deal with the type. uint8_t ValueTypeActions[MVT::LAST_VALUETYPE]; - LegalizeAction getExtendedTypeAction(EVT VT) const { - // Handle non-vector integers. - if (!VT.isVector()) { - assert(VT.isInteger() && "Unsupported extended type!"); - unsigned BitSize = VT.getSizeInBits(); - // First promote to a power-of-two size, then expand if necessary. - if (BitSize < 8 || !isPowerOf2_32(BitSize)) - return Promote; - return Expand; - } - - // Vectors with only one element are always scalarized. - if (VT.getVectorNumElements() == 1) - return Expand; - - // Vectors with a number of elements that is not a power of two are always - // widened, for example <3 x float> -> <4 x float>. - if (!VT.isPow2VectorType()) - return Promote; - - // Vectors with a crazy element type are always expanded, for example - // <4 x i2> is expanded into two vectors of type <2 x i2>. - if (!VT.getVectorElementType().isSimple()) - return Expand; - - // If this type is smaller than a legal vector type then widen it, - // otherwise expand it. E.g. <2 x float> -> <4 x float>. - MVT EltType = VT.getVectorElementType().getSimpleVT(); - unsigned NumElts = VT.getVectorNumElements(); - while (1) { - // Round up to the next power of 2. - NumElts = (unsigned)NextPowerOf2(NumElts); - - // If there is no simple vector type with this many elements then there - // cannot be a larger legal vector type. Note that this assumes that - // there are no skipped intermediate vector types in the simple types. - MVT LargerVector = MVT::getVectorVT(EltType, NumElts); - if (LargerVector == MVT()) - return Expand; - - // If this type is legal then widen the vector. - if (getTypeAction(LargerVector) == Legal) - return Promote; - } - } public: ValueTypeActionImpl() { std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); } - LegalizeAction getTypeAction(EVT VT) const { - if (!VT.isExtended()) - return getTypeAction(VT.getSimpleVT()); - return getExtendedTypeAction(VT); - } - - LegalizeAction getTypeAction(MVT VT) const { - return (LegalizeAction)ValueTypeActions[VT.SimpleTy]; + LegalizeTypeAction getTypeAction(MVT VT) const { + return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy]; } - void setTypeAction(EVT VT, LegalizeAction Action) { + void setTypeAction(EVT VT, LegalizeTypeAction Action) { unsigned I = VT.getSimpleVT().SimpleTy; ValueTypeActions[I] = Action; } @@ -278,10 +240,10 @@ public: /// it is already legal (return 'Legal') or we need to promote it to a larger /// type (return 'Promote'), or we need to expand it into multiple registers /// of smaller integer type (return 'Expand'). 'Custom' is not an option. - LegalizeAction getTypeAction(EVT VT) const { - return ValueTypeActions.getTypeAction(VT); + LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const { + return getTypeConversion(Context, VT).first; } - LegalizeAction getTypeAction(MVT VT) const { + LegalizeTypeAction getTypeAction(MVT VT) const { return ValueTypeActions.getTypeAction(VT); } @@ -292,38 +254,7 @@ public: /// to get to the smaller register. For illegal floating point types, this /// returns the integer type to transform to. EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const { - if (VT.isSimple()) { - assert((unsigned)VT.getSimpleVT().SimpleTy < - array_lengthof(TransformToType)); - EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; - assert(getTypeAction(NVT) != Promote && - "Promote may not follow Expand or Promote"); - return NVT; - } - - if (VT.isVector()) { - EVT NVT = VT.getPow2VectorType(Context); - if (NVT == VT) { - // Vector length is a power of 2 - split to half the size. - unsigned NumElts = VT.getVectorNumElements(); - EVT EltVT = VT.getVectorElementType(); - return (NumElts == 1) ? - EltVT : EVT::getVectorVT(Context, EltVT, NumElts / 2); - } - // Promote to a power of two size, avoiding multi-step promotion. - return getTypeAction(NVT) == Promote ? - getTypeToTransformTo(Context, NVT) : NVT; - } else if (VT.isInteger()) { - EVT NVT = VT.getRoundIntegerType(Context); - if (NVT == VT) // Size is a power of two - expand to half the size. - return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2); - - // Promote to a power of two size, avoiding multi-step promotion. - return getTypeAction(NVT) == Promote ? - getTypeToTransformTo(Context, NVT) : NVT; - } - assert(0 && "Unsupported extended type!"); - return MVT(MVT::Other); // Not reached + return getTypeConversion(Context, VT).second; } /// getTypeToExpandTo - For types supported by the target, this is an @@ -333,7 +264,7 @@ public: EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const { assert(!VT.isVector()); while (true) { - switch (getTypeAction(VT)) { + switch (getTypeAction(Context, VT)) { case Legal: return VT; case Expand: @@ -761,6 +692,18 @@ public: return MinStackArgumentAlignment; } + /// getMinFunctionAlignment - return the minimum function alignment. + /// + unsigned getMinFunctionAlignment() const { + return MinFunctionAlignment; + } + + /// getPrefFunctionAlignment - return the preferred function alignment. + /// + unsigned getPrefFunctionAlignment() const { + return PrefFunctionAlignment; + } + /// getPrefLoopAlignment - return the preferred loop alignment. /// unsigned getPrefLoopAlignment() const { @@ -824,9 +767,6 @@ public: /// PIC relocation models. virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; - /// getFunctionAlignment - Return the Log2 alignment of this function. - virtual unsigned getFunctionAlignment(const Function *) const = 0; - /// getStackCookieLocation - Return true if the target stores stack /// protector cookies at a fixed offset in some non-standard address /// space, and populates the address space and offset as @@ -1167,6 +1107,18 @@ protected: JumpBufAlignment = Align; } + /// setMinFunctionAlignment - Set the target's minimum function alignment. + void setMinFunctionAlignment(unsigned Align) { + MinFunctionAlignment = Align; + } + + /// setPrefFunctionAlignment - Set the target's preferred function alignment. + /// This should be set if there is a performance benefit to + /// higher-than-minimum alignment + void setPrefFunctionAlignment(unsigned Align) { + PrefFunctionAlignment = Align; + } + /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default /// alignment is zero, it means the target does not care about loop alignment. void setPrefLoopAlignment(unsigned Align) { @@ -1259,7 +1211,8 @@ public: /// return values described by the Outs array can fit into the return /// registers. If false is returned, an sret-demotion is performed. /// - virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, + virtual bool CanLowerReturn(CallingConv::ID CallConv, + MachineFunction &MF, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { @@ -1497,7 +1450,7 @@ public: /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops /// vector. If it is invalid, don't add anything to Ops. - virtual void LowerAsmOperandForConstraint(SDValue Op, char ConstraintLetter, + virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops, SelectionDAG &DAG) const; @@ -1583,6 +1536,14 @@ public: return true; } + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t Imm) const { + return true; + } + //===--------------------------------------------------------------------===// // Div utility functions // @@ -1637,6 +1598,13 @@ private: const TargetData *TD; const TargetLoweringObjectFile &TLOF; + /// We are in the process of implementing a new TypeLegalization action + /// which is the promotion of vector elements. This feature is under + /// development. Until this feature is complete, it is only enabled using a + /// flag. We pass this flag using a member because of circular dep issues. + /// This member will be removed with the flag once we complete the transition. + bool mayPromoteElements; + /// PointerTy - The type to use for pointers, usually i32 or i64. /// MVT PointerTy; @@ -1693,7 +1661,18 @@ private: /// unsigned MinStackArgumentAlignment; - /// PrefLoopAlignment - The perferred loop alignment. + /// MinFunctionAlignment - The minimum function alignment (used when + /// optimizing for size, and to prevent explicitly provided alignment + /// from leading to incorrect code). + /// + unsigned MinFunctionAlignment; + + /// PrefFunctionAlignment - The preferred function alignment (used when + /// alignment unspecified and optimizing for speed). + /// + unsigned PrefFunctionAlignment; + + /// PrefLoopAlignment - The preferred loop alignment. /// unsigned PrefLoopAlignment; @@ -1774,6 +1753,128 @@ private: ValueTypeActionImpl ValueTypeActions; + typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind; + + LegalizeKind + getTypeConversion(LLVMContext &Context, EVT VT) const { + // If this is a simple type, use the ComputeRegisterProp mechanism. + if (VT.isSimple()) { + assert((unsigned)VT.getSimpleVT().SimpleTy < + array_lengthof(TransformToType)); + EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; + LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT()); + + assert( + (!(NVT.isSimple() && LA != TypeLegal) || + ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger) + && "Promote may not follow Expand or Promote"); + + return LegalizeKind(LA, NVT); + } + + // Handle Extended Scalar Types. + if (!VT.isVector()) { + assert(VT.isInteger() && "Float types must be simple"); + unsigned BitSize = VT.getSizeInBits(); + // First promote to a power-of-two size, then expand if necessary. + if (BitSize < 8 || !isPowerOf2_32(BitSize)) { + EVT NVT = VT.getRoundIntegerType(Context); + assert(NVT != VT && "Unable to round integer VT"); + LegalizeKind NextStep = getTypeConversion(Context, NVT); + // Avoid multi-step promotion. + if (NextStep.first == TypePromoteInteger) return NextStep; + // Return rounded integer type. + return LegalizeKind(TypePromoteInteger, NVT); + } + + return LegalizeKind(TypeExpandInteger, + EVT::getIntegerVT(Context, VT.getSizeInBits()/2)); + } + + // Handle vector types. + unsigned NumElts = VT.getVectorNumElements(); + EVT EltVT = VT.getVectorElementType(); + + // Vectors with only one element are always scalarized. + if (NumElts == 1) + return LegalizeKind(TypeScalarizeVector, EltVT); + + // If we allow the promotion of vector elements using a flag, + // then try to widen vector elements until a legal type is found. + if (mayPromoteElements && EltVT.isInteger()) { + // Vectors with a number of elements that is not a power of two are always + // widened, for example <3 x float> -> <4 x float>. + if (!VT.isPow2VectorType()) { + NumElts = (unsigned)NextPowerOf2(NumElts); + EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts); + return LegalizeKind(TypeWidenVector, NVT); + } + + // Examine the element type. + LegalizeKind LK = getTypeConversion(Context, EltVT); + + // If type is to be expanded, split the vector. + // <4 x i140> -> <2 x i140> + if (LK.first == TypeExpandInteger) + return LegalizeKind(TypeSplitVector, + EVT::getVectorVT(Context, EltVT, NumElts / 2)); + + // Promote the integer element types until a legal vector type is found + // or until the element integer type is too big. If a legal type was not + // found, fallback to the usual mechanism of widening/splitting the + // vector. + while (1) { + // Increase the bitwidth of the element to the next pow-of-two + // (which is greater than 8 bits). + EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits() + ).getRoundIntegerType(Context); + + // Stop trying when getting a non-simple element type. + // Note that vector elements may be greater than legal vector element + // types. Example: X86 XMM registers hold 64bit element on 32bit systems. + if (!EltVT.isSimple()) break; + + // Build a new vector type and check if it is legal. + MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); + + // Found a legal promoted vector type. + if (ValueTypeActions.getTypeAction(NVT) == TypeLegal) + return LegalizeKind(TypePromoteInteger, + EVT::getVectorVT(Context, EltVT, NumElts)); + } + } + + // Try to widen the vector until a legal type is found. + // If there is no wider legal type, split the vector. + while (1) { + // Round up to the next power of 2. + NumElts = (unsigned)NextPowerOf2(NumElts); + + // If there is no simple vector type with this many elements then there + // cannot be a larger legal vector type. Note that this assumes that + // there are no skipped intermediate vector types in the simple types. + MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); + if (LargerVector == MVT()) break; + + // If this type is legal then widen the vector. + if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal) + return LegalizeKind(TypeWidenVector, LargerVector); + } + + // Widen odd vectors to next power of two. + if (!VT.isPow2VectorType()) { + EVT NVT = VT.getPow2VectorType(Context); + return LegalizeKind(TypeWidenVector, NVT); + } + + // Vectors with illegal element types are expanded. + EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); + return LegalizeKind(TypeSplitVector, NVT); + + assert(false && "Unable to handle this kind of vector type"); + return LegalizeKind(TypeLegal, VT); + } + std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses; /// TargetDAGCombineArray - Targets can specify ISD nodes that they would diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 7402ed6..3991035 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -97,10 +97,6 @@ protected: /// weak_definition of constant 0 for an omitted EH frame. bool SupportsWeakOmittedEHFrame; - /// IsFunctionEHSymbolGlobal - This flag is set to true if the ".eh" symbol - /// for a function should be marked .globl. - bool IsFunctionEHSymbolGlobal; - /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the /// "EH_frame" symbol for EH information should be an assembler temporary (aka /// private linkage, aka an L or .L label) or false if it should be a normal @@ -119,9 +115,6 @@ public: Ctx = &ctx; } - bool isFunctionEHSymbolGlobal() const { - return IsFunctionEHSymbolGlobal; - } bool isFunctionEHFrameSymbolPrivate() const { return IsFunctionEHFrameSymbolPrivate; } @@ -162,6 +155,8 @@ public: const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } + virtual const MCSection *getWin64EHFuncTableSection(StringRef suffix)const=0; + virtual const MCSection *getWin64EHTableSection(StringRef suffix) const = 0; /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively /// decide not to emit the UsedDirective for some symbols in llvm.used. diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 62190c1..beed039 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -125,10 +125,6 @@ namespace llvm { /// flag is hidden and is only for debugging the debug info. extern bool JITEmitDebugInfoToDisk; - /// UnwindTablesMandatory - This flag indicates that unwind tables should - /// be emitted for all functions. - extern bool UnwindTablesMandatory; - /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is /// specified on the commandline. When the flag is on, participating targets /// will perform tail call optimization on all calls which use the fastcc diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 205e76f..f6a8414 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -47,6 +47,7 @@ struct TargetRegisterDesc { const unsigned *SubRegs; // Sub-register set, described above const unsigned *SuperRegs; // Super-register set, described above unsigned CostPerUse; // Extra cost of instructions using register. + bool inAllocatableClass; // Register belongs to an allocatable regclass. }; class TargetRegisterClass { @@ -66,6 +67,7 @@ private: const sc_iterator SuperRegClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const int CopyCost; + const bool Allocatable; const iterator RegsBegin, RegsEnd; DenseSet<unsigned> RegSet; public: @@ -76,11 +78,12 @@ public: const TargetRegisterClass * const *supcs, const TargetRegisterClass * const *subregcs, const TargetRegisterClass * const *superregcs, - unsigned RS, unsigned Al, int CC, + unsigned RS, unsigned Al, int CC, bool Allocable, iterator RB, iterator RE) : ID(id), Name(name), VTs(vts), SubClasses(subcs), SuperClasses(supcs), SubRegClasses(subregcs), SuperRegClasses(superregcs), - RegSize(RS), Alignment(Al), CopyCost(CC), RegsBegin(RB), RegsEnd(RE) { + RegSize(RS), Alignment(Al), CopyCost(CC), Allocatable(Allocable), + RegsBegin(RB), RegsEnd(RE) { for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) RegSet.insert(*I); } @@ -182,6 +185,12 @@ public: return false; } + /// hasSubClassEq - Returns true if RC is a subclass of or equal to this + /// class. + bool hasSubClassEq(const TargetRegisterClass *RC) const { + return RC == this || hasSubClass(RC); + } + /// subclasses_begin / subclasses_end - Loop over all of the classes /// that are proper subsets of this register class. sc_iterator subclasses_begin() const { @@ -203,6 +212,12 @@ public: return false; } + /// hasSuperClassEq - Returns true if RC is a superclass of or equal to this + /// class. + bool hasSuperClassEq(const TargetRegisterClass *RC) const { + return RC == this || hasSuperClass(RC); + } + /// superclasses_begin / superclasses_end - Loop over all of the classes /// that are proper supersets of this register class. sc_iterator superclasses_begin() const { @@ -256,6 +271,10 @@ public: /// this class. A negative number means the register class is very expensive /// to copy e.g. status flag register classes. int getCopyCost() const { return CopyCost; } + + /// isAllocatable - Return true if this register class may be used to create + /// virtual registers. + bool isAllocatable() const { return Allocatable; } }; @@ -351,13 +370,13 @@ public: /// The first virtual register in a function will get the index 0. static unsigned virtReg2Index(unsigned Reg) { assert(isVirtualRegister(Reg) && "Not a virtual register"); - return Reg - (1u << 31); + return Reg & ~(1u << 31); } /// index2VirtReg - Convert a 0-based index to a virtual register number. /// This is the inverse operation of VirtReg2IndexFunctor below. static unsigned index2VirtReg(unsigned Index) { - return Index + (1u << 31); + return Index | (1u << 31); } /// getMinimalPhysRegClass - Returns the Register Class of a physical @@ -802,6 +821,8 @@ public: /// debugging info. virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0; + virtual int getLLVMRegNum(unsigned RegNum, bool isEH) const = 0; + /// getFrameRegister - This method should return the register used as a base /// for values allocated in the current stack frame. virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0; @@ -809,6 +830,12 @@ public: /// getRARegister - This method should return the register where the return /// address can be found. virtual unsigned getRARegister() const = 0; + + /// getSEHRegNum - Map a target register to an equivalent SEH register + /// number. Returns -1 if there is no equivalent value. + virtual int getSEHRegNum(unsigned i) const { + return i; + } }; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index ff8d07d..672117f 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -354,6 +354,7 @@ def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; +def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 088775a..8d55231 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -28,7 +28,8 @@ ModulePass *createOptimalEdgeProfilerPass(); ModulePass *createPathProfilerPass(); // Insert GCOV profiling instrumentation -ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true); +ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, + bool Use402Format = false); } // End llvm namespace diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index e61dcb3..7f99dbc 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -43,8 +43,10 @@ template<typename T> class SmallVectorImpl; /// constant value, convert it into an unconditional branch to the constant /// destination. This is a nontrivial operation because the successors of this /// basic block must have their PHI nodes updated. -/// -bool ConstantFoldTerminator(BasicBlock *BB); +/// Also calls RecursivelyDeleteTriviallyDeadInstructions() on any branch/switch +/// conditions and indirectbr addresses this might make dead if +/// DeleteDeadConditions is true. +bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false); //===----------------------------------------------------------------------===// // Local dead code elimination. @@ -176,6 +178,10 @@ bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, /// of llvm.dbg.value intrinsics. bool LowerDbgDeclare(Function &F); +/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic corresponding to +/// an alloca, if any. +DbgDeclareInst *FindAllocaDbgDeclare(Value *V); + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index b4048b9..51c8467 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -21,6 +21,8 @@ namespace llvm { class PHINode; template<typename T> class SmallVectorImpl; template<typename T> class SSAUpdaterTraits; + class DbgDeclareInst; + class DIBuilder; class BumpPtrAllocator; /// SSAUpdater - This class updates SSA form for a set of values defined in @@ -120,9 +122,12 @@ private: class LoadAndStorePromoter { protected: SSAUpdater &SSA; + DbgDeclareInst *DDI; + DIBuilder *DIB; public: LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts, - SSAUpdater &S, StringRef Name = StringRef()); + SSAUpdater &S, DbgDeclareInst *DDI, DIBuilder *DIB, + StringRef Name = StringRef()); virtual ~LoadAndStorePromoter() {} /// run - This does the promotion. Insts is a list of loads and stores to diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 0939d67..3bda91d 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -273,6 +273,9 @@ public: /// @brief Determine if this type could be losslessly bitcast to Ty bool canLosslesslyBitCastTo(const Type *Ty) const; + /// isEmptyTy - Return true if this type is empty, that is, it has no + /// elements or all its elements are empty. + bool isEmptyTy() const; /// Here are some useful little methods to query what type derived types are /// Note that all other types can just compare to see if this == Type::xxxTy; |