diff options
Diffstat (limited to 'include/llvm')
96 files changed, 1560 insertions, 1079 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 958e3fd..76615af 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -276,6 +276,10 @@ public: /// \param isIEEE - If 128 bit number, select between PPC and IEEE static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); + /// Returns the size of the floating point number (in bits) in the given + /// semantics. + static unsigned getSizeInBits(const fltSemantics &Sem); + /// @} /// Used to insert APFloat objects, or objects that contain APFloat objects, diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 06f5870..947812d 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -569,6 +569,22 @@ public: /// architecture if no such variant can be found. llvm::Triple get64BitArchVariant() const; + /// Form a triple with a big endian variant of the current architecture. + /// + /// This can be used to move across "families" of architectures where useful. + /// + /// \returns A new triple with a big endian architecture or an unknown + /// architecture if no such variant can be found. + llvm::Triple getBigEndianArchVariant() const; + + /// Form a triple with a little endian variant of the current architecture. + /// + /// This can be used to move across "families" of architectures where useful. + /// + /// \returns A new triple with a little endian architecture or an unknown + /// architecture if no such variant can be found. + llvm::Triple getLittleEndianArchVariant() const; + /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. /// /// \param Arch the architecture name (e.g., "armv7s"). If it is an empty diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h index c2b2041..06a01b1 100644 --- a/include/llvm/ADT/edit_distance.h +++ b/include/llvm/ADT/edit_distance.h @@ -50,50 +50,51 @@ unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray, // http://en.wikipedia.org/wiki/Levenshtein_distance // // Although the algorithm is typically described using an m x n - // array, only two rows are used at a time, so this implementation - // just keeps two separate vectors for those two rows. + // array, only one row plus one element are used at a time, so this + // implementation just keeps one vector for the row. To update one entry, + // only the entries to the left, top, and top-left are needed. The left + // entry is in Row[x-1], the top entry is what's in Row[x] from the last + // iteration, and the top-left entry is stored in Previous. typename ArrayRef<T>::size_type m = FromArray.size(); typename ArrayRef<T>::size_type n = ToArray.size(); const unsigned SmallBufferSize = 64; unsigned SmallBuffer[SmallBufferSize]; std::unique_ptr<unsigned[]> Allocated; - unsigned *Previous = SmallBuffer; - if (2*(n + 1) > SmallBufferSize) { - Previous = new unsigned [2*(n+1)]; - Allocated.reset(Previous); + unsigned *Row = SmallBuffer; + if (n + 1 > SmallBufferSize) { + Row = new unsigned[n + 1]; + Allocated.reset(Row); } - unsigned *Current = Previous + (n + 1); - for (unsigned i = 0; i <= n; ++i) - Previous[i] = i; + for (unsigned i = 1; i <= n; ++i) + Row[i] = i; for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) { - Current[0] = y; - unsigned BestThisRow = Current[0]; + Row[0] = y; + unsigned BestThisRow = Row[0]; + unsigned Previous = y - 1; for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) { + int OldRow = Row[x]; if (AllowReplacements) { - Current[x] = std::min( - Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u), - std::min(Current[x-1], Previous[x])+1); + Row[x] = std::min( + Previous + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u), + std::min(Row[x-1], Row[x])+1); } else { - if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1]; - else Current[x] = std::min(Current[x-1], Previous[x]) + 1; + if (FromArray[y-1] == ToArray[x-1]) Row[x] = Previous; + else Row[x] = std::min(Row[x-1], Row[x]) + 1; } - BestThisRow = std::min(BestThisRow, Current[x]); + Previous = OldRow; + BestThisRow = std::min(BestThisRow, Row[x]); } if (MaxEditDistance && BestThisRow > MaxEditDistance) return MaxEditDistance + 1; - - unsigned *tmp = Current; - Current = Previous; - Previous = tmp; } - unsigned Result = Previous[n]; + unsigned Result = Row[n]; return Result; } diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index f4c1167..36f8199 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -211,6 +211,8 @@ public: /// (if it has any) are non-volatile loads from objects pointed to by its /// pointer-typed arguments, with arbitrary offsets. /// + /// This property corresponds to the LLVM IR 'argmemonly' attribute combined + /// with 'readonly' attribute. /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag. OnlyReadsArgumentPointees = ArgumentPointees | Ref, @@ -218,6 +220,7 @@ public: /// function (if it has any) are non-volatile loads and stores from objects /// pointed to by its pointer-typed arguments, with arbitrary offsets. /// + /// This property corresponds to the LLVM IR 'argmemonly' attribute. /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag. OnlyAccessesArgumentPointees = ArgumentPointees | ModRef, @@ -518,14 +521,6 @@ public: /// virtual void deleteValue(Value *V); - /// copyValue - This method should be used whenever a preexisting value in the - /// program is copied or cloned, introducing a new value. Note that analysis - /// implementations should tolerate clients that use this method to introduce - /// the same value multiple times: if the analysis already knows about a - /// value, it should ignore the request. - /// - virtual void copyValue(Value *From, Value *To); - /// addEscapingUse - This method should be used whenever an escaping use is /// added to a pointer value. Analysis implementations may either return /// conservative responses for that value in the future, or may recompute @@ -541,7 +536,6 @@ public: /// above, and it provided as a helper to simplify client code. /// void replaceWithNewValue(Value *Old, Value *New) { - copyValue(Old, New); deleteValue(Old); } }; diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index 541a210..e8185b3 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -72,6 +72,17 @@ namespace llvm { Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef<unsigned> Idxs); +/// \brief Attempt to constant fold an extractvalue instruction with the +/// specified operands and indices. The constant result is returned if +/// successful; if not, null is returned. +Constant *ConstantFoldExtractValueInstruction(Constant *Agg, + ArrayRef<unsigned> Idxs); + +/// \brief Attempt to constant fold an extractelement instruction with the +/// specified operands and indices. The constant result is returned if +/// successful; if not, null is returned. +Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx); + /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would /// produce if it is constant and determinable. If this is not determinable, /// return null. diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h index 996700e..fb73005 100644 --- a/include/llvm/Analysis/DominanceFrontier.h +++ b/include/llvm/Analysis/DominanceFrontier.h @@ -202,8 +202,8 @@ public: void dump() const; }; -EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>); -EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>); +extern template class DominanceFrontierBase<BasicBlock>; +extern template class ForwardDominanceFrontierBase<BasicBlock>; } // End llvm namespace diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index ae9c1f5..00dbcbd 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -21,6 +21,7 @@ namespace llvm { +class AssumptionCache; class DominatorTree; class Instruction; class Value; @@ -119,15 +120,19 @@ private: class IVUsers : public LoopPass { friend class IVStrideUse; Loop *L; + AssumptionCache *AC; LoopInfo *LI; DominatorTree *DT; ScalarEvolution *SE; - SmallPtrSet<Instruction*,16> Processed; + SmallPtrSet<Instruction*, 16> Processed; /// IVUses - A list of all tracked IV uses of induction variable expressions /// we are interested in. ilist<IVStrideUse> IVUses; + // Ephemeral values used by @llvm.assume in this function. + SmallPtrSet<const Value *, 32> EphValues; + void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnLoop(Loop *L, LPPassManager &LPM) override; diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 706bd80..d44c5ff 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -212,7 +212,7 @@ namespace llvm { /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout &DL, + FastMathFlags FMF, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, @@ -244,6 +244,24 @@ namespace llvm { AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr); + /// \brief Given operands for an ExtractValueInst, see if we can fold the + /// result. If not, this returns null. + Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs, + const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr, + const DominatorTree *DT = nullptr, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr); + + /// \brief Given operands for an ExtractElementInst, see if we can fold the + /// result. If not, this returns null. + Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, + const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr, + const DominatorTree *DT = nullptr, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr); + /// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold /// the result. If not, this returns null. Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL, diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h deleted file mode 100644 index b6dad47..0000000 --- a/include/llvm/Analysis/JumpInstrTableInfo.h +++ /dev/null @@ -1,71 +0,0 @@ -//===-- JumpInstrTableInfo.h: Info for Jump-Instruction Tables --*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Information about jump-instruction tables that have been created by -/// JumpInstrTables pass. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H -#define LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/Pass.h" -#include <vector> - -namespace llvm { -class Function; -class FunctionType; - -/// This class stores information about jump-instruction tables created by the -/// JumpInstrTables pass (in lib/CodeGen/JumpInstrTables.cpp). Each table is a -/// map from a function type to a vector of pairs. The first element of each -/// pair is the function that has the jumptable annotation. The second element -/// is a function that was declared by JumpInstrTables and used to replace all -/// address-taking sites for the original function. -/// -/// The information in this pass is used in AsmPrinter -/// (lib/CodeGen/AsmPrinter/AsmPrinter.cpp) to generate the required assembly -/// for the jump-instruction tables. -class JumpInstrTableInfo : public ImmutablePass { -public: - static char ID; - - /// The default byte alignment for jump tables is 16, which is large but - /// usually safe. - JumpInstrTableInfo(uint64_t ByteAlign = 16); - ~JumpInstrTableInfo() override; - const char *getPassName() const override { - return "Jump-Instruction Table Info"; - } - - typedef std::pair<Function *, Function *> JumpPair; - typedef DenseMap<FunctionType *, std::vector<JumpPair> > JumpTables; - - /// Inserts an entry in a table, adding the table if it doesn't exist. - void insertEntry(FunctionType *TableFunTy, Function *Target, Function *Jump); - - /// Gets the tables. - const JumpTables &getTables() const { return Tables; } - - /// Gets the alignment in bytes of a jumptable entry. - uint64_t entryByteAlignment() const { return ByteAlignment; } -private: - JumpTables Tables; - - /// A power-of-two alignment of a jumptable entry. - uint64_t ByteAlignment; -}; - -/// Creates a JumpInstrTableInfo pass with the given bound on entry size. This -/// bound specifies the maximum number of bytes needed to represent an -/// unconditional jump or a trap instruction in the back end currently in use. -ModulePass *createJumpInstrTableInfoPass(unsigned Bound); -} - -#endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */ diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h index 170e2a4..b4bef31 100644 --- a/include/llvm/Analysis/LibCallSemantics.h +++ b/include/llvm/Analysis/LibCallSemantics.h @@ -206,6 +206,18 @@ class InvokeInst; llvm_unreachable("invalid enum"); } + /// \brief Return true if this personality may be safely removed if there + /// are no invoke instructions remaining in the current function. + inline bool isNoOpWithoutInvoke(EHPersonality Pers) { + switch (Pers) { + case EHPersonality::Unknown: + return false; + // All known personalities currently have this behavior + default: return true; + } + llvm_unreachable("invalid enum"); + } + bool canSimplifyInvokeNoUnwind(const Function *F); } // end namespace llvm diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 7b635a8..476e4b6 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -292,6 +292,133 @@ private: bool couldPreventStoreLoadForward(unsigned Distance, unsigned TypeByteSize); }; +/// \brief Holds information about the memory runtime legality checks to verify +/// that a group of pointers do not overlap. +class RuntimePointerChecking { +public: + struct PointerInfo { + /// Holds the pointer value that we need to check. + TrackingVH<Value> PointerValue; + /// Holds the pointer value at the beginning of the loop. + const SCEV *Start; + /// Holds the pointer value at the end of the loop. + const SCEV *End; + /// Holds the information if this pointer is used for writing to memory. + bool IsWritePtr; + /// Holds the id of the set of pointers that could be dependent because of a + /// shared underlying object. + unsigned DependencySetId; + /// Holds the id of the disjoint alias set to which this pointer belongs. + unsigned AliasSetId; + /// SCEV for the access. + const SCEV *Expr; + + PointerInfo(Value *PointerValue, const SCEV *Start, const SCEV *End, + bool IsWritePtr, unsigned DependencySetId, unsigned AliasSetId, + const SCEV *Expr) + : PointerValue(PointerValue), Start(Start), End(End), + IsWritePtr(IsWritePtr), DependencySetId(DependencySetId), + AliasSetId(AliasSetId), Expr(Expr) {} + }; + + RuntimePointerChecking(ScalarEvolution *SE) : Need(false), SE(SE) {} + + /// Reset the state of the pointer runtime information. + void reset() { + Need = false; + Pointers.clear(); + } + + /// Insert a pointer and calculate the start and end SCEVs. + void insert(Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId, + unsigned ASId, const ValueToValueMap &Strides); + + /// \brief No run-time memory checking is necessary. + bool empty() const { return Pointers.empty(); } + + /// A grouping of pointers. A single memcheck is required between + /// two groups. + struct CheckingPtrGroup { + /// \brief Create a new pointer checking group containing a single + /// pointer, with index \p Index in RtCheck. + CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck) + : RtCheck(RtCheck), High(RtCheck.Pointers[Index].End), + Low(RtCheck.Pointers[Index].Start) { + Members.push_back(Index); + } + + /// \brief Tries to add the pointer recorded in RtCheck at index + /// \p Index to this pointer checking group. We can only add a pointer + /// to a checking group if we will still be able to get + /// the upper and lower bounds of the check. Returns true in case + /// of success, false otherwise. + bool addPointer(unsigned Index); + + /// Constitutes the context of this pointer checking group. For each + /// pointer that is a member of this group we will retain the index + /// at which it appears in RtCheck. + RuntimePointerChecking &RtCheck; + /// The SCEV expression which represents the upper bound of all the + /// pointers in this group. + const SCEV *High; + /// The SCEV expression which represents the lower bound of all the + /// pointers in this group. + const SCEV *Low; + /// Indices of all the pointers that constitute this grouping. + SmallVector<unsigned, 2> Members; + }; + + /// \brief Groups pointers such that a single memcheck is required + /// between two different groups. This will clear the CheckingGroups vector + /// and re-compute it. We will only group dependecies if \p UseDependencies + /// is true, otherwise we will create a separate group for each pointer. + void groupChecks(MemoryDepChecker::DepCandidates &DepCands, + bool UseDependencies); + + /// \brief Decide if we need to add a check between two groups of pointers, + /// according to needsChecking. + bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N, + const SmallVectorImpl<int> *PtrPartition) const; + + /// \brief Return true if any pointer requires run-time checking according + /// 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 + /// pointers (-1 if the pointer belongs to multiple partitions). In this + /// case omit checks between pointers belonging to the same partition. + void print(raw_ostream &OS, unsigned Depth = 0, + const SmallVectorImpl<int> *PtrPartition = nullptr) const; + + /// This flag indicates if we need to add the runtime check. + bool Need; + + /// Information about the pointers that may require checking. + SmallVector<PointerInfo, 2> Pointers; + + /// Holds a partitioning of pointers into "check groups". + SmallVector<CheckingPtrGroup, 2> CheckingGroups; + +private: + /// \brief Decide whether we need to issue a run-time check for pointer at + /// index \p I and \p J to prove their independence. + /// + /// If \p PtrPartition is set, it contains the partition number for + /// pointers (-1 if the pointer belongs to multiple partitions). In this + /// case omit checks between pointers belonging to the same partition. + bool needsChecking(unsigned I, unsigned J, + const SmallVectorImpl<int> *PtrPartition) const; + + /// Holds a pointer to the ScalarEvolution analysis. + ScalarEvolution *SE; +}; + /// \brief Drive the analysis of memory accesses in the loop /// /// This class is responsible for analyzing the memory accesses of a loop. It @@ -308,72 +435,6 @@ private: /// RuntimePointerCheck class. class LoopAccessInfo { public: - /// This struct holds information about the memory runtime legality check that - /// a group of pointers do not overlap. - struct RuntimePointerCheck { - RuntimePointerCheck() : Need(false) {} - - /// Reset the state of the pointer runtime information. - void reset() { - Need = false; - Pointers.clear(); - Starts.clear(); - Ends.clear(); - IsWritePtr.clear(); - DependencySetId.clear(); - AliasSetId.clear(); - } - - /// Insert a pointer and calculate the start and end SCEVs. - void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr, - unsigned DepSetId, unsigned ASId, - const ValueToValueMap &Strides); - - /// \brief No run-time memory checking is necessary. - bool empty() const { return Pointers.empty(); } - - /// \brief Decide whether we need to issue a run-time check for pointer at - /// index \p I and \p J to prove their independence. - /// - /// If \p PtrPartition is set, it contains the partition number for - /// pointers (-1 if the pointer belongs to multiple partitions). In this - /// case omit checks between pointers belonging to the same partition. - bool needsChecking(unsigned I, unsigned J, - const SmallVectorImpl<int> *PtrPartition) const; - - /// \brief Return true if any pointer requires run-time checking according - /// 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 - /// pointers (-1 if the pointer belongs to multiple partitions). In this - /// case omit checks between pointers belonging to the same partition. - void print(raw_ostream &OS, unsigned Depth = 0, - const SmallVectorImpl<int> *PtrPartition = nullptr) const; - - /// This flag indicates if we need to add the runtime check. - bool Need; - /// Holds the pointers that we need to check. - SmallVector<TrackingVH<Value>, 2> Pointers; - /// Holds the pointer value at the beginning of the loop. - SmallVector<const SCEV*, 2> Starts; - /// Holds the pointer value at the end of the loop. - SmallVector<const SCEV*, 2> Ends; - /// Holds the information if this pointer is used for writing to memory. - SmallVector<bool, 2> IsWritePtr; - /// Holds the id of the set of pointers that could be dependent because of a - /// shared underlying object. - SmallVector<unsigned, 2> DependencySetId; - /// Holds the id of the disjoint alias set to which this pointer belongs. - SmallVector<unsigned, 2> AliasSetId; - }; - LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL, const TargetLibraryInfo *TLI, AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI, @@ -383,15 +444,15 @@ public: /// no memory dependence cycles. bool canVectorizeMemory() const { return CanVecMem; } - const RuntimePointerCheck *getRuntimePointerCheck() const { - return &PtrRtCheck; + const RuntimePointerChecking *getRuntimePointerChecking() const { + return &PtrRtChecking; } /// \brief Number of memchecks required to prove independence of otherwise /// may-alias pointers. unsigned getNumRuntimePointerChecks( const SmallVectorImpl<int> *PtrPartition = nullptr) const { - return PtrRtCheck.getNumberOfChecks(PtrPartition); + return PtrRtChecking.getNumberOfChecks(PtrPartition); } /// Return true if the block BB needs to be predicated in order for the loop @@ -461,7 +522,7 @@ private: /// We need to check that all of the pointers in this list are disjoint /// at runtime. - RuntimePointerCheck PtrRtCheck; + RuntimePointerChecking PtrRtChecking; /// \brief the Memory Dependence Checker which can determine the /// loop-independent and loop-carried dependences between memory accesses. diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index bbcde8d..3ec83f2 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -347,9 +347,7 @@ raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) { } // Implementation in LoopInfoImpl.h -#ifdef __GNUC__ -__extension__ extern template class LoopBase<BasicBlock, Loop>; -#endif +extern template class LoopBase<BasicBlock, Loop>; class Loop : public LoopBase<BasicBlock, Loop> { public: @@ -633,9 +631,7 @@ public: }; // Implementation in LoopInfoImpl.h -#ifdef __GNUC__ -__extension__ extern template class LoopInfoBase<BasicBlock, Loop>; -#endif +extern template class LoopInfoBase<BasicBlock, Loop>; class LoopInfo : public LoopInfoBase<BasicBlock, Loop> { typedef LoopInfoBase<BasicBlock, Loop> BaseT; diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 7ceb086..8560f1f 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -902,9 +902,9 @@ inline raw_ostream &operator<<(raw_ostream &OS, return OS << Node.template getNodeAs<BlockT>()->getName(); } -EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>); -EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>); -EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>); +extern template class RegionBase<RegionTraits<Function>>; +extern template class RegionNodeBase<RegionTraits<Function>>; +extern template class RegionInfoBase<RegionTraits<Function>>; } // End llvm namespace #endif diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index bb6e266..01f0089 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -69,7 +69,7 @@ public: /// /// The TTI implementation will reflect the information in the DataLayout /// provided if non-null. - explicit TargetTransformInfo(const DataLayout *DL); + explicit TargetTransformInfo(const DataLayout &DL); // Provide move semantics. TargetTransformInfo(TargetTransformInfo &&Arg); @@ -541,7 +541,7 @@ private: class TargetTransformInfo::Concept { public: virtual ~Concept() = 0; - + virtual const DataLayout &getDataLayout() const = 0; virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0; virtual unsigned getGEPCost(const Value *Ptr, ArrayRef<const Value *> Operands) = 0; @@ -636,6 +636,10 @@ public: Model(T Impl) : Impl(std::move(Impl)) {} ~Model() override {} + const DataLayout &getDataLayout() const override { + return Impl.getDataLayout(); + } + unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override { return Impl.getOperationCost(Opcode, Ty, OpTy); } diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 403175a..035cb04 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -30,26 +30,17 @@ class TargetTransformInfoImplBase { protected: typedef TargetTransformInfo TTI; - const DataLayout *DL; + const DataLayout &DL; - explicit TargetTransformInfoImplBase(const DataLayout *DL) - : DL(DL) {} + explicit TargetTransformInfoImplBase(const DataLayout &DL) : DL(DL) {} public: // Provide value semantics. MSVC requires that we spell all of these out. TargetTransformInfoImplBase(const TargetTransformInfoImplBase &Arg) : DL(Arg.DL) {} - TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg) - : DL(std::move(Arg.DL)) {} - TargetTransformInfoImplBase & - operator=(const TargetTransformInfoImplBase &RHS) { - DL = RHS.DL; - return *this; - } - TargetTransformInfoImplBase &operator=(TargetTransformInfoImplBase &&RHS) { - DL = std::move(RHS.DL); - return *this; - } + TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg) : DL(Arg.DL) {} + + const DataLayout &getDataLayout() const { return DL; } unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) { switch (Opcode) { @@ -70,28 +61,22 @@ public: return TTI::TCC_Basic; case Instruction::IntToPtr: { - if (!DL) - return TTI::TCC_Basic; - // An inttoptr cast is free so long as the input is a legal integer type // which doesn't contain values outside the range of a pointer. unsigned OpSize = OpTy->getScalarSizeInBits(); - if (DL->isLegalInteger(OpSize) && - OpSize <= DL->getPointerTypeSizeInBits(Ty)) + if (DL.isLegalInteger(OpSize) && + OpSize <= DL.getPointerTypeSizeInBits(Ty)) return TTI::TCC_Free; // Otherwise it's not a no-op. return TTI::TCC_Basic; } case Instruction::PtrToInt: { - if (!DL) - return TTI::TCC_Basic; - // A ptrtoint cast is free so long as the result is large enough to store // the pointer, and a legal integer type. unsigned DestSize = Ty->getScalarSizeInBits(); - if (DL->isLegalInteger(DestSize) && - DestSize >= DL->getPointerTypeSizeInBits(OpTy)) + if (DL.isLegalInteger(DestSize) && + DestSize >= DL.getPointerTypeSizeInBits(OpTy)) return TTI::TCC_Free; // Otherwise it's not a no-op. @@ -100,7 +85,7 @@ public: case Instruction::Trunc: // trunc to a native type is free (assuming the target has compare and // shift-right of the same width). - if (DL && DL->isLegalInteger(DL->getTypeSizeInBits(Ty))) + if (DL.isLegalInteger(DL.getTypeSizeInBits(Ty))) return TTI::TCC_Free; return TTI::TCC_Basic; @@ -353,8 +338,7 @@ private: typedef TargetTransformInfoImplBase BaseT; protected: - explicit TargetTransformInfoImplCRTPBase(const DataLayout *DL) - : BaseT(DL) {} + explicit TargetTransformInfoImplCRTPBase(const DataLayout &DL) : BaseT(DL) {} public: // Provide value semantics. MSVC requires that we spell all of these out. @@ -362,16 +346,6 @@ public: : BaseT(static_cast<const BaseT &>(Arg)) {} TargetTransformInfoImplCRTPBase(TargetTransformInfoImplCRTPBase &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))) {} - TargetTransformInfoImplCRTPBase & - operator=(const TargetTransformInfoImplCRTPBase &RHS) { - BaseT::operator=(static_cast<const BaseT &>(RHS)); - return *this; - } - TargetTransformInfoImplCRTPBase & - operator=(TargetTransformInfoImplCRTPBase &&RHS) { - BaseT::operator=(std::move(static_cast<BaseT &>(RHS))); - return *this; - } using BaseT::getCallCost; diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h index aa538ec..d8e9ca4 100644 --- a/include/llvm/Analysis/VectorUtils.h +++ b/include/llvm/Analysis/VectorUtils.h @@ -20,6 +20,12 @@ namespace llvm { +class GetElementPtrInst; +class Loop; +class ScalarEvolution; +class Type; +class Value; + /// \brief Identify if the intrinsic is trivially vectorizable. /// This method returns true if the intrinsic's argument types are all /// scalars for the scalar form of the intrinsic and all vectors for @@ -51,6 +57,28 @@ Intrinsic::ID checkBinaryFloatSignature(const CallInst &I, /// its intrinsic ID, in case it does not found it return not_intrinsic. Intrinsic::ID getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI); +/// \brief Find the operand of the GEP that should be checked for consecutive +/// stores. This ignores trailing indices that have no effect on the final +/// pointer. +unsigned getGEPInductionOperand(const GetElementPtrInst *Gep); + +/// \brief If the argument is a GEP, then returns the operand identified by +/// getGEPInductionOperand. However, if there is some other non-loop-invariant +/// operand, it returns that instead. +Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp); + +/// \brief If a value has only one user that is a CastInst, return it. +Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty); + +/// \brief Get the stride of a pointer access in a loop. Looks for symbolic +/// strides "a[i*stride]". Returns the symbolic stride, or null otherwise. +Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp); + +/// \brief Given a vector and an element number, see if the scalar value is +/// already around as a register, for example if it were inserted then extracted +/// from the vector. +Value *findScalarElement(Value *V, unsigned EltNo); + } // llvm namespace #endif diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 605c417..7130ee7 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -407,6 +407,7 @@ namespace bitc { ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42, ATTR_KIND_CONVERGENT = 43, ATTR_KIND_SAFESTACK = 44, + ATTR_KIND_ARGMEMONLY = 45 }; enum ComdatSelectionKindCodes { diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 6797aa1..452ec3b 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -146,7 +146,7 @@ namespace llvm { } const std::error_category &BitcodeErrorCategory(); - enum class BitcodeError { InvalidBitcodeSignature, CorruptedBitcode }; + enum class BitcodeError { InvalidBitcodeSignature = 1, CorruptedBitcode }; inline std::error_code make_error_code(BitcodeError E) { return std::error_code(static_cast<int>(E), BitcodeErrorCategory()); } diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index c4b94ed..82d1e8a 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -64,7 +64,7 @@ inline unsigned ComputeLinearIndex(Type *Ty, /// If Offsets is non-null, it points to a vector to be filled in /// with the in-memory offsets of each of the individual values. /// -void ComputeValueVTs(const TargetLowering &TLI, Type *Ty, +void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl<EVT> &ValueVTs, SmallVectorImpl<uint64_t> *Offsets = nullptr, uint64_t StartingOffset = 0); diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index 3e464f4..9ba2516 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -91,8 +91,10 @@ private: } protected: - explicit BasicTTIImplBase(const TargetMachine *TM) - : BaseT(TM->getDataLayout()) {} + explicit BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL) + : BaseT(DL) {} + + using TargetTransformInfoImplBase::DL; public: // Provide value semantics. MSVC requires that we spell all of these out. @@ -100,14 +102,6 @@ public: : BaseT(static_cast<const BaseT &>(Arg)) {} BasicTTIImplBase(BasicTTIImplBase &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))) {} - BasicTTIImplBase &operator=(const BasicTTIImplBase &RHS) { - BaseT::operator=(static_cast<const BaseT &>(RHS)); - return *this; - } - BasicTTIImplBase &operator=(BasicTTIImplBase &&RHS) { - BaseT::operator=(std::move(static_cast<BaseT &>(RHS))); - return *this; - } /// \name Scalar TTI Implementations /// @{ @@ -132,7 +126,7 @@ public: AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace); + return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, @@ -142,7 +136,7 @@ public: AM.BaseOffs = BaseOffset; AM.HasBaseReg = HasBaseReg; AM.Scale = Scale; - return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace); + return getTLI()->getScalingFactorCost(DL, AM, Ty, AddrSpace); } bool isTruncateFree(Type *Ty1, Type *Ty2) { @@ -154,7 +148,7 @@ public: } bool isTypeLegal(Type *Ty) { - EVT VT = getTLI()->getValueType(Ty); + EVT VT = getTLI()->getValueType(DL, Ty); return getTLI()->isTypeLegal(VT); } @@ -192,7 +186,7 @@ public: bool haveFastSqrt(Type *Ty) { const TargetLoweringBase *TLI = getTLI(); - EVT VT = TLI->getValueType(Ty); + EVT VT = TLI->getValueType(DL, Ty); return TLI->isTypeLegal(VT) && TLI->isOperationLegalOrCustom(ISD::FSQRT, VT); } @@ -282,7 +276,7 @@ public: /// \name Vector TTI Implementations /// @{ - unsigned getNumberOfRegisters(bool Vector) { return 1; } + unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; } unsigned getRegisterBitWidth(bool Vector) { return 32; } @@ -299,7 +293,7 @@ public: int ISD = TLI->InstructionOpcodeToISD(Opcode); assert(ISD && "Invalid opcode"); - std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty); + std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty); bool IsFloat = Ty->getScalarType()->isFloatingPointTy(); // Assume that floating point arithmetic operations cost twice as much as @@ -349,9 +343,8 @@ public: const TargetLoweringBase *TLI = getTLI(); int ISD = TLI->InstructionOpcodeToISD(Opcode); assert(ISD && "Invalid opcode"); - - std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(Src); - std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(Dst); + std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(DL, Src); + std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(DL, Dst); // Check for NOOP conversions. if (SrcLT.first == DstLT.first && @@ -455,8 +448,7 @@ public: if (CondTy->isVectorTy()) ISD = ISD::VSELECT; } - - std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(ValTy); + std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy); if (!(ValTy->isVectorTy() && !LT.second.isVector()) && !TLI->isOperationExpand(ISD, LT.second)) { @@ -485,7 +477,7 @@ public: unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) { std::pair<unsigned, MVT> LT = - getTLI()->getTypeLegalizationCost(Val->getScalarType()); + getTLI()->getTypeLegalizationCost(DL, Val->getScalarType()); return LT.first; } @@ -493,7 +485,7 @@ public: unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace) { assert(!Src->isVoidTy() && "Invalid type"); - std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Src); + std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Src); // Assuming that all loads of legal types cost 1. unsigned Cost = LT.first; @@ -504,7 +496,7 @@ public: // itself. Unless the corresponding extending load or truncating store is // legal, then this will scalarize. TargetLowering::LegalizeAction LA = TargetLowering::Expand; - EVT MemVT = getTLI()->getValueType(Src, true); + EVT MemVT = getTLI()->getValueType(DL, Src, true); if (MemVT.isSimple() && MemVT != MVT::Other) { if (Opcode == Instruction::Store) LA = getTLI()->getTruncStoreAction(LT.second, MemVT.getSimpleVT()); @@ -700,7 +692,7 @@ public: } const TargetLoweringBase *TLI = getTLI(); - std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy); + std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, RetTy); if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { // The operation is legal. Assume it costs 1. @@ -771,7 +763,7 @@ public: } unsigned getNumberOfParts(Type *Tp) { - std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp); + std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Tp); return LT.first; } @@ -816,18 +808,6 @@ public: BasicTTIImpl(BasicTTIImpl &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {} - BasicTTIImpl &operator=(const BasicTTIImpl &RHS) { - BaseT::operator=(static_cast<const BaseT &>(RHS)); - ST = RHS.ST; - TLI = RHS.TLI; - return *this; - } - BasicTTIImpl &operator=(BasicTTIImpl &&RHS) { - BaseT::operator=(std::move(static_cast<BaseT &>(RHS))); - ST = std::move(RHS.ST); - TLI = std::move(RHS.TLI); - return *this; - } }; } diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index 554511d..4b2e0b0 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -206,6 +206,10 @@ cl::opt<std::string> StartAfter("start-after", cl::value_desc("pass-name"), cl::init("")); +cl::opt<std::string> + RunPass("run-pass", cl::desc("Run compiler only for one specific pass"), + cl::value_desc("pass-name"), cl::init("")); + cl::opt<bool> DataSections("data-sections", cl::desc("Emit data into separate sections"), cl::init(false)); diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index c7237fd..fa44301 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -72,10 +72,13 @@ namespace ISD { /// the parent's frame or return address, and so on. FRAMEADDR, RETURNADDR, - /// FRAME_ALLOC_RECOVER - Represents the llvm.framerecover - /// intrinsic. Materializes the offset from the frame pointer of another - /// function to the result of llvm.frameallocate. - FRAME_ALLOC_RECOVER, + /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic. + /// Materializes the offset from the local object pointer of another + /// function to a particular local object passed to llvm.localescape. The + /// operand is the MCSymbol label used to represent this offset, since + /// typically the offset is not known until after code generation of the + /// parent. + LOCAL_RECOVER, /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on /// the DAG, which implements the named register global variables extension. @@ -725,7 +728,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+200; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+300; //===--------------------------------------------------------------------===// /// MemIndexedMode enum - This enum defines the load / store indexed diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h index 967f0cb..f0f1637 100644 --- a/include/llvm/CodeGen/LiveIntervalUnion.h +++ b/include/llvm/CodeGen/LiveIntervalUnion.h @@ -203,6 +203,11 @@ public: assert(idx < Size && "idx out of bounds"); return LIUs[idx]; } + + const LiveIntervalUnion& operator[](unsigned Idx) const { + assert(Idx < Size && "Idx out of bounds"); + return LIUs[Idx]; + } }; }; diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h index 878b4d9..e169058 100644 --- a/include/llvm/CodeGen/LiveRegMatrix.h +++ b/include/llvm/CodeGen/LiveRegMatrix.h @@ -32,13 +32,11 @@ namespace llvm { class LiveInterval; class LiveIntervalAnalysis; -class MachineRegisterInfo; class TargetRegisterInfo; class VirtRegMap; class LiveRegMatrix : public MachineFunctionPass { const TargetRegisterInfo *TRI; - MachineRegisterInfo *MRI; LiveIntervals *LIS; VirtRegMap *VRM; @@ -114,6 +112,9 @@ public: /// the assignment and updates VirtRegMap accordingly. void unassign(LiveInterval &VirtReg); + /// Returns true if the given \p PhysReg has any live intervals assigned. + bool isPhysRegUsed(unsigned PhysReg) const; + //===--------------------------------------------------------------------===// // Low-level interface. //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index a6ffeb3..9798e5c 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -81,15 +81,30 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue) namespace llvm { namespace yaml { +struct VirtualRegisterDefinition { + unsigned ID; + StringValue Class; + // TODO: Serialize the virtual register hints. +}; + +template <> struct MappingTraits<VirtualRegisterDefinition> { + static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) { + YamlIO.mapRequired("id", Reg.ID); + YamlIO.mapRequired("class", Reg.Class); + } + + static const bool flow = true; +}; + struct MachineBasicBlock { unsigned ID; - std::string Name; + StringValue Name; unsigned Alignment = 0; bool IsLandingPad = false; bool AddressTaken = false; - // TODO: Serialize the successor weights and liveins. + // TODO: Serialize the successor weights. std::vector<FlowStringValue> Successors; - + std::vector<FlowStringValue> LiveIns; std::vector<StringValue> Instructions; }; @@ -97,23 +112,153 @@ template <> struct MappingTraits<MachineBasicBlock> { static void mapping(IO &YamlIO, MachineBasicBlock &MBB) { YamlIO.mapRequired("id", MBB.ID); YamlIO.mapOptional("name", MBB.Name, - std::string()); // Don't print out an empty name. + StringValue()); // Don't print out an empty name. YamlIO.mapOptional("alignment", MBB.Alignment); YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad); YamlIO.mapOptional("addressTaken", MBB.AddressTaken); YamlIO.mapOptional("successors", MBB.Successors); + YamlIO.mapOptional("liveins", MBB.LiveIns); YamlIO.mapOptional("instructions", MBB.Instructions); } }; +/// Serializable representation of stack object from the MachineFrameInfo class. +/// +/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are +/// determined by the object's type and frame information flags. +/// Dead stack objects aren't serialized. +/// +/// TODO: Determine isPreallocated flag by mapping between objects and local +/// objects (Serialize local objects). +struct MachineStackObject { + enum ObjectType { DefaultType, SpillSlot, VariableSized }; + // TODO: Serialize LLVM alloca reference. + unsigned ID; + ObjectType Type = DefaultType; + int64_t Offset = 0; + uint64_t Size = 0; + unsigned Alignment = 0; +}; + +template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> { + static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) { + IO.enumCase(Type, "default", MachineStackObject::DefaultType); + IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot); + IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized); + } +}; + +template <> struct MappingTraits<MachineStackObject> { + static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) { + YamlIO.mapRequired("id", Object.ID); + YamlIO.mapOptional( + "type", Object.Type, + MachineStackObject::DefaultType); // Don't print the default type. + YamlIO.mapOptional("offset", Object.Offset); + if (Object.Type != MachineStackObject::VariableSized) + YamlIO.mapRequired("size", Object.Size); + YamlIO.mapOptional("alignment", Object.Alignment); + } + + static const bool flow = true; +}; + +/// Serializable representation of the fixed stack object from the +/// MachineFrameInfo class. +struct FixedMachineStackObject { + enum ObjectType { DefaultType, SpillSlot }; + unsigned ID; + ObjectType Type = DefaultType; + int64_t Offset = 0; + uint64_t Size = 0; + unsigned Alignment = 0; + bool IsImmutable = false; + bool IsAliased = false; +}; + +template <> +struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> { + static void enumeration(yaml::IO &IO, + FixedMachineStackObject::ObjectType &Type) { + IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType); + IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot); + } +}; + +template <> struct MappingTraits<FixedMachineStackObject> { + static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) { + YamlIO.mapRequired("id", Object.ID); + YamlIO.mapOptional( + "type", Object.Type, + FixedMachineStackObject::DefaultType); // Don't print the default type. + YamlIO.mapOptional("offset", Object.Offset); + YamlIO.mapOptional("size", Object.Size); + YamlIO.mapOptional("alignment", Object.Alignment); + if (Object.Type != FixedMachineStackObject::SpillSlot) { + YamlIO.mapOptional("isImmutable", Object.IsImmutable); + YamlIO.mapOptional("isAliased", Object.IsAliased); + } + } + + static const bool flow = true; +}; + } // end namespace yaml } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject) namespace llvm { namespace yaml { +/// Serializable representation of MachineFrameInfo. +/// +/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and +/// 'RealignOption' as they are determined by the target and LLVM function +/// attributes. +/// It also doesn't serialize attributes like 'NumFixedObject' and +/// 'HasVarSizedObjects' as they are determined by the frame objects themselves. +struct MachineFrameInfo { + bool IsFrameAddressTaken = false; + bool IsReturnAddressTaken = false; + bool HasStackMap = false; + bool HasPatchPoint = false; + uint64_t StackSize = 0; + int OffsetAdjustment = 0; + unsigned MaxAlignment = 0; + bool AdjustsStack = false; + bool HasCalls = false; + // TODO: Serialize StackProtectorIdx and FunctionContextIdx + unsigned MaxCallFrameSize = 0; + // TODO: Serialize callee saved info. + // TODO: Serialize local frame objects. + bool HasOpaqueSPAdjustment = false; + bool HasVAStart = false; + bool HasMustTailInVarArgFunc = false; + // TODO: Serialize save and restore MBB references. +}; + +template <> struct MappingTraits<MachineFrameInfo> { + static void mapping(IO &YamlIO, MachineFrameInfo &MFI) { + YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken); + YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken); + YamlIO.mapOptional("hasStackMap", MFI.HasStackMap); + YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint); + YamlIO.mapOptional("stackSize", MFI.StackSize); + YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment); + YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment); + YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack); + YamlIO.mapOptional("hasCalls", MFI.HasCalls); + YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize); + YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment); + YamlIO.mapOptional("hasVAStart", MFI.HasVAStart); + YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc); + } +}; + struct MachineFunction { StringRef Name; unsigned Alignment = 0; @@ -123,9 +268,13 @@ struct MachineFunction { bool IsSSA = false; bool TracksRegLiveness = false; bool TracksSubRegLiveness = false; - // TODO: Serialize virtual register definitions. + std::vector<VirtualRegisterDefinition> VirtualRegisters; // TODO: Serialize the various register masks. // TODO: Serialize live in registers. + // Frame information + MachineFrameInfo FrameInfo; + std::vector<FixedMachineStackObject> FixedStackObjects; + std::vector<MachineStackObject> StackObjects; std::vector<MachineBasicBlock> BasicBlocks; }; @@ -139,6 +288,10 @@ template <> struct MappingTraits<MachineFunction> { YamlIO.mapOptional("isSSA", MF.IsSSA); YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness); YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness); + YamlIO.mapOptional("registers", MF.VirtualRegisters); + YamlIO.mapOptional("frameInfo", MF.FrameInfo); + YamlIO.mapOptional("fixedStack", MF.FixedStackObjects); + YamlIO.mapOptional("stack", MF.StackObjects); YamlIO.mapOptional("body", MF.BasicBlocks); } }; diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index c619afb..6284003 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -135,17 +135,18 @@ public: /// address of the function constant pool values. /// @brief The machine constant pool. class MachineConstantPool { - const TargetMachine &TM; ///< The target machine. unsigned PoolAlignment; ///< The alignment for the pool. std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants. /// MachineConstantPoolValues that use an existing MachineConstantPoolEntry. DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries; + const DataLayout &DL; + + const DataLayout &getDataLayout() const { return DL; } - const DataLayout *getDataLayout() const; public: /// @brief The only constructor. - explicit MachineConstantPool(const TargetMachine &TM) - : TM(TM), PoolAlignment(1) {} + explicit MachineConstantPool(const DataLayout &DL) + : PoolAlignment(1), DL(DL) {} ~MachineConstantPool(); /// getConstantPoolAlignment - Return the alignment required by diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index 4428fa6..735dd06 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -29,8 +29,8 @@ inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB this->Roots.push_back(MBB); } -EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>); -EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>); +extern template class DomTreeNodeBase<MachineBasicBlock>; +extern template class DominatorTreeBase<MachineBasicBlock>; typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode; diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 0f5a4b1..cbc4e66 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -229,9 +229,9 @@ class MachineFrameInfo { /// Whether the "realign-stack" option is on. bool RealignOption; - /// True if the function includes inline assembly that adjusts the stack - /// pointer. - bool HasInlineAsmWithSPAdjust; + /// True if the function dynamically adjusts the stack pointer through some + /// opaque mechanism like inline assembly or Win32 EH. + bool HasOpaqueSPAdjustment; /// True if the function contains a call to the llvm.vastart intrinsic. bool HasVAStart; @@ -269,7 +269,7 @@ public: LocalFrameSize = 0; LocalFrameMaxAlign = 0; UseLocalStackAllocationBlock = false; - HasInlineAsmWithSPAdjust = false; + HasOpaqueSPAdjustment = false; HasVAStart = false; HasMustTailInVarArgFunc = false; Save = nullptr; @@ -468,9 +468,9 @@ public: bool hasCalls() const { return HasCalls; } void setHasCalls(bool V) { HasCalls = V; } - /// Returns true if the function contains any stack-adjusting inline assembly. - bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; } - void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; } + /// Returns true if the function contains opaque dynamic stack adjustments. + bool hasOpaqueSPAdjustment() const { return HasOpaqueSPAdjustment; } + void setHasOpaqueSPAdjustment(bool B) { HasOpaqueSPAdjustment = B; } /// Returns true if the function calls the llvm.va_start intrinsic. bool hasVAStart() const { return HasVAStart; } @@ -541,6 +541,14 @@ public: return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; } + /// Returns true if the specified index corresponds to a variable sized + /// object. + bool isVariableSizedObjectIndex(int ObjectIdx) const { + assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + return Objects[ObjectIdx + NumFixedObjects].Size == 0; + } + /// Create a new statically sized stack object, returning /// a nonnegative identifier to represent it. int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 94610ca..c15ee1c 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -155,6 +155,9 @@ public: MachineModuleInfo &getMMI() const { return MMI; } MCContext &getContext() const { return Ctx; } + /// Return the DataLayout attached to the Module associated to this MF. + const DataLayout &getDataLayout() const; + /// getFunction - Return the LLVM function that this machine code represents /// const Function *getFunction() const { return Fn; } diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 438ef2e..4868b73 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -37,10 +37,8 @@ namespace llvm { // Implementation in LoopInfoImpl.h -#ifdef __GNUC__ class MachineLoop; -__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop>; -#endif +extern template class LoopBase<MachineBasicBlock, MachineLoop>; class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> { public: @@ -65,10 +63,7 @@ private: }; // Implementation in LoopInfoImpl.h -#ifdef __GNUC__ -__extension__ extern template -class LoopInfoBase<MachineBasicBlock, MachineLoop>; -#endif +extern template class LoopInfoBase<MachineBasicBlock, MachineLoop>; class MachineLoopInfo : public MachineFunctionPass { LoopInfoBase<MachineBasicBlock, MachineLoop> LI; diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index ccaa83a..4cdfe24 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -320,6 +320,7 @@ public: /// information. void addPersonality(MachineBasicBlock *LandingPad, const Function *Personality); + void addPersonality(const Function *Personality); void addWinEHState(MachineBasicBlock *LandingPad, int State); diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h index cf49c29..df9823f 100644 --- a/include/llvm/CodeGen/MachineRegionInfo.h +++ b/include/llvm/CodeGen/MachineRegionInfo.h @@ -172,10 +172,9 @@ template <> struct GraphTraits<MachineRegionInfoPass*> } }; -EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>); -EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>); -EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>); - +extern template class RegionBase<RegionTraits<MachineFunction>>; +extern template class RegionNodeBase<RegionTraits<MachineFunction>>; +extern template class RegionInfoBase<RegionTraits<MachineFunction>>; } #endif diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index e5b837a..67583be 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -95,20 +95,8 @@ private: return MO->Contents.Reg.Next; } - /// UsedRegUnits - This is a bit vector that is computed and set by the - /// register allocator, and must be kept up to date by passes that run after - /// register allocation (though most don't modify this). This is used - /// so that the code generator knows which callee save registers to save and - /// for other target specific uses. - /// This vector has bits set for register units that are modified in the - /// current function. It doesn't include registers clobbered by function - /// calls with register mask operands. - BitVector UsedRegUnits; - /// UsedPhysRegMask - Additional used physregs including aliases. /// This bit vector represents all the registers clobbered by function calls. - /// It can model things that UsedRegUnits can't, such as function calls that - /// clobber ymm7 but preserve the low half in xmm7. BitVector UsedPhysRegMask; /// ReservedRegs - This is a bit vector of reserved registers. The target @@ -647,40 +635,11 @@ public: /// deleted during LiveDebugVariables analysis. void markUsesInDebugValueAsUndef(unsigned Reg) const; - //===--------------------------------------------------------------------===// - // Physical Register Use Info - //===--------------------------------------------------------------------===// - - /// isPhysRegUsed - Return true if the specified register is used in this - /// function. Also check for clobbered aliases and registers clobbered by - /// function calls with register mask operands. - /// - /// This only works after register allocation. It is primarily used by - /// PrologEpilogInserter to determine which callee-saved registers need - /// spilling. - bool isPhysRegUsed(unsigned Reg) const { - if (UsedPhysRegMask.test(Reg)) - return true; - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - if (UsedRegUnits.test(*Units)) - return true; - return false; - } - - /// Mark the specified register unit as used in this function. - /// This should only be called during and after register allocation. - void setRegUnitUsed(unsigned RegUnit) { - UsedRegUnits.set(RegUnit); - } - - /// setPhysRegUsed - Mark the specified register used in this function. - /// This should only be called during and after register allocation. - void setPhysRegUsed(unsigned Reg) { - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - UsedRegUnits.set(*Units); - } + /// Return true if the specified register is modified in this function. + /// This checks that no defining machine operands exist for the register or + /// any of its aliases. Definitions found on functions marked noreturn are + /// ignored. + bool isPhysRegModified(unsigned PhysReg) const; /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used. /// This corresponds to the bit mask attached to register mask operands. @@ -688,16 +647,6 @@ public: UsedPhysRegMask.setBitsNotInMask(RegMask); } - /// setPhysRegUnused - Mark the specified register unused in this function. - /// This should only be called during and after register allocation. - void setPhysRegUnused(unsigned Reg) { - UsedPhysRegMask.reset(Reg); - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - UsedRegUnits.reset(*Units); - } - - //===--------------------------------------------------------------------===// // Reserved Register Info //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 538c995..5d82921 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -101,7 +101,7 @@ public: private: PassManagerBase *PM; - AnalysisID StartAfter; + AnalysisID StartBefore, StartAfter; AnalysisID StopAfter; bool Started; bool Stopped; @@ -142,16 +142,24 @@ public: CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } - /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow - /// running only a portion of the normal code-gen pass sequence. If the - /// Start pass ID is zero, then compilation will begin at the normal point; - /// otherwise, clear the Started flag to indicate that passes should not be - /// added until the starting pass is seen. If the Stop pass ID is zero, - /// then compilation will continue to the end. - void setStartStopPasses(AnalysisID Start, AnalysisID Stop) { - StartAfter = Start; - StopAfter = Stop; - Started = (StartAfter == nullptr); + /// Set the StartAfter, StartBefore and StopAfter passes to allow running only + /// a portion of the normal code-gen pass sequence. + /// + /// If the StartAfter and StartBefore pass ID is zero, then compilation will + /// begin at the normal point; otherwise, clear the Started flag to indicate + /// that passes should not be added until the starting pass is seen. If the + /// Stop pass ID is zero, then compilation will continue to the end. + /// + /// This function expects that at least one of the StartAfter or the + /// StartBefore pass IDs is null. + void setStartStopPasses(AnalysisID StartBefore, AnalysisID StartAfter, + AnalysisID StopAfter) { + if (StartAfter) + assert(!StartBefore && "Start after and start before passes are given"); + this->StartBefore = StartBefore; + this->StartAfter = StartAfter; + this->StopAfter = StopAfter; + Started = (StartAfter == nullptr) && (StartBefore == nullptr); } void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } @@ -597,7 +605,7 @@ namespace llvm { /// createSjLjEHPreparePass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. /// - FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM); + FunctionPass *createSjLjEHPreparePass(); /// LocalStackSlotAllocation - This pass assigns local frame indices to stack /// slots relative to one another and allocates base registers to access them diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h index fcb6fee..9d8843d 100644 --- a/include/llvm/CodeGen/RegisterPressure.h +++ b/include/llvm/CodeGen/RegisterPressure.h @@ -135,6 +135,8 @@ public: void addPressureChange(unsigned RegUnit, bool IsDec, const MachineRegisterInfo *MRI); + + LLVM_DUMP_METHOD void dump(const TargetRegisterInfo &TRI) const; }; /// Array of PressureDiffs. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index c2b1243..1ee9238 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -281,6 +281,7 @@ public: void clear(); MachineFunction &getMachineFunction() const { return *MF; } + const DataLayout &getDataLayout() const { return MF->getDataLayout(); } const TargetMachine &getTarget() const { return TM; } const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); } const TargetLowering &getTargetLoweringInfo() const { return *TLI; } @@ -322,6 +323,14 @@ public: return AllNodes.size(); } + iterator_range<allnodes_iterator> allnodes() { + return iterator_range<allnodes_iterator>(allnodes_begin(), allnodes_end()); + } + iterator_range<allnodes_const_iterator> allnodes() const { + return iterator_range<allnodes_const_iterator>(allnodes_begin(), + allnodes_end()); + } + /// Return the root tag of the SelectionDAG. const SDValue &getRoot() const { return Root; } diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 6191190..4821d1a 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -140,7 +140,7 @@ public: } // Return true if this node is an operand of N. - bool isOperandOf(SDNode *N) const; + bool isOperandOf(const SDNode *N) const; /// Return the ValueType of the referenced return value. inline EVT getValueType() const; @@ -357,9 +357,6 @@ private: /// The number of entries in the Operand/Value list. unsigned short NumOperands, NumValues; - /// Source line information. - DebugLoc debugLoc; - // The ordering of the SDNodes. It roughly corresponds to the ordering of the // original LLVM instructions. // This is used for turning off scheduling, because we'll forgo @@ -367,6 +364,9 @@ private: // this ordering. unsigned IROrder; + /// Source line information. + DebugLoc debugLoc; + /// Return a pointer to the specified value type. static const EVT *getValueTypeList(EVT VT); @@ -532,10 +532,10 @@ public: bool hasAnyUseOfValue(unsigned Value) const; /// Return true if this node is the only use of N. - bool isOnlyUserOf(SDNode *N) const; + bool isOnlyUserOf(const SDNode *N) const; /// Return true if this node is an operand of N. - bool isOperandOf(SDNode *N) const; + bool isOperandOf(const SDNode *N) const; /// Return true if this node is a predecessor of N. /// NOTE: Implemented on top of hasPredecessor and every bit as @@ -732,7 +732,7 @@ protected: SubclassData(0), NodeId(-1), OperandList(Ops.size() ? new SDUse[Ops.size()] : nullptr), ValueList(VTs.VTs), UseList(nullptr), NumOperands(Ops.size()), - NumValues(VTs.NumVTs), debugLoc(std::move(dl)), IROrder(Order) { + NumValues(VTs.NumVTs), IROrder(Order), debugLoc(std::move(dl)) { assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); assert(NumOperands == Ops.size() && "NumOperands wasn't wide enough for its operands!"); @@ -752,7 +752,7 @@ protected: : NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false), SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs), UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs), - debugLoc(std::move(dl)), IROrder(Order) { + IROrder(Order), debugLoc(std::move(dl)) { assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); assert(NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!"); diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index 46a773f..fdc1a91 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -1,5 +1,4 @@ //===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===// - // // The LLVM Compiler Infrastructure // @@ -42,10 +41,12 @@ class PatchPointOpers { public: /// Enumerate the meta operands. enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd }; + private: const MachineInstr *MI; bool HasDef; bool IsAnyReg; + public: explicit PatchPointOpers(const MachineInstr *MI); @@ -66,8 +67,8 @@ public: /// Get the operand index of the variable list of non-argument operands. /// These hold the "live state". unsigned getVarIdx() const { - return getMetaIdx() + MetaEnd - + MI->getOperand(getMetaIdx(NArgPos)).getImm(); + return getMetaIdx() + MetaEnd + + MI->getOperand(getMetaIdx(NArgPos)).getImm(); } /// Get the index at which stack map locations will be recorded. @@ -98,15 +99,10 @@ private: // These values are relative offests from the start of the statepoint meta // arguments (i.e. the end of the call arguments). - enum { - CCOffset = 1, - FlagsOffset = 3, - NumVMSArgsOffset = 5 - }; + enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 }; public: - explicit StatepointOpers(const MachineInstr *MI): - MI(MI) { } + explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {} /// Get starting index of non call related arguments /// (calling convention, statepoint flags, vm state and gc state). @@ -134,31 +130,32 @@ private: class StackMaps { public: struct Location { - enum LocationType { Unprocessed, Register, Direct, Indirect, Constant, - ConstantIndex }; - LocationType LocType; + enum LocationType { + Unprocessed, + Register, + Direct, + Indirect, + Constant, + ConstantIndex + }; + LocationType Type; unsigned Size; unsigned Reg; int64_t Offset; - Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {} - Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset) - : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {} + Location() : Type(Unprocessed), Size(0), Reg(0), Offset(0) {} + Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset) + : Type(Type), Size(Size), Reg(Reg), Offset(Offset) {} }; struct LiveOutReg { unsigned short Reg; - unsigned short RegNo; + unsigned short DwarfRegNum; unsigned short Size; - LiveOutReg() : Reg(0), RegNo(0), Size(0) {} - LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size) - : Reg(Reg), RegNo(RegNo), Size(Size) {} - - void MarkInvalid() { Reg = 0; } - - // Only sort by the dwarf register number. - bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; } - static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; } + LiveOutReg() : Reg(0), DwarfRegNum(0), Size(0) {} + LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum, + unsigned short Size) + : Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {} }; // OpTypes are used to encode information about the following logical @@ -205,8 +202,8 @@ private: CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {} CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID, LocationVec &&Locations, LiveOutVec &&LiveOuts) - : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)), - LiveOuts(std::move(LiveOuts)) {} + : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)), + LiveOuts(std::move(LiveOuts)) {} }; typedef std::vector<CallsiteInfo> CallsiteInfoList; @@ -218,8 +215,8 @@ private: MachineInstr::const_mop_iterator parseOperand(MachineInstr::const_mop_iterator MOI, - MachineInstr::const_mop_iterator MOE, - LocationVec &Locs, LiveOutVec &LiveOuts) const; + MachineInstr::const_mop_iterator MOE, LocationVec &Locs, + LiveOutVec &LiveOuts) const; /// \brief Create a live-out register record for the given register @p Reg. LiveOutReg createLiveOutReg(unsigned Reg, @@ -254,7 +251,6 @@ private: void print(raw_ostream &OS); void debug() { print(dbgs()); } }; - } #endif diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index 291f390..75638a0 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -91,7 +91,7 @@ private: // When the parseEHActions function is called to populate a vector of // instances of this class, the ExceptionObjectVar field will be nullptr // and the ExceptionObjectIndex will be the index of the exception object in - // the parent function's frameescape block. + // the parent function's localescape block. const Value *ExceptionObjectVar; int ExceptionObjectIndex; TinyPtrVector<BasicBlock *> ReturnTargets; @@ -148,7 +148,7 @@ struct WinEHFuncInfo { int UnwindHelpFrameOffset = -1; unsigned NumIPToStateFuncsVisited = 0; - /// frameescape index of the 32-bit EH registration node. Set by + /// localescape index of the 32-bit EH registration node. Set by /// WinEHStatePass and used indirectly by SEH filter functions of the parent. int EHRegNodeEscapeIndex = INT_MAX; diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index e8af601..821c018 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -31,6 +31,7 @@ #include <map> #include <string> #include <vector> +#include <functional> namespace llvm { @@ -89,6 +90,8 @@ public: uint64_t RemoveMapping(StringRef Name); }; +using FunctionCreator = std::function<void *(const std::string &)>; + /// \brief Abstract interface for implementation execution of LLVM modules, /// designed to support both interpreter and just-in-time (JIT) compiler /// implementations. @@ -147,7 +150,7 @@ protected: /// LazyFunctionCreator - If an unknown function is needed, this function /// pointer is invoked to create it. If this returns null, the JIT will /// abort. - void *(*LazyFunctionCreator)(const std::string &); + FunctionCreator LazyFunctionCreator; /// getMangledName - Get mangled name. std::string getMangledName(const GlobalValue *GV); @@ -470,8 +473,8 @@ public: /// InstallLazyFunctionCreator - If an unknown function is needed, the /// specified function pointer is invoked to create it. If it returns null, /// the JIT will abort. - void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { - LazyFunctionCreator = P; + void InstallLazyFunctionCreator(FunctionCreator C) { + LazyFunctionCreator = C; } protected: diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 94c4038..a808d92 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -153,6 +153,10 @@ public: /// This method returns the address of the specified function or variable. /// It is used to resolve symbols during module linking. + /// + /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will + /// skip all relocations for that symbol, and the client will be responsible + /// for handling them manually. virtual SymbolInfo findSymbol(const std::string &Name) = 0; /// This method returns the address of the specified symbol if it exists diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 366bf70..4d6d7da 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -98,6 +98,8 @@ public: OptimizeNone, ///< Function must not be optimized. ReadNone, ///< Function does not access memory ReadOnly, ///< Function only reads from memory + ArgMemOnly, ///< Funciton can access memory only using pointers + ///< based on its arguments. Returned, ///< Return value is always equal to this argument ReturnsTwice, ///< Function can return twice SExt, ///< Sign extended before/after call diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index dd2903e..2841781 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -290,6 +290,15 @@ public: CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory()); } + /// @brief Determine if the call can access memmory only using pointers based + /// on its arguments. + bool onlyAccessesArgMemory() const { + CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory()); + } + void setOnlyAccessesArgMemory() { + CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory()); + } + /// @brief Determine if the call cannot return. bool doesNotReturn() const { CALLSITE_DELEGATE_GETTER(doesNotReturn()); diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index d6296b6..aa43c02 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -47,7 +47,7 @@ namespace llvm { SmallVector<Metadata *, 4> AllGVs; SmallVector<TrackingMDNodeRef, 4> AllImportedModules; - /// \brief Track nodes that may be unresolved. + /// Track nodes that may be unresolved. SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes; bool AllowUnresolvedNodes; @@ -57,49 +57,52 @@ namespace llvm { DIBuilder(const DIBuilder &) = delete; void operator=(const DIBuilder &) = delete; - /// \brief Create a temporary. + /// Create a temporary. /// /// Create an \a temporary node and track it in \a UnresolvedNodes. void trackIfUnresolved(MDNode *N); public: - /// \brief Construct a builder for a module. + /// Construct a builder for a module. /// /// If \c AllowUnresolved, collect unresolved nodes attached to the module /// in order to resolve cycles during \a finalize(). explicit DIBuilder(Module &M, bool AllowUnresolved = true); enum DebugEmissionKind { FullDebug=1, LineTablesOnly }; - /// finalize - Construct any deferred debug info descriptors. + /// Construct any deferred debug info descriptors. void finalize(); - /// createCompileUnit - A CompileUnit provides an anchor for all debugging + /// A CompileUnit provides an anchor for all debugging /// information generated during this instance of compilation. - /// @param Lang Source programming language, eg. dwarf::DW_LANG_C99 - /// @param File File name - /// @param Dir Directory - /// @param Producer Identify the producer of debugging information and code. - /// Usually this is a compiler version string. - /// @param isOptimized A boolean flag which indicates whether optimization - /// is ON or not. - /// @param Flags This string lists command line options. This string is - /// directly embedded in debug info output which may be used - /// by a tool analyzing generated debugging information. - /// @param RV This indicates runtime version for languages like - /// Objective-C. - /// @param SplitName The name of the file that we'll split debug info out - /// into. - /// @param Kind The kind of debug information to generate. - /// @param DWOId The DWOId if this is a split skeleton compile unit. - /// @param EmitDebugInfo A boolean flag which indicates whether debug - /// information should be written to the final - /// output or not. When this is false, debug - /// information annotations will be present in - /// the IL but they are not written to the final - /// assembly or object file. This supports tracking - /// source location information in the back end - /// without actually changing the output (e.g., - /// when using optimization remarks). + /// \param Lang Source programming language, eg. dwarf::DW_LANG_C99 + /// \param File File name + /// \param Dir Directory + /// \param Producer Identify the producer of debugging information + /// and code. Usually this is a compiler + /// version string. + /// \param isOptimized A boolean flag which indicates whether optimization + /// is enabled or not. + /// \param Flags This string lists command line options. This + /// string is directly embedded in debug info + /// output which may be used by a tool + /// analyzing generated debugging information. + /// \param RV This indicates runtime version for languages like + /// Objective-C. + /// \param SplitName The name of the file that we'll split debug info + /// out into. + /// \param Kind The kind of debug information to generate. + /// \param DWOId The DWOId if this is a split skeleton compile unit. + /// \param EmitDebugInfo A boolean flag which indicates whether + /// debug information should be written to + /// the final output or not. When this is + /// false, debug information annotations will + /// be present in the IL but they are not + /// written to the final assembly or object + /// file. This supports tracking source + /// location information in the back end + /// without actually changing the output + /// (e.g., when using optimization remarks). DICompileUnit * createCompileUnit(unsigned Lang, StringRef File, StringRef Dir, StringRef Producer, bool isOptimized, StringRef Flags, @@ -107,155 +110,155 @@ namespace llvm { DebugEmissionKind Kind = FullDebug, uint64_t DWOId = 0, bool EmitDebugInfo = true); - /// createFile - Create a file descriptor to hold debugging information + /// Create a file descriptor to hold debugging information /// for a file. DIFile *createFile(StringRef Filename, StringRef Directory); - /// createEnumerator - Create a single enumerator value. + /// Create a single enumerator value. DIEnumerator *createEnumerator(StringRef Name, int64_t Val); - /// \brief Create a DWARF unspecified type. + /// Create a DWARF unspecified type. DIBasicType *createUnspecifiedType(StringRef Name); - /// \brief Create C++11 nullptr type. + /// Create C++11 nullptr type. DIBasicType *createNullPtrType(); - /// createBasicType - Create debugging information entry for a basic + /// Create debugging information entry for a basic /// type. - /// @param Name Type name. - /// @param SizeInBits Size of the type. - /// @param AlignInBits Type alignment. - /// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float. + /// \param Name Type name. + /// \param SizeInBits Size of the type. + /// \param AlignInBits Type alignment. + /// \param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float. DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding); - /// createQualifiedType - Create debugging information entry for a qualified + /// Create debugging information entry for a qualified /// type, e.g. 'const int'. - /// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type - /// @param FromTy Base Type. + /// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type + /// \param FromTy Base Type. DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy); - /// createPointerType - Create debugging information entry for a pointer. - /// @param PointeeTy Type pointed by this pointer. - /// @param SizeInBits Size. - /// @param AlignInBits Alignment. (optional) - /// @param Name Pointer type name. (optional) + /// Create debugging information entry for a pointer. + /// \param PointeeTy Type pointed by this pointer. + /// \param SizeInBits Size. + /// \param AlignInBits Alignment. (optional) + /// \param Name Pointer type name. (optional) DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits, uint64_t AlignInBits = 0, StringRef Name = ""); - /// \brief Create debugging information entry for a pointer to member. - /// @param PointeeTy Type pointed to by this pointer. - /// @param SizeInBits Size. - /// @param AlignInBits Alignment. (optional) - /// @param Class Type for which this pointer points to members of. + /// Create debugging information entry for a pointer to member. + /// \param PointeeTy Type pointed to by this pointer. + /// \param SizeInBits Size. + /// \param AlignInBits Alignment. (optional) + /// \param Class Type for which this pointer points to members of. DIDerivedType *createMemberPointerType(DIType *PointeeTy, DIType *Class, uint64_t SizeInBits, uint64_t AlignInBits = 0); - /// createReferenceType - Create debugging information entry for a c++ + /// Create debugging information entry for a c++ /// style reference or rvalue reference type. DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy); - /// createTypedef - Create debugging information entry for a typedef. - /// @param Ty Original type. - /// @param Name Typedef name. - /// @param File File where this type is defined. - /// @param LineNo Line number. - /// @param Context The surrounding context for the typedef. + /// Create debugging information entry for a typedef. + /// \param Ty Original type. + /// \param Name Typedef name. + /// \param File File where this type is defined. + /// \param LineNo Line number. + /// \param Context The surrounding context for the typedef. DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File, unsigned LineNo, DIScope *Context); - /// createFriend - Create debugging information entry for a 'friend'. + /// Create debugging information entry for a 'friend'. DIDerivedType *createFriend(DIType *Ty, DIType *FriendTy); - /// createInheritance - Create debugging information entry to establish + /// Create debugging information entry to establish /// inheritance relationship between two types. - /// @param Ty Original type. - /// @param BaseTy Base type. Ty is inherits from base. - /// @param BaseOffset Base offset. - /// @param Flags Flags to describe inheritance attribute, + /// \param Ty Original type. + /// \param BaseTy Base type. Ty is inherits from base. + /// \param BaseOffset Base offset. + /// \param Flags Flags to describe inheritance attribute, /// e.g. private DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy, uint64_t BaseOffset, unsigned Flags); - /// createMemberType - Create debugging information entry for a member. - /// @param Scope Member scope. - /// @param Name Member name. - /// @param File File where this member is defined. - /// @param LineNo Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param OffsetInBits Member offset. - /// @param Flags Flags to encode member attribute, e.g. private - /// @param Ty Parent type. + /// Create debugging information entry for a member. + /// \param Scope Member scope. + /// \param Name Member name. + /// \param File File where this member is defined. + /// \param LineNo Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param OffsetInBits Member offset. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Ty Parent type. DIDerivedType *createMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType *Ty); - /// createStaticMemberType - Create debugging information entry for a + /// Create debugging information entry for a /// C++ static data member. - /// @param Scope Member scope. - /// @param Name Member name. - /// @param File File where this member is declared. - /// @param LineNo Line number. - /// @param Ty Type of the static member. - /// @param Flags Flags to encode member attribute, e.g. private. - /// @param Val Const initializer of the member. + /// \param Scope Member scope. + /// \param Name Member name. + /// \param File File where this member is declared. + /// \param LineNo Line number. + /// \param Ty Type of the static member. + /// \param Flags Flags to encode member attribute, e.g. private. + /// \param Val Const initializer of the member. DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, unsigned Flags, llvm::Constant *Val); - /// createObjCIVar - Create debugging information entry for Objective-C + /// Create debugging information entry for Objective-C /// instance variable. - /// @param Name Member name. - /// @param File File where this member is defined. - /// @param LineNo Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param OffsetInBits Member offset. - /// @param Flags Flags to encode member attribute, e.g. private - /// @param Ty Parent type. - /// @param PropertyNode Property associated with this ivar. + /// \param Name Member name. + /// \param File File where this member is defined. + /// \param LineNo Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param OffsetInBits Member offset. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Ty Parent type. + /// \param PropertyNode Property associated with this ivar. DIDerivedType *createObjCIVar(StringRef Name, DIFile *File, unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType *Ty, MDNode *PropertyNode); - /// createObjCProperty - Create debugging information entry for Objective-C + /// Create debugging information entry for Objective-C /// property. - /// @param Name Property name. - /// @param File File where this property is defined. - /// @param LineNumber Line number. - /// @param GetterName Name of the Objective C property getter selector. - /// @param SetterName Name of the Objective C property setter selector. - /// @param PropertyAttributes Objective C property attributes. - /// @param Ty Type. + /// \param Name Property name. + /// \param File File where this property is defined. + /// \param LineNumber Line number. + /// \param GetterName Name of the Objective C property getter selector. + /// \param SetterName Name of the Objective C property setter selector. + /// \param PropertyAttributes Objective C property attributes. + /// \param Ty Type. DIObjCProperty *createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber, StringRef GetterName, StringRef SetterName, unsigned PropertyAttributes, DIType *Ty); - /// createClassType - Create debugging information entry for a class. - /// @param Scope Scope in which this class is defined. - /// @param Name class name. - /// @param File File where this member is defined. - /// @param LineNumber Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param OffsetInBits Member offset. - /// @param Flags Flags to encode member attribute, e.g. private - /// @param Elements class members. - /// @param VTableHolder Debug info of the base class that contains vtable + /// Create debugging information entry for a class. + /// \param Scope Scope in which this class is defined. + /// \param Name class name. + /// \param File File where this member is defined. + /// \param LineNumber Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param OffsetInBits Member offset. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Elements class members. + /// \param VTableHolder Debug info of the base class that contains vtable /// for this type. This is used in /// DW_AT_containing_type. See DWARF documentation /// for more info. - /// @param TemplateParms Template type parameters. - /// @param UniqueIdentifier A unique identifier for the class. + /// \param TemplateParms Template type parameters. + /// \param UniqueIdentifier A unique identifier for the class. DICompositeType *createClassType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, @@ -265,34 +268,34 @@ namespace llvm { MDNode *TemplateParms = nullptr, StringRef UniqueIdentifier = ""); - /// createStructType - Create debugging information entry for a struct. - /// @param Scope Scope in which this struct is defined. - /// @param Name Struct name. - /// @param File File where this member is defined. - /// @param LineNumber Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param Flags Flags to encode member attribute, e.g. private - /// @param Elements Struct elements. - /// @param RunTimeLang Optional parameter, Objective-C runtime version. - /// @param UniqueIdentifier A unique identifier for the struct. + /// Create debugging information entry for a struct. + /// \param Scope Scope in which this struct is defined. + /// \param Name Struct name. + /// \param File File where this member is defined. + /// \param LineNumber Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Elements Struct elements. + /// \param RunTimeLang Optional parameter, Objective-C runtime version. + /// \param UniqueIdentifier A unique identifier for the struct. DICompositeType *createStructType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0, DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = ""); - /// createUnionType - Create debugging information entry for an union. - /// @param Scope Scope in which this union is defined. - /// @param Name Union name. - /// @param File File where this member is defined. - /// @param LineNumber Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param Flags Flags to encode member attribute, e.g. private - /// @param Elements Union elements. - /// @param RunTimeLang Optional parameter, Objective-C runtime version. - /// @param UniqueIdentifier A unique identifier for the union. + /// Create debugging information entry for an union. + /// \param Scope Scope in which this union is defined. + /// \param Name Union name. + /// \param File File where this member is defined. + /// \param LineNumber Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param Flags Flags to encode member attribute, e.g. private + /// \param Elements Union elements. + /// \param RunTimeLang Optional parameter, Objective-C runtime version. + /// \param UniqueIdentifier A unique identifier for the union. DICompositeType *createUnionType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, @@ -300,95 +303,95 @@ namespace llvm { unsigned RunTimeLang = 0, StringRef UniqueIdentifier = ""); - /// createTemplateTypeParameter - Create debugging information for template + /// Create debugging information for template /// type parameter. - /// @param Scope Scope in which this type is defined. - /// @param Name Type parameter name. - /// @param Ty Parameter type. + /// \param Scope Scope in which this type is defined. + /// \param Name Type parameter name. + /// \param Ty Parameter type. DITemplateTypeParameter * createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty); - /// createTemplateValueParameter - Create debugging information for template + /// Create debugging information for template /// value parameter. - /// @param Scope Scope in which this type is defined. - /// @param Name Value parameter name. - /// @param Ty Parameter type. - /// @param Val Constant parameter value. + /// \param Scope Scope in which this type is defined. + /// \param Name Value parameter name. + /// \param Ty Parameter type. + /// \param Val Constant parameter value. DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope, StringRef Name, DIType *Ty, Constant *Val); - /// \brief Create debugging information for a template template parameter. - /// @param Scope Scope in which this type is defined. - /// @param Name Value parameter name. - /// @param Ty Parameter type. - /// @param Val The fully qualified name of the template. + /// Create debugging information for a template template parameter. + /// \param Scope Scope in which this type is defined. + /// \param Name Value parameter name. + /// \param Ty Parameter type. + /// \param Val The fully qualified name of the template. DITemplateValueParameter *createTemplateTemplateParameter(DIScope *Scope, StringRef Name, DIType *Ty, StringRef Val); - /// \brief Create debugging information for a template parameter pack. - /// @param Scope Scope in which this type is defined. - /// @param Name Value parameter name. - /// @param Ty Parameter type. - /// @param Val An array of types in the pack. + /// Create debugging information for a template parameter pack. + /// \param Scope Scope in which this type is defined. + /// \param Name Value parameter name. + /// \param Ty Parameter type. + /// \param Val An array of types in the pack. DITemplateValueParameter *createTemplateParameterPack(DIScope *Scope, StringRef Name, DIType *Ty, DINodeArray Val); - /// createArrayType - Create debugging information entry for an array. - /// @param Size Array size. - /// @param AlignInBits Alignment. - /// @param Ty Element type. - /// @param Subscripts Subscripts. + /// Create debugging information entry for an array. + /// \param Size Array size. + /// \param AlignInBits Alignment. + /// \param Ty Element type. + /// \param Subscripts Subscripts. DICompositeType *createArrayType(uint64_t Size, uint64_t AlignInBits, DIType *Ty, DINodeArray Subscripts); - /// createVectorType - Create debugging information entry for a vector type. - /// @param Size Array size. - /// @param AlignInBits Alignment. - /// @param Ty Element type. - /// @param Subscripts Subscripts. + /// Create debugging information entry for a vector type. + /// \param Size Array size. + /// \param AlignInBits Alignment. + /// \param Ty Element type. + /// \param Subscripts Subscripts. DICompositeType *createVectorType(uint64_t Size, uint64_t AlignInBits, DIType *Ty, DINodeArray Subscripts); - /// createEnumerationType - Create debugging information entry for an + /// Create debugging information entry for an /// enumeration. - /// @param Scope Scope in which this enumeration is defined. - /// @param Name Union name. - /// @param File File where this member is defined. - /// @param LineNumber Line number. - /// @param SizeInBits Member size. - /// @param AlignInBits Member alignment. - /// @param Elements Enumeration elements. - /// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum. - /// @param UniqueIdentifier A unique identifier for the enum. + /// \param Scope Scope in which this enumeration is defined. + /// \param Name Union name. + /// \param File File where this member is defined. + /// \param LineNumber Line number. + /// \param SizeInBits Member size. + /// \param AlignInBits Member alignment. + /// \param Elements Enumeration elements. + /// \param UnderlyingType Underlying type of a C++11/ObjC fixed enum. + /// \param UniqueIdentifier A unique identifier for the enum. DICompositeType *createEnumerationType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DINodeArray Elements, DIType *UnderlyingType, StringRef UniqueIdentifier = ""); - /// createSubroutineType - Create subroutine type. - /// @param File File in which this subroutine is defined. - /// @param ParameterTypes An array of subroutine parameter types. This + /// Create subroutine type. + /// \param File File in which this subroutine is defined. + /// \param ParameterTypes An array of subroutine parameter types. This /// includes return type at 0th index. - /// @param Flags E.g.: LValueReference. + /// \param Flags E.g.: LValueReference. /// These flags are used to emit dwarf attributes. DISubroutineType *createSubroutineType(DIFile *File, DITypeRefArray ParameterTypes, unsigned Flags = 0); - /// createArtificialType - Create a new DIType* with "artificial" flag set. + /// Create a new DIType* with "artificial" flag set. DIType *createArtificialType(DIType *Ty); - /// createObjectPointerType - Create a new DIType* with the "object pointer" + /// Create a new DIType* with the "object pointer" /// flag set. DIType *createObjectPointerType(DIType *Ty); - /// \brief Create a permanent forward-declared type. + /// Create a permanent forward-declared type. DICompositeType *createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, unsigned RuntimeLang = 0, @@ -396,43 +399,43 @@ namespace llvm { uint64_t AlignInBits = 0, StringRef UniqueIdentifier = ""); - /// \brief Create a temporary forward-declared type. + /// Create a temporary forward-declared type. DICompositeType *createReplaceableCompositeType( unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, unsigned RuntimeLang = 0, uint64_t SizeInBits = 0, uint64_t AlignInBits = 0, unsigned Flags = DINode::FlagFwdDecl, StringRef UniqueIdentifier = ""); - /// retainType - Retain DIType* in a module even if it is not referenced + /// Retain DIType* in a module even if it is not referenced /// through debug info anchors. void retainType(DIType *T); - /// createUnspecifiedParameter - Create unspecified parameter type + /// Create unspecified parameter type /// for a subroutine type. DIBasicType *createUnspecifiedParameter(); - /// getOrCreateArray - Get a DINodeArray, create one if required. + /// Get a DINodeArray, create one if required. DINodeArray getOrCreateArray(ArrayRef<Metadata *> Elements); - /// getOrCreateTypeArray - Get a DITypeRefArray, create one if required. + /// Get a DITypeRefArray, create one if required. DITypeRefArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements); - /// getOrCreateSubrange - Create a descriptor for a value range. This + /// Create a descriptor for a value range. This /// implicitly uniques the values returned. DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count); - /// createGlobalVariable - Create a new descriptor for the specified + /// Create a new descriptor for the specified /// variable. - /// @param Context Variable scope. - /// @param Name Name of the variable. - /// @param LinkageName Mangled name of the variable. - /// @param File File where this variable is defined. - /// @param LineNo Line number. - /// @param Ty Variable Type. - /// @param isLocalToUnit Boolean flag indicate whether this variable is + /// \param Context Variable scope. + /// \param Name Name of the variable. + /// \param LinkageName Mangled name of the variable. + /// \param File File where this variable is defined. + /// \param LineNo Line number. + /// \param Ty Variable Type. + /// \param isLocalToUnit Boolean flag indicate whether this variable is /// externally visible or not. - /// @param Val llvm::Value of the variable. - /// @param Decl Reference to the corresponding declaration. + /// \param Val llvm::Value of the variable. + /// \param Decl Reference to the corresponding declaration. DIGlobalVariable *createGlobalVariable(DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, @@ -440,26 +443,26 @@ namespace llvm { llvm::Constant *Val, MDNode *Decl = nullptr); - /// createTempGlobalVariableFwdDecl - Identical to createGlobalVariable + /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. DIGlobalVariable *createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val, MDNode *Decl = nullptr); - /// createLocalVariable - Create a new descriptor for the specified + /// Create a new descriptor for the specified /// local variable. - /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or + /// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or /// DW_TAG_arg_variable. - /// @param Scope Variable scope. - /// @param Name Variable name. - /// @param File File where this variable is defined. - /// @param LineNo Line number. - /// @param Ty Variable Type - /// @param AlwaysPreserve Boolean. Set to true if debug info for this + /// \param Scope Variable scope. + /// \param Name Variable name. + /// \param File File where this variable is defined. + /// \param LineNo Line number. + /// \param Ty Variable Type + /// \param AlwaysPreserve Boolean. Set to true if debug info for this /// variable should be preserved in optimized build. - /// @param Flags Flags, e.g. artificial variable. - /// @param ArgNo If this variable is an argument then this argument's + /// \param Flags Flags, e.g. artificial variable. + /// \param ArgNo If this variable is an argument then this argument's /// number. 1 indicates 1st argument. DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope, StringRef Name, DIFile *File, @@ -468,36 +471,36 @@ namespace llvm { unsigned Flags = 0, unsigned ArgNo = 0); - /// createExpression - Create a new descriptor for the specified + /// Create a new descriptor for the specified /// variable which has a complex address expression for its address. - /// @param Addr An array of complex address operations. + /// \param Addr An array of complex address operations. DIExpression *createExpression(ArrayRef<uint64_t> Addr = None); DIExpression *createExpression(ArrayRef<int64_t> Addr); - /// createBitPieceExpression - Create a descriptor to describe one part + /// Create a descriptor to describe one part /// of aggregate variable that is fragmented across multiple Values. /// - /// @param OffsetInBits Offset of the piece in bits. - /// @param SizeInBits Size of the piece in bits. + /// \param OffsetInBits Offset of the piece in bits. + /// \param SizeInBits Size of the piece in bits. DIExpression *createBitPieceExpression(unsigned OffsetInBits, unsigned SizeInBits); - /// createFunction - Create a new descriptor for the specified subprogram. + /// Create a new descriptor for the specified subprogram. /// See comments in DISubprogram* for descriptions of these fields. - /// @param Scope Function scope. - /// @param Name Function name. - /// @param LinkageName Mangled function name. - /// @param File File where this variable is defined. - /// @param LineNo Line number. - /// @param Ty Function type. - /// @param isLocalToUnit True if this function is not externally visible. - /// @param isDefinition True if this is a function definition. - /// @param ScopeLine Set to the beginning of the scope this starts - /// @param Flags e.g. is this function prototyped or not. + /// \param Scope Function scope. + /// \param Name Function name. + /// \param LinkageName Mangled function name. + /// \param File File where this variable is defined. + /// \param LineNo Line number. + /// \param Ty Function type. + /// \param isLocalToUnit True if this function is not externally visible. + /// \param isDefinition True if this is a function definition. + /// \param ScopeLine Set to the beginning of the scope this starts + /// \param Flags e.g. is this function prototyped or not. /// These flags are used to emit dwarf attributes. - /// @param isOptimized True if optimization is ON. - /// @param Fn llvm::Function pointer. - /// @param TParam Function template parameters. + /// \param isOptimized True if optimization is ON. + /// \param Fn llvm::Function pointer. + /// \param TParam Function template parameters. DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, @@ -506,7 +509,7 @@ namespace llvm { Function *Fn = nullptr, MDNode *TParam = nullptr, MDNode *Decl = nullptr); - /// createTempFunctionFwdDecl - Identical to createFunction, + /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. DISubprogram *createTempFunctionFwdDecl( DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, @@ -525,25 +528,25 @@ namespace llvm { Function *Fn = nullptr, MDNode *TParam = nullptr, MDNode *Decl = nullptr); - /// createMethod - Create a new descriptor for the specified C++ method. - /// See comments in DISubprogram* for descriptions of these fields. - /// @param Scope Function scope. - /// @param Name Function name. - /// @param LinkageName Mangled function name. - /// @param File File where this variable is defined. - /// @param LineNo Line number. - /// @param Ty Function type. - /// @param isLocalToUnit True if this function is not externally visible.. - /// @param isDefinition True if this is a function definition. - /// @param Virtuality Attributes describing virtualness. e.g. pure + /// Create a new descriptor for the specified C++ method. + /// See comments in \a DISubprogram* for descriptions of these fields. + /// \param Scope Function scope. + /// \param Name Function name. + /// \param LinkageName Mangled function name. + /// \param File File where this variable is defined. + /// \param LineNo Line number. + /// \param Ty Function type. + /// \param isLocalToUnit True if this function is not externally visible.. + /// \param isDefinition True if this is a function definition. + /// \param Virtuality Attributes describing virtualness. e.g. pure /// virtual function. - /// @param VTableIndex Index no of this method in virtual table. - /// @param VTableHolder Type that holds vtable. - /// @param Flags e.g. is this function prototyped or not. + /// \param VTableIndex Index no of this method in virtual table. + /// \param VTableHolder Type that holds vtable. + /// \param Flags e.g. is this function prototyped or not. /// This flags are used to emit dwarf attributes. - /// @param isOptimized True if optimization is ON. - /// @param Fn llvm::Function pointer. - /// @param TParam Function template parameters. + /// \param isOptimized True if optimization is ON. + /// \param Fn llvm::Function pointer. + /// \param TParam Function template parameters. DISubprogram * createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, @@ -552,131 +555,131 @@ namespace llvm { unsigned Flags = 0, bool isOptimized = false, Function *Fn = nullptr, MDNode *TParam = nullptr); - /// createNameSpace - This creates new descriptor for a namespace - /// with the specified parent scope. - /// @param Scope Namespace scope - /// @param Name Name of this namespace - /// @param File Source file - /// @param LineNo Line number + /// This creates new descriptor for a namespace with the specified + /// parent scope. + /// \param Scope Namespace scope + /// \param Name Name of this namespace + /// \param File Source file + /// \param LineNo Line number DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo); - /// createModule - This creates new descriptor for a module - /// with the specified parent scope. - /// @param Scope Parent scope - /// @param Name Name of this module - /// @param ConfigurationMacros + /// This creates new descriptor for a module with the specified + /// parent scope. + /// \param Scope Parent scope + /// \param Name Name of this module + /// \param ConfigurationMacros /// A space-separated shell-quoted list of -D macro /// definitions as they would appear on a command line. - /// @param IncludePath The path to the module map file. - /// @param ISysRoot The clang system root (value of -isysroot). + /// \param IncludePath The path to the module map file. + /// \param ISysRoot The clang system root (value of -isysroot). DIModule *createModule(DIScope *Scope, StringRef Name, StringRef ConfigurationMacros, StringRef IncludePath, StringRef ISysRoot); - /// createLexicalBlockFile - This creates a descriptor for a lexical - /// block with a new file attached. This merely extends the existing + /// This creates a descriptor for a lexical block with a new file + /// attached. This merely extends the existing /// lexical block as it crosses a file. - /// @param Scope Lexical block. - /// @param File Source file. - /// @param Discriminator DWARF path discriminator value. + /// \param Scope Lexical block. + /// \param File Source file. + /// \param Discriminator DWARF path discriminator value. DILexicalBlockFile *createLexicalBlockFile(DIScope *Scope, DIFile *File, unsigned Discriminator = 0); - /// createLexicalBlock - This creates a descriptor for a lexical block - /// with the specified parent context. - /// @param Scope Parent lexical scope. - /// @param File Source file. - /// @param Line Line number. - /// @param Col Column number. + /// This creates a descriptor for a lexical block with the + /// specified parent context. + /// \param Scope Parent lexical scope. + /// \param File Source file. + /// \param Line Line number. + /// \param Col Column number. DILexicalBlock *createLexicalBlock(DIScope *Scope, DIFile *File, unsigned Line, unsigned Col); - /// \brief Create a descriptor for an imported module. - /// @param Context The scope this module is imported into - /// @param NS The namespace being imported here - /// @param Line Line number + /// Create a descriptor for an imported module. + /// \param Context The scope this module is imported into + /// \param NS The namespace being imported here + /// \param Line Line number DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS, unsigned Line); - /// \brief Create a descriptor for an imported module. - /// @param Context The scope this module is imported into - /// @param NS An aliased namespace - /// @param Line Line number + /// Create a descriptor for an imported module. + /// \param Context The scope this module is imported into + /// \param NS An aliased namespace + /// \param Line Line number DIImportedEntity *createImportedModule(DIScope *Context, DIImportedEntity *NS, unsigned Line); - /// \brief Create a descriptor for an imported module. - /// @param Context The scope this module is imported into - /// @param M The module being imported here - /// @param Line Line number + /// Create a descriptor for an imported module. + /// \param Context The scope this module is imported into + /// \param M The module being imported here + /// \param Line Line number DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M, unsigned Line); - /// \brief Create a descriptor for an imported function. - /// @param Context The scope this module is imported into - /// @param Decl The declaration (or definition) of a function, type, or + /// Create a descriptor for an imported function. + /// \param Context The scope this module is imported into + /// \param Decl The declaration (or definition) of a function, type, or /// variable - /// @param Line Line number + /// \param Line Line number DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl, unsigned Line, StringRef Name = ""); - /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. - /// @param Storage llvm::Value of the variable - /// @param VarInfo Variable's debug info descriptor. - /// @param Expr A complex location expression. - /// @param DL Debug info location. - /// @param InsertAtEnd Location for the new intrinsic. + /// Insert a new llvm.dbg.declare intrinsic call. + /// \param Storage llvm::Value of the variable + /// \param VarInfo Variable's debug info descriptor. + /// \param Expr A complex location expression. + /// \param DL Debug info location. + /// \param InsertAtEnd Location for the new intrinsic. Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, BasicBlock *InsertAtEnd); - /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. - /// @param Storage llvm::Value of the variable - /// @param VarInfo Variable's debug info descriptor. - /// @param Expr A complex location expression. - /// @param DL Debug info location. - /// @param InsertBefore Location for the new intrinsic. + /// Insert a new llvm.dbg.declare intrinsic call. + /// \param Storage llvm::Value of the variable + /// \param VarInfo Variable's debug info descriptor. + /// \param Expr A complex location expression. + /// \param DL Debug info location. + /// \param InsertBefore Location for the new intrinsic. Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, Instruction *InsertBefore); - /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - /// @param Val llvm::Value of the variable - /// @param Offset Offset - /// @param VarInfo Variable's debug info descriptor. - /// @param Expr A complex location expression. - /// @param DL Debug info location. - /// @param InsertAtEnd Location for the new intrinsic. + /// Insert a new llvm.dbg.value intrinsic call. + /// \param Val llvm::Value of the variable + /// \param Offset Offset + /// \param VarInfo Variable's debug info descriptor. + /// \param Expr A complex location expression. + /// \param DL Debug info location. + /// \param InsertAtEnd Location for the new intrinsic. Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, BasicBlock *InsertAtEnd); - /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - /// @param Val llvm::Value of the variable - /// @param Offset Offset - /// @param VarInfo Variable's debug info descriptor. - /// @param Expr A complex location expression. - /// @param DL Debug info location. - /// @param InsertBefore Location for the new intrinsic. + /// Insert a new llvm.dbg.value intrinsic call. + /// \param Val llvm::Value of the variable + /// \param Offset Offset + /// \param VarInfo Variable's debug info descriptor. + /// \param Expr A complex location expression. + /// \param DL Debug info location. + /// \param InsertBefore Location for the new intrinsic. Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, Instruction *InsertBefore); - /// \brief Replace the vtable holder in the given composite type. + /// Replace the vtable holder in the given composite type. /// /// If this creates a self reference, it may orphan some unresolved cycles /// in the operands of \c T, so \a DIBuilder needs to track that. void replaceVTableHolder(DICompositeType *&T, DICompositeType *VTableHolder); - /// \brief Replace arrays on a composite type. + /// Replace arrays on a composite type. /// /// If \c T is resolved, but the arrays aren't -- which can happen if \c T /// has a self-reference -- \a DIBuilder needs to track the array to @@ -684,7 +687,7 @@ namespace llvm { void replaceArrays(DICompositeType *&T, DINodeArray Elements, DINodeArray TParems = DINodeArray()); - /// \brief Replace a temporary node. + /// Replace a temporary node. /// /// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c /// Replacement. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 5c99300..9c5a957 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -1085,10 +1085,10 @@ public: /// deleted on a uniquing collision. In practice, uniquing collisions on \a /// DICompileUnit should be fairly rare. /// @{ - void replaceEnumTypes(DISubprogramArray N) { + void replaceEnumTypes(DICompositeTypeArray N) { replaceOperandWith(4, N.get()); } - void replaceRetainedTypes(DISubprogramArray N) { + void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); } void replaceSubprograms(DISubprogramArray N) { @@ -1097,7 +1097,7 @@ public: void replaceGlobalVariables(DIGlobalVariableArray N) { replaceOperandWith(7, N.get()); } - void replaceImportedEntities(DIGlobalVariableArray N) { + void replaceImportedEntities(DIImportedEntityArray N) { replaceOperandWith(8, N.get()); } /// @} @@ -1650,14 +1650,14 @@ class DIModule : public DIScope { StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, ConfigurationMacros), - getCanonicalMDString(Context, IncludePath), - getCanonicalMDString(Context, ISysRoot), + getCanonicalMDString(Context, IncludePath), + getCanonicalMDString(Context, ISysRoot), Storage, ShouldCreate); } static DIModule *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, - MDString *IncludePath, MDString *ISysRoot, - StorageType Storage, bool ShouldCreate = true); + MDString *IncludePath, MDString *ISysRoot, + StorageType Storage, bool ShouldCreate = true); TempDIModule cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), @@ -1667,12 +1667,12 @@ class DIModule : public DIScope { public: DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name, - StringRef ConfigurationMacros, StringRef IncludePath, - StringRef ISysRoot), + StringRef ConfigurationMacros, StringRef IncludePath, + StringRef ISysRoot), (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) DEFINE_MDNODE_GET(DIModule, (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, - MDString *IncludePath, MDString *ISysRoot), + MDString *IncludePath, MDString *ISysRoot), (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot)) TempDIModule clone() const { return cloneImpl(); } diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index c1f208e..27d989b 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -36,18 +36,14 @@ namespace llvm { template <typename IRUnitT> class AnalysisManager; class PreservedAnalyses; -EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>); -EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>); - -#define LLVM_COMMA , -EXTERN_TEMPLATE_INSTANTIATION(void Calculate<Function LLVM_COMMA BasicBlock *>( - DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA - Function &F)); -EXTERN_TEMPLATE_INSTANTIATION( - void Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >( - DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT - LLVM_COMMA Function &F)); -#undef LLVM_COMMA +extern template class DomTreeNodeBase<BasicBlock>; +extern template class DominatorTreeBase<BasicBlock>; + +extern template void Calculate<Function, BasicBlock *>( + DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F); +extern template void Calculate<Function, Inverse<BasicBlock *>>( + DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT, + Function &F); typedef DomTreeNodeBase<BasicBlock> DomTreeNode; diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 02ea056..ec9f4cad 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -293,6 +293,16 @@ public: addFnAttr(Attribute::ReadOnly); } + /// @brief Determine if the call can access memmory only using pointers based + /// on its arguments. + bool onlyAccessesArgMemory() const { + return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, + Attribute::ArgMemOnly); + } + void setOnlyAccessesArgMemory() { + addFnAttr(Attribute::ArgMemOnly); + } + /// @brief Determine if the function cannot return. bool doesNotReturn() const { return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index f237970..2961369 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -252,10 +252,9 @@ public: /// mistake: when working at the IR level use mayBeOverridden instead as it /// knows about ODR semantics. static bool isWeakForLinker(LinkageTypes Linkage) { - return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage || - Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage || - Linkage == LinkOnceODRLinkage || Linkage == CommonLinkage || - Linkage == ExternalWeakLinkage; + return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage || + Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage || + Linkage == CommonLinkage || Linkage == ExternalWeakLinkage; } bool hasExternalLinkage() const { return isExternalLinkage(Linkage); } @@ -349,6 +348,12 @@ public: return isDeclaration(); } + /// Returns true if this global's definition will be the one chosen by the + /// linker. + bool isStrongDefinitionForLinker() const { + return !(isDeclarationForLinker() || isWeakForLinker()); + } + /// This method unlinks 'this' from the containing module, but does not delete /// it. virtual void removeFromParent() = 0; diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index e6b5393..6c67c79 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -1382,47 +1382,61 @@ public: return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); } - Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name); + Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name); + Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name); + Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name); + Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name); + Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name); + Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name); + Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name); + Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name); + Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name); + Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name); + Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name); + Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name); + Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name, FPMathTag); } - Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") { - return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name); + Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "", + MDNode *FPMathTag = nullptr) { + return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name, FPMathTag); } Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, @@ -1433,11 +1447,12 @@ public: return Insert(new ICmpInst(P, LHS, RHS), Name); } Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, - const Twine &Name = "") { + const Twine &Name = "", MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast<Constant>(LHS)) if (Constant *RC = dyn_cast<Constant>(RHS)) return Insert(Folder.CreateFCmp(P, LC, RC), Name); - return Insert(new FCmpInst(P, LHS, RHS), Name); + return Insert(AddFPMathAttributes(new FCmpInst(P, LHS, RHS), + FPMathTag, FMF), Name); } //===--------------------------------------------------------------------===// @@ -1449,7 +1464,7 @@ public: return Insert(PHINode::Create(Ty, NumReservedValues), Name); } - CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, + CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None, const Twine &Name = "") { return Insert(CallInst::Create(Callee, Args), Name); } diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 6e3de1f..31f363f 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -382,7 +382,7 @@ public: /// /// Note that this does not consider malloc and alloca to have side /// effects because the newly allocated memory is completely invisible to - /// instructions which don't used the returned value. For cases where this + /// instructions which don't use the returned value. For cases where this /// matters, isSafeToSpeculativelyExecute may be more appropriate. bool mayHaveSideEffects() const { return mayWriteToMemory() || mayThrow() || !mayReturn(); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index c5890f0..07d5f11 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -990,10 +990,14 @@ public: Ptr->getType()->getPointerAddressSpace()); // Vector GEP if (Ptr->getType()->isVectorTy()) { - unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements(); + unsigned NumElem = Ptr->getType()->getVectorNumElements(); return VectorType::get(PtrTy, NumElem); } - + for (Value *Index : IdxList) + if (Index->getType()->isVectorTy()) { + unsigned NumElem = Index->getType()->getVectorNumElements(); + return VectorType::get(PtrTy, NumElem); + } // Scalar GEP return PtrTy; } @@ -1591,6 +1595,15 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } + /// @brief Determine if the call can access memmory only using pointers based + /// on its arguments. + bool onlyAccessesArgMemory() const { + return hasFnAttr(Attribute::ArgMemOnly); + } + void setOnlyAccessesArgMemory() { + addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly); + } + /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { @@ -3360,6 +3373,15 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); } + /// @brief Determine if the call access memmory only using it's pointer + /// arguments. + bool onlyAccessesArgMemory() const { + return hasFnAttr(Attribute::ArgMemOnly); + } + void setOnlyAccessesArgMemory() { + addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly); + } + /// \brief Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index e6f6d0f..bbae720 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -268,15 +268,23 @@ def int_gcwrite : Intrinsic<[], // def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; -def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>; -def int_framerecover : Intrinsic<[llvm_ptr_ty], - [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrNoMem]>; def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty], [IntrReadMem], "llvm.read_register">; def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty], [], "llvm.write_register">; +// Gets the address of the local variable area. This is typically a copy of the +// stack, frame, or base pointer depending on the type of prologue. +def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; + +// Escapes local variables to allow access from other functions. +def int_localescape : Intrinsic<[], [llvm_vararg_ty]>; + +// Given a function and the localaddress of a parent frame, returns a pointer +// to an escaped allocation indicated by the index. +def int_localrecover : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], + [IntrNoMem]>; // Note: we treat stacksave/stackrestore as writemem because we don't otherwise // model their dependencies on allocas. def int_stacksave : Intrinsic<[llvm_ptr_ty]>, @@ -362,6 +370,8 @@ let Properties = [IntrNoMem] in { def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], + [IntrNoMem]>; } // NOTE: these are internal interfaces. @@ -638,3 +648,4 @@ include "llvm/IR/IntrinsicsMips.td" include "llvm/IR/IntrinsicsAMDGPU.td" include "llvm/IR/IntrinsicsBPF.td" include "llvm/IR/IntrinsicsSystemZ.td" +include "llvm/IR/IntrinsicsWebAssembly.td" diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index 05adc5a..eb8f1e6 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -694,6 +694,18 @@ def int_ppc_vsx_xvrspip : def int_ppc_vsx_xvrdpip : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; +// Vector reciprocal estimate +def int_ppc_vsx_xvresp : GCCBuiltin<"__builtin_vsx_xvresp">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvredp : GCCBuiltin<"__builtin_vsx_xvredp">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + +// Vector rsqrte +def int_ppc_vsx_xvrsqrtesp : GCCBuiltin<"__builtin_vsx_xvrsqrtesp">, + Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xvrsqrtedp : GCCBuiltin<"__builtin_vsx_xvrsqrtedp">, + Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + // Vector compare def int_ppc_vsx_xvcmpeqdp : PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty], @@ -713,6 +725,9 @@ def int_ppc_vsx_xvcmpgtdp : def int_ppc_vsx_xvcmpgtsp : PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>; +def int_ppc_vsx_xxleqv : + PowerPC_VSX_Intrinsic<"xxleqv", [llvm_v4i32_ty], + [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>; } //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td new file mode 100644 index 0000000..3ccde47 --- /dev/null +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -0,0 +1,16 @@ +//===- IntrinsicsWebAssembly.td - Defines wasm intrinsics --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file defines all of the WebAssembly-specific intrinsics. +/// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.". +} diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index b90825d..a3bc4af 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -28,7 +28,7 @@ let TargetPrefix = "x86" in { def int_x86_seh_restoreframe : Intrinsic<[], [], []>; // Given a pointer to the end of an EH registration object, returns the true - // parent frame address that can be used with llvm.framerecover. + // parent frame address that can be used with llvm.localrecover. def int_x86_seh_recoverfp : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty], [IntrNoMem]>; @@ -2107,6 +2107,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw256">, Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty], [IntrNoMem, Commutative]>; + def int_x86_avx512_mask_pmul_hr_sw_128 : GCCBuiltin<"__builtin_ia32_pmulhrsw128_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, + llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmul_hr_sw_256 : GCCBuiltin<"__builtin_ia32_pmulhrsw256_mask">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, + llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmul_hr_sw_512 : GCCBuiltin<"__builtin_ia32_pmulhrsw512_mask">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, + llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; } // Vector sign and zero extend @@ -4466,6 +4475,24 @@ let TargetPrefix = "x86" in { def int_x86_avx512_mask_pmull_q_512 : GCCBuiltin<"__builtin_ia32_pmullq512_mask">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulhu_w_512 : GCCBuiltin<"__builtin_ia32_pmulhuw512_mask">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, + llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulh_w_512 : GCCBuiltin<"__builtin_ia32_pmulhw512_mask">, + Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty, + llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulhu_w_128 : GCCBuiltin<"__builtin_ia32_pmulhuw128_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, + llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulhu_w_256 : GCCBuiltin<"__builtin_ia32_pmulhuw256_mask">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, + llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulh_w_128 : GCCBuiltin<"__builtin_ia32_pmulhw128_mask">, + Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, + llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>; + def int_x86_avx512_mask_pmulh_w_256 : GCCBuiltin<"__builtin_ia32_pmulhw256_mask">, + Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, + llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>; def int_x86_avx512_mask_pavg_b_512 : GCCBuiltin<"__builtin_ia32_pavgb512_mask">, Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>; diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 1b9102e..372b254 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -305,7 +305,8 @@ public: float getFPAccuracy() const; static inline bool classof(const Instruction *I) { - return I->getType()->isFPOrFPVectorTy(); + return I->getType()->isFPOrFPVectorTy() || + I->getOpcode() == Instruction::FCmp; } static inline bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 484afc6..17a80c8 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -104,8 +104,8 @@ protected: /// /// Note, this should *NOT* be used directly by any class other than User. /// User uses this value to find the Use list. - static const unsigned NumUserOperandsBits = 29; - unsigned NumUserOperands : 29; + enum : unsigned { NumUserOperandsBits = 29 }; + unsigned NumUserOperands : NumUserOperandsBits; bool IsUsedByMD : 1; bool HasName : 1; diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 74fbc0f..e3b9a95 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -130,6 +130,7 @@ void initializeSanitizerCoverageModulePass(PassRegistry&); void initializeDataFlowSanitizerPass(PassRegistry&); void initializeScalarizerPass(PassRegistry&); void initializeEarlyCSELegacyPassPass(PassRegistry &); +void initializeEliminateAvailableExternallyPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); void initializeGCMachineCodeAnalysisPass(PassRegistry&); @@ -302,6 +303,7 @@ void initializePlaceSafepointsPass(PassRegistry&); void initializeDwarfEHPreparePass(PassRegistry&); void initializeFloat2IntPass(PassRegistry&); void initializeLoopDistributePass(PassRegistry&); +void initializeSjLjEHPreparePass(PassRegistry&); } #endif diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 8ac1b21..cea5530 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -176,6 +176,7 @@ namespace { (void) llvm::createStraightLineStrengthReducePass(); (void) llvm::createMemDerefPrinter(); (void) llvm::createFloat2IntPass(); + (void) llvm::createEliminateAvailableExternallyPass(); (void)new llvm::IntervalPartition(); (void)new llvm::ScalarEvolution(); diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 52017fd..41169e9 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -273,7 +273,7 @@ namespace llvm { /// Gets a symbol that will be defined to the final stack offset of a local /// variable after codegen. /// - /// \param Idx - The index of a local variable passed to @llvm.frameescape. + /// \param Idx - The index of a local variable passed to @llvm.localescape. MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx); MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName); diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index c7bed8e..1e72dfe 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -54,13 +54,13 @@ struct MCDwarfFile { /// \brief Instances of this class represent the information from a /// dwarf .loc directive. class MCDwarfLoc { - unsigned FileNum; - unsigned Line; - unsigned Column; + uint32_t FileNum; + uint32_t Line; + uint16_t Column; // Flags (see #define's below) - unsigned Flags; - unsigned Isa; - unsigned Discriminator; + uint8_t Flags; + uint8_t Isa; + uint32_t Discriminator; // Flag that indicates the initial value of the is_stmt_start flag. #define DWARF2_LINE_DEFAULT_IS_STMT 1 @@ -107,13 +107,22 @@ public: void setLine(unsigned line) { Line = line; } /// \brief Set the Column of this MCDwarfLoc. - void setColumn(unsigned column) { Column = column; } + void setColumn(unsigned column) { + assert(column <= UINT16_MAX); + Column = column; + } /// \brief Set the Flags of this MCDwarfLoc. - void setFlags(unsigned flags) { Flags = flags; } + void setFlags(unsigned flags) { + assert(flags <= UINT8_MAX); + Flags = flags; + } /// \brief Set the Isa of this MCDwarfLoc. - void setIsa(unsigned isa) { Isa = isa; } + void setIsa(unsigned isa) { + assert(isa <= UINT8_MAX); + Isa = isa; + } /// \brief Set the Discriminator of this MCDwarfLoc. void setDiscriminator(unsigned discriminator) { diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 3209a2c..6a582e8 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -154,7 +154,8 @@ public: // A complex method to determine is a certain is deprecated or not, and return // the reason for deprecation. - bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &); + bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &, + std::string &); /// \brief Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. @@ -170,7 +171,7 @@ public: /// \brief Returns true if a certain instruction is deprecated and if so /// returns the reason in \p Info. - bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI, + bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI, std::string &Info) const; /// \brief Return the opcode number for this descriptor. diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 1adfedd..c097916 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -224,25 +224,9 @@ struct MCSchedModel { return &SchedClassTable[SchedClassIdx]; } - // /\brief Returns a default initialized model. Used for unknown processors. - static MCSchedModel GetDefaultSchedModel() { - MCSchedModel Ret = { DefaultIssueWidth, - DefaultMicroOpBufferSize, - DefaultLoopMicroOpBufferSize, - DefaultLoadLatency, - DefaultHighLatency, - DefaultMispredictPenalty, - false, - true, - 0, - nullptr, - nullptr, - 0, - 0, - nullptr - }; - return Ret; - } + /// Returns the default initialized model. + static const MCSchedModel &GetDefaultSchedModel() { return Default; } + static const MCSchedModel Default; }; } // End llvm namespace diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index b8ad02f..d5ad4ee 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -37,22 +37,26 @@ class MCSubtargetInfo { const MCWriteProcResEntry *WriteProcResTable; const MCWriteLatencyEntry *WriteLatencyTable; const MCReadAdvanceEntry *ReadAdvanceTable; - MCSchedModel CPUSchedModel; + const MCSchedModel *CPUSchedModel; const InstrStage *Stages; // Instruction itinerary stages const unsigned *OperandCycles; // Itinerary operand cycles const unsigned *ForwardingPaths; // Forwarding paths FeatureBitset FeatureBits; // Feature bits for current CPU + FS + MCSubtargetInfo() = delete; + MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete; + MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete; + public: - void InitMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS, - ArrayRef<SubtargetFeatureKV> PF, - ArrayRef<SubtargetFeatureKV> PD, - const SubtargetInfoKV *ProcSched, - const MCWriteProcResEntry *WPR, - const MCWriteLatencyEntry *WL, - const MCReadAdvanceEntry *RA, const InstrStage *IS, - const unsigned *OC, const unsigned *FP); + MCSubtargetInfo(const MCSubtargetInfo &) = default; + MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS, + ArrayRef<SubtargetFeatureKV> PF, + ArrayRef<SubtargetFeatureKV> PD, + const SubtargetInfoKV *ProcSched, + const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, const InstrStage *IS, + const unsigned *OC, const unsigned *FP); /// getTargetTriple - Return the target triple string. const Triple &getTargetTriple() const { return TargetTriple; } @@ -74,12 +78,16 @@ public: FeatureBits = FeatureBits_; } - /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with - /// feature string). Recompute feature bits and scheduling model. +protected: + /// Initialize the scheduling model and feature bits. + /// + /// FIXME: Find a way to stick this in the constructor, since it should only + /// be called during initialization. void InitMCProcessorInfo(StringRef CPU, StringRef FS); - /// InitCPUSchedModel - Recompute scheduling model based on CPU. - void InitCPUSchedModel(StringRef CPU); +public: + /// Set the features to the default for the given CPU. + void setDefaultFeatures(StringRef CPU); /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version does not change the implied bits. @@ -99,11 +107,10 @@ public: /// getSchedModelForCPU - Get the machine model of a CPU. /// - MCSchedModel getSchedModelForCPU(StringRef CPU) const; + const MCSchedModel &getSchedModelForCPU(StringRef CPU) const; - /// getSchedModel - Get the machine model for this subtarget's CPU. - /// - const MCSchedModel &getSchedModel() const { return CPUSchedModel; } + /// Get the machine model for this subtarget's CPU. + const MCSchedModel &getSchedModel() const { return *CPUSchedModel; } /// Return an iterator at the first process resource consumed by the given /// scheduling class. @@ -151,7 +158,7 @@ public: void initInstrItins(InstrItineraryData &InstrItins) const; /// Check whether the CPU string is valid. - bool isCPUStringValid(StringRef CPU) { + bool isCPUStringValid(StringRef CPU) const { auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(), [=](const SubtargetFeatureKV &KV) { return CPU == KV.Key; diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 17e6b85..b2910df 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -114,12 +114,12 @@ protected: /// The alignment is stored as log2(align) + 1. This allows all values from /// 0 to 2^31 to be stored which is every power of 2 representable by an /// unsigned. - static const unsigned NumCommonAlignmentBits = 5; + enum : unsigned { NumCommonAlignmentBits = 5 }; unsigned CommonAlignLog2 : NumCommonAlignmentBits; /// The Flags field is used by object file implementations to store /// additional per symbol information which is not easily classified. - static const unsigned NumFlagsBits = 16; + enum : unsigned { NumFlagsBits = 16 }; mutable uint32_t Flags : NumFlagsBits; /// Index field, for use by the object file implementation. diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h index 166ae9e..5b0321f 100644 --- a/include/llvm/MC/MCSymbolMachO.h +++ b/include/llvm/MC/MCSymbolMachO.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCSYMBOLMACHO_H -#define setIsWeakExternal +#define LLVM_MC_MCSYMBOLMACHO_H #include "llvm/MC/MCSymbol.h" diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h index ce28a19..7f4f23e 100644 --- a/include/llvm/MC/MCTargetOptions.h +++ b/include/llvm/MC/MCTargetOptions.h @@ -55,7 +55,7 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) { ARE_EQUAL(ShowMCInst) && ARE_EQUAL(AsmVerbose) && ARE_EQUAL(DwarfVersion) && - ARE_EQUAL(ABIName)); + ARE_EQUAL(ABIName)); #undef ARE_EQUAL } diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 8da6919..597f0d4 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -94,9 +94,7 @@ public: /// \return the size in the archive header for this member. uint64_t getRawSize() const; - StringRef getBuffer() const { - return StringRef(Data.data() + StartOfFile, getSize()); - } + ErrorOr<StringRef> getBuffer() const; uint64_t getChildOffset() const; ErrorOr<MemoryBufferRef> getMemoryBufferRef() const; @@ -183,6 +181,7 @@ public: }; Kind kind() const { return (Kind)Format; } + bool isThin() const { return IsThin; } child_iterator child_begin(bool SkipInternal = true) const; child_iterator child_end() const; @@ -207,6 +206,11 @@ public: bool hasSymbolTable() const; child_iterator getSymbolTableChild() const { return SymbolTable; } + StringRef getSymbolTable() const { + // We know that the symbol table is not an external file, + // so we just assert there is no error. + return *SymbolTable->getBuffer(); + } uint32_t getNumberOfSymbols() const; private: @@ -215,6 +219,7 @@ private: child_iterator FirstRegular; unsigned Format : 2; unsigned IsThin : 1; + mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers; }; } diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h index 1616e46..3648d0c 100644 --- a/include/llvm/Object/ArchiveWriter.h +++ b/include/llvm/Object/ArchiveWriter.h @@ -31,7 +31,6 @@ class NewArchiveIterator { public: NewArchiveIterator(object::Archive::child_iterator I, StringRef Name); NewArchiveIterator(StringRef I, StringRef Name); - NewArchiveIterator(); bool isNewMember() const; StringRef getName() const; @@ -44,8 +43,7 @@ public: std::pair<StringRef, std::error_code> writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, - bool WriteSymtab); - + bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic); } #endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index fc60582..025a9db 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -474,7 +474,7 @@ struct coff_import_header { support::ulittle16_t OrdinalHint; support::ulittle16_t TypeInfo; int getType() const { return TypeInfo & 0x3; } - int getNameType() const { return (TypeInfo & 0x7) >> 2; } + int getNameType() const { return (TypeInfo >> 2) & 0x7; } }; struct coff_import_directory_table_entry { @@ -648,9 +648,8 @@ public: protected: void moveSymbolNext(DataRefImpl &Symb) const override; ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; - std::error_code getSymbolAddress(DataRefImpl Symb, - uint64_t &Res) const override; - uint64_t getSymbolValue(DataRefImpl Symb) const override; + ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; @@ -672,7 +671,6 @@ protected: relocation_iterator section_rel_end(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; uint64_t getRelocationType(DataRefImpl Rel) const override; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 3b0c548..cc27185 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" @@ -139,6 +140,7 @@ public: typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; typedef Elf_Versym_Impl<ELFT> Elf_Versym; + typedef Elf_Hash_Impl<ELFT> Elf_Hash; typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter; typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range; typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; @@ -174,8 +176,8 @@ private: StringRef DotShstrtab; // Section header string table. StringRef DotStrtab; // Symbol header string table. const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section. - StringRef DynSymStrTab; // Dynnamic symbol string table. const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. + const Elf_Hash *HashTable = nullptr; const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr; DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable; @@ -197,6 +199,7 @@ private: DynRegionInfo DynamicRegion; DynRegionInfo DynHashRegion; + DynRegionInfo DynStrRegion; DynRegionInfo DynRelaRegion; // Pointer to SONAME entry in dynamic string table @@ -229,6 +232,8 @@ private: void LoadVersionNeeds(const Elf_Shdr *ec) const; void LoadVersionMap() const; + void scanDynamicTable(); + public: template<typename T> const T *getEntry(uint32_t Section, uint32_t Entry) const; @@ -237,6 +242,7 @@ public: const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; } const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; } + const Elf_Hash *getHashTable() const { return HashTable; } ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const; const char *getDynamicString(uintX_t Offset) const; @@ -578,8 +584,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) Header = reinterpret_cast<const Elf_Ehdr *>(base()); - if (Header->e_shoff == 0) + if (Header->e_shoff == 0) { + scanDynamicTable(); return; + } const uint64_t SectionTableOffset = Header->e_shoff; @@ -604,6 +612,13 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) for (const Elf_Shdr &Sec : sections()) { switch (Sec.sh_type) { + case ELF::SHT_HASH: + if (HashTable) { + EC = object_error::parse_failed; + return; + } + HashTable = reinterpret_cast<const Elf_Hash *>(base() + Sec.sh_offset); + break; case ELF::SHT_SYMTAB_SHNDX: if (SymbolTableSectionHeaderIndex) { // More than one .symtab_shndx! @@ -640,7 +655,9 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr); if ((EC = SymtabOrErr.getError())) return; - DynSymStrTab = *SymtabOrErr; + DynStrRegion.Addr = SymtabOrErr->data(); + DynStrRegion.Size = SymtabOrErr->size(); + DynStrRegion.EntSize = 1; break; } case ELF::SHT_DYNAMIC: @@ -701,7 +718,23 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) } } - // Scan program headers. + scanDynamicTable(); + + EC = std::error_code(); +} + +template <class ELFT> +void ELFFile<ELFT>::scanDynamicTable() { + // Build load-address to file-offset map. + typedef IntervalMap< + uintX_t, uintptr_t, + IntervalMapImpl::NodeSizer<uintX_t, uintptr_t>::LeafSize, + IntervalMapHalfOpenInfo<uintX_t>> LoadMapT; + typename LoadMapT::Allocator Alloc; + // Allocate the IntervalMap on the heap to work around MSVC bug where the + // stack doesn't get realigned despite LoadMap having alignment 8 (PR24113). + std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc)); + for (Elf_Phdr_Iter PhdrI = program_header_begin(), PhdrE = program_header_end(); PhdrI != PhdrE; ++PhdrI) { @@ -709,34 +742,44 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) DynamicRegion.Addr = base() + PhdrI->p_offset; DynamicRegion.Size = PhdrI->p_filesz; DynamicRegion.EntSize = sizeof(Elf_Dyn); - break; + continue; } + if (PhdrI->p_type != ELF::PT_LOAD) + continue; + if (PhdrI->p_filesz == 0) + continue; + LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz, + PhdrI->p_offset); } - // Scan dynamic table. + auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * { + auto I = LoadMap->find(VAddr); + if (I == LoadMap->end()) + return nullptr; + return this->base() + I.value() + (VAddr - I.start()); + }; + for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end(); DynI != DynE; ++DynI) { switch (DynI->d_tag) { - case ELF::DT_RELA: { - uint64_t VBase = 0; - const uint8_t *FBase = nullptr; - for (Elf_Phdr_Iter PhdrI = program_header_begin(), - PhdrE = program_header_end(); - PhdrI != PhdrE; ++PhdrI) { - if (PhdrI->p_type != ELF::PT_LOAD) - continue; - if (DynI->getPtr() >= PhdrI->p_vaddr && - DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) { - VBase = PhdrI->p_vaddr; - FBase = base() + PhdrI->p_offset; - break; - } - } - if (!VBase) - return; - DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase; + case ELF::DT_HASH: + if (HashTable) + continue; + HashTable = + reinterpret_cast<const Elf_Hash *>(toMappedAddr(DynI->getPtr())); + break; + case ELF::DT_STRTAB: + if (!DynStrRegion.Addr) + DynStrRegion.Addr = toMappedAddr(DynI->getPtr()); + break; + case ELF::DT_STRSZ: + if (!DynStrRegion.Size) + DynStrRegion.Size = DynI->getVal(); + break; + case ELF::DT_RELA: + if (!DynRelaRegion.Addr) + DynRelaRegion.Addr = toMappedAddr(DynI->getPtr()); break; - } case ELF::DT_RELASZ: DynRelaRegion.Size = DynI->getVal(); break; @@ -744,8 +787,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) DynRelaRegion.EntSize = DynI->getVal(); } } - - EC = std::error_code(); } template <class ELFT> @@ -868,9 +909,9 @@ ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const { template <class ELFT> const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const { - if (!DotDynSymSec || Offset >= DynSymStrTab.size()) + if (Offset >= DynStrRegion.Size) return nullptr; - return (const char *)DynSymStrTab.begin() + Offset; + return (const char *)DynStrRegion.Addr + Offset; } template <class ELFT> @@ -983,7 +1024,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, IsDefault = false; } - if (name_offset >= DynSymStrTab.size()) + if (name_offset >= DynStrRegion.Size) return object_error::parse_failed; return StringRef(getDynamicString(name_offset)); } diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 5b9b113..6e8ace4 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -196,9 +196,8 @@ protected: void moveSymbolNext(DataRefImpl &Symb) const override; ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; - std::error_code getSymbolAddress(DataRefImpl Symb, - uint64_t &Res) const override; - uint64_t getSymbolValue(DataRefImpl Symb) const override; + ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; uint32_t getSymbolAlignment(DataRefImpl Symb) const override; uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; @@ -226,7 +225,6 @@ protected: section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; uint64_t getRelocationType(DataRefImpl Rel) const override; @@ -235,7 +233,6 @@ protected: uint32_t getSectionType(DataRefImpl Sec) const override; uint64_t getSectionFlags(DataRefImpl Sec) const override; - uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; /// \brief Get the relocation section that contains \a Rel. @@ -276,11 +273,6 @@ protected: return DRI; } - Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const { - return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(), - reinterpret_cast<const char *>(Dyn.p)); - } - DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const { DataRefImpl DRI; DRI.p = reinterpret_cast<uintptr_t>(Dyn.get()); @@ -378,19 +370,13 @@ uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const { } template <class ELFT> -uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const { +uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const { const Elf_Sym *ESym = getSymbol(Symb); - switch (ESym->st_shndx) { - case ELF::SHN_COMMON: - case ELF::SHN_UNDEF: - return UnknownAddress; - case ELF::SHN_ABS: - return ESym->st_value; - } - - const Elf_Ehdr *Header = EF.getHeader(); uint64_t Ret = ESym->st_value; + if (ESym->st_shndx == ELF::SHN_ABS) + return Ret; + const Elf_Ehdr *Header = EF.getHeader(); // Clear the ARM/Thumb or microMIPS indicator flag. if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) && ESym->getType() == ELF::STT_FUNC) @@ -400,15 +386,15 @@ uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const { } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { - Result = getSymbolValue(Symb); +ErrorOr<uint64_t> +ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const { + uint64_t Result = getSymbolValue(Symb); const Elf_Sym *ESym = getSymbol(Symb); switch (ESym->st_shndx) { case ELF::SHN_COMMON: case ELF::SHN_UNDEF: case ELF::SHN_ABS: - return std::error_code(); + return Result; } const Elf_Ehdr *Header = EF.getHeader(); @@ -422,7 +408,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, Result += Section->sh_addr; } - return std::error_code(); + return Result; } template <class ELFT> @@ -689,31 +675,9 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { } template <class ELFT> -ErrorOr<uint64_t> -ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel) const { - uint64_t ROffset = getROffset(Rel); - const Elf_Ehdr *Header = EF.getHeader(); - - if (Header->e_type == ELF::ET_REL) { - const Elf_Shdr *RelocationSec = getRelSection(Rel); - ErrorOr<const Elf_Shdr *> RelocatedSec = - EF.getSection(RelocationSec->sh_info); - if (std::error_code EC = RelocatedSec.getError()) - return EC; - return ROffset + (*RelocatedSec)->sh_addr; - } - return ROffset; -} - -template <class ELFT> uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const { assert(EF.getHeader()->e_type == ELF::ET_REL && "Only relocatable object files have relocation offsets"); - return getROffset(Rel); -} - -template <class ELFT> -uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { const Elf_Shdr *sec = getRelSection(Rel); if (sec->sh_type == ELF::SHT_REL) return getRel(Rel)->r_offset; diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 63e1390..27e987b 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -10,6 +10,7 @@ #ifndef LLVM_OBJECT_ELFTYPES_H #define LLVM_OBJECT_ELFTYPES_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Object/Error.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" @@ -463,6 +464,23 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> { Elf_Xword p_align; // Segment alignment constraint }; +// ELFT needed for endianess. +template <class ELFT> +struct Elf_Hash_Impl { + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Elf_Word nbucket; + Elf_Word nchain; + + ArrayRef<Elf_Word> buckets() const { + return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket); + } + + ArrayRef<Elf_Word> chains() const { + return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket, + &nbucket + 2 + nbucket + nchain); + } +}; + // MIPS .reginfo section template <class ELFT> struct Elf_Mips_RegInfo; diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index b455079..df0aa50 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -85,7 +85,13 @@ struct SectionOrType { }; struct Section { - enum class SectionKind { Group, RawContent, Relocation, MipsABIFlags }; + enum class SectionKind { + Group, + RawContent, + Relocation, + NoBits, + MipsABIFlags + }; SectionKind Kind; StringRef Name; ELF_SHT Type; @@ -106,6 +112,14 @@ struct RawContentSection : Section { } }; +struct NoBitsSection : Section { + llvm::yaml::Hex64 Size; + NoBitsSection() : Section(SectionKind::NoBits) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::NoBits; + } +}; + struct Group : Section { // Members of a group contain a flag and a list of section indices // that are part of the group. diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index f4edfd0..489ecef 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -205,9 +205,7 @@ public: std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; unsigned getSectionType(SectionRef Sec) const; - std::error_code getSymbolAddress(DataRefImpl Symb, - uint64_t &Res) const override; - uint64_t getSymbolValue(DataRefImpl Symb) const override; + ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; uint32_t getSymbolAlignment(DataRefImpl Symb) const override; uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; SymbolRef::Type getSymbolType(DataRefImpl Symb) const override; @@ -233,7 +231,6 @@ public: relocation_iterator section_rel_end(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override; uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; section_iterator getRelocationSection(DataRefImpl Rel) const; @@ -245,6 +242,8 @@ public: // MachO specific. std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; + section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const; + // TODO: Would be useful to have an iterator based version // of the load command interface too. @@ -425,6 +424,8 @@ public: } private: + uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; + union { MachO::mach_header_64 Header64; MachO::mach_header Header; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 62eab10..8dd5256 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -50,7 +50,6 @@ public: void moveNext(); - ErrorOr<uint64_t> getAddress() const; uint64_t getOffset() const; symbol_iterator getSymbol() const; uint64_t getType() const; @@ -135,7 +134,7 @@ public: ErrorOr<StringRef> getName() const; /// Returns the symbol virtual address (i.e. address at which it will be /// mapped). - std::error_code getAddress(uint64_t &Result) const; + ErrorOr<uint64_t> getAddress() const; /// Return the value of the symbol depending on the object this can be an /// offset or a virtual address. @@ -198,9 +197,8 @@ protected: virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0; std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override; - virtual std::error_code getSymbolAddress(DataRefImpl Symb, - uint64_t &Res) const = 0; - virtual uint64_t getSymbolValue(DataRefImpl Symb) const = 0; + virtual ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0; + virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0; virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0; virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0; @@ -229,13 +227,14 @@ protected: // Same as above for RelocationRef. friend class RelocationRef; virtual void moveRelocationNext(DataRefImpl &Rel) const = 0; - virtual ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const = 0; virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0; virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0; virtual void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const = 0; + uint64_t getSymbolValue(DataRefImpl Symb) const; + public: uint64_t getCommonSymbolSize(DataRefImpl Symb) const { assert(getSymbolFlags(Symb) & SymbolRef::SF_Common); @@ -308,8 +307,8 @@ inline ErrorOr<StringRef> SymbolRef::getName() const { return getObject()->getSymbolName(getRawDataRefImpl()); } -inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { - return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); +inline ErrorOr<uint64_t> SymbolRef::getAddress() const { + return getObject()->getSymbolAddress(getRawDataRefImpl()); } inline uint64_t SymbolRef::getValue() const { @@ -430,10 +429,6 @@ inline void RelocationRef::moveNext() { return OwningObject->moveRelocationNext(RelocationPimpl); } -inline ErrorOr<uint64_t> RelocationRef::getAddress() const { - return OwningObject->getRelocationAddress(RelocationPimpl); -} - inline uint64_t RelocationRef::getOffset() const { return OwningObject->getRelocationOffset(RelocationPimpl); } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 950e2ed..d5e4258 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -100,9 +100,9 @@ private: case Triple::mips64: switch (RelocType) { case llvm::ELF::R_MIPS_32: - return visitELF_MIPS_32(R, Value); + return visitELF_MIPS64_32(R, Value); case llvm::ELF::R_MIPS_64: - return visitELF_MIPS_64(R, Value); + return visitELF_MIPS64_64(R, Value); default: HasError = true; return RelocToApply(); @@ -313,11 +313,18 @@ private: /// MIPS ELF RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { - uint32_t Res = (Value)&0xFFFFFFFF; + uint32_t Res = Value & 0xFFFFFFFF; + return RelocToApply(Res, 4); + } + + /// MIPS64 ELF + RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { + int64_t Addend = getELFAddend(R); + uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } - RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) { + RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); uint64_t Res = (Value + Addend); return RelocToApply(Res, 8); diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 3a38231..537997a 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -115,8 +115,6 @@ public: typedef content_iterator<BasicSymbolRef> basic_symbol_iterator; -const uint64_t UnknownAddress = ~0ULL; - class SymbolicFile : public Binary { public: ~SymbolicFile() override; diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index b26af61..3c5ee06 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -655,6 +655,7 @@ namespace COFF { }; enum CodeViewIdentifiers { + DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS = 0x1, DEBUG_SECTION_MAGIC = 0x4, DEBUG_SYMBOL_SUBSECTION = 0xF1, DEBUG_LINE_TABLE_SUBSECTION = 0xF2, diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index ed80921..379d06a 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -790,7 +790,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); +extern template class basic_parser<bool>; //-------------------------------------------------- // parser<boolOrDefault> @@ -816,7 +816,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>); +extern template class basic_parser<boolOrDefault>; //-------------------------------------------------- // parser<int> @@ -838,7 +838,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>); +extern template class basic_parser<int>; //-------------------------------------------------- // parser<unsigned> @@ -860,7 +860,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>); +extern template class basic_parser<unsigned>; //-------------------------------------------------- // parser<unsigned long long> @@ -885,7 +885,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>); +extern template class basic_parser<unsigned long long>; //-------------------------------------------------- // parser<double> @@ -907,7 +907,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>); +extern template class basic_parser<double>; //-------------------------------------------------- // parser<float> @@ -929,7 +929,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>); +extern template class basic_parser<float>; //-------------------------------------------------- // parser<std::string> @@ -954,7 +954,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>); +extern template class basic_parser<std::string>; //-------------------------------------------------- // parser<char> @@ -979,7 +979,7 @@ public: void anchor() override; }; -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>); +extern template class basic_parser<char>; //-------------------------------------------------- // PrintOptionDiff @@ -1254,11 +1254,11 @@ public: } }; -EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>); -EXTERN_TEMPLATE_INSTANTIATION(class opt<int>); -EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>); -EXTERN_TEMPLATE_INSTANTIATION(class opt<char>); -EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>); +extern template class opt<unsigned>; +extern template class opt<int>; +extern template class opt<std::string>; +extern template class opt<char>; +extern template class opt<bool>; //===----------------------------------------------------------------------===// // list_storage class diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 67ef23d..1416398 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -174,19 +174,6 @@ #define LLVM_UNLIKELY(EXPR) (EXPR) #endif -// C++ doesn't support 'extern template' of template specializations. GCC does, -// but requires __extension__ before it. In the header, use this: -// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>); -// in the .cpp file, use this: -// TEMPLATE_INSTANTIATION(class foo<bar>); -#ifdef __GNUC__ -#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X -#define TEMPLATE_INSTANTIATION(X) template X -#else -#define EXTERN_TEMPLATE_INSTANTIATION(X) -#define TEMPLATE_INSTANTIATION(X) -#endif - /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, /// mark a method "not for inlining". #if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0) diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h index 0f097f2..08e277a 100644 --- a/include/llvm/Support/OnDiskHashTable.h +++ b/include/llvm/Support/OnDiskHashTable.h @@ -280,13 +280,19 @@ public: }; /// \brief Look up the stored data for a particular key. - iterator find(const external_key_type &EKey, Info *InfoPtr = 0) { - if (!InfoPtr) - InfoPtr = &InfoObj; - - using namespace llvm::support; + iterator find(const external_key_type &EKey, Info *InfoPtr = nullptr) { const internal_key_type &IKey = InfoObj.GetInternalKey(EKey); hash_value_type KeyHash = InfoObj.ComputeHash(IKey); + return find_hashed(IKey, KeyHash, InfoPtr); + } + + /// \brief Look up the stored data for a particular key with a known hash. + iterator find_hashed(const internal_key_type &IKey, hash_value_type KeyHash, + Info *InfoPtr = nullptr) { + using namespace llvm::support; + + if (!InfoPtr) + InfoPtr = &InfoObj; // Each bucket is just an offset into the hash table file. offset_type Idx = KeyHash & (NumBuckets - 1); diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index d2e8b95..40bf6fb 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -71,7 +71,7 @@ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx); -MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, +MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo); @@ -92,17 +92,18 @@ public: typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, const Triple &TT); - typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM, + typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(const Triple &TT, + Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info); - typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT); + typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT); typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(const Triple &TT, StringRef CPU, StringRef Features); typedef TargetMachine *(*TargetMachineCtorTy)( - const Target &T, StringRef TT, StringRef CPU, StringRef Features, + const Target &T, const Triple &TT, StringRef CPU, StringRef Features, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); // If it weren't for layering issues (this header is in llvm/Support, but @@ -150,7 +151,7 @@ public: typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(const Triple &TT, MCContext &Ctx); typedef MCSymbolizer *(*MCSymbolizerCtorTy)( - StringRef TT, LLVMOpInfoCallback GetOpInfo, + const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo); @@ -300,12 +301,12 @@ public: /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. /// - MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM, + MCCodeGenInfo *createMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) const { if (!MCCodeGenInfoCtorFn) return nullptr; - return MCCodeGenInfoCtorFn(Triple, RM, CM, OL); + return MCCodeGenInfoCtorFn(Triple(TT), RM, CM, OL); } /// createMCInstrInfo - Create a MCInstrInfo implementation. @@ -326,10 +327,10 @@ public: /// createMCRegInfo - Create a MCRegisterInfo implementation. /// - MCRegisterInfo *createMCRegInfo(StringRef Triple) const { + MCRegisterInfo *createMCRegInfo(StringRef TT) const { if (!MCRegInfoCtorFn) return nullptr; - return MCRegInfoCtorFn(Triple); + return MCRegInfoCtorFn(Triple(TT)); } /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. @@ -351,20 +352,20 @@ public: /// createTargetMachine - Create a target specific machine implementation /// for the specified \p Triple. /// - /// \param Triple This argument is used to determine the target machine + /// \param TT 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. TargetMachine * - createTargetMachine(StringRef Triple, StringRef CPU, StringRef Features, + createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, Reloc::Model RM = Reloc::Default, CodeModel::Model CM = CodeModel::Default, CodeGenOpt::Level OL = CodeGenOpt::Default) const { if (!TargetMachineCtorFn) return nullptr; - return TargetMachineCtorFn(*this, Triple, CPU, Features, Options, RM, CM, - OL); + return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM, + CM, OL); } /// createMCAsmBackend - Create a target specific assembly parser. @@ -529,7 +530,8 @@ public: std::unique_ptr<MCRelocationInfo> &&RelInfo) const { MCSymbolizerCtorTy Fn = MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer; - return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo)); + return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx, + std::move(RelInfo)); } /// @} @@ -924,7 +926,7 @@ template <class MCCodeGenInfoImpl> struct RegisterMCCodeGenInfo { } private: - static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/, + static MCCodeGenInfo *Allocator(const Triple & /*TT*/, Reloc::Model /*RM*/, CodeModel::Model /*CM*/, CodeGenOpt::Level /*OL*/) { return new MCCodeGenInfoImpl(); @@ -1023,7 +1025,7 @@ template <class MCRegisterInfoImpl> struct RegisterMCRegInfo { } private: - static MCRegisterInfo *Allocator(StringRef /*TT*/) { + static MCRegisterInfo *Allocator(const Triple & /*TT*/) { return new MCRegisterInfoImpl(); } }; @@ -1090,11 +1092,11 @@ template <class TargetMachineImpl> struct RegisterTargetMachine { } private: - static TargetMachine *Allocator(const Target &T, StringRef TT, StringRef CPU, - StringRef FS, const TargetOptions &Options, - Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) { - return new TargetMachineImpl(T, Triple(TT), CPU, FS, Options, RM, CM, OL); + static TargetMachine *Allocator(const Target &T, const Triple &TT, + StringRef CPU, StringRef FS, + const TargetOptions &Options, Reloc::Model RM, + CodeModel::Model CM, CodeGenOpt::Level OL) { + return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL); } }; diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index b593171..28e512c 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -165,8 +165,10 @@ public: if (Size > (size_t)(OutBufEnd - OutBufCur)) return write(Str.data(), Size); - memcpy(OutBufCur, Str.data(), Size); - OutBufCur += Size; + if (Size) { + memcpy(OutBufCur, Str.data(), Size); + OutBufCur += Size; + } return *this; } diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 717a2a4..b4642c9 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1222,11 +1222,11 @@ public: /// get the corresponding DefInit. DefInit *getDefInit(); - const std::vector<Init *> &getTemplateArgs() const { + ArrayRef<Init *> getTemplateArgs() const { return TemplateArgs; } - const std::vector<RecordVal> &getValues() const { return Values; } - const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } + ArrayRef<RecordVal> getValues() const { return Values; } + ArrayRef<Record *> getSuperClasses() const { return SuperClasses; } ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } bool isTemplateArg(Init *Name) const { diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 6123499..e0aea18 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -872,7 +872,7 @@ def LOAD_STACK_GUARD : Instruction { let hasSideEffects = 0; bit isPseudo = 1; } -def FRAME_ALLOC : Instruction { +def LOCAL_ESCAPE : Instruction { // This instruction is really just a label. It has to be part of the chain so // that it doesn't get dropped from the DAG, but it produces nothing and has // no side effects. @@ -1014,7 +1014,7 @@ class InstAlias<string Asm, dag Result, int Emit = 1> { // Predicates - Predicates that must be true for this to match. list<Predicate> Predicates = []; - // If the instruction specified in Result has defined an AsmMatchConverter + // If the instruction specified in Result has defined an AsmMatchConverter // then setting this to 1 will cause the alias to use the AsmMatchConverter // function when converting the OperandVector into an MCInst instead of the // function that is generated by the dag Result. diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 0e31724..3af2227 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -19,6 +19,7 @@ #include <vector> namespace llvm { + class BitVector; class CalleeSavedInfo; class MachineFunction; class RegScavenger; @@ -226,13 +227,15 @@ public: return 0; } - /// processFunctionBeforeCalleeSavedScan - This method is called immediately - /// before PrologEpilogInserter scans the physical registers used to determine - /// what callee saved registers should be spilled. This method is optional. - virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS = nullptr) const { - - } + /// This method determines which of the registers reported by + /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved. + /// The default implementation checks populates the \p SavedRegs bitset with + /// all registers which are modified in the function, targets may override + /// this function to save additional registers. + /// This method also sets up the register scavenger ensuring there is a free + /// register or a frameindex available. + virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS = nullptr) const; /// processFunctionBeforeFrameFinalized - This method is called immediately /// before the specified function's frame layout (MF.getFrameInfo()) is diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 277487f..4412d9b 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -161,27 +161,27 @@ protected: public: const TargetMachine &getTargetMachine() const { return TM; } - const DataLayout *getDataLayout() const { return TM.getDataLayout(); } - bool isBigEndian() const { return !IsLittleEndian; } - bool isLittleEndian() const { return IsLittleEndian; } virtual bool useSoftFloat() const { return false; } /// Return the pointer type for the given address space, defaults to /// the pointer type from the data layout. /// FIXME: The default needs to be removed once all the code is updated. - virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const; - unsigned getPointerSizeInBits(uint32_t AS = 0) const; - unsigned getPointerTypeSizeInBits(Type *Ty) const; - virtual MVT getScalarShiftAmountTy(EVT LHSTy) const; + MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const { + return MVT::getIntegerVT(DL.getPointerSizeInBits(AS)); + } + + /// EVT is not used in-tree, but is used by out-of-tree target. + /// A documentation for this function would be nice... + virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const; - EVT getShiftAmountTy(EVT LHSTy) const; + EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const; /// Returns the type to be used for the index operand of: /// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT, /// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR - virtual MVT getVectorIdxTy() const { - return getPointerTy(); + virtual MVT getVectorIdxTy(const DataLayout &DL) const { + return getPointerTy(DL); } /// Return true if the select operation is expensive for this target. @@ -327,7 +327,8 @@ public: } /// Return the ValueType of the result of SETCC operations. - virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const; + virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, + EVT VT) const; /// Return the ValueType for comparison libcalls. Comparions libcalls include /// floating point comparion calls, and Ordered/Unordered check calls on @@ -715,17 +716,18 @@ public: /// operations except for the pointer size. If AllowUnknown is true, this /// will return MVT::Other for types with no EVT counterpart (e.g. structs), /// otherwise it will assert. - EVT getValueType(Type *Ty, bool AllowUnknown = false) const { + EVT getValueType(const DataLayout &DL, Type *Ty, + bool AllowUnknown = false) const { // Lower scalar pointers to native pointer types. if (PointerType *PTy = dyn_cast<PointerType>(Ty)) - return getPointerTy(PTy->getAddressSpace()); + return getPointerTy(DL, PTy->getAddressSpace()); if (Ty->isVectorTy()) { VectorType *VTy = cast<VectorType>(Ty); Type *Elm = VTy->getElementType(); // Lower vectors of pointers to native pointer types. if (PointerType *PT = dyn_cast<PointerType>(Elm)) { - EVT PointerTy(getPointerTy(PT->getAddressSpace())); + EVT PointerTy(getPointerTy(DL, PT->getAddressSpace())); Elm = PointerTy.getTypeForEVT(Ty->getContext()); } @@ -736,14 +738,15 @@ public: } /// Return the MVT corresponding to this LLVM type. See getValueType. - MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const { - return getValueType(Ty, AllowUnknown).getSimpleVT(); + MVT getSimpleValueType(const DataLayout &DL, Type *Ty, + bool AllowUnknown = false) const { + return getValueType(DL, Ty, AllowUnknown).getSimpleVT(); } /// Return the desired alignment for ByVal or InAlloca aggregate function /// arguments in the caller parameter area. This is the actual alignment, not /// its logarithm. - virtual unsigned getByValTypeAlignment(Type *Ty) const; + virtual unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const; /// Return the type of registers that this ValueType will eventually require. MVT getRegisterType(MVT VT) const { @@ -818,8 +821,8 @@ public: /// When splitting a value of the specified type into parts, does the Lo /// or Hi part come first? This usually follows the endianness, except /// for ppcf128, where the Hi part always comes first. - bool hasBigEndianPartOrdering(EVT VT) const { - return isBigEndian() || VT == MVT::ppcf128; + bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const { + return DL.isBigEndian() || VT == MVT::ppcf128; } /// If true, the target has custom DAG combine transformations that it can @@ -1006,7 +1009,8 @@ public: int InstructionOpcodeToISD(unsigned Opcode) const; /// Estimate the cost of type-legalization and the legalized type. - std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; + std::pair<unsigned, MVT> getTypeLegalizationCost(const DataLayout &DL, + Type *Ty) const; /// @} @@ -1460,8 +1464,8 @@ public: /// 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; + virtual bool isLegalAddressingMode(const DataLayout &DL, 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. @@ -1470,10 +1474,10 @@ public: /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. /// TODO: Remove default argument - virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty, - unsigned AS = 0) const { + virtual int getScalingFactorCost(const DataLayout &DL, 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, AS)) + if (isLegalAddressingMode(DL, AM, Ty, AS)) return 0; return -1; } @@ -1734,9 +1738,6 @@ public: private: const TargetMachine &TM; - /// True if this is a little endian target. - bool IsLittleEndian; - /// Tells the code generator not to expand operations into sequences that use /// the select operations if possible. bool SelectIsExpensive; @@ -2414,6 +2415,7 @@ public: ArgListTy &getArgs() { return Args; } + }; /// This function lowers an abstract call to a function into an actual call. @@ -2485,7 +2487,8 @@ public: /// Return the register ID of the name passed in. Used by named register /// global variables extension. There is no target-independent behaviour /// so the default action is to bail. - virtual unsigned getRegisterByName(const char* RegName, EVT VT) const { + virtual unsigned getRegisterByName(const char* RegName, EVT VT, + SelectionDAG &DAG) const { report_fatal_error("Named registers not implemented for this target"); } @@ -2657,7 +2660,8 @@ public: /// specific constraints and their prefixes, and also tie in the associated /// operand values. If this returns an empty vector, and if the constraint /// string itself isn't empty, there was an error parsing. - virtual AsmOperandInfoVector ParseConstraints(const TargetRegisterInfo *TRI, + virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, + const TargetRegisterInfo *TRI, ImmutableCallSite CS) const; /// Examine constraint type and operand type and determine a weight value. @@ -2679,7 +2683,7 @@ public: SelectionDAG *DAG = nullptr) const; /// Given a constraint, return the type of constraint it is for this target. - virtual ConstraintType getConstraintType(const std::string &Constraint) const; + virtual ConstraintType getConstraintType(StringRef Constraint) const; /// Given a physical register constraint (e.g. {edx}), return the register /// number and the register class for the register. @@ -2692,10 +2696,9 @@ public: /// returns a register number of 0 and a null register class pointer. virtual std::pair<unsigned, const TargetRegisterClass *> getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, - const std::string &Constraint, MVT VT) const; + StringRef Constraint, MVT VT) const; - virtual unsigned - getInlineAsmMemConstraint(const std::string &ConstraintCode) const { + virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const { if (ConstraintCode == "i") return InlineAsm::Constraint_i; else if (ConstraintCode == "m") @@ -2823,9 +2826,9 @@ public: /// Given an LLVM IR type and return type attributes, compute the return value /// EVTs and flags, and optionally also the offsets, if the return value is /// being lowered to memory. -void GetReturnInfo(Type* ReturnType, AttributeSet attr, +void GetReturnInfo(Type *ReturnType, AttributeSet attr, SmallVectorImpl<ISD::OutputArg> &Outs, - const TargetLowering &TLI); + const TargetLowering &TLI, const DataLayout &DL); } // end llvm namespace diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 64a923b..06a2b13 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -212,8 +212,8 @@ public: /// supported, or false on success. virtual bool addPassesToEmitFile( PassManagerBase &, raw_pwrite_stream &, CodeGenFileType, - bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr, - AnalysisID /*StopAfter*/ = nullptr, + bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr, + AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr, MachineFunctionInitializer * /*MFInitializer*/ = nullptr) { return true; } @@ -260,8 +260,8 @@ public: /// emitted. Typically this will involve several steps of code generation. bool addPassesToEmitFile( PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, - bool DisableVerify = true, AnalysisID StartAfter = nullptr, - AnalysisID StopAfter = nullptr, + bool DisableVerify = true, AnalysisID StartBefore = nullptr, + AnalysisID StartAfter = nullptr, AnalysisID StopAfter = nullptr, MachineFunctionInitializer *MFInitializer = nullptr) override; /// Add passes to the specified pass manager to get machine code emitted with diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 1f9a5d4..5019719 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -118,10 +118,10 @@ enum { /// collectors and deoptimizations in either the callee or caller. STATEPOINT = 20, - /// Instruction that records the offset of a function's frame allocation in a - /// label. Created by the llvm.frameallocate intrinsic. It has two arguments: - /// the symbol for the label and the frame index of the stack allocation. - FRAME_ALLOC = 21, + /// Instruction that records the offset of a local stack allocation passed to + /// llvm.localescape. It has two arguments: the symbol for the label and the + /// frame index of the local stack allocation. + LOCAL_ESCAPE = 21, /// Loading instruction that may page fault, bundled with associated /// information on how to handle such a page fault. It is intended to support diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h index bacdd95..53db5aa 100644 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -20,8 +20,6 @@ namespace llvm { -class DataLayout; - //===----------------------------------------------------------------------===// /// TargetSelectionDAGInfo - Targets can subclass this to parameterize the /// SelectionDAG lowering and instruction selection process. @@ -30,13 +28,8 @@ class TargetSelectionDAGInfo { TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) = delete; void operator=(const TargetSelectionDAGInfo &) = delete; - const DataLayout *DL; - -protected: - const DataLayout *getDataLayout() const { return DL; } - public: - explicit TargetSelectionDAGInfo(const DataLayout *DL); + explicit TargetSelectionDAGInfo() = default; virtual ~TargetSelectionDAGInfo(); /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index e42c56a..07c0c66 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -44,9 +44,17 @@ template <typename T> class SmallVectorImpl; class TargetSubtargetInfo : public MCSubtargetInfo { TargetSubtargetInfo(const TargetSubtargetInfo &) = delete; void operator=(const TargetSubtargetInfo &) = delete; + TargetSubtargetInfo() = delete; protected: // Can only create subclasses... - TargetSubtargetInfo(); + TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS, + ArrayRef<SubtargetFeatureKV> PF, + ArrayRef<SubtargetFeatureKV> PD, + const SubtargetInfoKV *ProcSched, + const MCWriteProcResEntry *WPR, + const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, const InstrStage *IS, + const unsigned *OC, const unsigned *FP); public: // AntiDepBreakMode - Type of anti-dependence breaking that should diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index fbd999c..2ea4730 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -71,6 +71,12 @@ ModulePass *createGlobalOptimizerPass(); ModulePass *createGlobalDCEPass(); //===----------------------------------------------------------------------===// +/// This transform is designed to eliminate available external globals +/// (functions or global variables) +/// +ModulePass *createEliminateAvailableExternallyPass(); + +//===----------------------------------------------------------------------===// /// createGVExtractionPass - If deleteFn is true, this pass deletes /// the specified global values. Otherwise, it deletes as much of the module as /// possible, except for the global values specified. diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index 5d574ae..1334dd0 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -121,6 +121,7 @@ public: bool VerifyInput; bool VerifyOutput; bool MergeFunctions; + bool PrepareForLTO; private: /// ExtensionList - This is list of all of the extensions that are registered. diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index cb187ec..2caa9a2 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -45,6 +45,7 @@ class LoopInfo; class AllocaInst; class AliasAnalysis; class AssumptionCacheTracker; +class DominatorTree; /// CloneModule - Return an exact copy of the specified module /// @@ -233,6 +234,21 @@ bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, bool InsertLifetime = true); +/// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p +/// Blocks. +/// +/// Updates LoopInfo and DominatorTree assuming the loop is dominated by block +/// \p LoopDomBB. Insert the new blocks before block specified in \p Before. +Loop *cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, + Loop *OrigLoop, ValueToValueMapTy &VMap, + const Twine &NameSuffix, LoopInfo *LI, + DominatorTree *DT, + SmallVectorImpl<BasicBlock *> &Blocks); + +/// \brief Remaps instructions in \p Blocks using the mapping in \p VMap. +void remapInstructionsInBlocks(const SmallVectorImpl<BasicBlock *> &Blocks, + ValueToValueMapTy &VMap); + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/LoopVersioning.h b/include/llvm/Transforms/Utils/LoopVersioning.h new file mode 100644 index 0000000..009fba4 --- /dev/null +++ b/include/llvm/Transforms/Utils/LoopVersioning.h @@ -0,0 +1,100 @@ +//===- LoopVersioning.h - Utility to version a loop -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a utility class to perform loop versioning. The versioned +// loop speculates that otherwise may-aliasing memory accesses don't overlap and +// emits checks to prove this. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H +#define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H + +#include "llvm/Transforms/Utils/ValueMapper.h" + +namespace llvm { + +class Loop; +class LoopAccessInfo; +class LoopInfo; + +/// \brief This class emits a version of the loop where run-time checks ensure +/// that may-alias pointers can't overlap. +/// +/// It currently only supports single-exit loops and assumes that the loop +/// already has a preheader. +class LoopVersioning { +public: + LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI, + DominatorTree *DT, + const SmallVector<int, 8> *PtrToPartition = nullptr); + + /// \brief Returns true if we need memchecks to disambiguate may-aliasing + /// accesses. + bool needsRuntimeChecks() const; + + /// \brief Performs the CFG manipulation part of versioning the loop including + /// the DominatorTree and LoopInfo updates. + /// + /// The loop that was used to construct the class will be the "versioned" loop + /// i.e. the loop that will receive control if all the memchecks pass. + /// + /// This allows the loop transform pass to operate on the same loop regardless + /// of whether versioning was necessary or not: + /// + /// for each loop L: + /// analyze L + /// if versioning is necessary version L + /// transform L + void versionLoop(Pass *P); + + /// \brief Adds the necessary PHI nodes for the versioned loops based on the + /// loop-defined values used outside of the loop. + /// + /// This needs to be called after versionLoop if there are defs in the loop + /// that are used outside the loop. FIXME: this should be invoked internally + /// by versionLoop and made private. + void addPHINodes(const SmallVectorImpl<Instruction *> &DefsUsedOutside); + + /// \brief Returns the versioned loop. Control flows here if pointers in the + /// loop don't alias (i.e. all memchecks passed). (This loop is actually the + /// same as the original loop that we got constructed with.) + Loop *getVersionedLoop() { return VersionedLoop; } + + /// \brief Returns the fall-back loop. Control flows here if pointers in the + /// loop may alias (i.e. one of the memchecks failed). + Loop *getNonVersionedLoop() { return NonVersionedLoop; } + +private: + /// \brief The original loop. This becomes the "versioned" one. I.e., + /// control flows here if pointers in the loop don't alias. + Loop *VersionedLoop; + /// \brief The fall-back loop. I.e. control flows here if pointers in the + /// loop may alias (memchecks failed). + Loop *NonVersionedLoop; + + /// \brief For each memory pointer it contains the partitionId it is used in. + /// If nullptr, no partitioning is used. + /// + /// The I-th entry corresponds to I-th entry in LAI.getRuntimePointerCheck(). + /// If the pointer is used in multiple partitions the entry is set to -1. + const SmallVector<int, 8> *PtrToPartition; + + /// \brief This maps the instructions from VersionedLoop to their counterpart + /// in NonVersionedLoop. + ValueToValueMapTy VMap; + + /// \brief Analyses used. + const LoopAccessInfo &LAI; + LoopInfo *LI; + DominatorTree *DT; +}; +} + +#endif |