diff options
Diffstat (limited to 'contrib/llvm/include')
100 files changed, 2403 insertions, 1749 deletions
diff --git a/contrib/llvm/include/llvm-c/Core.h b/contrib/llvm/include/llvm-c/Core.h index effbd15..73bff0b 100644 --- a/contrib/llvm/include/llvm-c/Core.h +++ b/contrib/llvm/include/llvm-c/Core.h @@ -998,6 +998,13 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); /** + * Get the type of the element at a given index in the structure. + * + * @see llvm::StructType::getTypeAtIndex() + */ +LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i); + +/** * Determine whether a structure is packed. * * @see llvm::StructType::isPacked() diff --git a/contrib/llvm/include/llvm-c/Support.h b/contrib/llvm/include/llvm-c/Support.h index a9216d0..eca3b7a 100644 --- a/contrib/llvm/include/llvm-c/Support.h +++ b/contrib/llvm/include/llvm-c/Support.h @@ -58,6 +58,24 @@ LLVMBool LLVMLoadLibraryPermanently(const char* Filename); void LLVMParseCommandLineOptions(int argc, const char *const *argv, const char *Overview); +/** + * This function will search through all previously loaded dynamic + * libraries for the symbol \p symbolName. If it is found, the address of + * that symbol is returned. If not, null is returned. + * + * @see sys::DynamicLibrary::SearchForAddressOfSymbol() + */ +void *LLVMSearchForAddressOfSymbol(const char *symbolName); + +/** + * This functions permanently adds the symbol \p symbolName with the + * value \p symbolValue. These symbols are searched before any + * libraries. + * + * @see sys::DynamicLibrary::AddSymbol() + */ +void LLVMAddSymbol(const char *symbolName, void *symbolValue); + #ifdef __cplusplus } #endif diff --git a/contrib/llvm/include/llvm/ADT/APInt.h b/contrib/llvm/include/llvm/ADT/APInt.h index 36d8159..e5d143d 100644 --- a/contrib/llvm/include/llvm/ADT/APInt.h +++ b/contrib/llvm/include/llvm/ADT/APInt.h @@ -351,8 +351,7 @@ public: /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. bool isMaxSignedValue() const { - return BitWidth == 1 ? VAL == 0 - : !isNegative() && countPopulation() == BitWidth - 1; + return !isNegative() && countPopulation() == BitWidth - 1; } /// \brief Determine if this is the smallest unsigned value. @@ -366,7 +365,7 @@ public: /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. bool isMinSignedValue() const { - return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2(); + return isNegative() && isPowerOf2(); } /// \brief Check if this APInt has an N-bits unsigned integer value. diff --git a/contrib/llvm/include/llvm/ADT/Triple.h b/contrib/llvm/include/llvm/ADT/Triple.h index 2416ce3..1362fe3 100644 --- a/contrib/llvm/include/llvm/ADT/Triple.h +++ b/contrib/llvm/include/llvm/ADT/Triple.h @@ -50,7 +50,8 @@ public: armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be - bpf, // eBPF or extended BPF or 64-bit BPF (little endian) + bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) + bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) hexagon, // Hexagon: hexagon mips, // MIPS: mips, mipsallegrex mipsel, // MIPSEL: mipsel, mipsallegrexel @@ -255,6 +256,15 @@ public: /// getEnvironment - Get the parsed environment type of this triple. EnvironmentType getEnvironment() const { return Environment; } + /// \brief Parse the version number from the OS name component of the + /// triple, if present. + /// + /// For example, "fooos1.2.3" would return (1, 2, 3). + /// + /// If an entry is not defined, it will be returned as 0. + void getEnvironmentVersion(unsigned &Major, unsigned &Minor, + unsigned &Micro) const; + /// getFormat - Get the object format for this triple. ObjectFormatType getObjectFormat() const { return ObjectFormat; } diff --git a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h index ac9d21c..de18e58 100644 --- a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -40,6 +40,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Metadata.h" +#include "llvm/Analysis/MemoryLocation.h" namespace llvm { @@ -82,7 +83,7 @@ public: /// UnknownSize - This is a special value which can be used with the /// size arguments in alias queries to indicate that the caller does not /// know the sizes of the potential memory references. - static uint64_t const UnknownSize = ~UINT64_C(0); + static uint64_t const UnknownSize = MemoryLocation::UnknownSize; /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo /// object, or null if no TargetLibraryInfo object is available. @@ -98,70 +99,9 @@ public: /// Alias Queries... /// - /// Location - A description of a memory location. - struct Location { - /// Ptr - The address of the start of the location. - const Value *Ptr; - /// Size - The maximum size of the location, in address-units, or - /// UnknownSize if the size is not known. Note that an unknown size does - /// not mean the pointer aliases the entire virtual address space, because - /// there are restrictions on stepping out of one object and into another. - /// See http://llvm.org/docs/LangRef.html#pointeraliasing - uint64_t Size; - /// AATags - The metadata nodes which describes the aliasing of the - /// location (each member is null if that kind of information is - /// unavailable).. - AAMDNodes AATags; - - explicit Location(const Value *P = nullptr, uint64_t S = UnknownSize, - const AAMDNodes &N = AAMDNodes()) - : Ptr(P), Size(S), AATags(N) {} - - Location getWithNewPtr(const Value *NewPtr) const { - Location Copy(*this); - Copy.Ptr = NewPtr; - return Copy; - } - - Location getWithNewSize(uint64_t NewSize) const { - Location Copy(*this); - Copy.Size = NewSize; - return Copy; - } - - Location getWithoutAATags() const { - Location Copy(*this); - Copy.AATags = AAMDNodes(); - return Copy; - } - - bool operator==(const AliasAnalysis::Location &Other) const { - return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; - } - }; - - /// getLocation - Fill in Loc with information about the memory reference by - /// the given instruction. - Location getLocation(const LoadInst *LI); - Location getLocation(const StoreInst *SI); - Location getLocation(const VAArgInst *VI); - Location getLocation(const AtomicCmpXchgInst *CXI); - Location getLocation(const AtomicRMWInst *RMWI); - static Location getLocationForSource(const MemTransferInst *MTI); - static Location getLocationForDest(const MemIntrinsic *MI); - Location getLocation(const Instruction *Inst) { - if (auto *I = dyn_cast<LoadInst>(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast<StoreInst>(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast<VAArgInst>(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst)) - return getLocation(I); - else if (auto *I = dyn_cast<AtomicRMWInst>(Inst)) - return getLocation(I); - llvm_unreachable("unsupported memory instruction"); - } + /// Legacy typedef for the AA location object. New code should use \c + /// MemoryLocation directly. + typedef MemoryLocation Location; /// Alias analysis result - Either we know for sure that it does not alias, we /// know for sure it must alias, or we don't know anything: The two pointers @@ -601,28 +541,6 @@ public: } }; -// Specialize DenseMapInfo for Location. -template<> -struct DenseMapInfo<AliasAnalysis::Location> { - static inline AliasAnalysis::Location getEmptyKey() { - return AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(), - 0); - } - static inline AliasAnalysis::Location getTombstoneKey() { - return AliasAnalysis::Location( - DenseMapInfo<const Value *>::getTombstoneKey(), 0); - } - static unsigned getHashValue(const AliasAnalysis::Location &Val) { - return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^ - DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^ - DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags); - } - static bool isEqual(const AliasAnalysis::Location &LHS, - const AliasAnalysis::Location &RHS) { - return LHS == RHS; - } -}; - /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool isNoAliasCall(const Value *V); diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 9acc863..85a299b 100644 --- a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -191,8 +191,8 @@ public: /// \brief Data about a loop. /// - /// Contains the data necessary to represent represent a loop as a - /// pseudo-node once it's packaged. + /// Contains the data necessary to represent a loop as a pseudo-node once it's + /// packaged. struct LoopData { typedef SmallVector<std::pair<BlockNode, BlockMass>, 4> ExitMap; typedef SmallVector<BlockNode, 4> NodeList; @@ -930,7 +930,7 @@ void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F, initializeRPOT(); initializeLoops(); - // Visit loops in post-order to find thelocal mass distribution, and then do + // Visit loops in post-order to find the local mass distribution, and then do // the full function. computeMassInLoops(); computeMassInFunction(); diff --git a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h index 89eef68..9d86756 100644 --- a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h @@ -47,6 +47,9 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnFunction(Function &F) override; + + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M = nullptr) const override; /// \brief Get an edge's probability, relative to other out-edges of the Src. diff --git a/contrib/llvm/include/llvm/Analysis/CallGraph.h b/contrib/llvm/include/llvm/Analysis/CallGraph.h index 14b8822..5b64d85 100644 --- a/contrib/llvm/include/llvm/Analysis/CallGraph.h +++ b/contrib/llvm/include/llvm/Analysis/CallGraph.h @@ -230,7 +230,7 @@ public: void addCalledFunction(CallSite CS, CallGraphNode *M) { assert(!CS.getInstruction() || !CS.getCalledFunction() || !CS.getCalledFunction()->isIntrinsic()); - CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M)); + CalledFunctions.emplace_back(CS.getInstruction(), M); M->AddRef(); } diff --git a/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h index 0b3b2ea..a08ce57 100644 --- a/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/DependenceAnalysis.h @@ -41,6 +41,7 @@ #define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" @@ -520,11 +521,11 @@ namespace llvm { /// in LoopNest. bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const; - /// Makes sure both subscripts (i.e. Pair->Src and Pair->Dst) share the same - /// integer type by sign-extending one of them when necessary. + /// Makes sure all subscript pairs share the same integer type by + /// sign-extending as necessary. /// Sign-extending a subscript is safe because getelementptr assumes the - /// array subscripts are signed. - void unifySubscriptType(Subscript *Pair); + /// array subscripts are signed. + void unifySubscriptType(ArrayRef<Subscript *> Pairs); /// removeMatchingExtensions - Examines a subscript pair. /// If the source and destination are identically sign (or zero) diff --git a/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h index c14e145..7b635a8 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/contrib/llvm/include/llvm/Analysis/LoopAccessAnalysis.h @@ -345,6 +345,10 @@ public: /// to needsChecking. bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const; + /// \brief Returns the number of run-time checks required according to + /// needsChecking. + unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const; + /// \brief Print the list run-time memory checks necessary. /// /// If \p PtrPartition is set, it contains the partition number for @@ -385,7 +389,10 @@ public: /// \brief Number of memchecks required to prove independence of otherwise /// may-alias pointers. - unsigned getNumRuntimePointerChecks() const { return NumComparisons; } + unsigned getNumRuntimePointerChecks( + const SmallVectorImpl<int> *PtrPartition = nullptr) const { + return PtrRtCheck.getNumberOfChecks(PtrPartition); + } /// Return true if the block BB needs to be predicated in order for the loop /// to be vectorized. @@ -460,10 +467,6 @@ private: /// loop-independent and loop-carried dependences between memory accesses. MemoryDepChecker DepChecker; - /// \brief Number of memchecks required to prove independence of otherwise - /// may-alias pointers - unsigned NumComparisons; - Loop *TheLoop; ScalarEvolution *SE; const DataLayout &DL; @@ -501,6 +504,11 @@ const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE, const ValueToValueMap &PtrToStride, Value *Ptr, Value *OrigPtr = nullptr); +/// \brief Check the stride of the pointer and ensure that it does not wrap in +/// the address space. +int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, + const ValueToValueMap &StridesMap); + /// \brief This analysis provides dependence information for the memory accesses /// of a loop. /// diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfo.h b/contrib/llvm/include/llvm/Analysis/LoopInfo.h index be78c15..bbcde8d 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopInfo.h +++ b/contrib/llvm/include/llvm/Analysis/LoopInfo.h @@ -47,13 +47,6 @@ namespace llvm { template <typename IRUnitT> class AnalysisManager; class PreservedAnalyses; -template<typename T> -inline void RemoveFromVector(std::vector<T*> &V, T *N) { - typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N); - assert(I != V.end() && "N is not in this list!"); - V.erase(I); -} - class DominatorTree; class LoopInfo; class Loop; @@ -324,7 +317,10 @@ public: /// current loop, updating the Blocks as appropriate. This does not update /// the mapping in the LoopInfo class. void removeBlockFromLoop(BlockT *BB) { - RemoveFromVector(Blocks, BB); + auto I = std::find(Blocks.begin(), Blocks.end(), BB); + assert(I != Blocks.end() && "N is not in this list!"); + Blocks.erase(I); + DenseBlockSet.erase(BB); } @@ -493,7 +489,7 @@ private: template<class BlockT, class LoopT> class LoopInfoBase { // BBMap - Mapping of basic blocks to the inner most loop they occur in - DenseMap<BlockT *, LoopT *> BBMap; + DenseMap<const BlockT *, LoopT *> BBMap; std::vector<LoopT *> TopLevelLoops; friend class LoopBase<BlockT, LoopT>; friend class LoopInfo; @@ -543,9 +539,7 @@ public: /// getLoopFor - Return the inner most loop that BB lives in. If a basic /// block is in no loop (for example the entry node), null is returned. /// - LoopT *getLoopFor(const BlockT *BB) const { - return BBMap.lookup(const_cast<BlockT*>(BB)); - } + LoopT *getLoopFor(const BlockT *BB) const { return BBMap.lookup(BB); } /// operator[] - same as getLoopFor... /// @@ -562,7 +556,7 @@ public: } // isLoopHeader - True if the block is a loop header node - bool isLoopHeader(BlockT *BB) const { + bool isLoopHeader(const BlockT *BB) const { const LoopT *L = getLoopFor(BB); return L && L->getHeader() == BB; } @@ -729,12 +723,6 @@ public: /// \brief Provide a name for the analysis for debugging and logging. static StringRef name() { return "LoopAnalysis"; } - LoopAnalysis() {} - LoopAnalysis(const LoopAnalysis &Arg) {} - LoopAnalysis(LoopAnalysis &&Arg) {} - LoopAnalysis &operator=(const LoopAnalysis &RHS) { return *this; } - LoopAnalysis &operator=(LoopAnalysis &&RHS) { return *this; } - LoopInfo run(Function &F, AnalysisManager<Function> *AM); }; diff --git a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h index 0490bb1..f5cc856 100644 --- a/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h +++ b/contrib/llvm/include/llvm/Analysis/LoopInfoImpl.h @@ -527,7 +527,7 @@ void LoopInfoBase<BlockT, LoopT>::verify() const { // Verify that blocks are mapped to valid loops. #ifndef NDEBUG for (auto &Entry : BBMap) { - BlockT *BB = Entry.first; + const BlockT *BB = Entry.first; LoopT *L = Entry.second; assert(Loops.count(L) && "orphaned loop"); assert(L->contains(BB) && "orphaned block"); diff --git a/contrib/llvm/include/llvm/Analysis/MemoryLocation.h b/contrib/llvm/include/llvm/Analysis/MemoryLocation.h new file mode 100644 index 0000000..94d938d --- /dev/null +++ b/contrib/llvm/include/llvm/Analysis/MemoryLocation.h @@ -0,0 +1,137 @@ +//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides utility analysis objects describing memory locations. +/// These are used both by the Alias Analysis infrastructure and more +/// specialized memory analysis layers. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H +#define LLVM_ANALYSIS_MEMORYLOCATION_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Metadata.h" + +namespace llvm { + +class LoadInst; +class StoreInst; +class MemTransferInst; +class MemIntrinsic; + +/// Representation for a specific memory location. +/// +/// This abstraction can be used to represent a specific location in memory. +/// The goal of the location is to represent enough information to describe +/// abstract aliasing, modification, and reference behaviors of whatever +/// value(s) are stored in memory at the particular location. +/// +/// The primary user of this interface is LLVM's Alias Analysis, but other +/// memory analyses such as MemoryDependence can use it as well. +class MemoryLocation { +public: + /// UnknownSize - This is a special value which can be used with the + /// size arguments in alias queries to indicate that the caller does not + /// know the sizes of the potential memory references. + enum : uint64_t { UnknownSize = ~UINT64_C(0) }; + + /// The address of the start of the location. + const Value *Ptr; + + /// The maximum size of the location, in address-units, or + /// UnknownSize if the size is not known. + /// + /// Note that an unknown size does not mean the pointer aliases the entire + /// virtual address space, because there are restrictions on stepping out of + /// one object and into another. See + /// http://llvm.org/docs/LangRef.html#pointeraliasing + uint64_t Size; + + /// The metadata nodes which describes the aliasing of the location (each + /// member is null if that kind of information is unavailable). + AAMDNodes AATags; + + /// Return a location with information about the memory reference by the given + /// instruction. + static MemoryLocation get(const LoadInst *LI); + static MemoryLocation get(const StoreInst *SI); + static MemoryLocation get(const VAArgInst *VI); + static MemoryLocation get(const AtomicCmpXchgInst *CXI); + static MemoryLocation get(const AtomicRMWInst *RMWI); + static MemoryLocation get(const Instruction *Inst) { + if (auto *I = dyn_cast<LoadInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<StoreInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<VAArgInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst)) + return get(I); + else if (auto *I = dyn_cast<AtomicRMWInst>(Inst)) + return get(I); + llvm_unreachable("unsupported memory instruction"); + } + + /// Return a location representing the source of a memory transfer. + static MemoryLocation getForSource(const MemTransferInst *MTI); + + /// Return a location representing the destination of a memory set or + /// transfer. + static MemoryLocation getForDest(const MemIntrinsic *MI); + + explicit MemoryLocation(const Value *Ptr = nullptr, + uint64_t Size = UnknownSize, + const AAMDNodes &AATags = AAMDNodes()) + : Ptr(Ptr), Size(Size), AATags(AATags) {} + + MemoryLocation getWithNewPtr(const Value *NewPtr) const { + MemoryLocation Copy(*this); + Copy.Ptr = NewPtr; + return Copy; + } + + MemoryLocation getWithNewSize(uint64_t NewSize) const { + MemoryLocation Copy(*this); + Copy.Size = NewSize; + return Copy; + } + + MemoryLocation getWithoutAATags() const { + MemoryLocation Copy(*this); + Copy.AATags = AAMDNodes(); + return Copy; + } + + bool operator==(const MemoryLocation &Other) const { + return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; + } +}; + +// Specialize DenseMapInfo for MemoryLocation. +template <> struct DenseMapInfo<MemoryLocation> { + static inline MemoryLocation getEmptyKey() { + return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0); + } + static inline MemoryLocation getTombstoneKey() { + return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0); + } + static unsigned getHashValue(const MemoryLocation &Val) { + return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^ + DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^ + DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags); + } + static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) { + return LHS == RHS; + } +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/Analysis/PHITransAddr.h b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h index 84bb9d8..cbdbb88 100644 --- a/contrib/llvm/include/llvm/Analysis/PHITransAddr.h +++ b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h @@ -75,12 +75,12 @@ public: bool IsPotentiallyPHITranslatable() const; /// PHITranslateValue - PHI translate the current address up the CFG from - /// CurBB to Pred, updating our state to reflect any needed changes. If the - /// dominator tree DT is non-null, the translated value must dominate + /// CurBB to Pred, updating our state to reflect any needed changes. If + /// 'MustDominate' is true, the translated value must dominate /// PredBB. This returns true on failure and sets Addr to null. bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB, - const DominatorTree *DT); - + const DominatorTree *DT, bool MustDominate); + /// PHITranslateWithInsertion - PHI translate this value into the specified /// predecessor block, inserting a computation of the value if it is /// unavailable. diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h index 86bf154..3700c9e 100644 --- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -221,19 +221,21 @@ public: /// Parameters that control the generic loop unrolling transformation. struct UnrollingPreferences { - /// The cost threshold for the unrolled loop, compared to - /// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body. - /// The unrolling factor is set such that the unrolled loop body does not - /// exceed this cost. Set this to UINT_MAX to disable the loop body cost + /// The cost threshold for the unrolled loop. Should be relative to the + /// getUserCost values returned by this API, and the expectation is that + /// the unrolled loop's instructions when run through that interface should + /// not exceed this cost. However, this is only an estimate. Also, specific + /// loops may be unrolled even with a cost above this threshold if deemed + /// profitable. Set this to UINT_MAX to disable the loop body cost /// restriction. unsigned Threshold; - /// If complete unrolling could help other optimizations (e.g. InstSimplify) - /// to remove N% of instructions, then we can go beyond unroll threshold. - /// This value set the minimal percent for allowing that. - unsigned MinPercentOfOptimized; - /// The absolute cost threshold. We won't go beyond this even if complete - /// unrolling could result in optimizing out 90% of instructions. - unsigned AbsoluteThreshold; + /// If complete unrolling will reduce the cost of the loop below its + /// expected dynamic cost while rolled by this percentage, apply a discount + /// (below) to its unrolled cost. + unsigned PercentDynamicCostSavedThreshold; + /// The discount applied to the unrolled cost when the *dynamic* cost + /// savings of unrolling exceed the \c PercentDynamicCostSavedThreshold. + unsigned DynamicCostSavingsDiscount; /// The cost threshold for the unrolled loop when optimizing for size (set /// to UINT_MAX to disable). unsigned OptSizeThreshold; @@ -303,7 +305,8 @@ public: /// mode is legal for a load/store of any legal type. /// TODO: Handle pre/postinc as well. bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const; + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace = 0) const; /// \brief Return true if the target works with masked instruction /// AVX2 allows masks for consecutive load and store for i32 and i64 elements. @@ -319,7 +322,8 @@ public: /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const; + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace = 0) const; /// \brief Return true if it's free to truncate a value of type Ty1 to type /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16 @@ -444,6 +448,20 @@ public: unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace) const; + /// \return The cost of the interleaved memory operation. + /// \p Opcode is the memory operation code + /// \p VecTy is the vector type of the interleaved access. + /// \p Factor is the interleave factor + /// \p Indices is the indices for interleaved load members (as interleaved + /// load allows gaps) + /// \p Alignment is the alignment of the memory operation + /// \p AddressSpace is address space of the pointer. + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, + unsigned Alignment, + unsigned AddressSpace) const; + /// \brief Calculate the cost of performing a vector reduction. /// /// This is the cost of reducing the vector value of type \p Ty to a scalar @@ -539,12 +557,13 @@ public: virtual bool isLegalICmpImmediate(int64_t Imm) = 0; virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) = 0; + int64_t Scale, + unsigned AddrSpace) = 0; virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0; virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0; virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) = 0; + int64_t Scale, unsigned AddrSpace) = 0; virtual bool isTruncateFree(Type *Ty1, Type *Ty2) = 0; virtual bool isProfitableToHoist(Instruction *I) = 0; virtual bool isTypeLegal(Type *Ty) = 0; @@ -582,6 +601,11 @@ public: virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace) = 0; + virtual unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, + unsigned Alignment, + unsigned AddressSpace) = 0; virtual unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) = 0; virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, @@ -648,9 +672,10 @@ public: return Impl.isLegalICmpImmediate(Imm); } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) override { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) override { return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale); + Scale, AddrSpace); } bool isLegalMaskedStore(Type *DataType, int Consecutive) override { return Impl.isLegalMaskedStore(DataType, Consecutive); @@ -659,8 +684,10 @@ public: return Impl.isLegalMaskedLoad(DataType, Consecutive); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) override { - return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale); + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) override { + return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale, AddrSpace); } bool isTruncateFree(Type *Ty1, Type *Ty2) override { return Impl.isTruncateFree(Ty1, Ty2); @@ -740,6 +767,14 @@ public: unsigned AddressSpace) override { return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace); } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, + unsigned Alignment, + unsigned AddressSpace) override { + return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, + Alignment, AddressSpace); + } unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) override { return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm); diff --git a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index 253319c..e6a8a76 100644 --- a/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/contrib/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -207,7 +207,8 @@ public: bool isLegalICmpImmediate(int64_t Imm) { return false; } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) { // Guess that only reg and reg+reg addressing is allowed. This heuristic is // taken from the implementation of LSR. return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1); @@ -218,9 +219,10 @@ public: bool isLegalMaskedLoad(Type *DataType, int Consecutive) { return false; } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, unsigned AddrSpace) { // Guess that all legal addressing mode are free. - if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale)) + if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale, AddrSpace)) return 0; return -1; } @@ -300,6 +302,14 @@ public: return 1; } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, + unsigned Alignment, + unsigned AddressSpace) { + return 1; + } + unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys) { return 1; diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h index 46e64d1..4c040a7 100644 --- a/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h +++ b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h @@ -113,7 +113,7 @@ public: return *const_cast<BlockInfo*>(BI); // Otherwise, add a new record. - BlockInfoRecords.push_back(BlockInfo()); + BlockInfoRecords.emplace_back(); BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h index 9e2c2fa..f7487a0 100644 --- a/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h +++ b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h @@ -215,7 +215,7 @@ public: // Push the outer block's abbrev set onto the stack, start out with an // empty abbrev set. - BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); + BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); // If there is a blockinfo for this BlockID, add all the predefined abbrevs @@ -503,7 +503,7 @@ private: return *BI; // Otherwise, add a new record. - BlockInfoRecords.push_back(BlockInfo()); + BlockInfoRecords.emplace_back(); BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } diff --git a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h index d072655..3e464f4 100644 --- a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -125,23 +125,24 @@ public: } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, + unsigned AddrSpace) { TargetLoweringBase::AddrMode AM; AM.BaseGV = BaseGV; AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->isLegalAddressingMode(AM, Ty); + return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) { + bool HasBaseReg, int64_t Scale, unsigned AddrSpace) { TargetLoweringBase::AddrMode AM; AM.BaseGV = BaseGV; AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->getScalingFactorCost(AM, Ty); + return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace); } bool isTruncateFree(Type *Ty1, Type *Ty2) { @@ -522,6 +523,73 @@ public: return Cost; } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, + unsigned Alignment, + unsigned AddressSpace) { + VectorType *VT = dyn_cast<VectorType>(VecTy); + assert(VT && "Expect a vector type for interleaved memory op"); + + unsigned NumElts = VT->getNumElements(); + assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor"); + + unsigned NumSubElts = NumElts / Factor; + VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts); + + // Firstly, the cost of load/store operation. + unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace); + + // Then plus the cost of interleave operation. + if (Opcode == Instruction::Load) { + // The interleave cost is similar to extract sub vectors' elements + // from the wide vector, and insert them into sub vectors. + // + // E.g. An interleaved load of factor 2 (with one member of index 0): + // %vec = load <8 x i32>, <8 x i32>* %ptr + // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0 + // The cost is estimated as extract elements at 0, 2, 4, 6 from the + // <8 x i32> vector and insert them into a <4 x i32> vector. + + assert(Indices.size() <= Factor && + "Interleaved memory op has too many members"); + for (unsigned Index : Indices) { + assert(Index < Factor && "Invalid index for interleaved memory op"); + + // Extract elements from loaded vector for each sub vector. + for (unsigned i = 0; i < NumSubElts; i++) + Cost += getVectorInstrCost(Instruction::ExtractElement, VT, + Index + i * Factor); + } + + unsigned InsSubCost = 0; + for (unsigned i = 0; i < NumSubElts; i++) + InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i); + + Cost += Indices.size() * InsSubCost; + } else { + // The interleave cost is extract all elements from sub vectors, and + // insert them into the wide vector. + // + // E.g. An interleaved store of factor 2: + // %v0_v1 = shuffle %v0, %v1, <0, 4, 1, 5, 2, 6, 3, 7> + // store <8 x i32> %interleaved.vec, <8 x i32>* %ptr + // The cost is estimated as extract all elements from both <4 x i32> + // vectors and insert into the <8 x i32> vector. + + unsigned ExtSubCost = 0; + for (unsigned i = 0; i < NumSubElts; i++) + ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i); + + Cost += Factor * ExtSubCost; + + for (unsigned i = 0; i < NumElts; i++) + Cost += getVectorInstrCost(Instruction::InsertElement, VT, i); + } + + return Cost; + } + unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> Tys) { unsigned ISD = 0; diff --git a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h index a1b9b4e..b824df3 100644 --- a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h @@ -24,6 +24,7 @@ #include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRecip.h" #include <string> using namespace llvm; @@ -152,6 +153,12 @@ FuseFPOps("fp-contract", "Only fuse FP ops when the result won't be effected."), clEnumValEnd)); +cl::list<std::string> +ReciprocalOps("recip", + cl::CommaSeparated, + cl::desc("Choose reciprocal operation types and parameters."), + cl::value_desc("all,none,default,divf,!vec-sqrtd,vec-divd:0,sqrt:9...")); + cl::opt<bool> DontPlaceZerosInBSS("nozero-initialized-in-bss", cl::desc("Don't place zero-initialized symbols into bss section"), @@ -230,6 +237,7 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { TargetOptions Options; Options.LessPreciseFPMADOption = EnableFPMAD; Options.AllowFPOpFusion = FuseFPOps; + Options.Reciprocals = TargetRecip(ReciprocalOps); Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; diff --git a/contrib/llvm/include/llvm/CodeGen/DIE.h b/contrib/llvm/include/llvm/CodeGen/DIE.h index 8e40ef7..464e0fa 100644 --- a/contrib/llvm/include/llvm/CodeGen/DIE.h +++ b/contrib/llvm/include/llvm/CodeGen/DIE.h @@ -105,153 +105,13 @@ public: }; //===--------------------------------------------------------------------===// -/// DIE - A structured debug information entry. Has an abbreviation which -/// describes its organization. -class DIEValue; - -class DIE { -protected: - /// Offset - Offset in debug info section. - /// - unsigned Offset; - - /// Size - Size of instance + children. - /// - unsigned Size; - - /// Abbrev - Buffer for constructing abbreviation. - /// - DIEAbbrev Abbrev; - - /// Children DIEs. - /// - // This can't be a vector<DIE> because pointer validity is requirent for the - // Parent pointer and DIEEntry. - // It can't be a list<DIE> because some clients need pointer validity before - // the object has been added to any child list - // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may - // be more convoluted than beneficial. - std::vector<std::unique_ptr<DIE>> Children; - - DIE *Parent; - - /// Attribute values. - /// - SmallVector<DIEValue *, 12> Values; - -protected: - DIE() - : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} - -public: - explicit DIE(dwarf::Tag Tag) - : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} - - // Accessors. - DIEAbbrev &getAbbrev() { return Abbrev; } - const DIEAbbrev &getAbbrev() const { return Abbrev; } - unsigned getAbbrevNumber() const { return Abbrev.getNumber(); } - dwarf::Tag getTag() const { return Abbrev.getTag(); } - unsigned getOffset() const { return Offset; } - unsigned getSize() const { return Size; } - const std::vector<std::unique_ptr<DIE>> &getChildren() const { - return Children; - } - const SmallVectorImpl<DIEValue *> &getValues() const { return Values; } - DIE *getParent() const { return Parent; } - /// Climb up the parent chain to get the compile or type unit DIE this DIE - /// belongs to. - const DIE *getUnit() const; - /// Similar to getUnit, returns null when DIE is not added to an - /// owner yet. - const DIE *getUnitOrNull() const; - void setOffset(unsigned O) { Offset = O; } - void setSize(unsigned S) { Size = S; } - - /// addValue - Add a value and attributes to a DIE. - /// - void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue *Value) { - Abbrev.AddAttribute(Attribute, Form); - Values.push_back(Value); - } - - /// addChild - Add a child to the DIE. - /// - void addChild(std::unique_ptr<DIE> Child) { - assert(!Child->getParent()); - Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); - Child->Parent = this; - Children.push_back(std::move(Child)); - } - - /// findAttribute - Find a value in the DIE with the attribute given, - /// returns NULL if no such attribute exists. - DIEValue *findAttribute(dwarf::Attribute Attribute) const; - -#ifndef NDEBUG - void print(raw_ostream &O, unsigned IndentCount = 0) const; - void dump(); -#endif -}; - -//===--------------------------------------------------------------------===// -/// DIEValue - A debug information entry value. Some of these roughly correlate -/// to DWARF attribute classes. -/// -class DIEValue { -public: - enum Type { - isInteger, - isString, - isExpr, - isLabel, - isDelta, - isEntry, - isTypeSignature, - isBlock, - isLoc, - isLocList, - }; - -private: - /// Ty - Type of data stored in the value. - /// - Type Ty; - -protected: - explicit DIEValue(Type T) : Ty(T) {} - ~DIEValue() {} - -public: - // Accessors - Type getType() const { return Ty; } - - /// EmitValue - Emit value via the Dwarf writer. - /// - void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; - - /// SizeOf - Return the size of a value in bytes. - /// - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; - -#ifndef NDEBUG - void print(raw_ostream &O) const; - void dump() const; -#endif -}; - -//===--------------------------------------------------------------------===// /// DIEInteger - An integer value DIE. /// -class DIEInteger : public DIEValue { - friend DIEValue; - +class DIEInteger { uint64_t Integer; public: - explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} + explicit DIEInteger(uint64_t I) : Integer(I) {} /// BestForm - Choose the best form for integer. /// @@ -278,120 +138,91 @@ public: uint64_t getValue() const { return Integer; } void setValue(uint64_t Val) { Integer = Val; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *I) { return I->getType() == isInteger; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEExpr - An expression DIE. // -class DIEExpr : public DIEValue { - friend class DIEValue; - +class DIEExpr { const MCExpr *Expr; public: - explicit DIEExpr(const MCExpr *E) : DIEValue(isExpr), Expr(E) {} + explicit DIEExpr(const MCExpr *E) : Expr(E) {} /// getValue - Get MCExpr. /// const MCExpr *getValue() const { return Expr; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isExpr; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIELabel - A label DIE. // -class DIELabel : public DIEValue { - friend class DIEValue; - +class DIELabel { const MCSymbol *Label; public: - explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {} + explicit DIELabel(const MCSymbol *L) : Label(L) {} /// getValue - Get MCSymbol. /// const MCSymbol *getValue() const { return Label; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *L) { return L->getType() == isLabel; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEDelta - A simple label difference DIE. /// -class DIEDelta : public DIEValue { - friend class DIEValue; - +class DIEDelta { const MCSymbol *LabelHi; const MCSymbol *LabelLo; public: - DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) - : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *D) { return D->getType() == isDelta; } + DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {} -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEString - A container for string values. /// -class DIEString : public DIEValue { - friend class DIEValue; - +class DIEString { DwarfStringPoolEntryRef S; public: - DIEString(DwarfStringPoolEntryRef S) : DIEValue(isString), S(S) {} + DIEString(DwarfStringPoolEntryRef S) : S(S) {} /// getString - Grab the string out of the object. StringRef getString() const { return S.getString(); } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *D) { return D->getType() == isString; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; @@ -399,72 +230,350 @@ private: /// DIEEntry - A pointer to another debug information entry. An instance of /// this class can also be used as a proxy for a debug information entry not /// yet defined (ie. types.) -class DIEEntry : public DIEValue { - friend class DIEValue; +class DIE; +class DIEEntry { + DIE *Entry; - DIE &Entry; + DIEEntry() = delete; public: - explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) { - } + explicit DIEEntry(DIE &E) : Entry(&E) {} - DIE &getEntry() const { return Entry; } + DIE &getEntry() const { return *Entry; } /// Returns size of a ref_addr entry. static unsigned getRefAddrSize(const AsmPrinter *AP); - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isEntry; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) : sizeof(int32_t); } #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// \brief A signature reference to a type unit. -class DIETypeSignature : public DIEValue { - friend class DIEValue; +class DIETypeSignature { + const DwarfTypeUnit *Unit; - const DwarfTypeUnit &Unit; + DIETypeSignature() = delete; public: - explicit DIETypeSignature(const DwarfTypeUnit &Unit) - : DIEValue(isTypeSignature), Unit(Unit) {} + explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {} - // \brief Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { - return E->getType() == isTypeSignature; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { + assert(Form == dwarf::DW_FORM_ref_sig8); + return 8; } +#ifndef NDEBUG + void print(raw_ostream &O) const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIELocList - Represents a pointer to a location list in the debug_loc +/// section. +// +class DIELocList { + // Index into the .debug_loc vector. + size_t Index; + +public: + DIELocList(size_t I) : Index(I) {} + + /// getValue - Grab the current index out. + size_t getValue() const { return Index; } + + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + +#ifndef NDEBUG + void print(raw_ostream &O) const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIEValue - A debug information entry value. Some of these roughly correlate +/// to DWARF attribute classes. +/// +class DIEBlock; +class DIELoc; +class DIEValue { +public: + enum Type { + isNone, +#define HANDLE_DIEVALUE(T) is##T, +#include "llvm/CodeGen/DIEValue.def" + }; + private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const { - assert(Form == dwarf::DW_FORM_ref_sig8); - return 8; + /// Ty - Type of data stored in the value. + /// + Type Ty = isNone; + dwarf::Attribute Attribute = (dwarf::Attribute)0; + dwarf::Form Form = (dwarf::Form)0; + + /// Storage for the value. + /// + /// All values that aren't standard layout (or are larger than 8 bytes) + /// should be stored by reference instead of by value. + typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel, + DIEDelta *, DIEEntry, DIETypeSignature, + DIEBlock *, DIELoc *, DIELocList> ValTy; + static_assert(sizeof(ValTy) <= sizeof(uint64_t) || + sizeof(ValTy) <= sizeof(void *), + "Expected all large types to be stored via pointer"); + + /// Underlying stored value. + ValTy Val; + + template <class T> void construct(T V) { + static_assert(std::is_standard_layout<T>::value || + std::is_pointer<T>::value, + "Expected standard layout or pointer"); + new (reinterpret_cast<void *>(Val.buffer)) T(V); + } + + template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); } + template <class T> const T *get() const { + return reinterpret_cast<const T *>(Val.buffer); + } + template <class T> void destruct() { get<T>()->~T(); } + + /// Destroy the underlying value. + /// + /// This should get optimized down to a no-op. We could skip it if we could + /// add a static assert on \a std::is_trivially_copyable(), but we currently + /// support versions of GCC that don't understand that. + void destroyVal() { + switch (Ty) { + case isNone: + return; +#define HANDLE_DIEVALUE_SMALL(T) \ + case is##T: \ + destruct<DIE##T>(); + return; +#define HANDLE_DIEVALUE_LARGE(T) \ + case is##T: \ + destruct<const DIE##T *>(); + return; +#include "llvm/CodeGen/DIEValue.def" + } + } + + /// Copy the underlying value. + /// + /// This should get optimized down to a simple copy. We need to actually + /// construct the value, rather than calling memcpy, to satisfy strict + /// aliasing rules. + void copyVal(const DIEValue &X) { + switch (Ty) { + case isNone: + return; +#define HANDLE_DIEVALUE_SMALL(T) \ + case is##T: \ + construct<DIE##T>(*X.get<DIE##T>()); \ + return; +#define HANDLE_DIEVALUE_LARGE(T) \ + case is##T: \ + construct<const DIE##T *>(*X.get<const DIE##T *>()); \ + return; +#include "llvm/CodeGen/DIEValue.def" + } } +public: + DIEValue() = default; + DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { + copyVal(X); + } + DIEValue &operator=(const DIEValue &X) { + destroyVal(); + Ty = X.Ty; + Attribute = X.Attribute; + Form = X.Form; + copyVal(X); + return *this; + } + ~DIEValue() { destroyVal(); } + +#define HANDLE_DIEVALUE_SMALL(T) \ + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ + construct<DIE##T>(V); \ + } +#define HANDLE_DIEVALUE_LARGE(T) \ + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ + assert(V && "Expected valid value"); \ + construct<const DIE##T *>(V); \ + } +#include "llvm/CodeGen/DIEValue.def" + + // Accessors + Type getType() const { return Ty; } + dwarf::Attribute getAttribute() const { return Attribute; } + dwarf::Form getForm() const { return Form; } + explicit operator bool() const { return Ty; } + +#define HANDLE_DIEVALUE_SMALL(T) \ + const DIE##T &getDIE##T() const { \ + assert(getType() == is##T && "Expected " #T); \ + return *get<DIE##T>(); \ + } +#define HANDLE_DIEVALUE_LARGE(T) \ + const DIE##T &getDIE##T() const { \ + assert(getType() == is##T && "Expected " #T); \ + return **get<const DIE##T *>(); \ + } +#include "llvm/CodeGen/DIEValue.def" + + /// EmitValue - Emit value via the Dwarf writer. + /// + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + + /// SizeOf - Return the size of a value in bytes. + /// + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; + void dump() const; +#endif +}; + +//===--------------------------------------------------------------------===// +/// DIE - A structured debug information entry. Has an abbreviation which +/// describes its organization. +class DIE { +protected: + /// Offset - Offset in debug info section. + /// + unsigned Offset; + + /// Size - Size of instance + children. + /// + unsigned Size; + + unsigned AbbrevNumber = ~0u; + + /// Tag - Dwarf tag code. + /// + dwarf::Tag Tag = (dwarf::Tag)0; + + /// Children DIEs. + /// + // This can't be a vector<DIE> because pointer validity is requirent for the + // Parent pointer and DIEEntry. + // It can't be a list<DIE> because some clients need pointer validity before + // the object has been added to any child list + // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may + // be more convoluted than beneficial. + std::vector<std::unique_ptr<DIE>> Children; + + DIE *Parent; + + /// Attribute values. + /// + SmallVector<DIEValue, 12> Values; + +protected: + DIE() : Offset(0), Size(0), Parent(nullptr) {} + +public: + explicit DIE(dwarf::Tag Tag) + : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {} + + // Accessors. + unsigned getAbbrevNumber() const { return AbbrevNumber; } + dwarf::Tag getTag() const { return Tag; } + unsigned getOffset() const { return Offset; } + unsigned getSize() const { return Size; } + bool hasChildren() const { return !Children.empty(); } + + typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator; + typedef iterator_range<child_iterator> child_range; + + child_range children() const { + return llvm::make_range(Children.begin(), Children.end()); + } + + typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator; + typedef iterator_range<value_iterator> value_range; + + value_iterator values_begin() const { return Values.begin(); } + value_iterator values_end() const { return Values.end(); } + value_range values() const { + return llvm::make_range(values_begin(), values_end()); + } + + void setValue(unsigned I, DIEValue New) { + assert(I < Values.size()); + Values[I] = New; + } + DIE *getParent() const { return Parent; } + + /// Generate the abbreviation for this DIE. + /// + /// Calculate the abbreviation for this, which should be uniqued and + /// eventually used to call \a setAbbrevNumber(). + DIEAbbrev generateAbbrev() const; + + /// Set the abbreviation number for this DIE. + void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } + + /// Climb up the parent chain to get the compile or type unit DIE this DIE + /// belongs to. + const DIE *getUnit() const; + /// Similar to getUnit, returns null when DIE is not added to an + /// owner yet. + const DIE *getUnitOrNull() const; + void setOffset(unsigned O) { Offset = O; } + void setSize(unsigned S) { Size = S; } + + /// addValue - Add a value and attributes to a DIE. + /// + void addValue(DIEValue Value) { Values.push_back(Value); } + template <class T> + void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) { + Values.emplace_back(Attribute, Form, std::forward<T>(Value)); + } + + /// addChild - Add a child to the DIE. + /// + DIE &addChild(std::unique_ptr<DIE> Child) { + assert(!Child->getParent()); + Child->Parent = this; + Children.push_back(std::move(Child)); + return *Children.back(); + } + + /// Find a value in the DIE with the attribute given. + /// + /// Returns a default-constructed DIEValue (where \a DIEValue::getType() + /// gives \a DIEValue::isNone) if no such attribute exists. + DIEValue findAttribute(dwarf::Attribute Attribute) const; + +#ifndef NDEBUG + void print(raw_ostream &O, unsigned IndentCount = 0) const; + void dump(); #endif }; //===--------------------------------------------------------------------===// /// DIELoc - Represents an expression location. // -class DIELoc : public DIEValue, public DIE { - friend class DIEValue; - +class DIELoc : public DIE { mutable unsigned Size; // Size in bytes excluding size header. + public: - DIELoc() : DIEValue(isLoc), Size(0) {} + DIELoc() : Size(0) {} /// ComputeSize - Calculate the size of the location expression. /// @@ -485,27 +594,22 @@ public: return dwarf::DW_FORM_block; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isLoc; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; //===--------------------------------------------------------------------===// /// DIEBlock - Represents a block of values. // -class DIEBlock : public DIEValue, public DIE { - friend class DIEValue; - +class DIEBlock : public DIE { mutable unsigned Size; // Size in bytes excluding size header. + public: - DIEBlock() : DIEValue(isBlock), Size(0) {} + DIEBlock() : Size(0) {} /// ComputeSize - Calculate the size of the location expression. /// @@ -523,43 +627,11 @@ public: return dwarf::DW_FORM_block; } - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isBlock; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; - -#ifndef NDEBUG - void printImpl(raw_ostream &O) const; -#endif -}; - -//===--------------------------------------------------------------------===// -/// DIELocList - Represents a pointer to a location list in the debug_loc -/// section. -// -class DIELocList : public DIEValue { - friend class DIEValue; - - // Index into the .debug_loc vector. - size_t Index; - -public: - DIELocList(size_t I) : DIEValue(isLocList), Index(I) {} - - /// getValue - Grab the current index out. - size_t getValue() const { return Index; } - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *E) { return E->getType() == isLocList; } - -private: - void EmitValueImpl(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOfImpl(const AsmPrinter *AP, dwarf::Form Form) const; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; #ifndef NDEBUG - void printImpl(raw_ostream &O) const; + void print(raw_ostream &O) const; #endif }; diff --git a/contrib/llvm/include/llvm/CodeGen/DIEValue.def b/contrib/llvm/include/llvm/CodeGen/DIEValue.def new file mode 100644 index 0000000..2cfae7b --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/DIEValue.def @@ -0,0 +1,47 @@ +//===- llvm/CodeGen/DIEValue.def - DIEValue types ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Macros for running through all types of DIEValue. +// +//===----------------------------------------------------------------------===// + +#if !(defined HANDLE_DIEVALUE || defined HANDLE_DIEVALUE_SMALL || \ + defined HANDLE_DIEVALUE_LARGE) +#error "Missing macro definition of HANDLE_DIEVALUE" +#endif + +// Handler for all values. +#ifndef HANDLE_DIEVALUE +#define HANDLE_DIEVALUE(T) +#endif + +// Handler for small values. +#ifndef HANDLE_DIEVALUE_SMALL +#define HANDLE_DIEVALUE_SMALL(T) HANDLE_DIEVALUE(T) +#endif + +// Handler for large values. +#ifndef HANDLE_DIEVALUE_LARGE +#define HANDLE_DIEVALUE_LARGE(T) HANDLE_DIEVALUE(T) +#endif + +HANDLE_DIEVALUE_SMALL(Integer) +HANDLE_DIEVALUE_SMALL(String) +HANDLE_DIEVALUE_SMALL(Expr) +HANDLE_DIEVALUE_SMALL(Label) +HANDLE_DIEVALUE_LARGE(Delta) +HANDLE_DIEVALUE_SMALL(Entry) +HANDLE_DIEVALUE_SMALL(TypeSignature) +HANDLE_DIEVALUE_LARGE(Block) +HANDLE_DIEVALUE_LARGE(Loc) +HANDLE_DIEVALUE_SMALL(LocList) + +#undef HANDLE_DIEVALUE +#undef HANDLE_DIEVALUE_SMALL +#undef HANDLE_DIEVALUE_LARGE diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h index 357b2d8..e883bd1 100644 --- a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h +++ b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h @@ -121,7 +121,7 @@ public: /// label just prior to the safe point (if the code generator is using /// MachineModuleInfo). void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) { - SafePoints.push_back(GCPoint(Kind, Label, DL)); + SafePoints.emplace_back(Kind, Label, DL); } /// getFrameSize/setFrameSize - Records the function's frame size. diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h index de855f2..c97c636 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -102,6 +102,10 @@ private: /// registers are created. void MRI_NoteNewVirtualRegister(unsigned VReg) override; + /// \brief Check if MachineOperand \p MO is a last use/kill either in the + /// main live range of \p LI or in one of the matching subregister ranges. + bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const; + public: /// Create a LiveRangeEdit for breaking down parent into smaller pieces. /// @param parent The register being spilled or split. diff --git a/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h new file mode 100644 index 0000000..710b2d4 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h @@ -0,0 +1,52 @@ +//===- MIRParser.h - MIR serialization format parser ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This MIR serialization library is currently a work in progress. It can't +// serialize machine functions at this time. +// +// This file declares the functions that parse the MIR serialization format +// files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MIRPARSER_MIRPARSER_H +#define LLVM_CODEGEN_MIRPARSER_MIRPARSER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/MemoryBuffer.h" +#include <memory> + +namespace llvm { + +class SMDiagnostic; + +/// This function is the main interface to the MIR serialization format parser. +/// +/// It reads a YAML file that has an optional LLVM IR and returns an LLVM +/// module. +/// \param Filename - The name of the file to parse. +/// \param Error - Error result info. +/// \param Context - Context in which to allocate globals info. +std::unique_ptr<Module> parseMIRFile(StringRef Filename, SMDiagnostic &Error, + LLVMContext &Context); + +/// This function is another interface to the MIR serialization format parser. +/// +/// It parses the optional LLVM IR in the given buffer, and returns an LLVM +/// module. +/// \param Contents - The MemoryBuffer containing the machine level IR. +/// \param Error - Error result info. +/// \param Context - Context in which to allocate globals info. +std::unique_ptr<Module> parseMIR(std::unique_ptr<MemoryBuffer> Contents, + SMDiagnostic &Error, LLVMContext &Context); + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h new file mode 100644 index 0000000..f9d4c74 --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h @@ -0,0 +1,40 @@ +//===- MIRYAMLMapping.h - Describes the mapping between MIR and YAML ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The MIR serialization library is currently a work in progress. It can't +// serialize machine functions at this time. +// +// This file implements the mapping between various MIR data structures and +// their corresponding YAML representation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H +#define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { +namespace yaml { + +struct MachineFunction { + StringRef Name; +}; + +template <> struct MappingTraits<MachineFunction> { + static void mapping(IO &YamlIO, MachineFunction &MF) { + YamlIO.mapRequired("name", MF.Name); + } +}; + +} // end namespace yaml +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h index 40f3b49..3889d471 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -256,11 +256,6 @@ class MachineFrameInfo { /// Not null, if shrink-wrapping found a better place for the epilogue. MachineBasicBlock *Restore; - /// Check if it exists a path from \p MBB leading to the basic - /// block with a SavePoint (a.k.a. prologue). - bool isBeforeSavePoint(const MachineFunction &MF, - const MachineBasicBlock &MBB) const; - public: explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign, bool RealignOpt) @@ -627,16 +622,15 @@ public: MachineBasicBlock *getRestorePoint() const { return Restore; } void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; } - /// getPristineRegs - Return a set of physical registers that are pristine on - /// entry to the MBB. + /// Return a set of physical registers that are pristine. /// /// Pristine registers hold a value that is useless to the current function, - /// but that must be preserved - they are callee saved registers that have not - /// been saved yet. + /// but that must be preserved - they are callee saved registers that are not + /// saved. /// /// Before the PrologueEpilogueInserter has placed the CSR spill code, this /// method always returns an empty set. - BitVector getPristineRegs(const MachineBasicBlock *MBB) const; + BitVector getPristineRegs(const MachineFunction &MF) const; /// print - Used by the MachineFunction printer to print information about /// stack objects. Implemented in MachineFunction.cpp diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h index e57257c..edda03f 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h @@ -331,6 +331,11 @@ public: operands_begin() + getDesc().getNumDefs(), operands_end()); } + /// Returns the number of the operand iterator \p I points to. + unsigned getOperandNo(const_mop_iterator I) const { + return I - operands_begin(); + } + /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } @@ -483,6 +488,13 @@ public: return hasProperty(MCID::NotDuplicable, Type); } + /// Return true if this instruction is convergent. + /// Convergent instructions can only be moved to locations that are + /// control-equivalent to their initial position. + bool isConvergent(QueryType Type = AnyInBundle) const { + return hasProperty(MCID::Convergent, Type); + } + /// Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot(QueryType Type = AnyInBundle) const { @@ -924,7 +936,7 @@ public: /// For normal instructions, this is derived from the MCInstrDesc. /// For inline assembly it is derived from the flag words. /// - /// Returns NULL if the static register classs constraint cannot be + /// Returns NULL if the static register class constraint cannot be /// determined. /// const TargetRegisterClass* @@ -936,10 +948,10 @@ public: /// the given \p CurRC. /// If \p ExploreBundle is set and MI is part of a bundle, all the /// instructions inside the bundle will be taken into account. In other words, - /// this method accumulates all the constrains of the operand of this MI and + /// this method accumulates all the constraints of the operand of this MI and /// the related bundle if MI is a bundle or inside a bundle. /// - /// Returns the register class that statisfies both \p CurRC and the + /// Returns the register class that satisfies both \p CurRC and the /// constraints set by MI. Returns NULL if such a register class does not /// exist. /// @@ -952,7 +964,7 @@ public: /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand /// to the given \p CurRC. /// - /// Returns the register class that statisfies both \p CurRC and the + /// Returns the register class that satisfies both \p CurRC and the /// constraints set by \p OpIdx MI. Returns NULL if such a register class /// does not exist. /// diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h index f7bcf45..438ef2e 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h @@ -114,7 +114,7 @@ public: } // isLoopHeader - True if the block is a loop header node - inline bool isLoopHeader(MachineBasicBlock *BB) const { + inline bool isLoopHeader(const MachineBasicBlock *BB) const { return LI.isLoopHeader(BB); } diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h index 39f6954..9c7e7b4 100644 --- a/contrib/llvm/include/llvm/CodeGen/Passes.h +++ b/contrib/llvm/include/llvm/CodeGen/Passes.h @@ -17,11 +17,11 @@ #include "llvm/Pass.h" #include "llvm/Target/TargetMachine.h" +#include <functional> #include <string> namespace llvm { -class FunctionPass; class MachineFunctionPass; class PassConfigImpl; class PassInfo; @@ -374,6 +374,10 @@ namespace llvm { createMachineFunctionPrinterPass(raw_ostream &OS, const std::string &Banner =""); + /// MIRPrinting pass - this pass prints out the LLVM IR into the given stream + /// using the MIR serialization format. + MachineFunctionPass *createPrintMIRPass(raw_ostream &OS); + /// createCodeGenPreparePass - Transform the code to expose more pattern /// matching during instruction selection. FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr); @@ -488,6 +492,10 @@ namespace llvm { /// MachineFunctionPrinterPass - This pass prints out MachineInstr's. extern char &MachineFunctionPrinterPassID; + /// MIRPrintingPass - this pass prints out the LLVM IR using the MIR + /// serialization format. + extern char &MIRPrintingPassID; + /// TailDuplicate - Duplicate blocks with unconditional branches /// into tails of their predecessors. extern char &TailDuplicateID; @@ -511,6 +519,8 @@ namespace llvm { /// IfConverter - This pass performs machine code if conversion. extern char &IfConverterID; + FunctionPass *createIfConverter(std::function<bool(const Function &)> Ftor); + /// MachineBlockPlacement - This pass places basic blocks based on branch /// probabilities. extern char &MachineBlockPlacementID; @@ -605,6 +615,9 @@ namespace llvm { /// UnpackMachineBundles - This pass unpack machine instruction bundles. extern char &UnpackMachineBundlesID; + FunctionPass * + createUnpackMachineBundles(std::function<bool(const Function &)> Ftor); + /// FinalizeMachineBundles - This pass finalize machine instruction /// bundles (created earlier, e.g. during pre-RA scheduling). extern char &FinalizeMachineBundlesID; diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h index 1196783..b56d5ec 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -260,7 +260,7 @@ namespace llvm { #ifndef NDEBUG const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0]; #endif - SUnits.push_back(SUnit(MI, (unsigned)SUnits.size())); + SUnits.emplace_back(MI, (unsigned)SUnits.size()); assert((Addr == nullptr || Addr == &SUnits[0]) && "SUnits std::vector reallocated on the fly!"); SUnits.back().OrigNode = &SUnits.back(); diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h index 89f9005..78fdd04 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -878,6 +878,10 @@ public: /// Return an MDNodeSDNode which holds an MDNode. SDValue getMDNode(const MDNode *MD); + /// Return a bitcast using the SDLoc of the value operand, and casting to the + /// provided type. Use getNode to set a custom SDLoc. + SDValue getBitcast(EVT VT, SDValue V); + /// Return an AddrSpaceCastSDNode. SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS); diff --git a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h index e2644ed..1cff320 100644 --- a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h @@ -23,6 +23,7 @@ class BasicBlock; class Constant; class Function; class GlobalVariable; +class InvokeInst; class IntrinsicInst; class LandingPadInst; class MCSymbol; @@ -153,5 +154,11 @@ struct WinEHFuncInfo { NumIPToStateFuncsVisited(0) {} }; +/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which +/// describes the state numbers and tables used by __CxxFrameHandler3. This +/// analysis assumes that WinEHPrepare has already been run. +void calculateWinCXXEHStateNumbers(const Function *ParentFn, + WinEHFuncInfo &FuncInfo); + } #endif // LLVM_CODEGEN_WINEHFUNCINFO_H diff --git a/contrib/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm/include/llvm/DebugInfo/DIContext.h index dddc7fa..871e60c 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DIContext.h +++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h @@ -141,8 +141,7 @@ private: /// on the fly. class LoadedObjectInfo { public: - LoadedObjectInfo() {} - virtual ~LoadedObjectInfo() {} + virtual ~LoadedObjectInfo() = default; /// Obtain the Load Address of a section by Name. /// @@ -170,7 +169,7 @@ public: /// Obtain a copy of this LoadedObjectInfo. /// /// The caller is responsible for deallocation once the copy is no longer required. - virtual LoadedObjectInfo *clone() const = 0; + virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0; }; } diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 37b22c2..93e7c79 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -38,12 +38,12 @@ public: // The size in bytes of the statement information for this compilation unit // (not including the total_length field itself). - uint32_t TotalLength; + uint64_t TotalLength; // Version identifier for the statement information format. uint16_t Version; // The number of bytes following the prologue_length field to the beginning // of the first byte of the statement program itself. - uint32_t PrologueLength; + uint64_t PrologueLength; // The size in bytes of the smallest target machine instruction. Statement // program opcodes that alter the address register first multiply their // operands by this value. @@ -63,14 +63,22 @@ public: std::vector<const char*> IncludeDirectories; std::vector<FileNameEntry> FileNames; + bool IsDWARF64; + uint32_t sizeofTotalLength() const { + return IsDWARF64 ? 12 : 4; + } + uint32_t sizeofPrologueLength() const { + return IsDWARF64 ? 8 : 4; + } + // Length of the prologue in bytes. uint32_t getLength() const { - return PrologueLength + sizeof(TotalLength) + sizeof(Version) + - sizeof(PrologueLength); + return PrologueLength + sizeofTotalLength() + sizeof(Version) + + sizeofPrologueLength(); } // Length of the line table data in bytes (not including the prologue). uint32_t getStatementTableLength() const { - return TotalLength + sizeof(TotalLength) - getLength(); + return TotalLength + sizeofTotalLength() - getLength(); } int32_t getMaxLineIncrementForSpecialOpcode() const { return LineBase + (int8_t)LineRange - 1; @@ -163,6 +171,9 @@ public: struct LineTable { LineTable(); + // Represents an invalid row + const uint32_t UnknownRowIndex = UINT32_MAX; + void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } @@ -171,7 +182,7 @@ public: } // Returns the index of the row with file/line info for a given address, - // or -1 if there is no such row. + // or UnknownRowIndex if there is no such row. uint32_t lookupAddress(uint64_t address) const; bool lookupAddressRange(uint64_t address, uint64_t size, @@ -203,6 +214,10 @@ public: typedef SequenceVector::const_iterator SequenceIter; RowVector Rows; SequenceVector Sequences; + + private: + uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq, + uint64_t address) const; }; const LineTable *getLineTable(uint32_t offset) const; diff --git a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 719adbc..074d55e 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -390,8 +390,7 @@ public: for (auto &F : *M) { if (F.isDeclaration()) continue; - Partitioning.push_back(std::vector<Function*>()); - Partitioning.back().push_back(&F); + Partitioning.emplace_back(1, &F); } addLogicalModule(*LogicalDylibs.back(), std::shared_ptr<Module>(std::move(M)), diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index ac0151a..94c4038 100644 --- a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H #include "JITSymbolFlags.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Memory.h" #include "llvm/DebugInfo/DIContext.h" @@ -62,8 +63,6 @@ public: unsigned EndIdx) : RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { } - virtual ~LoadedObjectInfo() = default; - virtual object::OwningBinary<object::ObjectFile> getObjectForDebug(const object::ObjectFile &Obj) const = 0; @@ -80,8 +79,8 @@ public: LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, unsigned EndIdx) : LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {} - llvm::LoadedObjectInfo *clone() const override { - return new Derived(static_cast<const Derived &>(*this)); + std::unique_ptr<llvm::LoadedObjectInfo> clone() const override { + return llvm::make_unique<Derived>(static_cast<const Derived &>(*this)); } }; diff --git a/contrib/llvm/include/llvm/IR/InlineAsm.h b/contrib/llvm/include/llvm/IR/InlineAsm.h index 15942f1..08b5102 100644 --- a/contrib/llvm/include/llvm/IR/InlineAsm.h +++ b/contrib/llvm/include/llvm/IR/InlineAsm.h @@ -248,6 +248,13 @@ public: Constraint_R, Constraint_S, Constraint_T, + Constraint_Um, + Constraint_Un, + Constraint_Uq, + Constraint_Us, + Constraint_Ut, + Constraint_Uv, + Constraint_Uy, Constraint_X, Constraint_Z, Constraint_ZC, diff --git a/contrib/llvm/include/llvm/IR/Instructions.h b/contrib/llvm/include/llvm/IR/Instructions.h index 9f5e244..8d8c530 100644 --- a/contrib/llvm/include/llvm/IR/Instructions.h +++ b/contrib/llvm/include/llvm/IR/Instructions.h @@ -810,6 +810,7 @@ inline Type *checkGEPType(Type *Ty) { /// class GetElementPtrInst : public Instruction { Type *SourceElementType; + Type *ResultElementType; GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr); @@ -903,9 +904,12 @@ public: Type *getSourceElementType() const { return SourceElementType; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; } + void setResultElementType(Type *Ty) { ResultElementType = Ty; } Type *getResultElementType() const { - return cast<PointerType>(getType()->getScalarType())->getElementType(); + assert(ResultElementType == + cast<PointerType>(getType()->getScalarType())->getElementType()); + return ResultElementType; } /// \brief Returns the address space of this instruction's pointer type. @@ -1028,7 +1032,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - Values, Values, InsertBefore), - SourceElementType(PointeeType) { + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast<PointerType>(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, @@ -1038,7 +1045,10 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - Values, Values, InsertAtEnd), - SourceElementType(PointeeType) { + SourceElementType(PointeeType), + ResultElementType(getIndexedType(PointeeType, IdxList)) { + assert(ResultElementType == + cast<PointerType>(getType()->getScalarType())->getElementType()); init(Ptr, IdxList, NameStr); } diff --git a/contrib/llvm/include/llvm/IR/Intrinsics.td b/contrib/llvm/include/llvm/IR/Intrinsics.td index 8f6cdeb..beeffde 100644 --- a/contrib/llvm/include/llvm/IR/Intrinsics.td +++ b/contrib/llvm/include/llvm/IR/Intrinsics.td @@ -537,7 +537,8 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty], def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_anyptr_ty, llvm_i32_ty, - llvm_i32_ty, llvm_vararg_ty]>; + llvm_i32_ty, llvm_vararg_ty], + [Throws]>; def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>; def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty], diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsX86.td b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td index 3a8a4a6..0826aa2 100644 --- a/contrib/llvm/include/llvm/IR/IntrinsicsX86.td +++ b/contrib/llvm/include/llvm/IR/IntrinsicsX86.td @@ -3372,10 +3372,40 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>; - def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">, + def int_x86_avx512_mask_sqrt_pd_128 : GCCBuiltin<"__builtin_ia32_sqrtpd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_pd_256 : GCCBuiltin<"__builtin_ia32_sqrtpd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512_mask">, + Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, + llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ps_128 : GCCBuiltin<"__builtin_ia32_sqrtps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ps_256 : GCCBuiltin<"__builtin_ia32_sqrtps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">, + Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, + llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_128 : GCCBuiltin<"__builtin_ia32_getexppd128_mask">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_256 : GCCBuiltin<"__builtin_ia32_getexppd256_mask">, + Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_pd_512 : GCCBuiltin<"__builtin_ia32_getexppd512_mask">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512_mask">, + def int_x86_avx512_mask_getexp_ps_128 : GCCBuiltin<"__builtin_ia32_getexpps128_mask">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_ps_256 : GCCBuiltin<"__builtin_ia32_getexpps256_mask">, + Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, + llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_getexp_ps_512 : GCCBuiltin<"__builtin_ia32_getexpps512_mask">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>; diff --git a/contrib/llvm/include/llvm/IR/MDBuilder.h b/contrib/llvm/include/llvm/IR/MDBuilder.h index ba14457..ceb1c73 100644 --- a/contrib/llvm/include/llvm/IR/MDBuilder.h +++ b/contrib/llvm/include/llvm/IR/MDBuilder.h @@ -153,7 +153,7 @@ public: /// \brief Return metadata for a TBAA tag node with the given /// base type, access type and offset relative to the base type. MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, - uint64_t Offset); + uint64_t Offset, bool IsConstant = false); }; } // end namespace llvm diff --git a/contrib/llvm/include/llvm/IR/Value.h b/contrib/llvm/include/llvm/IR/Value.h index 3bf2943..19a1d6c 100644 --- a/contrib/llvm/include/llvm/IR/Value.h +++ b/contrib/llvm/include/llvm/IR/Value.h @@ -69,9 +69,8 @@ class Value { Type *VTy; Use *UseList; - friend class ValueAsMetadata; // Allow access to NameAndIsUsedByMD. + friend class ValueAsMetadata; // Allow access to IsUsedByMD. friend class ValueHandleBase; - PointerIntPair<ValueName *, 1> NameAndIsUsedByMD; const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? @@ -101,7 +100,10 @@ protected: /// This is stored here to save space in User on 64-bit hosts. Since most /// instances of Value have operands, 32-bit hosts aren't significantly /// affected. - unsigned NumOperands; + unsigned NumOperands : 30; + + bool IsUsedByMD : 1; + bool HasName : 1; private: template <typename UseT> // UseT == 'Use' or 'const Use' @@ -210,9 +212,9 @@ public: LLVMContext &getContext() const; // \brief All values can potentially be named. - bool hasName() const { return getValueName() != nullptr; } - ValueName *getValueName() const { return NameAndIsUsedByMD.getPointer(); } - void setValueName(ValueName *VN) { NameAndIsUsedByMD.setPointer(VN); } + bool hasName() const { return HasName; } + ValueName *getValueName() const; + void setValueName(ValueName *VN); private: void destroyValueName(); @@ -394,7 +396,7 @@ public: bool hasValueHandle() const { return HasValueHandle; } /// \brief Return true if there is metadata referencing this value. - bool isUsedByMetadata() const { return NameAndIsUsedByMD.getInt(); } + bool isUsedByMetadata() const { return IsUsedByMD; } /// \brief Strip off pointer casts, all-zero GEPs, and aliases. /// diff --git a/contrib/llvm/include/llvm/InitializePasses.h b/contrib/llvm/include/llvm/InitializePasses.h index 497ac55..4f95c88 100644 --- a/contrib/llvm/include/llvm/InitializePasses.h +++ b/contrib/llvm/include/llvm/InitializePasses.h @@ -289,6 +289,7 @@ void initializeLoopVectorizePass(PassRegistry&); void initializeSLPVectorizerPass(PassRegistry&); void initializeBBVectorizePass(PassRegistry&); void initializeMachineFunctionPrinterPassPass(PassRegistry&); +void initializeMIRPrintingPassPass(PassRegistry&); void initializeStackMapLivenessPass(PassRegistry&); void initializeMachineCombinerPass(PassRegistry &); void initializeLoadCombinePass(PassRegistry&); diff --git a/contrib/llvm/include/llvm/LTO/LTOCodeGenerator.h b/contrib/llvm/include/llvm/LTO/LTOCodeGenerator.h index 3b4be81..0c46fc0 100644 --- a/contrib/llvm/include/llvm/LTO/LTOCodeGenerator.h +++ b/contrib/llvm/include/llvm/LTO/LTOCodeGenerator.h @@ -82,7 +82,7 @@ struct LTOCodeGenerator { void setShouldInternalize(bool Value) { ShouldInternalize = Value; } void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; } - void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } + void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; } // To pass options to the driver and optimization passes. These options are // not necessarily for debugging purpose (The function name is misleading). @@ -117,11 +117,10 @@ struct LTOCodeGenerator { // (linker), it brings the object to a buffer, and return the buffer to the // caller. This function should delete intermediate object file once its content // is brought to memory. Return NULL if the compilation was not successful. - const void *compile(size_t *length, - bool disableInline, - bool disableGVNLoadPRE, - bool disableVectorization, - std::string &errMsg); + std::unique_ptr<MemoryBuffer> compile(bool disableInline, + bool disableGVNLoadPRE, + bool disableVectorization, + std::string &errMsg); // Optimizes the merged module. Returns true on success. bool optimize(bool disableInline, @@ -132,7 +131,7 @@ struct LTOCodeGenerator { // Compiles the merged optimized module into a single object file. It brings // the object to a buffer, and returns the buffer to the caller. Return NULL // if the compilation was not successful. - const void *compileOptimized(size_t *length, std::string &errMsg); + std::unique_ptr<MemoryBuffer> compileOptimized(std::string &errMsg); void setDiagnosticHandler(lto_diagnostic_handler_t, void *); @@ -166,7 +165,6 @@ private: lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT; StringSet MustPreserveSymbols; StringSet AsmUndefinedRefs; - std::unique_ptr<MemoryBuffer> NativeObjectFile; std::vector<char *> CodegenOptions; std::string MCpu; std::string MAttr; diff --git a/contrib/llvm/include/llvm/MC/MCAsmBackend.h b/contrib/llvm/include/llvm/MC/MCAsmBackend.h index c0a95d4..2bfad2d 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmBackend.h +++ b/contrib/llvm/include/llvm/MC/MCAsmBackend.h @@ -97,6 +97,12 @@ public: /// Target specific predicate for whether a given fixup requires the /// associated instruction to be relaxed. + virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, + uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const; + + /// Simple predicate for targets where !Resolved implies requiring relaxation virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfo.h b/contrib/llvm/include/llvm/MC/MCAsmInfo.h index 0335f31..9bb0fa6 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmInfo.h +++ b/contrib/llvm/include/llvm/MC/MCAsmInfo.h @@ -155,6 +155,10 @@ protected: /// Defaults to false. bool AllowAtInName; + /// If this is true, symbol names with invalid characters will be printed in + /// quotes. + bool SupportsQuotedNames; + /// This is true if data region markers should be printed as /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels /// instead. @@ -406,6 +410,10 @@ public: unsigned Encoding, MCStreamer &Streamer) const; + /// Return true if the identifier \p Name does not need quotes to be + /// syntactically correct. + virtual bool isValidUnquotedName(StringRef Name) const; + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } @@ -456,6 +464,7 @@ public: const char *getCode64Directive() const { return Code64Directive; } unsigned getAssemblerDialect() const { return AssemblerDialect; } bool doesAllowAtInName() const { return AllowAtInName; } + bool supportsNameQuoting() const { return SupportsQuotedNames; } bool doesSupportDataRegionDirectives() const { return UseDataRegionDirectives; } diff --git a/contrib/llvm/include/llvm/MC/MCAsmLayout.h b/contrib/llvm/include/llvm/MC/MCAsmLayout.h index fb28420..1b20d5b 100644 --- a/contrib/llvm/include/llvm/MC/MCAsmLayout.h +++ b/contrib/llvm/include/llvm/MC/MCAsmLayout.h @@ -18,7 +18,6 @@ class MCAssembler; class MCFragment; class MCSection; class MCSymbol; -class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// diff --git a/contrib/llvm/include/llvm/MC/MCAssembler.h b/contrib/llvm/include/llvm/MC/MCAssembler.h index 593504c..a6178c2 100644 --- a/contrib/llvm/include/llvm/MC/MCAssembler.h +++ b/contrib/llvm/include/llvm/MC/MCAssembler.h @@ -12,7 +12,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" @@ -24,7 +23,6 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <algorithm> @@ -60,7 +58,8 @@ public: FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_LEB + FT_LEB, + FT_SafeSEH }; private: @@ -531,6 +530,28 @@ public: } }; +class MCSafeSEHFragment : public MCFragment { + virtual void anchor(); + + const MCSymbol *Sym; + +public: + MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) + : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {} + + /// \name Accessors + /// @{ + + const MCSymbol *getSymbol() { return Sym; } + const MCSymbol *getSymbol() const { return Sym; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_SafeSEH; + } +}; + // FIXME: This really doesn't belong here. See comments below. struct IndirectSymbolData { MCSymbol *Symbol; @@ -551,7 +572,7 @@ class MCAssembler { friend class MCAsmLayout; public: - typedef SetVector<MCSection *> SectionListType; + typedef std::vector<MCSection *> SectionListType; typedef std::vector<const MCSymbol *> SymbolDataListType; typedef pointee_iterator<SectionListType::const_iterator> const_iterator; @@ -564,9 +585,6 @@ public: typedef iterator_range<symbol_iterator> symbol_range; typedef iterator_range<const_symbol_iterator> const_symbol_range; - typedef std::vector<std::string> FileNameVectorType; - typedef FileNameVectorType::const_iterator const_file_name_iterator; - typedef std::vector<IndirectSymbolData>::const_iterator const_indirect_symbol_iterator; typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; @@ -613,7 +631,7 @@ private: std::vector<std::vector<std::string>> LinkerOptions; /// List of declared file names - FileNameVectorType FileNames; + std::vector<std::string> FileNames; /// The set of function symbols for which a .thumb_func directive has /// been seen. @@ -883,39 +901,21 @@ public: /// \name Backend Data Access /// @{ - bool registerSection(MCSection &Section) { return Sections.insert(&Section); } - - bool hasSymbolData(const MCSymbol &Symbol) const { return Symbol.hasData(); } - - MCSymbolData &getSymbolData(const MCSymbol &Symbol) { - return const_cast<MCSymbolData &>( - static_cast<const MCAssembler &>(*this).getSymbolData(Symbol)); - } - - const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { - return Symbol.getData(); - } - - MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, - bool *Created = nullptr) { - if (Created) - *Created = !hasSymbolData(Symbol); - if (!hasSymbolData(Symbol)) { - Symbol.initializeData(); - Symbols.push_back(&Symbol); - } - return Symbol.getData(); + bool registerSection(MCSection &Section) { + if (Section.isRegistered()) + return false; + Sections.push_back(&Section); + Section.setIsRegistered(true); + return true; } - const_file_name_iterator file_names_begin() const { - return FileNames.begin(); - } + void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr); - const_file_name_iterator file_names_end() const { return FileNames.end(); } + ArrayRef<std::string> getFileNames() { return FileNames; } void addFileName(StringRef FileName) { - if (std::find(file_names_begin(), file_names_end(), FileName) == - file_names_end()) + if (std::find(FileNames.begin(), FileNames.end(), FileName) == + FileNames.end()) FileNames.push_back(FileName); } diff --git a/contrib/llvm/include/llvm/MC/MCContext.h b/contrib/llvm/include/llvm/MC/MCContext.h index 5b57b9d..1790905 100644 --- a/contrib/llvm/include/llvm/MC/MCContext.h +++ b/contrib/llvm/include/llvm/MC/MCContext.h @@ -30,6 +30,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSymbol; + class MCSymbolELF; class MCLabel; struct MCDwarfFile; class MCDwarfLoc; @@ -75,7 +76,7 @@ namespace llvm { /// ELF sections can have a corresponding symbol. This maps one to the /// other. - DenseMap<const MCSectionELF *, MCSymbol *> SectionSymbols; + DenseMap<const MCSectionELF *, MCSymbolELF *> SectionSymbols; /// A mapping from a local label number and an instance count to a symbol. /// For example, in the assembly @@ -205,7 +206,10 @@ namespace llvm { /// Do automatic reset in destructor bool AutoReset; - MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix); + MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name, + bool IsTemporary); + MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix, + bool IsTemporary); MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance); @@ -263,7 +267,7 @@ namespace llvm { /// \param Name - The symbol name, which must be unique across all symbols. MCSymbol *getOrCreateSymbol(const Twine &Name); - MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section); + MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section); /// Gets a symbol that will be defined to the final stack offset of a local /// variable after codegen. @@ -340,18 +344,18 @@ namespace llvm { MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, unsigned UniqueID, + const MCSymbolELF *Group, unsigned UniqueID, const char *BeginSymName, const MCSectionELF *Associated); MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, + const MCSymbolELF *Group, const MCSectionELF *Associated); void renameELFSection(MCSectionELF *Section, StringRef Name); - MCSectionELF *createELFGroupSection(const MCSymbol *Group); + MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, diff --git a/contrib/llvm/include/llvm/MC/MCELF.h b/contrib/llvm/include/llvm/MC/MCELF.h deleted file mode 100644 index f409988..0000000 --- a/contrib/llvm/include/llvm/MC/MCELF.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some support functions used by the ELF Streamer and -// ObjectWriter. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELF_H -#define LLVM_MC_MCELF_H - -namespace llvm { -class MCSymbolData; - -class MCELF { - public: - static void SetBinding(MCSymbolData &SD, unsigned Binding); - static unsigned GetBinding(const MCSymbolData &SD); - static void SetType(MCSymbolData &SD, unsigned Type); - static unsigned GetType(const MCSymbolData &SD); - static void SetVisibility(MCSymbolData &SD, unsigned Visibility); - static unsigned GetVisibility(const MCSymbolData &SD); - static void setOther(MCSymbolData &SD, unsigned Other); - static unsigned getOther(const MCSymbolData &SD); -}; - -} - -#endif diff --git a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h index cf73eca..01f694d 100644 --- a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -21,17 +21,17 @@ class MCFixup; class MCFragment; class MCObjectWriter; class MCSymbol; -class MCSymbolData; +class MCSymbolELF; class MCValue; class raw_pwrite_stream; struct ELFRelocationEntry { uint64_t Offset; // Where is the relocation. - const MCSymbol *Symbol; // The symbol to relocate with. + const MCSymbolELF *Symbol; // The symbol to relocate with. unsigned Type; // The type of the relocation. uint64_t Addend; // The addend to use. - ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type, + ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, uint64_t Addend) : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} }; @@ -69,7 +69,7 @@ public: virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const = 0; - virtual bool needsRelocateWithSymbol(const MCSymbolData &SD, + virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const; virtual void sortRelocs(const MCAssembler &Asm, diff --git a/contrib/llvm/include/llvm/MC/MCELFStreamer.h b/contrib/llvm/include/llvm/MC/MCELFStreamer.h index 97058f5..241db0dc 100644 --- a/contrib/llvm/include/llvm/MC/MCELFStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCELFStreamer.h @@ -23,8 +23,6 @@ class MCAssembler; class MCCodeEmitter; class MCExpr; class MCInst; -class MCSymbol; -class MCSymbolData; class raw_ostream; class MCELFStreamer : public MCObjectStreamer { @@ -39,7 +37,6 @@ public: void reset() override { SeenIdent = false; LocalCommons.clear(); - BindingExplicitlySet.clear(); BundleGroups.clear(); MCObjectStreamer::reset(); } @@ -62,7 +59,7 @@ public: void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; + void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; @@ -108,8 +105,6 @@ private: std::vector<LocalCommon> LocalCommons; - SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; - /// BundleGroups - The stack of fragments holding the bundle-locked /// instructions. llvm::SmallVector<MCDataFragment *, 4> BundleGroups; diff --git a/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h b/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h deleted file mode 100644 index 297c442..0000000 --- a/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the ELF target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H -#define LLVM_MC_MCELFSYMBOLFLAGS_H - -#include "llvm/Support/ELF.h" - -// Because all the symbol flags need to be stored in the MCSymbolData -// 'flags' variable we need to provide shift constants per flag type. - -namespace llvm { - enum { - ELF_STT_Shift = 0, // Shift value for STT_* flags. - ELF_STB_Shift = 4, // Shift value for STB_* flags. - ELF_STV_Shift = 8, // Shift value for STV_* flags. - ELF_STO_Shift = 10 // Shift value for STO_* flags. - }; - - enum ELFSymbolFlags { - ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift), - ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift), - ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift), - ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift), - ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift), - - ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift), - ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift), - ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift), - ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift), - ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift), - ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift), - ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift), - ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift), - ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift), - ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift), - - ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift), - ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift), - ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), - ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift) - }; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/MC/MCExpr.h b/contrib/llvm/include/llvm/MC/MCExpr.h index b38ad7d..b3a6073 100644 --- a/contrib/llvm/include/llvm/MC/MCExpr.h +++ b/contrib/llvm/include/llvm/MC/MCExpr.h @@ -46,7 +46,7 @@ private: MCExpr(const MCExpr&) = delete; void operator=(const MCExpr&) = delete; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs) const; @@ -57,7 +57,7 @@ private: protected: explicit MCExpr(ExprKind Kind) : Kind(Kind) {} - bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const; @@ -72,7 +72,7 @@ public: /// \name Utility Methods /// @{ - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; /// @} @@ -86,11 +86,11 @@ public: /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// \return - True on success. - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const; - bool EvaluateAsAbsolute(int64_t &Res) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool evaluateAsAbsolute(int64_t &Res) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; @@ -101,13 +101,13 @@ public: /// \param Layout - The assembler layout object to use for evaluating values. /// \param Fixup - The Fixup object if available. /// \return - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, + bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const; /// \brief Try to evaluate the expression to the form (a - b + constant) where /// neither a nor b are variables. /// - /// This is a more aggressive variant of EvaluateAsRelocatable. The intended + /// This is a more aggressive variant of evaluateAsRelocatable. The intended /// use is for when relocations are not available, like the .size directive. bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; @@ -115,13 +115,13 @@ public: /// currently defined as the absolute section for constants, or /// otherwise the section associated with the first defined symbol in the /// expression. - MCSection *FindAssociatedSection() const; + MCSection *findAssociatedSection() const; /// @} }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { - E.print(OS); + E.print(OS, nullptr); return OS; } @@ -136,7 +136,7 @@ public: /// \name Construction /// @{ - static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); + static const MCConstantExpr *create(int64_t Value, MCContext &Ctx); /// @} /// \name Accessors @@ -312,13 +312,13 @@ public: /// \name Construction /// @{ - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { - return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { + return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); } - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, MCContext &Ctx); - static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, + static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, MCContext &Ctx); /// @} @@ -369,19 +369,19 @@ public: /// \name Construction /// @{ - static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, + static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, MCContext &Ctx); - static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(LNot, Expr, Ctx); + static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx) { + return create(LNot, Expr, Ctx); } - static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Minus, Expr, Ctx); + static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx) { + return create(Minus, Expr, Ctx); } - static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(Not, Expr, Ctx); + static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx) { + return create(Not, Expr, Ctx); } - static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Plus, Expr, Ctx); + static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx) { + return create(Plus, Expr, Ctx); } /// @} @@ -441,83 +441,83 @@ public: /// \name Construction /// @{ - static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, + static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx); - static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Add, LHS, RHS, Ctx); + return create(Add, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(And, LHS, RHS, Ctx); + return create(And, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Div, LHS, RHS, Ctx); + return create(Div, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(EQ, LHS, RHS, Ctx); + return create(EQ, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GT, LHS, RHS, Ctx); + return create(GT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GTE, LHS, RHS, Ctx); + return create(GTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LAnd, LHS, RHS, Ctx); + return create(LAnd, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LOr, LHS, RHS, Ctx); + return create(LOr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LT, LHS, RHS, Ctx); + return create(LT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LTE, LHS, RHS, Ctx); + return create(LTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mod, LHS, RHS, Ctx); + return create(Mod, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mul, LHS, RHS, Ctx); + return create(Mul, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(NE, LHS, RHS, Ctx); + return create(NE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Or, LHS, RHS, Ctx); + return create(Or, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Shl, LHS, RHS, Ctx); + return create(Shl, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(AShr, LHS, RHS, Ctx); + return create(AShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LShr, LHS, RHS, Ctx); + return create(LShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Sub, LHS, RHS, Ctx); + return create(Sub, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Xor, LHS, RHS, Ctx); + return create(Xor, LHS, RHS, Ctx); } /// @} @@ -551,13 +551,12 @@ protected: MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} public: - - virtual void PrintImpl(raw_ostream &OS) const = 0; - virtual bool EvaluateAsRelocatableImpl(MCValue &Res, + virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; + virtual bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const = 0; virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; - virtual MCSection *FindAssociatedSection() const = 0; + virtual MCSection *findAssociatedSection() const = 0; virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; diff --git a/contrib/llvm/include/llvm/MC/MCInst.h b/contrib/llvm/include/llvm/MC/MCInst.h index 2fc5091..4688b5f 100644 --- a/contrib/llvm/include/llvm/MC/MCInst.h +++ b/contrib/llvm/include/llvm/MC/MCInst.h @@ -32,12 +32,12 @@ class MCInst; /// This is a simple discriminated union. class MCOperand { enum MachineOperandType : unsigned char { - kInvalid, ///< Uninitialized. - kRegister, ///< Register operand. - kImmediate, ///< Immediate operand. - kFPImmediate, ///< Floating-point immediate operand. - kExpr, ///< Relocatable immediate operand. - kInst ///< Sub-instruction operand. + kInvalid, ///< Uninitialized. + kRegister, ///< Register operand. + kImmediate, ///< Immediate operand. + kFPImmediate, ///< Floating-point immediate operand. + kExpr, ///< Relocatable immediate operand. + kInst ///< Sub-instruction operand. }; MachineOperandType Kind; @@ -48,8 +48,8 @@ class MCOperand { const MCExpr *ExprVal; const MCInst *InstVal; }; -public: +public: MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} bool isValid() const { return Kind != kInvalid; } @@ -151,6 +151,7 @@ class MCInst { unsigned Opcode; SMLoc Loc; SmallVector<MCOperand, 8> Operands; + public: MCInst() : Opcode(0) {} @@ -164,18 +165,16 @@ public: MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } - void addOperand(const MCOperand &Op) { - Operands.push_back(Op); - } - - void clear() { Operands.clear(); } - size_t size() const { return Operands.size(); } + void addOperand(const MCOperand &Op) { Operands.push_back(Op); } typedef SmallVectorImpl<MCOperand>::iterator iterator; typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator; + void clear() { Operands.clear(); } + void erase(iterator I) { Operands.erase(I); } + size_t size() const { return Operands.size(); } iterator begin() { return Operands.begin(); } const_iterator begin() const { return Operands.begin(); } - iterator end() { return Operands.end(); } + iterator end() { return Operands.end(); } const_iterator end() const { return Operands.end(); } iterator insert(iterator I, const MCOperand &Op) { return Operands.insert(I, Op); diff --git a/contrib/llvm/include/llvm/MC/MCInstPrinter.h b/contrib/llvm/include/llvm/MC/MCInstPrinter.h index 7e8563a..0eafd02 100644 --- a/contrib/llvm/include/llvm/MC/MCInstPrinter.h +++ b/contrib/llvm/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Format.h" @@ -22,11 +23,14 @@ class MCRegisterInfo; class MCSubtargetInfo; class StringRef; +/// Convert `Bytes' to a hex string and output to `OS' +void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS); + namespace HexStyle { - enum Style { - C, ///< 0xff - Asm ///< 0ffh - }; +enum Style { + C, ///< 0xff + Asm ///< 0ffh +}; } /// \brief This is an instance of a target assembly language printer that @@ -52,12 +56,12 @@ protected: /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); + public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) - : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), - UseMarkup(0), PrintImmHex(0), - PrintHexStyle(HexStyle::C) {} + : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), UseMarkup(0), + PrintImmHex(0), PrintHexStyle(HexStyle::C) {} virtual ~MCInstPrinter(); @@ -65,8 +69,8 @@ public: void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } /// \brief Print the specified MCInst to the specified raw_ostream. - virtual void printInst(const MCInst *MI, raw_ostream &OS, - StringRef Annot, const MCSubtargetInfo &STI) = 0; + virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, + const MCSubtargetInfo &STI) = 0; /// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or /// empty if we can't resolve it. @@ -85,8 +89,8 @@ public: bool getPrintImmHex() const { return PrintImmHex; } void setPrintImmHex(bool Value) { PrintImmHex = Value; } - HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; } - void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; } + HexStyle::Style getPrintHexStyle() const { return PrintHexStyle; } + void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } /// Utility function to print immediates in decimal or hex. format_object<int64_t> formatImm(int64_t Value) const { diff --git a/contrib/llvm/include/llvm/MC/MCInstrDesc.h b/contrib/llvm/include/llvm/MC/MCInstrDesc.h index de3a195..3209a2c 100644 --- a/contrib/llvm/include/llvm/MC/MCInstrDesc.h +++ b/contrib/llvm/include/llvm/MC/MCInstrDesc.h @@ -125,7 +125,8 @@ enum Flag { ExtraDefRegAllocReq, RegSequence, ExtractSubreg, - InsertSubreg + InsertSubreg, + Convergent }; } @@ -138,10 +139,10 @@ class MCInstrDesc { public: unsigned short Opcode; // The opcode number unsigned short NumOperands; // Num of args (may be more if variable_ops) - unsigned short NumDefs; // Num of args that are definitions + unsigned char NumDefs; // Num of args that are definitions + unsigned char Size; // Number of bytes in encoding. unsigned short SchedClass; // enum identifying instr sched class - unsigned short Size; // Number of bytes in encoding. - unsigned Flags; // Flags identifying machine instr class + uint64_t Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values const uint16_t *ImplicitUses; // Registers implicitly read by this instr const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr @@ -331,6 +332,13 @@ public: /// override accordingly. bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); } + + /// \brief Return true if this instruction is convergent. + /// + /// Convergent instructions may only be moved to locations that are + /// control-equivalent to their original positions. + bool isConvergent() const { return Flags & (1 << MCID::Convergent); } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/contrib/llvm/include/llvm/MC/MCLabel.h b/contrib/llvm/include/llvm/MC/MCLabel.h index de2d0af..a12473f 100644 --- a/contrib/llvm/include/llvm/MC/MCLabel.h +++ b/contrib/llvm/include/llvm/MC/MCLabel.h @@ -17,41 +17,41 @@ #include "llvm/Support/Compiler.h" namespace llvm { - class MCContext; - class raw_ostream; - - /// \brief Instances of this class represent a label name in the MC file, - /// and MCLabel are created and uniqued by the MCContext class. MCLabel - /// should only be constructed for valid instances in the object file. - class MCLabel { - // \brief The instance number of this Directional Local Label. - unsigned Instance; - - private: // MCContext creates and uniques these. - friend class MCContext; - MCLabel(unsigned instance) - : Instance(instance) {} - - MCLabel(const MCLabel&) = delete; - void operator=(const MCLabel&) = delete; - public: - /// \brief Get the current instance of this Directional Local Label. - unsigned getInstance() const { return Instance; } - - /// \brief Increment the current instance of this Directional Local Label. - unsigned incInstance() { return ++Instance; } - - /// \brief Print the value to the stream \p OS. - void print(raw_ostream &OS) const; - - /// \brief Print the value to stderr. - void dump() const; - }; - - inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { - Label.print(OS); - return OS; - } +class MCContext; +class raw_ostream; + +/// \brief Instances of this class represent a label name in the MC file, +/// and MCLabel are created and uniqued by the MCContext class. MCLabel +/// should only be constructed for valid instances in the object file. +class MCLabel { + // \brief The instance number of this Directional Local Label. + unsigned Instance; + +private: // MCContext creates and uniques these. + friend class MCContext; + MCLabel(unsigned instance) : Instance(instance) {} + + MCLabel(const MCLabel &) = delete; + void operator=(const MCLabel &) = delete; + +public: + /// \brief Get the current instance of this Directional Local Label. + unsigned getInstance() const { return Instance; } + + /// \brief Increment the current instance of this Directional Local Label. + unsigned incInstance() { return ++Instance; } + + /// \brief Print the value to the stream \p OS. + void print(raw_ostream &OS) const; + + /// \brief Print the value to stderr. + void dump() const; +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { + Label.print(OS); + return OS; +} } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h b/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h index a186a14..4b6f7ec 100644 --- a/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/contrib/llvm/include/llvm/MC/MCLinkerOptimizationHint.h @@ -106,7 +106,7 @@ class MCLOHDirective { /// Emit this directive in \p OutStream using the information available /// in the given \p ObjWriter and \p Layout to get the address of the /// arguments within the object file. - void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, + void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const; public: @@ -123,9 +123,9 @@ public: /// Emit this directive as: /// <kind, numArgs, addr1, ..., addrN> - void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { raw_ostream &OutStream = ObjWriter.getStream(); - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); } /// Get the size in bytes of this directive if emitted in \p ObjWriter with @@ -145,7 +145,7 @@ public: }; raw_counting_ostream OutStream; - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); return OutStream.tell(); } }; @@ -184,10 +184,10 @@ public: } /// Emit all Linker Optimization Hint in one big table. - /// Each line of the table is emitted by LOHDirective::Emit. - void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + /// Each line of the table is emitted by LOHDirective::emit. + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { for (const MCLOHDirective &D : Directives) - D.Emit(ObjWriter, Layout); + D.emit(ObjWriter, Layout); } void reset() { diff --git a/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h b/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h deleted file mode 100644 index 71f01fa..0000000 --- a/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h +++ /dev/null @@ -1,46 +0,0 @@ -//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the MachO target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H -#define LLVM_MC_MCMACHOSYMBOLFLAGS_H - -// These flags are mostly used in MCMachOStreamer.cpp but also needed in -// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit -// the correct relocation information. - -namespace llvm { - /// MachOSymbolFlags - We store the value for the 'desc' symbol field in the - /// lowest 16 bits of the implementation defined flags. - enum MachOSymbolFlags { // See <mach-o/nlist.h>. - SF_DescFlagsMask = 0xFFFF, - - // Reference type flags. - SF_ReferenceTypeMask = 0x0007, - SF_ReferenceTypeUndefinedNonLazy = 0x0000, - SF_ReferenceTypeUndefinedLazy = 0x0001, - SF_ReferenceTypeDefined = 0x0002, - SF_ReferenceTypePrivateDefined = 0x0003, - SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, - SF_ReferenceTypePrivateUndefinedLazy = 0x0005, - - // Other 'desc' flags. - SF_ThumbFunc = 0x0008, - SF_NoDeadStrip = 0x0020, - SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080, - SF_SymbolResolver = 0x0100 - }; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h index 63c2a28..175d73e 100644 --- a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -27,15 +27,11 @@ class MCMachObjectTargetWriter { const unsigned Is64Bit : 1; const uint32_t CPUType; const uint32_t CPUSubtype; - // FIXME: Remove this, we should just always use it once we no longer care - // about Darwin 'as' compatibility. - const unsigned UseAggressiveSymbolFolding : 1; unsigned LocalDifference_RIT; protected: MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, - uint32_t CPUSubtype_, - bool UseAggressiveSymbolFolding_ = false); + uint32_t CPUSubtype_); void setLocalDifferenceRelocationType(unsigned Type) { LocalDifference_RIT = Type; @@ -47,7 +43,7 @@ public: /// \name Lifetime Management /// @{ - virtual void reset() {}; + virtual void reset() {} /// @} @@ -55,7 +51,6 @@ public: /// @{ bool is64Bit() const { return Is64Bit; } - bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } uint32_t getCPUType() const { return CPUType; } uint32_t getCPUSubtype() const { return CPUSubtype; } unsigned getLocalDifferenceRelocationType() const { @@ -67,7 +62,7 @@ public: /// \name API /// @{ - virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, + virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, @@ -77,8 +72,7 @@ public: }; class MachObjectWriter : public MCObjectWriter { - /// MachSymbolData - Helper struct for containing some precomputed information - /// on symbols. + /// Helper struct for containing some precomputed information on symbols. struct MachSymbolData { const MCSymbol *Symbol; uint64_t StringIndex; @@ -104,6 +98,8 @@ class MachObjectWriter : public MCObjectWriter { llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations; llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase; + SectionAddrMap SectionAddress; + /// @} /// \name Symbol Table Data /// @{ @@ -136,8 +132,6 @@ public: bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); - SectionAddrMap SectionAddress; - SectionAddrMap &getSectionAddressMap() { return SectionAddress; } uint64_t getSectionAddress(const MCSection *Sec) const { @@ -165,41 +159,37 @@ public: /// @} - void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, + void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols); - /// WriteSegmentLoadCommand - Write a segment load command. + /// Write a segment load command. /// /// \param NumSections The number of sections in this segment. /// \param SectionDataSize The total size of the sections. - void WriteSegmentLoadCommand(unsigned NumSections, - uint64_t VMSize, + void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize); - void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, + void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations); - void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, + void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize); - void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, - uint32_t NumLocalSymbols, - uint32_t FirstExternalSymbol, - uint32_t NumExternalSymbols, - uint32_t FirstUndefinedSymbol, - uint32_t NumUndefinedSymbols, - uint32_t IndirectSymbolOffset, - uint32_t NumIndirectSymbols); + void writeDysymtabLoadCommand( + uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, + uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, + uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, + uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols); - void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); + void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); - void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, + void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize); - void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options); + void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options); // FIXME: We really need to improve the relocation validation. Basically, we // want to implement a separate computation which evaluates the relocation @@ -226,29 +216,25 @@ public: Relocations[Sec].push_back(P); } - void RecordScatteredRelocation(const MCAssembler &Asm, + void recordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - unsigned Log2Size, - uint64_t &FixedValue); + unsigned Log2Size, uint64_t &FixedValue); - void RecordTLVPRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); + void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); - void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; - void BindIndirectSymbols(MCAssembler &Asm); + void bindIndirectSymbols(MCAssembler &Asm); - /// ComputeSymbolTable - Compute the symbol table data - /// - void ComputeSymbolTable(MCAssembler &Asm, + /// Compute the symbol table data. + void computeSymbolTable(MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData, std::vector<MachSymbolData> &ExternalSymbolData, std::vector<MachSymbolData> &UndefinedSymbolData); @@ -256,19 +242,18 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); - void ExecutePostLayoutBinding(MCAssembler &Asm, + void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; - bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; }; - -/// \brief Construct a new Mach-O writer instance. +/// Construct a new Mach-O writer instance. /// /// This routine takes ownership of the target writer subclass. /// diff --git a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h index f28b9c6..0515f1c 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -18,28 +18,25 @@ #include "llvm/Support/CodeGen.h" namespace llvm { - class MCContext; - class MCSection; - class StringRef; +class MCContext; +class MCSection; +class StringRef; class MCObjectFileInfo { protected: - /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This - /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't - /// support alignment on comm. + /// True if .comm supports alignment. This is a hack for as long as we + /// support 10.4 Tiger, whose assembler doesn't support alignment on comm. bool CommDirectiveSupportsAlignment; - /// SupportsWeakEmptyEHFrame - True if target object file supports a - /// weak_definition of constant 0 for an omitted EH frame. + /// True if target object file supports a weak_definition of constant 0 for an + /// omitted EH frame. bool SupportsWeakOmittedEHFrame; - /// SupportsCompactUnwindWithoutEHFrame - True if the target object file - /// supports emitting a compact unwind section without an associated EH frame - /// section. + /// True if the target object file supports emitting a compact unwind section + /// without an associated EH frame section. bool SupportsCompactUnwindWithoutEHFrame; - /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values - /// for EH. + /// Some encoding values for EH. unsigned PersonalityEncoding; unsigned LSDAEncoding; unsigned FDECFIEncoding; @@ -49,16 +46,13 @@ protected: unsigned EHSectionType; unsigned EHSectionFlags; - /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we - /// should emit only an EH frame. + /// Compact unwind encoding indicating that we should emit only an EH frame. unsigned CompactUnwindDwarfEHFrameOnly; /// Section directive for standard text. - /// MCSection *TextSection; /// Section directive for standard data. - /// MCSection *DataSection; /// Section that is default initialized to zero. @@ -101,7 +95,7 @@ protected: // can be enabled by a compiler flag. MCSection *DwarfPubNamesSection; - // DWARF5 Experimental Debug Info Sections + /// DWARF5 Experimental Debug Info Sections /// DwarfAccelNamesSection, DwarfAccelObjCSection, /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - /// If we use the DWARF accelerated hash tables then we want to emit these @@ -111,7 +105,7 @@ protected: MCSection *DwarfAccelNamespaceSection; MCSection *DwarfAccelTypesSection; - /// These are used for the Fission separate debug information files. + // These are used for the Fission separate debug information files. MCSection *DwarfInfoDWOSection; MCSection *DwarfTypesDWOSection; MCSection *DwarfAbbrevDWOSection; @@ -121,32 +115,36 @@ protected: MCSection *DwarfStrOffDWOSection; MCSection *DwarfAddrSection; - /// Sections for newer gnu pubnames and pubtypes. + /// Section for newer gnu pubnames. MCSection *DwarfGnuPubNamesSection; + /// Section for newer gnu pubtypes. MCSection *DwarfGnuPubTypesSection; MCSection *COFFDebugSymbolsSection; - // Extra TLS Variable Data section. If the target needs to put additional - // information for a TLS variable, it'll go here. + /// Extra TLS Variable Data section. + /// + /// If the target needs to put additional information for a TLS variable, + /// it'll go here. MCSection *TLSExtraDataSection; /// Section directive for Thread Local data. ELF, MachO and COFF. MCSection *TLSDataSection; // Defaults to ".tdata". - /// Section directive for Thread Local uninitialized data. Null if this target - /// doesn't support a BSS section. ELF and MachO only. + /// Section directive for Thread Local uninitialized data. + /// + /// Null if this target doesn't support a BSS section. ELF and MachO only. MCSection *TLSBSSSection; // Defaults to ".tbss". /// StackMap section. MCSection *StackMapSection; - /// EH frame section. It is initialized on demand so it can be overwritten - /// (with uniquing). + /// EH frame section. + /// + /// It is initialized on demand so it can be overwritten (with uniquing). MCSection *EHFrameSection; - /// ELF specific sections. - /// + // ELF specific sections. MCSection *DataRelSection; const MCSection *DataRelLocalSection; MCSection *DataRelROSection; @@ -155,17 +153,16 @@ protected: MCSection *MergeableConst8Section; MCSection *MergeableConst16Section; - /// MachO specific sections. - /// + // MachO specific sections. - /// Section for thread local structure information. Contains the source code - /// name of the variable, visibility and a pointer to the initial value - /// (.tdata or .tbss). + /// Section for thread local structure information. + /// + /// Contains the source code name of the variable, visibility and a pointer to + /// the initial value (.tdata or .tbss). MCSection *TLSTLVSection; // Defaults to ".tlv". - /// TLSThreadInitSection - Section for thread local data initialization - /// functions. - const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". + /// Section for thread local data initialization functions. + const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". MCSection *CStringSection; MCSection *UStringSection; @@ -182,10 +179,10 @@ protected: MCSection *NonLazySymbolPointerSection; /// COFF specific sections. - /// MCSection *DrectveSection; MCSection *PDataSection; MCSection *XDataSection; + MCSection *SXDataSection; public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, @@ -266,8 +263,7 @@ public: MCSection *getStackMapSection() const { return StackMapSection; } - /// ELF specific sections. - /// + // ELF specific sections. MCSection *getDataRelSection() const { return DataRelSection; } const MCSection *getDataRelLocalSection() const { return DataRelLocalSection; @@ -284,8 +280,7 @@ public: return MergeableConst16Section; } - /// MachO specific sections. - /// + // MachO specific sections. const MCSection *getTLSTLVSection() const { return TLSTLVSection; } const MCSection *getTLSThreadInitSection() const { return TLSThreadInitSection; @@ -316,11 +311,11 @@ public: return NonLazySymbolPointerSection; } - /// COFF specific sections. - /// + // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } MCSection *getPDataSection() const { return PDataSection; } MCSection *getXDataSection() const { return XDataSection; } + MCSection *getSXDataSection() const { return SXDataSection; } MCSection *getEHFrameSection() { if (!EHFrameSection) @@ -329,13 +324,9 @@ public: } enum Environment { IsMachO, IsELF, IsCOFF }; - Environment getObjectFileType() const { - return Env; - } + Environment getObjectFileType() const { return Env; } - Reloc::Model getRelocM() const { - return RelocM; - } + Reloc::Model getRelocM() const { return RelocM; } private: Environment Env; @@ -344,12 +335,11 @@ private: MCContext *Ctx; Triple TT; - void InitMachOMCObjectFileInfo(Triple T); - void InitELFMCObjectFileInfo(Triple T); - void InitCOFFMCObjectFileInfo(Triple T); + void initMachOMCObjectFileInfo(Triple T); + void initELFMCObjectFileInfo(Triple T); + void initCOFFMCObjectFileInfo(Triple T); - /// InitEHFrameSection - Initialize EHFrameSection on demand. - /// + /// Initialize EHFrameSection on demand. void InitEHFrameSection(); public: diff --git a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h index e75bc86..462b3b4 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h @@ -35,11 +35,10 @@ class raw_pwrite_stream; /// implementation. class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; - MCSection *CurSectionData; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; bool EmitDebugFrame; - SmallVector<MCSymbolData *, 2> PendingLabels; + SmallVector<MCSymbol *, 2> PendingLabels; virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; @@ -57,21 +56,17 @@ public: /// Object streamers require the integrated assembler. bool isIntegratedAssemblerRequired() const override { return true; } - MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) { - return getAssembler().getOrCreateSymbolData(*Symbol); - } void EmitFrames(MCAsmBackend *MAB); void EmitCFISections(bool EH, bool Debug) override; protected: - MCSection *getCurrentSectionData() const { return CurSectionData; } - MCFragment *getCurrentFragment() const; void insert(MCFragment *F) { flushPendingLabels(F); - CurSectionData->getFragmentList().insert(CurInsertionPoint, F); - F->setParent(CurSectionData); + MCSection *CurSection = getCurrentSectionOnly(); + CurSection->getFragmentList().insert(CurInsertionPoint, F); + F->setParent(CurSection); } /// Get a data fragment to write into, creating a new one if the current diff --git a/contrib/llvm/include/llvm/MC/MCObjectWriter.h b/contrib/llvm/include/llvm/MC/MCObjectWriter.h index 999d294..2211673 100644 --- a/contrib/llvm/include/llvm/MC/MCObjectWriter.h +++ b/contrib/llvm/include/llvm/MC/MCObjectWriter.h @@ -22,18 +22,17 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; -class MCSymbolData; class MCSymbolRefExpr; class MCValue; -/// MCObjectWriter - Defines the object file and target independent interfaces -/// used by the assembler backend to write native file format object files. +/// Defines the object file and target independent interfaces used by the +/// assembler backend to write native file format object files. /// /// The object writer contains a few callbacks used by the assembler to allow /// the object writer to modify the assembler data structures at appropriate /// points. Once assembly is complete, the object writer is given the /// MCAssembler instance, which contains all the symbol and section data which -/// should be emitted as part of WriteObject(). +/// should be emitted as part of writeObject(). /// /// The object writer also contains a number of helper methods for writing /// binary data to the output stream. @@ -54,7 +53,7 @@ public: virtual ~MCObjectWriter(); /// lifetime management - virtual void reset() { } + virtual void reset() {} bool isLittleEndian() const { return IsLittleEndian; } @@ -63,109 +62,106 @@ public: /// \name High-Level API /// @{ - /// \brief Perform any late binding of symbols (for example, to assign symbol + /// Perform any late binding of symbols (for example, to assign symbol /// indices for use when generating relocations). /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; - /// \brief Record a relocation entry. + /// Record a relocation entry. /// /// This routine is called by the assembler after layout and relaxation, and /// post layout binding. The implementation is responsible for storing /// information about the relocation so that it can be emitted during - /// WriteObject(). - virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + /// writeObject(). + virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) = 0; - /// \brief Check whether the difference (A - B) between two symbol - /// references is fully resolved. + /// Check whether the difference (A - B) between two symbol references is + /// fully resolved. /// /// Clients are not required to answer precisely and may conservatively return /// false, even when a difference is fully resolved. - bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, bool InSet) const; - virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const; - /// \brief True if this symbol (which is a variable) is weak. This is not + /// True if this symbol (which is a variable) is weak. This is not /// just STB_WEAK, but more generally whether or not we can evaluate /// past it. virtual bool isWeak(const MCSymbol &Sym) const; - /// \brief Write the object file. + /// Write the object file. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations /// generated. - virtual void WriteObject(MCAssembler &Asm, - const MCAsmLayout &Layout) = 0; + virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; /// @} /// \name Binary Output /// @{ - void Write8(uint8_t Value) { - OS << char(Value); - } + void write8(uint8_t Value) { OS << char(Value); } - void WriteLE16(uint16_t Value) { + void writeLE16(uint16_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteLE32(uint32_t Value) { + void writeLE32(uint32_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteLE64(uint64_t Value) { + void writeLE64(uint64_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteBE16(uint16_t Value) { + void writeBE16(uint16_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void WriteBE32(uint32_t Value) { + void writeBE32(uint32_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void WriteBE64(uint64_t Value) { + void writeBE64(uint64_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void Write16(uint16_t Value) { + void write16(uint16_t Value) { if (IsLittleEndian) - WriteLE16(Value); + writeLE16(Value); else - WriteBE16(Value); + writeBE16(Value); } - void Write32(uint32_t Value) { + void write32(uint32_t Value) { if (IsLittleEndian) - WriteLE32(Value); + writeLE32(Value); else - WriteBE32(Value); + writeBE32(Value); } - void Write64(uint64_t Value) { + void write64(uint64_t Value) { if (IsLittleEndian) - WriteLE64(Value); + writeLE64(Value); else - WriteBE64(Value); + writeBE64(Value); } void WriteZeros(unsigned N) { - const char Zeros[16] = { 0 }; + const char Zeros[16] = {0}; for (unsigned i = 0, e = N / 16; i != e; ++i) OS << StringRef(Zeros, 16); @@ -173,22 +169,23 @@ public: OS << StringRef(Zeros, N % 16); } - void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { - WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + void writeBytes(const SmallVectorImpl<char> &ByteVec, + unsigned ZeroFillSize = 0) { + writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); } - void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) { // TODO: this version may need to go away once all fragment contents are // converted to SmallVector<char, N> - assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && - "data size greater than fill size, unexpected large write will occur"); + assert( + (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && + "data size greater than fill size, unexpected large write will occur"); OS << Str; if (ZeroFillSize) WriteZeros(ZeroFillSize - Str.size()); } /// @} - }; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/MC/MCSection.h b/contrib/llvm/include/llvm/MC/MCSection.h index 96a4ef1..5f6e8ec 100644 --- a/contrib/llvm/include/llvm/MC/MCSection.h +++ b/contrib/llvm/include/llvm/MC/MCSection.h @@ -73,11 +73,13 @@ private: /// \brief We've seen a bundle_lock directive but not its first instruction /// yet. - bool BundleGroupBeforeFirstInst = false; + unsigned BundleGroupBeforeFirstInst : 1; /// Whether this section has had instructions emitted into it. unsigned HasInstructions : 1; + unsigned IsRegistered : 1; + FragmentListType Fragments; /// Mapping from subsection number to insertion point for subsection numbers @@ -130,6 +132,9 @@ public: bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) { IsRegistered = Value; } + MCSection::FragmentListType &getFragmentList() { return Fragments; } const MCSection::FragmentListType &getFragmentList() const { return const_cast<MCSection *>(this)->getFragmentList(); diff --git a/contrib/llvm/include/llvm/MC/MCSectionELF.h b/contrib/llvm/include/llvm/MC/MCSectionELF.h index 9efe102..f673037 100644 --- a/contrib/llvm/include/llvm/MC/MCSectionELF.h +++ b/contrib/llvm/include/llvm/MC/MCSectionELF.h @@ -16,7 +16,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCSection.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" @@ -46,7 +46,7 @@ class MCSectionELF : public MCSection { /// section does not contain fixed-sized entries 'EntrySize' will be 0. unsigned EntrySize; - const MCSymbol *Group; + const MCSymbolELF *Group; /// Depending on the type of the section this is sh_link or sh_info. const MCSectionELF *Associated; @@ -54,11 +54,14 @@ class MCSectionELF : public MCSection { private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, unsigned UniqueID, + unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, MCSymbol *Begin, const MCSectionELF *Associated) : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group), - Associated(Associated) {} + Associated(Associated) { + if (Group) + Group->setIsSignature(); + } ~MCSectionELF() override; void setSectionName(StringRef Name) { SectionName = Name; } @@ -73,7 +76,7 @@ public: unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } - const MCSymbol *getGroup() const { return Group; } + const MCSymbolELF *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const override; diff --git a/contrib/llvm/include/llvm/MC/MCStreamer.h b/contrib/llvm/include/llvm/MC/MCStreamer.h index 957913e..628fb76 100644 --- a/contrib/llvm/include/llvm/MC/MCStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCStreamer.h @@ -34,6 +34,7 @@ class MCInstPrinter; class MCSection; class MCStreamer; class MCSymbol; +class MCSymbolELF; class MCSymbolRefExpr; class MCSubtargetInfo; class StringRef; @@ -272,6 +273,7 @@ public: return SectionStack.back().first; return MCSectionSubPair(); } + MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; } /// \brief Return the previous section that the streamer is emitting code to. MCSectionSubPair getPreviousSection() const { @@ -305,11 +307,15 @@ public: bool PopSection() { if (SectionStack.size() <= 1) return false; - MCSectionSubPair oldSection = SectionStack.pop_back_val().first; - MCSectionSubPair curSection = SectionStack.back().first; - - if (oldSection != curSection) - ChangeSection(curSection.first, curSection.second); + auto I = SectionStack.end(); + --I; + MCSectionSubPair OldSection = I->first; + --I; + MCSectionSubPair NewSection = I->first; + + if (OldSection != NewSection) + ChangeSection(NewSection.first, NewSection.second); + SectionStack.pop_back(); return true; } @@ -433,6 +439,8 @@ public: /// \brief Marks the end of the symbol definition. virtual void EndCOFFSymbolDef(); + virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol); + /// \brief Emits a COFF section index. /// /// \param Symbol - Symbol the section number relocation should point to. @@ -447,7 +455,7 @@ public: /// /// This corresponds to an assembler statement such as: /// .size symbol, expression - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + virtual void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value); /// \brief Emit a Linker Optimization Hint (LOH) directive. /// \param Args - Arguments of the LOH. diff --git a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h index 1778a6d..ee5d563 100644 --- a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -73,7 +73,9 @@ public: /// setFeatureBits - Set the feature bits. /// - void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; } + void setFeatureBits(const FeatureBitset &FeatureBits_) { + FeatureBits = FeatureBits_; + } /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with /// feature string). Recompute feature bits and scheduling model. @@ -94,6 +96,10 @@ public: /// feature bits. This version will also change all implied bits. FeatureBitset ToggleFeature(StringRef FS); + /// Apply a feature flag and return the re-computed feature bits, including + /// all feature bits implied by the flag. + FeatureBitset ApplyFeatureFlag(StringRef FS); + /// getSchedModelForCPU - Get the machine model of a CPU. /// MCSchedModel getSchedModelForCPU(StringRef CPU) const; diff --git a/contrib/llvm/include/llvm/MC/MCSymbol.h b/contrib/llvm/include/llvm/MC/MCSymbol.h index cf99c91..078f3d7 100644 --- a/contrib/llvm/include/llvm/MC/MCSymbol.h +++ b/contrib/llvm/include/llvm/MC/MCSymbol.h @@ -14,12 +14,14 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H -#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" namespace llvm { +class MCAsmInfo; class MCExpr; class MCSymbol; class MCFragment; @@ -27,109 +29,6 @@ class MCSection; class MCContext; class raw_ostream; -// TODO: Merge completely with MCSymbol. -class MCSymbolData { - /// Fragment - The fragment this symbol's value is relative to, if any. Also - /// stores if this symbol is visible outside this translation unit (bit 0) or - /// if it is private extern (bit 1). - PointerIntPair<MCFragment *, 2> Fragment; - - union { - /// Offset - The offset to apply to the fragment address to form this - /// symbol's value. - uint64_t Offset; - - /// CommonSize - The size of the symbol, if it is 'common'. - uint64_t CommonSize; - }; - - /// SymbolSize - An expression describing how to calculate the size of - /// a symbol. If a symbol has no size this field will be NULL. - const MCExpr *SymbolSize = nullptr; - - /// CommonAlign - The alignment of the symbol, if it is 'common', or -1. - // - // FIXME: Pack this in with other fields? - unsigned CommonAlign = -1U; - - /// Flags - The Flags field is used by object file implementations to store - /// additional per symbol information which is not easily classified. - uint32_t Flags = 0; - -public: - MCSymbolData() { Offset = 0; } - - MCFragment *getFragment() const { return Fragment.getPointer(); } - void setFragment(MCFragment *Value) { Fragment.setPointer(Value); } - - uint64_t getOffset() const { - assert(!isCommon()); - return Offset; - } - void setOffset(uint64_t Value) { - assert(!isCommon()); - Offset = Value; - } - - /// @} - /// \name Symbol Attributes - /// @{ - - bool isExternal() const { return Fragment.getInt() & 1; } - void setExternal(bool Value) { - Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value)); - } - - bool isPrivateExtern() const { return Fragment.getInt() & 2; } - void setPrivateExtern(bool Value) { - Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1)); - } - - /// isCommon - Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } - - /// setCommon - Mark this symbol as being 'common'. - /// - /// \param Size - The size of the symbol. - /// \param Align - The alignment of the symbol. - void setCommon(uint64_t Size, unsigned Align) { - assert(getOffset() == 0); - CommonSize = Size; - CommonAlign = Align; - } - - /// getCommonSize - Return the size of a 'common' symbol. - uint64_t getCommonSize() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonSize; - } - - void setSize(const MCExpr *SS) { SymbolSize = SS; } - - const MCExpr *getSize() const { return SymbolSize; } - - /// getCommonAlignment - Return the alignment of a 'common' symbol. - unsigned getCommonAlignment() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonAlign; - } - - /// getFlags - Get the (implementation defined) symbol flags. - uint32_t getFlags() const { return Flags; } - - /// setFlags - Set the (implementation defined) symbol flags. - void setFlags(uint32_t Value) { Flags = Value; } - - /// modifyFlags - Modify the flags via a mask - void modifyFlags(uint32_t Value, uint32_t Mask) { - Flags = (Flags & ~Mask) | Value; - } - - /// @} - - void dump() const; -}; - /// MCSymbol - Instances of this class represent a symbol name in the MC file, /// and MCSymbols are created and uniqued by the MCContext class. MCSymbols /// should only be constructed with valid names for the object file. @@ -138,6 +37,16 @@ public: /// Section member is set to indicate what section it lives in. Otherwise, if /// it is a reference to an external entity, it has a null section. class MCSymbol { +protected: + /// The kind of the symbol. If it is any value other than unset then this + /// class is actually one of the appropriate subclasses of MCSymbol. + enum SymbolKind { + SymbolKindUnset, + SymbolKindCOFF, + SymbolKindELF, + SymbolKindMachO, + }; + // Special sentinal value for the absolute pseudo section. // // FIXME: Use a PointerInt wrapper for this? @@ -147,10 +56,18 @@ class MCSymbol { /// held by the StringMap that lives in MCContext. const StringMapEntry<bool> *Name; - /// The section the symbol is defined in. This is null for undefined symbols, - /// and the special AbsolutePseudoSection value for absolute symbols. If this - /// is a variable symbol, this caches the variable value's section. - mutable MCSection *Section; + /// If a symbol has a Fragment, the section is implied, so we only need + /// one pointer. + /// FIXME: We might be able to simplify this by having the asm streamer create + /// dummy fragments. + /// If this is a section, then it gives the symbol is defined in. This is null + /// for undefined symbols, and the special AbsolutePseudoSection value for + /// absolute symbols. If this is a variable symbol, this caches the variable + /// value's section. + /// + /// If this is a fragment, then it gives the fragment this symbol's value is + /// relative to, if any. + mutable PointerUnion<MCSection *, MCFragment *> SectionOrFragment; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -166,46 +83,68 @@ class MCSymbol { /// IsUsed - True if this symbol has been used. mutable unsigned IsUsed : 1; - mutable bool HasData : 1; + mutable bool IsRegistered : 1; + + /// This symbol is visible outside this translation unit. + mutable unsigned IsExternal : 1; + + /// This symbol is private extern. + mutable unsigned IsPrivateExtern : 1; + + /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is + /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. + unsigned Kind : 2; /// Index field, for use by the object file implementation. - mutable uint64_t Index : 60; + mutable uint32_t Index = 0; + + union { + /// The offset to apply to the fragment address to form this symbol's value. + uint64_t Offset; + + /// The size of the symbol, if it is 'common'. + uint64_t CommonSize; + }; - mutable MCSymbolData Data; + /// The alignment of the symbol, if it is 'common', or -1. + // + // FIXME: Pack this in with other fields? + unsigned CommonAlign = -1U; + + /// The Flags field is used by object file implementations to store + /// additional per symbol information which is not easily classified. + mutable uint32_t Flags = 0; -private: // MCContext creates and uniques these. +protected: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; - MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary) - : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {} + MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) + : Name(Name), Value(nullptr), IsTemporary(isTemporary), + IsRedefinable(false), IsUsed(false), IsRegistered(false), + IsExternal(false), IsPrivateExtern(false), + Kind(Kind) { + Offset = 0; + } +private: MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; MCSection *getSectionPtr() const { + if (MCFragment *F = getFragment()) + return F->getParent(); + assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); + MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>(); if (Section || !Value) return Section; - return Section = Value->FindAssociatedSection(); + return Section = Value->findAssociatedSection(); } public: /// getName - Get the symbol name. StringRef getName() const { return Name ? Name->first() : ""; } - bool hasData() const { return HasData; } - - /// Get associated symbol data. - MCSymbolData &getData() const { - assert(HasData && "Missing symbol data!"); - return Data; - } - - /// Initialize symbol data. - /// - /// Nothing really to do here, but this is enables an assertion that \a - /// MCAssembler::getOrCreateSymbolData() has actually been called before - /// anyone calls \a getData(). - void initializeData() const { HasData = true; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) const { IsRegistered = Value; } /// \name Accessors /// @{ @@ -225,7 +164,7 @@ public: void redefineIfPossible() { if (IsRedefinable) { Value = nullptr; - Section = nullptr; + SectionOrFragment = nullptr; IsRedefinable = false; } } @@ -258,11 +197,20 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - Section = &S; + assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); + SectionOrFragment = &S; + } + + /// Mark the symbol as undefined. + void setUndefined() { + SectionOrFragment = nullptr; } - /// setUndefined - Mark the symbol as undefined. - void setUndefined() { Section = nullptr; } + bool isELF() const { return Kind == SymbolKindELF; } + + bool isCOFF() const { return Kind == SymbolKindCOFF; } + + bool isMachO() const { return Kind == SymbolKindMachO; } /// @} /// \name Variable Symbols @@ -283,27 +231,98 @@ public: /// @} /// Get the (implementation defined) index. - uint64_t getIndex() const { - assert(HasData && "Uninitialized symbol data"); + uint32_t getIndex() const { return Index; } /// Set the (implementation defined) index. - void setIndex(uint64_t Value) const { - assert(HasData && "Uninitialized symbol data"); - assert(!(Value >> 60) && "Not enough bits for value"); + void setIndex(uint32_t Value) const { Index = Value; } + uint64_t getOffset() const { + assert(!isCommon()); + return Offset; + } + void setOffset(uint64_t Value) { + assert(!isCommon()); + Offset = Value; + } + + /// Return the size of a 'common' symbol. + uint64_t getCommonSize() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonSize; + } + + /// Mark this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + void setCommon(uint64_t Size, unsigned Align) { + assert(getOffset() == 0); + CommonSize = Size; + CommonAlign = Align; + } + + /// Return the alignment of a 'common' symbol. + unsigned getCommonAlignment() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonAlign; + } + + /// Declare this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + /// \return True if symbol was already declared as a different type + bool declareCommon(uint64_t Size, unsigned Align) { + assert(isCommon() || getOffset() == 0); + if(isCommon()) { + if(CommonSize != Size || CommonAlign != Align) + return true; + } else + setCommon(Size, Align); + return false; + } + + /// Is this a 'common' symbol. + bool isCommon() const { return CommonAlign != -1U; } + + MCFragment *getFragment() const { + return SectionOrFragment.dyn_cast<MCFragment *>(); + } + void setFragment(MCFragment *Value) const { + SectionOrFragment = Value; + } + + bool isExternal() const { return IsExternal; } + void setExternal(bool Value) const { IsExternal = Value; } + + bool isPrivateExtern() const { return IsPrivateExtern; } + void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } + /// print - Print the value to the stream \p OS. - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. void dump() const; + +protected: + /// Get the (implementation defined) symbol flags. + uint32_t getFlags() const { return Flags; } + + /// Set the (implementation defined) symbol flags. + void setFlags(uint32_t Value) const { Flags = Value; } + + /// Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) const { + Flags = (Flags & ~Mask) | Value; + } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { - Sym.print(OS); + Sym.print(OS, nullptr); return OS; } } // end namespace llvm diff --git a/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h b/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h new file mode 100644 index 0000000..2172c67 --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCSymbolCOFF.h @@ -0,0 +1,64 @@ +//===- MCSymbolCOFF.h - ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLCOFF_H +#define LLVM_MC_MCSYMBOLCOFF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolCOFF : public MCSymbol { + + /// This corresponds to the e_type field of the COFF symbol. + mutable uint16_t Type; + + enum SymbolFlags : uint16_t { + SF_ClassMask = 0x00FF, + SF_ClassShift = 0, + + SF_WeakExternal = 0x0100, + SF_SafeSEH = 0x0200, + }; + +public: + MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindCOFF, Name, isTemporary), Type(0) {} + + uint16_t getType() const { + return Type; + } + void setType(uint16_t Ty) const { + Type = Ty; + } + + uint16_t getClass() const { + return (getFlags() & SF_ClassMask) >> SF_ClassShift; + } + void setClass(uint16_t StorageClass) const { + modifyFlags(StorageClass << SF_ClassShift, SF_ClassMask); + } + + bool isWeakExternal() const { + return getFlags() & SF_WeakExternal; + } + void setIsWeakExternal() const { + modifyFlags(SF_WeakExternal, SF_WeakExternal); + } + + bool isSafeSEH() const { + return getFlags() & SF_SafeSEH; + } + void setIsSafeSEH() const { + modifyFlags(SF_SafeSEH, SF_SafeSEH); + } + + static bool classof(const MCSymbol *S) { return S->isCOFF(); } +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCSymbolELF.h b/contrib/llvm/include/llvm/MC/MCSymbolELF.h new file mode 100644 index 0000000..0cc1115 --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCSymbolELF.h @@ -0,0 +1,57 @@ +//===- MCSymbolELF.h - -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLELF_H +#define LLVM_MC_MCSYMBOLELF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolELF : public MCSymbol { + /// An expression describing how to calculate the size of a symbol. If a + /// symbol has no size this field will be NULL. + const MCExpr *SymbolSize = nullptr; + +public: + MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindELF, Name, isTemporary) {} + void setSize(const MCExpr *SS) { SymbolSize = SS; } + + const MCExpr *getSize() const { return SymbolSize; } + + void setVisibility(unsigned Visibility); + unsigned getVisibility() const; + + void setOther(unsigned Other); + unsigned getOther() const; + + void setType(unsigned Type) const; + unsigned getType() const; + + void setBinding(unsigned Binding) const; + unsigned getBinding() const; + + bool isBindingSet() const; + + void setUsedInReloc() const; + bool isUsedInReloc() const; + + void setIsWeakrefUsedInReloc() const; + bool isWeakrefUsedInReloc() const; + + void setIsSignature() const; + bool isSignature() const; + + static bool classof(const MCSymbol *S) { return S->isELF(); } + +private: + void setIsBindingSet() const; +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCSymbolMachO.h b/contrib/llvm/include/llvm/MC/MCSymbolMachO.h new file mode 100644 index 0000000..166ae9e --- /dev/null +++ b/contrib/llvm/include/llvm/MC/MCSymbolMachO.h @@ -0,0 +1,123 @@ +//===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLMACHO_H +#define setIsWeakExternal + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolMachO : public MCSymbol { + /// \brief We store the value for the 'desc' symbol field in the + /// lowest 16 bits of the implementation defined flags. + enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>. + SF_DescFlagsMask = 0xFFFF, + + // Reference type flags. + SF_ReferenceTypeMask = 0x0007, + SF_ReferenceTypeUndefinedNonLazy = 0x0000, + SF_ReferenceTypeUndefinedLazy = 0x0001, + SF_ReferenceTypeDefined = 0x0002, + SF_ReferenceTypePrivateDefined = 0x0003, + SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, + SF_ReferenceTypePrivateUndefinedLazy = 0x0005, + + // Other 'desc' flags. + SF_ThumbFunc = 0x0008, + SF_NoDeadStrip = 0x0020, + SF_WeakReference = 0x0040, + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100, + + // Common alignment + SF_CommonAlignmentMask = 0xF0FF, + SF_CommonAlignmentShift = 8 + }; + +public: + MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindMachO, Name, isTemporary) {} + + // Reference type methods. + + void clearReferenceType() const { + modifyFlags(0, SF_ReferenceTypeMask); + } + + void setReferenceTypeUndefinedLazy(bool Value) const { + modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0, + SF_ReferenceTypeUndefinedLazy); + } + + // Other 'desc' methods. + + void setThumbFunc() const { + modifyFlags(SF_ThumbFunc, SF_ThumbFunc); + } + + bool isNoDeadStrip() const { + return getFlags() & SF_NoDeadStrip; + } + void setNoDeadStrip() const { + modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip); + } + + bool isWeakReference() const { + return getFlags() & SF_WeakReference; + } + void setWeakReference() const { + modifyFlags(SF_WeakReference, SF_WeakReference); + } + + bool isWeakDefinition() const { + return getFlags() & SF_WeakDefinition; + } + void setWeakDefinition() const { + modifyFlags(SF_WeakDefinition, SF_WeakDefinition); + } + + bool isSymbolResolver() const { + return getFlags() & SF_SymbolResolver; + } + void setSymbolResolver() const { + modifyFlags(SF_SymbolResolver, SF_SymbolResolver); + } + + void setDesc(unsigned Value) const { + assert(Value == (Value & SF_DescFlagsMask) && + "Invalid .desc value!"); + setFlags(Value & SF_DescFlagsMask); + } + + /// \brief Get the encoded value of the flags as they will be emitted in to + /// the MachO binary + uint16_t getEncodedFlags() const { + uint16_t Flags = getFlags(); + + // Common alignment is packed into the 'desc' bits. + if (isCommon()) { + if (unsigned Align = getCommonAlignment()) { + unsigned Log2Size = Log2_32(Align); + assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); + if (Log2Size > 15) + report_fatal_error("invalid 'common' alignment '" + + Twine(Align) + "' for '" + getName() + "'", + false); + Flags = (Flags & SF_CommonAlignmentMask) | + (Log2Size << SF_CommonAlignmentShift); + } + } + + return Flags; + } + + static bool classof(const MCSymbol *S) { return S->isMachO(); } +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h index 6a83e02..6fbc754 100644 --- a/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h +++ b/contrib/llvm/include/llvm/MC/MCWinCOFFStreamer.h @@ -50,9 +50,9 @@ public: void EmitCOFFSymbolStorageClass(int StorageClass) override; void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; + void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; void EmitCOFFSecRel32(MCSymbol const *Symbol) override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/contrib/llvm/include/llvm/MC/SubtargetFeature.h b/contrib/llvm/include/llvm/MC/SubtargetFeature.h index 6a631ff..2fb9b4a 100644 --- a/contrib/llvm/include/llvm/MC/SubtargetFeature.h +++ b/contrib/llvm/include/llvm/MC/SubtargetFeature.h @@ -103,6 +103,10 @@ public: FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String, ArrayRef<SubtargetFeatureKV> FeatureTable); + /// Apply the feature flag and return the newly updated feature bits. + FeatureBitset ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature, + ArrayRef<SubtargetFeatureKV> FeatureTable); + /// Get feature bits of a CPU. FeatureBitset getFeatureBits(StringRef CPU, ArrayRef<SubtargetFeatureKV> CPUTable, diff --git a/contrib/llvm/include/llvm/Object/ArchiveWriter.h b/contrib/llvm/include/llvm/Object/ArchiveWriter.h new file mode 100644 index 0000000..1616e46 --- /dev/null +++ b/contrib/llvm/include/llvm/Object/ArchiveWriter.h @@ -0,0 +1,51 @@ +//===- ArchiveWriter.h - ar archive file format writer ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declares the writeArchive function for writing an archive file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ARCHIVEWRITER_H +#define LLVM_OBJECT_ARCHIVEWRITER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Archive.h" +#include "llvm/Support/FileSystem.h" + +namespace llvm { + +class NewArchiveIterator { + bool IsNewMember; + StringRef Name; + + object::Archive::child_iterator OldI; + + StringRef NewFilename; + +public: + NewArchiveIterator(object::Archive::child_iterator I, StringRef Name); + NewArchiveIterator(StringRef I, StringRef Name); + NewArchiveIterator(); + bool isNewMember() const; + StringRef getName() const; + + object::Archive::child_iterator getOld() const; + + StringRef getNew() const; + llvm::ErrorOr<int> getFD(sys::fs::file_status &NewStatus) const; + const sys::fs::file_status &getStatus() const; +}; + +std::pair<StringRef, std::error_code> +writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, + bool WriteSymtab); + +} + +#endif diff --git a/contrib/llvm/include/llvm/Object/COFF.h b/contrib/llvm/include/llvm/Object/COFF.h index ccac020..564eb7a 100644 --- a/contrib/llvm/include/llvm/Object/COFF.h +++ b/contrib/llvm/include/llvm/Object/COFF.h @@ -613,7 +613,7 @@ protected: StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; @@ -647,10 +647,6 @@ protected: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; - public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); basic_symbol_iterator symbol_begin_impl() const override; @@ -699,7 +695,7 @@ public: return object_error::parse_failed; Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index; - return object_error::success; + return std::error_code(); } ErrorOr<COFFSymbolRef> getSymbol(uint32_t index) const { if (SymbolTable16) { @@ -722,7 +718,7 @@ public: if (std::error_code EC = s.getError()) return EC; Res = reinterpret_cast<const T *>(s->getRawPtr()); - return object_error::success; + return std::error_code(); } std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; diff --git a/contrib/llvm/include/llvm/Object/ELF.h b/contrib/llvm/include/llvm/Object/ELF.h index ddabf59..e87737d 100644 --- a/contrib/llvm/include/llvm/Object/ELF.h +++ b/contrib/llvm/include/llvm/Object/ELF.h @@ -318,7 +318,7 @@ public: std::pair<const Elf_Shdr *, const Elf_Sym *> getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const; - ELFFile(StringRef Object, std::error_code &ec); + ELFFile(StringRef Object, std::error_code &EC); bool isMipsELF64() const { return Header->e_machine == ELF::EM_MIPS && @@ -423,12 +423,10 @@ public: StringRef getLoadName() const; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile; -typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile; -typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile; -typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile; +typedef ELFFile<ELFType<support::little, false>> ELF32LEFile; +typedef ELFFile<ELFType<support::little, true>> ELF64LEFile; +typedef ELFFile<ELFType<support::big, false>> ELF32BEFile; +typedef ELFFile<ELFType<support::big, true>> ELF64BEFile; // Iterate through the version definitions, and place each Elf_Verdef // in the VersionMap according to its index. @@ -622,7 +620,7 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { } template <class ELFT> -ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) +ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), @@ -630,9 +628,11 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) dt_soname(nullptr) { const uint64_t FileSize = Buf.size(); - if (sizeof(Elf_Ehdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("File too short!"); + if (sizeof(Elf_Ehdr) > FileSize) { + // File too short! + EC = object_error::parse_failed; + return; + } Header = reinterpret_cast<const Elf_Ehdr *>(base()); @@ -641,40 +641,50 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) const uint64_t SectionTableOffset = Header->e_shoff; - if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section header table goes past end of file!"); + if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) { + // Section header table goes past end of file! + EC = object_error::parse_failed; + return; + } // The getNumSections() call below depends on SectionHeaderTable being set. SectionHeaderTable = reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; - if (SectionTableOffset + SectionTableSize > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section table goes past end of file!"); + if (SectionTableOffset + SectionTableSize > FileSize) { + // Section table goes past end of file! + EC = object_error::parse_failed; + return; + } // Scan sections for special sections. for (const Elf_Shdr &Sec : sections()) { switch (Sec.sh_type) { case ELF::SHT_SYMTAB_SHNDX: - if (SymbolTableSectionHeaderIndex) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab_shndx!"); + if (SymbolTableSectionHeaderIndex) { + // More than one .symtab_shndx! + EC = object_error::parse_failed; + return; + } SymbolTableSectionHeaderIndex = &Sec; break; case ELF::SHT_SYMTAB: - if (dot_symtab_sec) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab!"); + if (dot_symtab_sec) { + // More than one .symtab! + EC = object_error::parse_failed; + return; + } dot_symtab_sec = &Sec; dot_strtab_sec = getSection(Sec.sh_link); break; case ELF::SHT_DYNSYM: { - if (DynSymRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynsym!"); + if (DynSymRegion.Addr) { + // More than one .dynsym! + EC = object_error::parse_failed; + return; + } DynSymRegion.Addr = base() + Sec.sh_offset; DynSymRegion.Size = Sec.sh_size; DynSymRegion.EntSize = Sec.sh_entsize; @@ -685,29 +695,37 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) break; } case ELF::SHT_DYNAMIC: - if (DynamicRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynamic!"); + if (DynamicRegion.Addr) { + // More than one .dynamic! + EC = object_error::parse_failed; + return; + } DynamicRegion.Addr = base() + Sec.sh_offset; DynamicRegion.Size = Sec.sh_size; DynamicRegion.EntSize = Sec.sh_entsize; break; case ELF::SHT_GNU_versym: - if (dot_gnu_version_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version section!"); + if (dot_gnu_version_sec != nullptr) { + // More than one .gnu.version section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_sec = &Sec; break; case ELF::SHT_GNU_verdef: - if (dot_gnu_version_d_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_d section!"); + if (dot_gnu_version_d_sec != nullptr) { + // More than one .gnu.version_d section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_d_sec = &Sec; break; case ELF::SHT_GNU_verneed: - if (dot_gnu_version_r_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_r section!"); + if (dot_gnu_version_r_sec != nullptr) { + // More than one .gnu.version_r section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_r_sec = &Sec; break; } @@ -744,7 +762,7 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) } } - ec = std::error_code(); + EC = std::error_code(); } // Get the symbol table index in the symtab section given a symbol @@ -898,11 +916,8 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const { template <class ELFT> ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section, const Elf_Sym *Symb) const { - if (Symb->st_name == 0) { - const Elf_Shdr *ContainingSec = getSection(Symb); - if (ContainingSec) - return getSectionName(ContainingSec); - } + if (Symb->st_name == 0) + return StringRef(""); const Elf_Shdr *StrTab = getSection(Section->sh_link); if (Symb->st_name >= StrTab->sh_size) diff --git a/contrib/llvm/include/llvm/Object/ELFObjectFile.h b/contrib/llvm/include/llvm/Object/ELFObjectFile.h index 9bd4c32..78d77be 100644 --- a/contrib/llvm/include/llvm/Object/ELFObjectFile.h +++ b/contrib/llvm/include/llvm/Object/ELFObjectFile.h @@ -79,9 +79,8 @@ protected: StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; std::error_code getSymbolType(DataRefImpl Symb, @@ -119,9 +118,6 @@ protected: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -227,7 +223,7 @@ public: std::error_code getPlatformFlags(unsigned &Result) const override { Result = EF.getHeader()->e_flags; - return object_error::success; + return std::error_code(); } const ELFFile<ELFT> *getELFFile() const { return &EF; } @@ -244,12 +240,10 @@ public: bool isRelocatableObject() const override; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile; -typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile; -typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile; -typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile; +typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile; +typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile; +typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile; +typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile; template <class ELFT> void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const { @@ -263,7 +257,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -277,7 +271,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, if (!Ver) return Ver.getError(); Version = *Ver; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -300,10 +294,10 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, case ELF::SHN_COMMON: case ELF::SHN_UNDEF: Result = UnknownAddressOrSize; - return object_error::success; + return std::error_code(); case ELF::SHN_ABS: Result = ESym->st_value; - return object_error::success; + return std::error_code(); default: break; } @@ -322,32 +316,27 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, Result += Section->sh_addr; } - return object_error::success; + return std::error_code(); } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const { +uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { Elf_Sym_Iter Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) - Res = Sym->st_value; - else - Res = 0; - return object_error::success; + return Sym->st_value; + return 0; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { - Result = toELFSymIter(Symb)->st_size; - return object_error::success; +uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb) const { + return toELFSymIter(Symb)->st_size; } template <class ELFT> std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb, uint8_t &Result) const { Result = toELFSymIter(Symb)->st_other; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -378,7 +367,7 @@ ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, Result = SymbolRef::ST_Other; break; } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -435,7 +424,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { Res = getSymbolSection(getSymbol(Symb)); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -450,7 +439,7 @@ std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -469,7 +458,7 @@ ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, StringRef &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -624,7 +613,7 @@ ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, Result = ROffset; } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -634,7 +623,7 @@ ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, assert(EF.getHeader()->e_type == ELF::ET_REL && "Only relocatable object files have relocation offsets"); Result = getROffset(Rel); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -666,7 +655,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, break; } } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -693,7 +682,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationTypeName( } EF.getRelocationTypeName(type, Result); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -706,94 +695,13 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, report_fatal_error("Invalid section type in Rel!"); case ELF::SHT_REL: { Result = 0; - return object_error::success; + return std::error_code(); } case ELF::SHT_RELA: { Result = getRela(Rel)->r_addend; - return object_error::success; - } + return std::error_code(); } -} - -template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getRelocationValueString( - DataRefImpl Rel, SmallVectorImpl<char> &Result) const { - const Elf_Shdr *sec = getRelSection(Rel); - uint8_t type; - StringRef res; - int64_t addend = 0; - uint16_t symbol_index = 0; - switch (sec->sh_type) { - default: - return object_error::parse_failed; - case ELF::SHT_REL: { - type = getRel(Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); - // TODO: Read implicit addend from section data. - break; - } - case ELF::SHT_RELA: { - type = getRela(Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(Rel)->r_addend; - break; - } - } - const Elf_Sym *symb = - EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); - ErrorOr<StringRef> SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); - if (!SymName) - return SymName.getError(); - switch (EF.getHeader()->e_machine) { - case ELF::EM_X86_64: - switch (type) { - case ELF::R_X86_64_PC8: - case ELF::R_X86_64_PC16: - case ELF::R_X86_64_PC32: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - case ELF::R_X86_64_8: - case ELF::R_X86_64_16: - case ELF::R_X86_64_32: - case ELF::R_X86_64_32S: - case ELF::R_X86_64_64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - default: - res = "Unknown"; - } - break; - case ELF::EM_AARCH64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName; - if (addend != 0) - fmt << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - break; - } - case ELF::EM_386: - case ELF::EM_ARM: - case ELF::EM_HEXAGON: - case ELF::EM_MIPS: - res = *SymName; - break; - default: - res = "Unknown"; } - if (Result.empty()) - Result.append(res.begin(), res.end()); - return object_error::success; } template <class ELFT> diff --git a/contrib/llvm/include/llvm/Object/ELFTypes.h b/contrib/llvm/include/llvm/Object/ELFTypes.h index 287d367..3f323b5 100644 --- a/contrib/llvm/include/llvm/Object/ELFTypes.h +++ b/contrib/llvm/include/llvm/Object/ELFTypes.h @@ -10,7 +10,6 @@ #ifndef LLVM_OBJECT_ELFTYPES_H #define LLVM_OBJECT_ELFTYPES_H -#include "llvm/Support/AlignOf.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" @@ -20,95 +19,74 @@ namespace object { using support::endianness; -template <endianness target_endianness, std::size_t max_alignment, - bool is64Bits> -struct ELFType { +template <endianness target_endianness, bool is64Bits> struct ELFType { static const endianness TargetEndianness = target_endianness; - static const std::size_t MaxAlignment = max_alignment; static const bool Is64Bits = is64Bits; }; -template <typename T, int max_align> struct MaximumAlignment { - enum { value = AlignOf<T>::Alignment > max_align ? max_align - : AlignOf<T>::Alignment - }; -}; +// Use an alignment of 2 for the typedefs since that is the worst case for +// ELF files in archives. // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. -template <endianness target_endianness, std::size_t max_alignment> -struct ELFDataTypeTypedefHelperCommon { +template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon { typedef support::detail::packed_endian_specific_integral< - uint16_t, target_endianness, - MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; + uint16_t, target_endianness, 2> Elf_Half; typedef support::detail::packed_endian_specific_integral< - uint32_t, target_endianness, - MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; + uint32_t, target_endianness, 2> Elf_Word; typedef support::detail::packed_endian_specific_integral< - int32_t, target_endianness, - MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; + int32_t, target_endianness, 2> Elf_Sword; typedef support::detail::packed_endian_specific_integral< - uint64_t, target_endianness, - MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; + uint64_t, target_endianness, 2> Elf_Xword; typedef support::detail::packed_endian_specific_integral< - int64_t, target_endianness, - MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; + int64_t, target_endianness, 2> Elf_Sxword; }; template <class ELFT> struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template <endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> > - : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { +template <endianness TargetEndianness> +struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>> + : ELFDataTypeTypedefHelperCommon<TargetEndianness> { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; /// ELF 64bit types. -template <endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> > - : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { +template <endianness TargetEndianness> +struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>> + : ELFDataTypeTypedefHelperCommon<TargetEndianness> { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr \ - Elf_Addr; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off \ - Elf_Off; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half \ - Elf_Half; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word \ - Elf_Word; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword \ - Elf_Sword; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword \ - Elf_Xword; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword \ - Elf_Sxword; +#define LLVM_ELF_IMPORT_TYPES(E, W) \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Addr Elf_Addr; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Off Elf_Off; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Half Elf_Half; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Word Elf_Word; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sword Elf_Sword; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Xword Elf_Xword; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sxword Elf_Sxword; #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ - LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ - ELFT::Is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::Is64Bits) // Section header. template <class ELFT> struct Elf_Shdr_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -121,9 +99,9 @@ struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Word sh_entsize; // Size of records contained within the section }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -151,9 +129,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { template <class ELFT> struct Elf_Sym_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Sym_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -162,9 +140,9 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Sym_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -176,6 +154,7 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { template <class ELFT> struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { using Elf_Sym_Base<ELFT>::st_info; + using Elf_Sym_Base<ELFT>::st_shndx; using Elf_Sym_Base<ELFT>::st_other; // These accessors and mutators correspond to the ELF32_ST_BIND, @@ -198,6 +177,25 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { assert(v < 4 && "Invalid value for visibility"); st_other = (st_other & ~0x3) | v; } + + bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; } + bool isCommon() const { + return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON; + } + bool isDefined() const { + return !isUndefined() && + !(st_shndx >= ELF::SHN_LORESERVE && st_shndx < ELF::SHN_ABS); + } + bool isProcessorSpecific() const { + return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC; + } + bool isOSSpecific() const { + return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS; + } + bool isReserved() const { + return st_shndx > ELF::SHN_HIOS && st_shndx < ELF::SHN_ABS; + } + bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; } }; /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section @@ -267,9 +265,9 @@ struct Elf_Vernaux_Impl { /// table section (.dynamic) look like. template <class ELFT> struct Elf_Dyn_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Sword d_tag; union { Elf_Word d_val; @@ -277,9 +275,9 @@ struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { } d_un; }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -300,9 +298,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { // Elf_Rel: Elf Relocation template <class ELFT, bool isRela> struct Elf_Rel_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -316,9 +314,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply @@ -341,9 +339,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this @@ -358,9 +356,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply Elf_Sxword r_addend; // Compute value for relocatable field by adding this. @@ -386,11 +384,10 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { template <class ELFT, bool isRela> struct Elf_Rel_Impl; -template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, - isRela> : Elf_Rel_Base< - ELFType<TargetEndianness, MaxAlign, true>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness, bool isRela> +struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela> + : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: @@ -411,11 +408,10 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, } }; -template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, - isRela> : Elf_Rel_Base< - ELFType<TargetEndianness, MaxAlign, false>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness, bool isRela> +struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela> + : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, // and ELF32_R_INFO macros defined in the ELF specification: @@ -463,9 +459,9 @@ struct Elf_Ehdr_Impl { template <class ELFT> struct Elf_Phdr_Impl; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes Elf_Addr p_vaddr; // Virtual Address of beginning of segment @@ -476,9 +472,9 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Word p_align; // Segment alignment constraint }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes @@ -493,17 +489,17 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { template <class ELFT> struct Elf_Mips_RegInfo; -template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, false>> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <llvm::support::endianness TargetEndianness> +struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers Elf_Addr ri_gp_value; // gp register value }; -template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, true>> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <llvm::support::endianness TargetEndianness> +struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_pad; // unused padding field Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers diff --git a/contrib/llvm/include/llvm/Object/Error.h b/contrib/llvm/include/llvm/Object/Error.h index 90c2bd7..c9db1b8 100644 --- a/contrib/llvm/include/llvm/Object/Error.h +++ b/contrib/llvm/include/llvm/Object/Error.h @@ -22,12 +22,15 @@ namespace object { const std::error_category &object_category(); enum class object_error { - success = 0, - arch_not_found, + // Error code 0 is absent. Use std::error_code() instead. + arch_not_found = 1, invalid_file_type, parse_failed, unexpected_eof, bitcode_section_not_found, + macho_small_load_command, + macho_load_segment_too_many_sections, + macho_load_segment_too_small, }; inline std::error_code make_error_code(object_error e) { diff --git a/contrib/llvm/include/llvm/Object/MachO.h b/contrib/llvm/include/llvm/Object/MachO.h index 0a9b62c..b163534 100644 --- a/contrib/llvm/include/llvm/Object/MachO.h +++ b/contrib/llvm/include/llvm/Object/MachO.h @@ -190,6 +190,8 @@ public: const char *Ptr; // Where in memory the load command is. MachO::load_command C; // The command itself. }; + typedef SmallVector<LoadCommandInfo, 4> LoadCommandList; + typedef LoadCommandList::const_iterator load_command_iterator; MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, std::error_code &EC); @@ -204,9 +206,8 @@ public: std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; @@ -241,11 +242,9 @@ public: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; + uint8_t getRelocationLength(DataRefImpl Rel) const; // MachO specific. std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; @@ -273,10 +272,14 @@ public: dice_iterator begin_dices() const; dice_iterator end_dices() const; - + + load_command_iterator begin_load_commands() const; + load_command_iterator end_load_commands() const; + iterator_range<load_command_iterator> load_commands() const; + /// For use iterating over all exported symbols. iterator_range<export_iterator> exports() const; - + /// For use examining a trie not in a MachOObjectFile. static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie); @@ -329,10 +332,6 @@ public: unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const; - // Walk load commands. - LoadCommandInfo getFirstLoadCommandInfo() const; - LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; - // MachO specific structures. MachO::section getSection(DataRefImpl DRI) const; MachO::section_64 getSection64(DataRefImpl DRI) const; @@ -386,8 +385,8 @@ public: MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; MachO::data_in_code_entry getDice(DataRefImpl Rel) const; - MachO::mach_header getHeader() const; - MachO::mach_header_64 getHeader64() const; + const MachO::mach_header &getHeader() const; + const MachO::mach_header_64 &getHeader64() const; uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const; @@ -430,10 +429,15 @@ public: } private: + union { + MachO::mach_header_64 Header64; + MachO::mach_header Header; + }; typedef SmallVector<const char*, 1> SectionList; SectionList Sections; typedef SmallVector<const char*, 1> LibraryList; LibraryList Libraries; + LoadCommandList LoadCommands; typedef SmallVector<StringRef, 1> LibraryShortName; mutable LibraryShortName LibrariesShortNames; const char *SymtabLoadCmd; @@ -472,7 +476,7 @@ inline std::error_code DiceRef::getOffset(uint32_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.offset; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getLength(uint16_t &Result) const { @@ -480,7 +484,7 @@ inline std::error_code DiceRef::getLength(uint16_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.length; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getKind(uint16_t &Result) const { @@ -488,7 +492,7 @@ inline std::error_code DiceRef::getKind(uint16_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.kind; - return object_error::success; + return std::error_code(); } inline DataRefImpl DiceRef::getRawDataRefImpl() const { diff --git a/contrib/llvm/include/llvm/Object/ObjectFile.h b/contrib/llvm/include/llvm/Object/ObjectFile.h index 14cd082..a1ae19e 100644 --- a/contrib/llvm/include/llvm/Object/ObjectFile.h +++ b/contrib/llvm/include/llvm/Object/ObjectFile.h @@ -66,11 +66,6 @@ public: /// This is for display purposes only. std::error_code getTypeName(SmallVectorImpl<char> &Result) const; - /// @brief Get a string that represents the calculation of the value of this - /// relocation. - /// - /// This is for display purposes only. - std::error_code getValueString(SmallVectorImpl<char> &Result) const; DataRefImpl getRawDataRefImpl() const; const ObjectFile *getObjectFile() const; @@ -146,8 +141,8 @@ public: /// mapped). std::error_code getAddress(uint64_t &Result) const; /// @brief Get the alignment of this symbol as the actual value (not log 2). - std::error_code getAlignment(uint32_t &Result) const; - std::error_code getSize(uint64_t &Result) const; + uint32_t getAlignment() const; + uint64_t getSize() const; std::error_code getType(SymbolRef::Type &Result) const; std::error_code getOther(uint8_t &Result) const; @@ -206,10 +201,8 @@ protected: DataRefImpl Symb) const override; virtual std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; - virtual std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const; - virtual std::error_code getSymbolSize(DataRefImpl Symb, - uint64_t &Res) const = 0; + virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; + virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; virtual std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; virtual std::error_code getSymbolSection(DataRefImpl Symb, @@ -254,13 +247,10 @@ protected: virtual std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const = 0; - virtual std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const = 0; virtual std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const { Result = false; - return object_error::success; + return std::error_code(); } public: @@ -334,12 +324,12 @@ inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); } -inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const { - return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result); +inline uint32_t SymbolRef::getAlignment() const { + return getObject()->getSymbolAlignment(getRawDataRefImpl()); } -inline std::error_code SymbolRef::getSize(uint64_t &Result) const { - return getObject()->getSymbolSize(getRawDataRefImpl(), Result); +inline uint64_t SymbolRef::getSize() const { + return getObject()->getSymbolSize(getRawDataRefImpl()); } inline std::error_code SymbolRef::getSection(section_iterator &Result) const { @@ -482,11 +472,6 @@ RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { return OwningObject->getRelocationTypeName(RelocationPimpl, Result); } -inline std::error_code -RelocationRef::getValueString(SmallVectorImpl<char> &Result) const { - return OwningObject->getRelocationValueString(RelocationPimpl, Result); -} - inline std::error_code RelocationRef::getHidden(bool &Result) const { return OwningObject->getRelocationHidden(RelocationPimpl, Result); } diff --git a/contrib/llvm/include/llvm/Object/RelocVisitor.h b/contrib/llvm/include/llvm/Object/RelocVisitor.h index 91eafd5..02ffda5 100644 --- a/contrib/llvm/include/llvm/Object/RelocVisitor.h +++ b/contrib/llvm/include/llvm/Object/RelocVisitor.h @@ -19,9 +19,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -52,6 +54,8 @@ public: return visitELF(RelocType, R, Value); if (isa<COFFObjectFile>(ObjToVisit)) return visitCOFF(RelocType, R, Value); + if (isa<MachOObjectFile>(ObjToVisit)) + return visitMachO(RelocType, R, Value); HasError = true; return RelocToApply(); @@ -221,6 +225,20 @@ private: return RelocToApply(); } + RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { + switch (ObjToVisit.getArch()) { + default: break; + case Triple::x86_64: + switch (RelocType) { + default: break; + case MachO::X86_64_RELOC_UNSIGNED: + return visitMACHO_X86_64_UNSIGNED(R, Value); + } + } + HasError = true; + return RelocToApply(); + } + int64_t getELFAddend32LE(RelocationRef R) { const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile()); DataRefImpl DRI = R.getRawDataRefImpl(); @@ -252,6 +270,12 @@ private: Obj->getRelocationAddend(DRI, Addend); return Addend; } + + uint8_t getLengthMachO64(RelocationRef R) { + const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObjectFile()); + return Obj->getRelocationLength(R.getRawDataRefImpl()); + } + /// Operations /// 386-ELF @@ -413,6 +437,13 @@ private: RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { return RelocToApply(Value, /*Width=*/8); } + + // X86_64 MachO + RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { + uint8_t Length = getLengthMachO64(R); + Length = 1<<Length; + return RelocToApply(Value, Length); + } }; } diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h index 7f54822..b26af61 100644 --- a/contrib/llvm/include/llvm/Support/COFF.h +++ b/contrib/llvm/include/llvm/Support/COFF.h @@ -155,16 +155,6 @@ namespace COFF { uint8_t NumberOfAuxSymbols; }; - enum SymbolFlags { - SF_TypeMask = 0x0000FFFF, - SF_TypeShift = 0, - - SF_ClassMask = 0x00FF0000, - SF_ClassShift = 16, - - SF_WeakExternal = 0x01000000 - }; - enum SymbolSectionNumber : int32_t { IMAGE_SYM_DEBUG = -2, IMAGE_SYM_ABSOLUTE = -1, diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h index bd1d1cb..1ad8a3b 100644 --- a/contrib/llvm/include/llvm/Support/CommandLine.h +++ b/contrib/llvm/include/llvm/Support/CommandLine.h @@ -1284,24 +1284,81 @@ public: } }; -// Define how to hold a class type object, such as a string. Since we can -// inherit from a class, we do so. This makes us exactly compatible with the -// object in all cases that it is used. +// Define how to hold a class type object, such as a string. +// Originally this code inherited from std::vector. In transitioning to a new +// API for command line options we should change this. The new implementation +// of this list_storage specialization implements the minimum subset of the +// std::vector API required for all the current clients. // -template <class DataType> -class list_storage<DataType, bool> : public std::vector<DataType> { +// FIXME: Reduce this API to a more narrow subset of std::vector +// +template <class DataType> class list_storage<DataType, bool> { + std::vector<DataType> Storage; + public: - template <class T> void addValue(const T &V) { - std::vector<DataType>::push_back(V); + typedef typename std::vector<DataType>::iterator iterator; + + iterator begin() { return Storage.begin(); } + iterator end() { return Storage.end(); } + + typedef typename std::vector<DataType>::const_iterator const_iterator; + const_iterator begin() const { return Storage.begin(); } + const_iterator end() const { return Storage.end(); } + + typedef typename std::vector<DataType>::size_type size_type; + size_type size() const { return Storage.size(); } + + bool empty() const { return Storage.empty(); } + + void push_back(const DataType &value) { Storage.push_back(value); } + void push_back(DataType &&value) { Storage.push_back(value); } + + typedef typename std::vector<DataType>::reference reference; + typedef typename std::vector<DataType>::const_reference const_reference; + reference operator[](size_type pos) { return Storage[pos]; } + const_reference operator[](size_type pos) const { return Storage[pos]; } + + iterator erase(const_iterator pos) { return Storage.erase(pos); } + iterator erase(const_iterator first, const_iterator last) { + return Storage.erase(first, last); + } + + iterator erase(iterator pos) { return Storage.erase(pos); } + iterator erase(iterator first, iterator last) { + return Storage.erase(first, last); } + + iterator insert(const_iterator pos, const DataType &value) { + return Storage.insert(pos, value); + } + iterator insert(const_iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + iterator insert(iterator pos, const DataType &value) { + return Storage.insert(pos, value); + } + iterator insert(iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + reference front() { return Storage.front(); } + const_reference front() const { return Storage.front(); } + + operator std::vector<DataType>&() { return Storage; } + operator ArrayRef<DataType>() { return Storage; } + std::vector<DataType> *operator&() { return &Storage; } + const std::vector<DataType> *operator&() const { return &Storage; } + + template <class T> void addValue(const T &V) { Storage.push_back(V); } }; //===----------------------------------------------------------------------===// // list - A list of command line options. // -template <class DataType, class Storage = bool, +template <class DataType, class StorageClass = bool, class ParserClass = parser<DataType>> -class list : public Option, public list_storage<DataType, Storage> { +class list : public Option, public list_storage<DataType, StorageClass> { std::vector<unsigned> Positions; ParserClass Parser; @@ -1319,7 +1376,7 @@ class list : public Option, public list_storage<DataType, Storage> { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - list_storage<DataType, Storage>::addValue(Val); + list_storage<DataType, StorageClass>::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h index c81fbaf..67ef23d 100644 --- a/contrib/llvm/include/llvm/Support/Compiler.h +++ b/contrib/llvm/include/llvm/Support/Compiler.h @@ -350,19 +350,6 @@ # define LLVM_ADDRESS_SANITIZER_BUILD 0 #endif -/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST -/// \brief Is unaligned memory access fast on the host machine. -/// -/// Don't specialize on alignment for platforms where unaligned memory accesses -/// generates the same code as aligned memory accesses for common types. -#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \ - defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386) || defined(__i386__) -# define LLVM_IS_UNALIGNED_ACCESS_FAST 1 -#else -# define LLVM_IS_UNALIGNED_ACCESS_FAST 0 -#endif - /// \brief Mark debug helper function definitions like dump() that should not be /// stripped from debug builds. // FIXME: Move this to a private config.h as it's not usable in public headers. diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def b/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def index c9d35b8..a698ecb 100644 --- a/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def +++ b/contrib/llvm/include/llvm/Support/ELFRelocs/Hexagon.def @@ -90,3 +90,11 @@ ELF_RELOC(R_HEX_IE_GOT_11_X, 82) ELF_RELOC(R_HEX_TPREL_32_6_X, 83) ELF_RELOC(R_HEX_TPREL_16_X, 84) ELF_RELOC(R_HEX_TPREL_11_X, 85) +ELF_RELOC(R_HEX_LD_PLT_B22_PCREL, 86) +ELF_RELOC(R_HEX_LD_GOT_LO16, 87) +ELF_RELOC(R_HEX_LD_GOT_HI16, 88) +ELF_RELOC(R_HEX_LD_GOT_32, 89) +ELF_RELOC(R_HEX_LD_GOT_16, 90) +ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91) +ELF_RELOC(R_HEX_LD_GOT_16_X, 92) +ELF_RELOC(R_HEX_LD_GOT_11_X, 93) diff --git a/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h index e316616..2cf7e0e 100644 --- a/contrib/llvm/include/llvm/Support/MathExtras.h +++ b/contrib/llvm/include/llvm/Support/MathExtras.h @@ -562,7 +562,7 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) { /// /// Alignment should be a power of two. This method rounds up, so /// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. -inline uintptr_t alignAddr(void *Addr, size_t Alignment) { +inline uintptr_t alignAddr(const void *Addr, size_t Alignment) { assert(Alignment && isPowerOf2_64((uint64_t)Alignment) && "Alignment is not a power of two!"); @@ -573,7 +573,7 @@ inline uintptr_t alignAddr(void *Addr, size_t Alignment) { /// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment /// bytes, rounding up. -inline size_t alignmentAdjustment(void *Ptr, size_t Alignment) { +inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) { return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; } diff --git a/contrib/llvm/include/llvm/Support/TargetParser.h b/contrib/llvm/include/llvm/Support/TargetParser.h index ca626f2..777ee20 100644 --- a/contrib/llvm/include/llvm/Support/TargetParser.h +++ b/contrib/llvm/include/llvm/Support/TargetParser.h @@ -15,6 +15,10 @@ #ifndef LLVM_SUPPORT_TARGETPARSER_H #define LLVM_SUPPORT_TARGETPARSER_H +// FIXME: vector is used because that's what clang uses for subtarget feature +// lists, but SmallVector would probably be better +#include <vector> + namespace llvm { class StringRef; @@ -28,13 +32,16 @@ namespace ARM { // FPU names. enum FPUKind { FK_INVALID = 0, + FK_NONE, FK_VFP, FK_VFPV2, FK_VFPV3, FK_VFPV3_D16, FK_VFPV4, FK_VFPV4_D16, + FK_FPV4_SP_D16, FK_FPV5_D16, + FK_FPV5_SP_D16, FK_FP_ARMV8, FK_NEON, FK_NEON_VFPV4, @@ -44,6 +51,20 @@ namespace ARM { FK_LAST }; + // An FPU name implies one of three levels of Neon support: + enum NeonSupportLevel { + NS_None = 0, ///< No Neon + NS_Neon, ///< Neon + NS_Crypto ///< Neon with Crypto + }; + + // An FPU name restricts the FPU in one of three ways: + enum FPURestriction { + FR_None = 0, ///< No restriction + FR_D16, ///< Only 16 D registers + FR_SP_D16 ///< Only single-precision instructions, with 16 D registers + }; + // Arch names. enum ArchKind { AK_INVALID = 0, @@ -53,34 +74,34 @@ namespace ARM { AK_ARMV3M, AK_ARMV4, AK_ARMV4T, - AK_ARMV5, AK_ARMV5T, AK_ARMV5TE, + AK_ARMV5TEJ, AK_ARMV6, - AK_ARMV6J, AK_ARMV6K, AK_ARMV6T2, AK_ARMV6Z, AK_ARMV6ZK, AK_ARMV6M, - AK_ARMV7, + AK_ARMV6SM, AK_ARMV7A, AK_ARMV7R, AK_ARMV7M, + AK_ARMV7EM, AK_ARMV8A, AK_ARMV8_1A, // Non-standard Arch names. AK_IWMMXT, AK_IWMMXT2, AK_XSCALE, + AK_ARMV5, AK_ARMV5E, - AK_ARMV5TEJ, - AK_ARMV6SM, + AK_ARMV6J, AK_ARMV6HL, + AK_ARMV7, AK_ARMV7L, AK_ARMV7HL, AK_ARMV7S, - AK_ARMV7EM, AK_LAST }; @@ -92,8 +113,15 @@ namespace ARM { AEK_FP, AEK_HWDIV, AEK_MP, + AEK_SIMD, AEK_SEC, AEK_VIRT, + // Unsupported extensions. + AEK_OS, + AEK_IWMMXT, + AEK_IWMMXT2, + AEK_MAVERICK, + AEK_XSCALE, AEK_LAST }; @@ -132,9 +160,16 @@ public: // Information by ID static const char * getFPUName(unsigned FPUKind); + static unsigned getFPUVersion(unsigned FPUKind); + static unsigned getFPUNeonSupportLevel(unsigned FPUKind); + static unsigned getFPURestriction(unsigned FPUKind); + // FIXME: This should be moved to TargetTuple once it exists + static bool getFPUFeatures(unsigned FPUKind, + std::vector<const char*> &Features); static const char * getArchName(unsigned ArchKind); - static unsigned getArchDefaultCPUArch(unsigned ArchKind); - static const char * getArchDefaultCPUName(unsigned ArchKind); + static unsigned getArchAttr(unsigned ArchKind); + static const char * getCPUAttr(unsigned ArchKind); + static const char * getSubArch(unsigned ArchKind); static const char * getArchExtName(unsigned ArchExtKind); static const char * getDefaultCPU(StringRef Arch); diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h index 408e908..837fc66 100644 --- a/contrib/llvm/include/llvm/Support/TargetRegistry.h +++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h @@ -91,7 +91,7 @@ public: typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch); typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, - StringRef TT); + const Triple &TT); typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); @@ -287,15 +287,15 @@ public: /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified /// target triple. /// - /// \param Triple This argument is used to determine the target machine + /// \param TheTriple This argument is used to determine the target machine /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, - StringRef Triple) const { + StringRef TheTriple) const { if (!MCAsmInfoCtorFn) return nullptr; - return MCAsmInfoCtorFn(MRI, Triple); + return MCAsmInfoCtorFn(MRI, Triple(TheTriple)); } /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. @@ -889,7 +889,8 @@ template <class MCAsmInfoImpl> struct RegisterMCAsmInfo { } private: - static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, StringRef TT) { + static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, + const Triple &TT) { return new MCAsmInfoImpl(TT); } }; diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h index 3bdff20..c04294a 100644 --- a/contrib/llvm/include/llvm/Support/YAMLTraits.h +++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h @@ -1090,6 +1090,9 @@ public: bool setCurrentDocument(); bool nextDocument(); + /// Returns the current node that's being parsed by the YAML Parser. + const Node *getCurrentNode() const; + private: llvm::SourceMgr SrcMgr; // must be before Strm std::unique_ptr<llvm::yaml::Stream> Strm; @@ -1111,7 +1114,7 @@ private: /// class Output : public IO { public: - Output(llvm::raw_ostream &, void *Ctxt=nullptr); + Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); ~Output() override; bool outputting() override; @@ -1167,6 +1170,7 @@ private: }; llvm::raw_ostream &Out; + int WrapColumn; SmallVector<InState, 8> StateStack; int Column; int ColumnAtFlowStart; diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h index 7576555..14ad636 100644 --- a/contrib/llvm/include/llvm/TableGen/Record.h +++ b/contrib/llvm/include/llvm/TableGen/Record.h @@ -17,48 +17,20 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/Allocator.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SMLoc.h" #include "llvm/Support/raw_ostream.h" #include <map> namespace llvm { -// RecTy subclasses. -class BitRecTy; -class BitsRecTy; -class IntRecTy; -class StringRecTy; class ListRecTy; -class DagRecTy; -class RecordRecTy; - -// Init subclasses. -class Init; -class UnsetInit; -class BitInit; -class BitsInit; -class IntInit; -class StringInit; -class ListInit; -class UnOpInit; -class BinOpInit; -class TernOpInit; -class DefInit; -class DagInit; -class TypedInit; -class VarInit; -class FieldInit; -class VarBitInit; -class VarListElementInit; - -// Other classes. +struct MultiClass; class Record; class RecordVal; -struct MultiClass; class RecordKeeper; //===----------------------------------------------------------------------===// @@ -81,12 +53,11 @@ public: private: RecTyKind Kind; std::unique_ptr<ListRecTy> ListTy; - virtual void anchor(); public: RecTyKind getRecTyKind() const { return Kind; } - RecTy(RecTyKind K) : Kind(K), ListTy(nullptr) {} + RecTy(RecTyKind K) : Kind(K) {} virtual ~RecTy() {} virtual std::string getAsString() const = 0; @@ -95,40 +66,10 @@ public: /// typeIsConvertibleTo - Return true if all values of 'this' type can be /// converted to the specified type. - virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + virtual bool typeIsConvertibleTo(const RecTy *RHS) const; /// getListTy - Returns the type representing list<this>. ListRecTy *getListTy(); - -public: // These methods should only be called from subclasses of Init - virtual Init *convertValue( UnsetInit *UI) { return nullptr; } - virtual Init *convertValue( BitInit *BI) { return nullptr; } - virtual Init *convertValue( BitsInit *BI) { return nullptr; } - virtual Init *convertValue( IntInit *II) { return nullptr; } - virtual Init *convertValue(StringInit *SI) { return nullptr; } - virtual Init *convertValue( ListInit *LI) { return nullptr; } - virtual Init *convertValue( UnOpInit *UO) { - return convertValue((TypedInit*)UO); - } - virtual Init *convertValue( BinOpInit *BO) { - return convertValue((TypedInit*)BO); - } - virtual Init *convertValue( TernOpInit *TO) { - return convertValue((TypedInit*)TO); - } - virtual Init *convertValue(VarBitInit *VB) { return nullptr; } - virtual Init *convertValue( DefInit *DI) { return nullptr; } - virtual Init *convertValue( DagInit *DI) { return nullptr; } - virtual Init *convertValue( TypedInit *TI) { return nullptr; } - virtual Init *convertValue( VarInit *VI) { - return convertValue((TypedInit*)VI); - } - virtual Init *convertValue( FieldInit *FI) { - return convertValue((TypedInit*)FI); - } - -public: - virtual bool baseClassOf(const RecTy*) const; }; inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { @@ -149,20 +90,9 @@ public: static BitRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override { return (Init*)BI; } - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue(VarBitInit *VB) override { return (Init*)VB; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "bit"; } - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// BitsRecTy - 'bits<n>' - Represent a fixed number of bits @@ -180,19 +110,9 @@ public: unsigned getNumBits() const { return Size; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override; - Init *convertValue( BitInit *UI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// IntRecTy - 'int' - Represent an integer value of no particular size @@ -208,20 +128,9 @@ public: static IntRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override { return (Init*)II; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "int"; } - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// StringRecTy - 'string' - Represent an string value @@ -237,18 +146,7 @@ public: static StringRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue(StringInit *SI) override { return (Init*)SI; } - Init *convertValue( UnOpInit *UO) override; - Init *convertValue( BinOpInit *BO) override; - Init *convertValue( TypedInit *TI) override; - - std::string getAsString() const override { return "string"; } - - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } + std::string getAsString() const override; }; /// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of @@ -267,18 +165,9 @@ public: static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( ListInit *LI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// DagRecTy - 'dag' - Represent a dag fragment @@ -294,18 +183,7 @@ public: static DagRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( UnOpInit *UO) override; - Init *convertValue( BinOpInit *BO) override; - Init *convertValue( DagInit *DI) override { return (Init*)DI; } - Init *convertValue( TypedInit *TI) override; - - std::string getAsString() const override { return "dag"; } - - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } + std::string getAsString() const override; }; /// RecordRecTy - '[classname]' - Represent an instance of a class, such as: @@ -325,17 +203,9 @@ public: Record *getRecord() const { return Rec; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( DefInit *DI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; - bool typeIsConvertibleTo(const RecTy *RHS) const override { - return RHS->baseClassOf(this); - } - bool baseClassOf(const RecTy*) const override; + bool typeIsConvertibleTo(const RecTy *RHS) const override; }; /// resolveTypes - Find a common type that T1 and T2 convert to. @@ -418,10 +288,8 @@ public: /// invokes print on stderr. void dump() const; - /// convertInitializerTo - This virtual function is a simple call-back - /// function that should be overridden to call the appropriate - /// RecTy::convertValue method. - /// + /// convertInitializerTo - This virtual function converts to the appropriate + /// Init based on the passed in type. virtual Init *convertInitializerTo(RecTy *Ty) const = 0; /// convertInitializerBitRange - This method is used to implement the bitrange @@ -511,6 +379,8 @@ public: } RecTy *getType() const { return Ty; } + Init *convertInitializerTo(RecTy *Ty) const override; + Init * convertInitializerBitRange(const std::vector<unsigned> &Bits) const override; Init * @@ -535,7 +405,6 @@ class UnsetInit : public Init { UnsetInit() : Init(IK_UnsetInit) {} UnsetInit(const UnsetInit &) = delete; UnsetInit &operator=(const UnsetInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -543,9 +412,7 @@ public: } static UnsetInit *get(); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<UnsetInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { return const_cast<UnsetInit*>(this); @@ -563,7 +430,6 @@ class BitInit : public Init { explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} BitInit(const BitInit &Other) = delete; BitInit &operator=(BitInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -573,9 +439,7 @@ public: bool getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<BitInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { assert(Bit < 1 && "Bit index out of range!"); @@ -608,9 +472,7 @@ public: unsigned getNumBits() const { return Bits.size(); } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<BitsInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector<unsigned> &Bits) const override; @@ -661,9 +523,7 @@ public: int64_t getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<IntInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector<unsigned> &Bits) const override; @@ -692,7 +552,6 @@ class StringInit : public TypedInit { StringInit(const StringInit &Other) = delete; StringInit &operator=(const StringInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -702,9 +561,7 @@ public: const std::string &getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<StringInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; std::string getAsString() const override { return "\"" + Value + "\""; } std::string getAsUnquotedString() const override { return Value; } @@ -746,7 +603,6 @@ public: void Profile(FoldingSetNodeID &ID) const; - unsigned getSize() const { return Values.size(); } Init *getElement(unsigned i) const { assert(i < Values.size() && "List element index out of range!"); return Values[i]; @@ -757,9 +613,7 @@ public: Init * convertInitListSlice(const std::vector<unsigned> &Elements) const override; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<ListInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; /// resolveReferences - This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. @@ -772,10 +626,11 @@ public: ArrayRef<Init*> getValues() const { return Values; } - inline const_iterator begin() const { return Values.begin(); } - inline const_iterator end () const { return Values.end(); } + const_iterator begin() const { return Values.begin(); } + const_iterator end () const { return Values.end(); } - inline bool empty() const { return Values.empty(); } + size_t size () const { return Values.size(); } + bool empty() const { return Values.empty(); } /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable @@ -805,17 +660,13 @@ public: // Clone - Clone this operator, replacing arguments with the new list virtual OpInit *clone(std::vector<Init *> &Operands) const = 0; - virtual int getNumOperands() const = 0; - virtual Init *getOperand(int i) const = 0; + virtual unsigned getNumOperands() const = 0; + virtual Init *getOperand(unsigned i) const = 0; // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<OpInit *>(this)); - } - Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const override; @@ -851,8 +702,8 @@ public: return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); } - int getNumOperands() const override { return 1; } - Init *getOperand(int i) const override { + unsigned getNumOperands() const override { return 1; } + Init *getOperand(unsigned i) const override { assert(i == 0 && "Invalid operand id for unary operator"); return getOperand(); } @@ -899,13 +750,12 @@ public: return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); } - int getNumOperands() const override { return 2; } - Init *getOperand(int i) const override { - assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); - if (i == 0) { - return getLHS(); - } else { - return getRHS(); + unsigned getNumOperands() const override { return 2; } + Init *getOperand(unsigned i) const override { + switch (i) { + default: llvm_unreachable("Invalid operand id for binary operator"); + case 0: return getLHS(); + case 1: return getRHS(); } } @@ -955,16 +805,13 @@ public: getType()); } - int getNumOperands() const override { return 3; } - Init *getOperand(int i) const override { - assert((i == 0 || i == 1 || i == 2) && - "Invalid operand id for ternary operator"); - if (i == 0) { - return getLHS(); - } else if (i == 1) { - return getMHS(); - } else { - return getRHS(); + unsigned getNumOperands() const override { return 3; } + Init *getOperand(unsigned i) const override { + switch (i) { + default: llvm_unreachable("Invalid operand id for ternary operator"); + case 0: return getLHS(); + case 1: return getMHS(); + case 2: return getRHS(); } } @@ -1004,10 +851,6 @@ public: static VarInit *get(const std::string &VN, RecTy *T); static VarInit *get(Init *VN, RecTy *T); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<VarInit *>(this)); - } - const std::string &getName() const; Init *getNameInit() const { return VarName; } std::string getNameInitAsString() const { @@ -1056,9 +899,7 @@ public: } static VarBitInit *get(TypedInit *T, unsigned B); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<VarBitInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBitVar() const override { return TI; } unsigned getBitNum() const override { return Bit; } @@ -1095,10 +936,6 @@ public: } static VarListElementInit *get(TypedInit *T, unsigned E); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<VarListElementInit *>(this)); - } - TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } @@ -1131,9 +968,7 @@ public: } static DefInit *get(Record*); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<DefInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Record *getDef() const { return Def; } @@ -1179,10 +1014,6 @@ public: static FieldInit *get(Init *R, const std::string &FN); static FieldInit *get(Init *R, const Init *FN); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<FieldInit *>(this)); - } - Init *getBit(unsigned Bit) const override; Init *resolveListElementReference(Record &R, const RecordVal *RV, @@ -1228,9 +1059,7 @@ public: void Profile(FoldingSetNodeID &ID) const; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast<DagInit *>(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getOperator() const { return Val; } @@ -1280,22 +1109,21 @@ public: //===----------------------------------------------------------------------===// class RecordVal { - Init *Name; + PointerIntPair<Init *, 1, bool> NameAndPrefix; RecTy *Ty; - unsigned Prefix; Init *Value; public: - RecordVal(Init *N, RecTy *T, unsigned P); - RecordVal(const std::string &N, RecTy *T, unsigned P); + RecordVal(Init *N, RecTy *T, bool P); + RecordVal(const std::string &N, RecTy *T, bool P); const std::string &getName() const; - const Init *getNameInit() const { return Name; } + const Init *getNameInit() const { return NameAndPrefix.getPointer(); } std::string getNameInitAsString() const { return getNameInit()->getAsUnquotedString(); } - unsigned getPrefix() const { return Prefix; } + bool getPrefix() const { return NameAndPrefix.getInt(); } RecTy *getType() const { return Ty; } Init *getValue() const { return Value; } @@ -1344,7 +1172,7 @@ class Record { // def Def : Class<Struct<i>>; // // These need to get fully resolved before instantiating any other - // definitions that usie them (e.g. Def). However, inside a multiclass they + // definitions that use them (e.g. Def). However, inside a multiclass they // can't be immediately resolved so we mark them ResolveFirst to fully // resolve them later as soon as the multiclass is instantiated. bool ResolveFirst; @@ -1354,13 +1182,6 @@ class Record { public: // Constructs a record. - explicit Record(const std::string &N, ArrayRef<SMLoc> locs, - RecordKeeper &records, bool Anonymous = false) : - ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), - TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous), - ResolveFirst(false) { - init(); - } explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, bool Anonymous = false) : ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), @@ -1368,6 +1189,10 @@ public: ResolveFirst(false) { init(); } + explicit Record(const std::string &N, ArrayRef<SMLoc> locs, + RecordKeeper &records, bool Anonymous = false) + : Record(StringInit::get(N), locs, records, Anonymous) {} + // When copy-constructing a Record, we must still guarantee a globally unique // ID number. All other fields can be copied normally. @@ -1406,8 +1231,8 @@ public: ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } bool isTemplateArg(Init *Name) const { - for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) - if (TemplateArgs[i] == Name) return true; + for (Init *TA : TemplateArgs) + if (TA == Name) return true; return false; } bool isTemplateArg(StringRef Name) const { @@ -1415,16 +1240,16 @@ public: } const RecordVal *getValue(const Init *Name) const { - for (unsigned i = 0, e = Values.size(); i != e; ++i) - if (Values[i].getNameInit() == Name) return &Values[i]; + for (const RecordVal &Val : Values) + if (Val.getNameInit() == Name) return &Val; return nullptr; } const RecordVal *getValue(StringRef Name) const { return getValue(StringInit::get(Name)); } RecordVal *getValue(const Init *Name) { - for (unsigned i = 0, e = Values.size(); i != e; ++i) - if (Values[i].getNameInit() == Name) return &Values[i]; + for (RecordVal &Val : Values) + if (Val.getNameInit() == Name) return &Val; return nullptr; } RecordVal *getValue(StringRef Name) { @@ -1465,15 +1290,15 @@ public: } bool isSubClassOf(const Record *R) const { - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i] == R) + for (const Record *SC : SuperClasses) + if (SC == R) return true; return false; } bool isSubClassOf(StringRef Name) const { - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - if (SuperClasses[i]->getNameInitAsString() == Name) + for (const Record *SC : SuperClasses) + if (SC->getNameInitAsString() == Name) return true; return false; } @@ -1523,7 +1348,7 @@ public: /// Return true if the named field is unset. bool isValueUnset(StringRef FieldName) const { - return getValueInit(FieldName) == UnsetInit::get(); + return isa<UnsetInit>(getValueInit(FieldName)); } /// getValueAsString - This method looks up the specified field and returns @@ -1675,7 +1500,6 @@ struct LessRecordFieldName { }; struct LessRecordRegister { - static size_t min(size_t a, size_t b) { return a < b ? a : b; } static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; } struct RecordParts { diff --git a/contrib/llvm/include/llvm/TableGen/SetTheory.h b/contrib/llvm/include/llvm/TableGen/SetTheory.h index 595c29f..d4e0f53 100644 --- a/contrib/llvm/include/llvm/TableGen/SetTheory.h +++ b/contrib/llvm/include/llvm/TableGen/SetTheory.h @@ -47,9 +47,10 @@ #ifndef LLVM_TABLEGEN_SETTHEORY_H #define LLVM_TABLEGEN_SETTHEORY_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SMLoc.h" #include <map> #include <vector> @@ -58,7 +59,6 @@ namespace llvm { class DagInit; class Init; class Record; -class RecordKeeper; class SetTheory { public: diff --git a/contrib/llvm/include/llvm/Target/Target.td b/contrib/llvm/include/llvm/Target/Target.td index ec8a12d..d99f0e1 100644 --- a/contrib/llvm/include/llvm/Target/Target.td +++ b/contrib/llvm/include/llvm/Target/Target.td @@ -381,6 +381,7 @@ class Instruction { bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? + bit isConvergent = 0; // Is this instruction convergent? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? @@ -506,7 +507,7 @@ class Requires<list<Predicate> preds> { /// ops definition - This is just a simple marker used to identify the operand /// list for an instruction. outs and ins are identical both syntactically and -/// semanticallyr; they are used to define def operands and use operands to +/// semantically; they are used to define def operands and use operands to /// improve readibility. This should be used like this: /// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar. def ops; diff --git a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h index 5ec1565..902b99c 100644 --- a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h @@ -711,20 +711,22 @@ protected: /// Target-dependent implementation for foldMemoryOperand. /// Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr *MI, - ArrayRef<unsigned> Ops, - int FrameIndex) const { + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. + virtual MachineInstr *foldMemoryOperandImpl( + MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex) const { return nullptr; } /// Target-dependent implementation for foldMemoryOperand. /// Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr *MI, - ArrayRef<unsigned> Ops, - MachineInstr *LoadMI) const { + /// The instruction and any auxiliary instructions necessary will be inserted + /// at InsertPt. + virtual MachineInstr *foldMemoryOperandImpl( + MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const { return nullptr; } diff --git a/contrib/llvm/include/llvm/Target/TargetLowering.h b/contrib/llvm/include/llvm/Target/TargetLowering.h index e2fe9e8..616edd8 100644 --- a/contrib/llvm/include/llvm/Target/TargetLowering.h +++ b/contrib/llvm/include/llvm/Target/TargetLowering.h @@ -1431,7 +1431,8 @@ public: /// load/store. virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/, SmallVectorImpl<Value*> &/*Ops*/, - Type *&/*AccessTy*/) const { + Type *&/*AccessTy*/, + unsigned AddrSpace = 0) const { return false; } @@ -1456,7 +1457,12 @@ public: /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. TODO: Handle /// pre/postinc as well. - virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + /// + /// If the address space cannot be determined, it will be -1. + /// + /// TODO: Remove default argument + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty, + unsigned AddrSpace) const; /// \brief Return the cost of the scaling factor used in the addressing mode /// represented by AM for this target, for a load/store of the specified type. @@ -1464,9 +1470,12 @@ public: /// If the AM is supported, the return value must be >= 0. /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. - virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty) const { + /// TODO: Remove default argument + virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty, + unsigned AS = 0) const { // Default: assume that any scaling factor used in a legal AM is free. - if (isLegalAddressingMode(AM, Ty)) return 0; + if (isLegalAddressingMode(AM, Ty, AS)) + return 0; return -1; } diff --git a/contrib/llvm/include/llvm/Target/TargetOptions.h b/contrib/llvm/include/llvm/Target/TargetOptions.h index 07a8f6d..8f8b78d 100644 --- a/contrib/llvm/include/llvm/Target/TargetOptions.h +++ b/contrib/llvm/include/llvm/Target/TargetOptions.h @@ -15,6 +15,7 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H +#include "llvm/Target/TargetRecip.h" #include "llvm/MC/MCTargetOptions.h" #include <string> @@ -72,7 +73,8 @@ namespace llvm { CompressDebugSections(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), TrapFuncName(), FloatABIType(FloatABI::Default), - AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single), + AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), + JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -206,6 +208,9 @@ namespace llvm { /// the value of this option. FPOpFusion::FPOpFusionMode AllowFPOpFusion; + /// This class encapsulates options for reciprocal-estimate code generation. + TargetRecip Reciprocals; + /// JTType - This flag specifies the type of jump-instruction table to /// create for functions that have the jumptable attribute. JumpTable::JumpTableType JTType; @@ -240,6 +245,7 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(TrapFuncName) && ARE_EQUAL(FloatABIType) && ARE_EQUAL(AllowFPOpFusion) && + ARE_EQUAL(Reciprocals) && ARE_EQUAL(JTType) && ARE_EQUAL(ThreadModel) && ARE_EQUAL(MCOptions); diff --git a/contrib/llvm/include/llvm/Target/TargetRecip.h b/contrib/llvm/include/llvm/Target/TargetRecip.h new file mode 100644 index 0000000..4cc3672 --- /dev/null +++ b/contrib/llvm/include/llvm/Target/TargetRecip.h @@ -0,0 +1,73 @@ +//===--------------------- llvm/Target/TargetRecip.h ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class is used to customize machine-specific reciprocal estimate code +// generation in a target-independent way. +// If a target does not support operations in this specification, then code +// generation will default to using supported operations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETRECIP_H +#define LLVM_TARGET_TARGETRECIP_H + +#include "llvm/ADT/StringRef.h" +#include <vector> +#include <string> +#include <map> + +namespace llvm { + +struct TargetRecip { +public: + TargetRecip(); + + /// Initialize all or part of the operations from command-line options or + /// a front end. + TargetRecip(const std::vector<std::string> &Args); + + /// Set whether a particular reciprocal operation is enabled and how many + /// refinement steps are needed when using it. Use "all" to set enablement + /// and refinement steps for all operations. + void setDefaults(const StringRef &Key, bool Enable, unsigned RefSteps); + + /// Return true if the reciprocal operation has been enabled by default or + /// from the command-line. Return false if the operation has been disabled + /// by default or from the command-line. + bool isEnabled(const StringRef &Key) const; + + /// Return the number of iterations necessary to refine the + /// the result of a machine instruction for the given reciprocal operation. + unsigned getRefinementSteps(const StringRef &Key) const; + + bool operator==(const TargetRecip &Other) const; + +private: + enum { + Uninitialized = -1 + }; + + struct RecipParams { + int8_t Enabled; + int8_t RefinementSteps; + + RecipParams() : Enabled(Uninitialized), RefinementSteps(Uninitialized) {} + }; + + std::map<StringRef, RecipParams> RecipMap; + typedef std::map<StringRef, RecipParams>::iterator RecipIter; + typedef std::map<StringRef, RecipParams>::const_iterator ConstRecipIter; + + bool parseGlobalParams(const std::string &Arg); + void parseIndividualParams(const std::vector<std::string> &Args); +}; + +} // End llvm namespace + +#endif diff --git a/contrib/llvm/include/llvm/Transforms/Scalar.h b/contrib/llvm/include/llvm/Transforms/Scalar.h index c4669f1..4676c95 100644 --- a/contrib/llvm/include/llvm/Transforms/Scalar.h +++ b/contrib/llvm/include/llvm/Transforms/Scalar.h @@ -16,10 +16,12 @@ #define LLVM_TRANSFORMS_SCALAR_H #include "llvm/ADT/StringRef.h" +#include <functional> namespace llvm { class BasicBlockPass; +class Function; class FunctionPass; class ModulePass; class Pass; @@ -152,7 +154,14 @@ Pass *createLoopInterchangePass(); // Pass *createLoopStrengthReducePass(); -Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset); +//===----------------------------------------------------------------------===// +// +// GlobalMerge - This pass merges internal (by default) globals into structs +// to enable reuse of a base pointer by indexed addressing modes. +// It can also be configured to focus on size optimizations only. +// +Pass *createGlobalMergePass(const TargetMachine *TM, unsigned MaximalOffset, + bool OnlyOptimizeForSize = false); //===----------------------------------------------------------------------===// // @@ -238,7 +247,8 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1); // CFGSimplification - Merge basic blocks, eliminate unreachable blocks, // simplify terminator instructions, etc... // -FunctionPass *createCFGSimplificationPass(int Threshold = -1); +FunctionPass *createCFGSimplificationPass( + int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr); //===----------------------------------------------------------------------===// // @@ -456,7 +466,7 @@ FunctionPass *createPlaceSafepointsPass(); // RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have // explicit relocations to include explicit relocations. // -FunctionPass *createRewriteStatepointsForGCPass(); +ModulePass *createRewriteStatepointsForGCPass(); //===----------------------------------------------------------------------===// // |