diff options
Diffstat (limited to 'include')
160 files changed, 2507 insertions, 1706 deletions
diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h index a82ef49cb167..cf8306aee762 100644 --- a/include/llvm-c/Transforms/Vectorize.h +++ b/include/llvm-c/Transforms/Vectorize.h @@ -33,7 +33,7 @@ extern "C" { * @{ */ -/** See llvm::createBBVectorizePass function. */ +/** DEPRECATED - Use LLVMAddSLPVectorizePass */ void LLVMAddBBVectorizePass(LLVMPassManagerRef PM); /** See llvm::createLoopVectorizePass function. */ diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index eac97501c759..daafd2fabe78 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -69,10 +69,15 @@ class AliasSet : public ilist_node<AliasSet> { if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey()) // We don't have a AAInfo yet. Set it to NewAAInfo. AAInfo = NewAAInfo; - else if (AAInfo != NewAAInfo) - // NewAAInfo conflicts with AAInfo. - AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey(); - + else { + AAMDNodes Intersection(AAInfo.intersect(NewAAInfo)); + if (!Intersection) { + // NewAAInfo conflicts with AAInfo. + AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey(); + return SizeChanged; + } + AAInfo = Intersection; + } return SizeChanged; } diff --git a/include/llvm/Analysis/CFLAliasAnalysisUtils.h b/include/llvm/Analysis/CFLAliasAnalysisUtils.h new file mode 100644 index 000000000000..981a8ddc2289 --- /dev/null +++ b/include/llvm/Analysis/CFLAliasAnalysisUtils.h @@ -0,0 +1,58 @@ +//=- CFLAliasAnalysisUtils.h - Utilities for CFL Alias Analysis ----*- C++-*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// \file +// These are the utilities/helpers used by the CFL Alias Analyses available in +// tree, i.e. Steensgaard's and Andersens'. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H +#define LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/ValueHandle.h" + +namespace llvm { +namespace cflaa { + +template <typename AAResult> struct FunctionHandle final : public CallbackVH { + FunctionHandle(Function *Fn, AAResult *Result) + : CallbackVH(Fn), Result(Result) { + assert(Fn != nullptr); + assert(Result != nullptr); + } + + void deleted() override { removeSelfFromCache(); } + void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } + +private: + AAResult *Result; + + void removeSelfFromCache() { + assert(Result != nullptr); + auto *Val = getValPtr(); + Result->evict(cast<Function>(Val)); + setValPtr(nullptr); + } +}; + +static inline const Function *parentFunctionOfValue(const Value *Val) { + if (auto *Inst = dyn_cast<Instruction>(Val)) { + auto *Bb = Inst->getParent(); + return Bb->getParent(); + } + + if (auto *Arg = dyn_cast<Argument>(Val)) + return Arg->getParent(); + return nullptr; +} // namespace cflaa +} // namespace llvm +} + +#endif // LLVM_ANALYSIS_CFLALIASANALYSISUTILS_H diff --git a/include/llvm/Analysis/CFLAndersAliasAnalysis.h b/include/llvm/Analysis/CFLAndersAliasAnalysis.h index f3520aa3fe82..4146ad4d18ac 100644 --- a/include/llvm/Analysis/CFLAndersAliasAnalysis.h +++ b/include/llvm/Analysis/CFLAndersAliasAnalysis.h @@ -18,8 +18,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CFLAliasAnalysisUtils.h" #include "llvm/IR/Function.h" -#include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" #include <forward_list> @@ -47,7 +47,7 @@ public: return false; } /// Evict the given function from cache - void evict(const Function &Fn); + void evict(const Function *Fn); /// \brief Get the alias summary for the given function /// Return nullptr if the summary is not found or not available @@ -57,27 +57,6 @@ public: AliasResult alias(const MemoryLocation &, const MemoryLocation &); private: - struct FunctionHandle final : public CallbackVH { - FunctionHandle(Function *Fn, CFLAndersAAResult *Result) - : CallbackVH(Fn), Result(Result) { - assert(Fn != nullptr); - assert(Result != nullptr); - } - - void deleted() override { removeSelfFromCache(); } - void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } - - private: - CFLAndersAAResult *Result; - - void removeSelfFromCache() { - assert(Result != nullptr); - auto *Val = getValPtr(); - Result->evict(*cast<Function>(Val)); - setValPtr(nullptr); - } - }; - /// \brief Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. const Optional<FunctionInfo> &ensureCached(const Function &); @@ -97,7 +76,7 @@ private: /// that simply has empty sets. DenseMap<const Function *, Optional<FunctionInfo>> Cache; - std::forward_list<FunctionHandle> Handles; + std::forward_list<cflaa::FunctionHandle<CFLAndersAAResult>> Handles; }; /// Analysis pass providing a never-invalidated alias analysis result. diff --git a/include/llvm/Analysis/CFLSteensAliasAnalysis.h b/include/llvm/Analysis/CFLSteensAliasAnalysis.h index 3aae9a1e9b2e..fd3fa5febcdf 100644 --- a/include/llvm/Analysis/CFLSteensAliasAnalysis.h +++ b/include/llvm/Analysis/CFLSteensAliasAnalysis.h @@ -19,6 +19,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CFLAliasAnalysisUtils.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" @@ -85,27 +86,6 @@ public: } private: - struct FunctionHandle final : public CallbackVH { - FunctionHandle(Function *Fn, CFLSteensAAResult *Result) - : CallbackVH(Fn), Result(Result) { - assert(Fn != nullptr); - assert(Result != nullptr); - } - - void deleted() override { removeSelfFromCache(); } - void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } - - private: - CFLSteensAAResult *Result; - - void removeSelfFromCache() { - assert(Result != nullptr); - auto *Val = getValPtr(); - Result->evict(cast<Function>(Val)); - setValPtr(nullptr); - } - }; - const TargetLibraryInfo &TLI; /// \brief Cached mapping of Functions to their StratifiedSets. @@ -114,7 +94,7 @@ private: /// have any kind of recursion, it is discernable from a function /// that simply has empty sets. DenseMap<Function *, Optional<FunctionInfo>> Cache; - std::forward_list<FunctionHandle> Handles; + std::forward_list<cflaa::FunctionHandle<CFLSteensAAResult>> Handles; FunctionInfo buildSetsFrom(Function *F); }; diff --git a/include/llvm/Analysis/IteratedDominanceFrontier.h b/include/llvm/Analysis/IteratedDominanceFrontier.h index af788c818f80..bd74d6bd14c3 100644 --- a/include/llvm/Analysis/IteratedDominanceFrontier.h +++ b/include/llvm/Analysis/IteratedDominanceFrontier.h @@ -86,7 +86,6 @@ public: private: DominatorTreeBase<BasicBlock> &DT; bool useLiveIn; - DenseMap<DomTreeNode *, unsigned> DomLevels; const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks; const SmallPtrSetImpl<BasicBlock *> *DefBlocks; }; diff --git a/include/llvm/Analysis/MemorySSA.h b/include/llvm/Analysis/MemorySSA.h index 462e4594266e..5cec2bfb0cfb 100644 --- a/include/llvm/Analysis/MemorySSA.h +++ b/include/llvm/Analysis/MemorySSA.h @@ -139,7 +139,7 @@ public: // Methods for support type inquiry through isa, cast, and // dyn_cast - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { unsigned ID = V->getValueID(); return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal; } @@ -241,7 +241,7 @@ public: /// \brief Get the access that produces the memory state used by this Use. MemoryAccess *getDefiningAccess() const { return getOperand(0); } - static inline bool classof(const Value *MA) { + static bool classof(const Value *MA) { return MA->getValueID() == MemoryUseVal || MA->getValueID() == MemoryDefVal; } @@ -297,7 +297,7 @@ public: // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } - static inline bool classof(const Value *MA) { + static bool classof(const Value *MA) { return MA->getValueID() == MemoryUseVal; } @@ -353,7 +353,7 @@ public: // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } - static inline bool classof(const Value *MA) { + static bool classof(const Value *MA) { return MA->getValueID() == MemoryDefVal; } @@ -526,7 +526,7 @@ public: return getIncomingValue(Idx); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == MemoryPhiVal; } diff --git a/include/llvm/Analysis/OptimizationDiagnosticInfo.h b/include/llvm/Analysis/OptimizationDiagnosticInfo.h index edd9140a3493..64dd0737a112 100644 --- a/include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ b/include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -34,7 +34,7 @@ class Value; /// /// It allows reporting when optimizations are performed and when they are not /// along with the reasons for it. Hotness information of the corresponding -/// code region can be included in the remark if DiagnosticHotnessRequested is +/// code region can be included in the remark if DiagnosticsHotnessRequested is /// enabled in the LLVM context. class OptimizationRemarkEmitter { public: @@ -45,10 +45,10 @@ public: /// analysis pass). /// /// Note that this ctor has a very different cost depending on whether - /// F->getContext().getDiagnosticHotnessRequested() is on or not. If it's off + /// F->getContext().getDiagnosticsHotnessRequested() is on or not. If it's off /// the operation is free. /// - /// Whereas if DiagnosticHotnessRequested is on, it is fairly expensive + /// Whereas if DiagnosticsHotnessRequested is on, it is fairly expensive /// operation since BFI and all its required analyses are computed. This is /// for example useful for CGSCC passes that can't use function analyses /// passes in the old PM. diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 16ee07fa3177..2e34928b28ad 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -37,18 +37,38 @@ #ifndef LLVM_ANALYSIS_REGIONINFO_H #define LLVM_ANALYSIS_REGIONINFO_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/IR/CFG.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> #include <map> #include <memory> #include <set> +#include <string> +#include <type_traits> +#include <vector> namespace llvm { +class DominanceFrontier; +class DominatorTree; +class Loop; +class LoopInfo; +struct PostDominatorTree; +class Region; +template <class RegionTr> class RegionBase; +class RegionInfo; +template <class RegionTr> class RegionInfoBase; +class RegionNode; + // Class to be specialized for different users of RegionInfo // (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to // pass around an unreasonable number of template parameters. @@ -59,37 +79,23 @@ struct RegionTraits { // RegionT // RegionNodeT // RegionInfoT - typedef typename FuncT_::UnknownRegionTypeError BrokenT; + using BrokenT = typename FuncT_::UnknownRegionTypeError; }; -class DominatorTree; -class DominanceFrontier; -class Loop; -class LoopInfo; -struct PostDominatorTree; -class raw_ostream; -class Region; -template <class RegionTr> -class RegionBase; -class RegionNode; -class RegionInfo; -template <class RegionTr> -class RegionInfoBase; - template <> struct RegionTraits<Function> { - typedef Function FuncT; - typedef BasicBlock BlockT; - typedef Region RegionT; - typedef RegionNode RegionNodeT; - typedef RegionInfo RegionInfoT; - typedef DominatorTree DomTreeT; - typedef DomTreeNode DomTreeNodeT; - typedef DominanceFrontier DomFrontierT; - typedef PostDominatorTree PostDomTreeT; - typedef Instruction InstT; - typedef Loop LoopT; - typedef LoopInfo LoopInfoT; + using FuncT = Function; + using BlockT = BasicBlock; + using RegionT = Region; + using RegionNodeT = RegionNode; + using RegionInfoT = RegionInfo; + using DomTreeT = DominatorTree; + using DomTreeNodeT = DomTreeNode; + using DomFrontierT = DominanceFrontier; + using PostDomTreeT = PostDominatorTree; + using InstT = Instruction; + using LoopT = Loop; + using LoopInfoT = LoopInfo; static unsigned getNumSuccessors(BasicBlock *BB) { return BB->getTerminator()->getNumSuccessors(); @@ -113,13 +119,10 @@ class RegionNodeBase { friend class RegionBase<Tr>; public: - typedef typename Tr::BlockT BlockT; - typedef typename Tr::RegionT RegionT; + using BlockT = typename Tr::BlockT; + using RegionT = typename Tr::RegionT; private: - RegionNodeBase(const RegionNodeBase &) = delete; - const RegionNodeBase &operator=(const RegionNodeBase &) = delete; - /// This is the entry basic block that starts this region node. If this is a /// BasicBlock RegionNode, then entry is just the basic block, that this /// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode. @@ -150,6 +153,9 @@ protected: : entry(Entry, isSubRegion), parent(Parent) {} public: + RegionNodeBase(const RegionNodeBase &) = delete; + RegionNodeBase &operator=(const RegionNodeBase &) = delete; + /// @brief Get the parent Region of this RegionNode. /// /// The parent Region is the Region this RegionNode belongs to. If for @@ -247,24 +253,22 @@ public: /// tree, the second one creates a graphical representation using graphviz. template <class Tr> class RegionBase : public RegionNodeBase<Tr> { - typedef typename Tr::FuncT FuncT; - typedef typename Tr::BlockT BlockT; - typedef typename Tr::RegionInfoT RegionInfoT; - typedef typename Tr::RegionT RegionT; - typedef typename Tr::RegionNodeT RegionNodeT; - typedef typename Tr::DomTreeT DomTreeT; - typedef typename Tr::LoopT LoopT; - typedef typename Tr::LoopInfoT LoopInfoT; - typedef typename Tr::InstT InstT; - - typedef GraphTraits<BlockT *> BlockTraits; - typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits; - typedef typename BlockTraits::ChildIteratorType SuccIterTy; - typedef typename InvBlockTraits::ChildIteratorType PredIterTy; - friend class RegionInfoBase<Tr>; - RegionBase(const RegionBase &) = delete; - const RegionBase &operator=(const RegionBase &) = delete; + + using FuncT = typename Tr::FuncT; + using BlockT = typename Tr::BlockT; + using RegionInfoT = typename Tr::RegionInfoT; + using RegionT = typename Tr::RegionT; + using RegionNodeT = typename Tr::RegionNodeT; + using DomTreeT = typename Tr::DomTreeT; + using LoopT = typename Tr::LoopT; + using LoopInfoT = typename Tr::LoopInfoT; + using InstT = typename Tr::InstT; + + using BlockTraits = GraphTraits<BlockT *>; + using InvBlockTraits = GraphTraits<Inverse<BlockT *>>; + using SuccIterTy = typename BlockTraits::ChildIteratorType; + using PredIterTy = typename InvBlockTraits::ChildIteratorType; // Information necessary to manage this Region. RegionInfoT *RI; @@ -274,12 +278,12 @@ class RegionBase : public RegionNodeBase<Tr> { // (The entry BasicBlock is part of RegionNode) BlockT *exit; - typedef std::vector<std::unique_ptr<RegionT>> RegionSet; + using RegionSet = std::vector<std::unique_ptr<RegionT>>; // The subregions of this region. RegionSet children; - typedef std::map<BlockT *, std::unique_ptr<RegionNodeT>> BBNodeMapT; + using BBNodeMapT = std::map<BlockT *, std::unique_ptr<RegionNodeT>>; // Save the BasicBlock RegionNodes that are element of this Region. mutable BBNodeMapT BBNodeMap; @@ -308,6 +312,9 @@ public: RegionBase(BlockT *Entry, BlockT *Exit, RegionInfoT *RI, DomTreeT *DT, RegionT *Parent = nullptr); + RegionBase(const RegionBase &) = delete; + RegionBase &operator=(const RegionBase &) = delete; + /// Delete the Region and all its subregions. ~RegionBase(); @@ -543,8 +550,8 @@ public: /// /// These iterators iterator over all subregions of this Region. //@{ - typedef typename RegionSet::iterator iterator; - typedef typename RegionSet::const_iterator const_iterator; + using iterator = typename RegionSet::iterator; + using const_iterator = typename RegionSet::const_iterator; iterator begin() { return children.begin(); } iterator end() { return children.end(); } @@ -563,12 +570,13 @@ public: class block_iterator_wrapper : public df_iterator< typename std::conditional<IsConst, const BlockT, BlockT>::type *> { - typedef df_iterator< - typename std::conditional<IsConst, const BlockT, BlockT>::type *> super; + using super = + df_iterator< + typename std::conditional<IsConst, const BlockT, BlockT>::type *>; public: - typedef block_iterator_wrapper<IsConst> Self; - typedef typename super::value_type value_type; + using Self = block_iterator_wrapper<IsConst>; + using value_type = typename super::value_type; // Construct the begin iterator. block_iterator_wrapper(value_type Entry, value_type Exit) @@ -592,8 +600,8 @@ public: } }; - typedef block_iterator_wrapper<false> block_iterator; - typedef block_iterator_wrapper<true> const_block_iterator; + using block_iterator = block_iterator_wrapper<false>; + using const_block_iterator = block_iterator_wrapper<true>; block_iterator block_begin() { return block_iterator(getEntry(), getExit()); } @@ -604,8 +612,8 @@ public: } const_block_iterator block_end() const { return const_block_iterator(); } - typedef iterator_range<block_iterator> block_range; - typedef iterator_range<const_block_iterator> const_block_range; + using block_range = iterator_range<block_iterator>; + using const_block_range = iterator_range<const_block_iterator>; /// @brief Returns a range view of the basic blocks in the region. inline block_range blocks() { @@ -626,14 +634,14 @@ public: /// are direct children of this Region. It does not iterate over any /// RegionNodes that are also element of a subregion of this Region. //@{ - typedef df_iterator<RegionNodeT *, df_iterator_default_set<RegionNodeT *>, - false, GraphTraits<RegionNodeT *>> - element_iterator; + using element_iterator = + df_iterator<RegionNodeT *, df_iterator_default_set<RegionNodeT *>, false, + GraphTraits<RegionNodeT *>>; - typedef df_iterator<const RegionNodeT *, - df_iterator_default_set<const RegionNodeT *>, false, - GraphTraits<const RegionNodeT *>> - const_element_iterator; + using const_element_iterator = + df_iterator<const RegionNodeT *, + df_iterator_default_set<const RegionNodeT *>, false, + GraphTraits<const RegionNodeT *>>; element_iterator element_begin(); element_iterator element_end(); @@ -661,29 +669,26 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase<Tr> &Node); /// Tree. template <class Tr> class RegionInfoBase { - typedef typename Tr::BlockT BlockT; - typedef typename Tr::FuncT FuncT; - typedef typename Tr::RegionT RegionT; - typedef typename Tr::RegionInfoT RegionInfoT; - typedef typename Tr::DomTreeT DomTreeT; - typedef typename Tr::DomTreeNodeT DomTreeNodeT; - typedef typename Tr::PostDomTreeT PostDomTreeT; - typedef typename Tr::DomFrontierT DomFrontierT; - typedef GraphTraits<BlockT *> BlockTraits; - typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits; - typedef typename BlockTraits::ChildIteratorType SuccIterTy; - typedef typename InvBlockTraits::ChildIteratorType PredIterTy; - friend class RegionInfo; friend class MachineRegionInfo; - typedef DenseMap<BlockT *, BlockT *> BBtoBBMap; - typedef DenseMap<BlockT *, RegionT *> BBtoRegionMap; - RegionInfoBase(); - virtual ~RegionInfoBase(); + using BlockT = typename Tr::BlockT; + using FuncT = typename Tr::FuncT; + using RegionT = typename Tr::RegionT; + using RegionInfoT = typename Tr::RegionInfoT; + using DomTreeT = typename Tr::DomTreeT; + using DomTreeNodeT = typename Tr::DomTreeNodeT; + using PostDomTreeT = typename Tr::PostDomTreeT; + using DomFrontierT = typename Tr::DomFrontierT; + using BlockTraits = GraphTraits<BlockT *>; + using InvBlockTraits = GraphTraits<Inverse<BlockT *>>; + using SuccIterTy = typename BlockTraits::ChildIteratorType; + using PredIterTy = typename InvBlockTraits::ChildIteratorType; + + using BBtoBBMap = DenseMap<BlockT *, BlockT *>; + using BBtoRegionMap = DenseMap<BlockT *, RegionT *>; - RegionInfoBase(const RegionInfoBase &) = delete; - const RegionInfoBase &operator=(const RegionInfoBase &) = delete; + RegionInfoBase(); RegionInfoBase(RegionInfoBase &&Arg) : DT(std::move(Arg.DT)), PDT(std::move(Arg.PDT)), DF(std::move(Arg.DF)), @@ -691,6 +696,7 @@ class RegionInfoBase { BBtoRegion(std::move(Arg.BBtoRegion)) { Arg.wipe(); } + RegionInfoBase &operator=(RegionInfoBase &&RHS) { DT = std::move(RHS.DT); PDT = std::move(RHS.PDT); @@ -701,12 +707,14 @@ class RegionInfoBase { return *this; } + virtual ~RegionInfoBase(); + DomTreeT *DT; PostDomTreeT *PDT; DomFrontierT *DF; /// The top level region. - RegionT *TopLevelRegion; + RegionT *TopLevelRegion = nullptr; /// Map every BB to the smallest region, that contains BB. BBtoRegionMap BBtoRegion; @@ -785,6 +793,9 @@ private: void calculate(FuncT &F); public: + RegionInfoBase(const RegionInfoBase &) = delete; + RegionInfoBase &operator=(const RegionInfoBase &) = delete; + static bool VerifyRegionInfo; static typename RegionT::PrintStyle printStyle; @@ -887,21 +898,22 @@ public: class RegionInfo : public RegionInfoBase<RegionTraits<Function>> { public: - typedef RegionInfoBase<RegionTraits<Function>> Base; + using Base = RegionInfoBase<RegionTraits<Function>>; explicit RegionInfo(); - ~RegionInfo() override; - RegionInfo(RegionInfo &&Arg) : Base(std::move(static_cast<Base &>(Arg))) { updateRegionTree(*this, TopLevelRegion); } + RegionInfo &operator=(RegionInfo &&RHS) { Base::operator=(std::move(static_cast<Base &>(RHS))); updateRegionTree(*this, TopLevelRegion); return *this; } + ~RegionInfo() override; + /// Handle invalidation explicitly. bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &); @@ -931,8 +943,8 @@ class RegionInfoPass : public FunctionPass { public: static char ID; - explicit RegionInfoPass(); + explicit RegionInfoPass(); ~RegionInfoPass() override; RegionInfo &getRegionInfo() { return RI; } @@ -953,10 +965,11 @@ public: /// \brief Analysis pass that exposes the \c RegionInfo for a function. class RegionInfoAnalysis : public AnalysisInfoMixin<RegionInfoAnalysis> { friend AnalysisInfoMixin<RegionInfoAnalysis>; + static AnalysisKey Key; public: - typedef RegionInfo Result; + using Result = RegionInfo; RegionInfo run(Function &F, FunctionAnalysisManager &AM); }; @@ -967,6 +980,7 @@ class RegionInfoPrinterPass : public PassInfoMixin<RegionInfoPrinterPass> { public: explicit RegionInfoPrinterPass(raw_ostream &OS); + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; @@ -995,8 +1009,8 @@ RegionNodeBase<RegionTraits<Function>>::getNodeAs<Region>() const { template <class Tr> inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase<Tr> &Node) { - typedef typename Tr::BlockT BlockT; - typedef typename Tr::RegionT RegionT; + using BlockT = typename Tr::BlockT; + using RegionT = typename Tr::RegionT; if (Node.isSubRegion()) return OS << Node.template getNodeAs<RegionT>()->getNameStr(); @@ -1008,5 +1022,6 @@ extern template class RegionBase<RegionTraits<Function>>; extern template class RegionNodeBase<RegionTraits<Function>>; extern template class RegionInfoBase<RegionTraits<Function>>; -} // End llvm namespace -#endif +} // end namespace llvm + +#endif // LLVM_ANALYSIS_REGIONINFO_H diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h index a16c534484b3..c0337b6daf37 100644 --- a/include/llvm/Analysis/RegionInfoImpl.h +++ b/include/llvm/Analysis/RegionInfoImpl.h @@ -12,7 +12,11 @@ #ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H #define LLVM_ANALYSIS_REGIONINFOIMPL_H +#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/PostDominators.h" @@ -20,9 +24,15 @@ #include "llvm/Analysis/RegionIterator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> +#include <cassert> #include <iterator> +#include <memory> #include <set> +#include <string> +#include <type_traits> +#include <vector> namespace llvm { @@ -303,7 +313,8 @@ RegionBase<Tr>::element_end() const { template <class Tr> typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const { - typedef typename Tr::RegionT RegionT; + using RegionT = typename Tr::RegionT; + RegionT *R = RI->getRegionFor(BB); if (!R || R == this) @@ -330,7 +341,8 @@ typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const { if (at == BBNodeMap.end()) { auto Deconst = const_cast<RegionBase<Tr> *>(this); typename BBNodeMapT::value_type V = { - BB, make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB)}; + BB, + llvm::make_unique<RegionNodeT>(static_cast<RegionT *>(Deconst), BB)}; at = BBNodeMap.insert(std::move(V)).first; } return at->second.get(); @@ -357,10 +369,10 @@ void RegionBase<Tr>::transferChildrenTo(RegionT *To) { template <class Tr> void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) { assert(!SubRegion->parent && "SubRegion already has a parent!"); - assert(find_if(*this, - [&](const std::unique_ptr<RegionT> &R) { - return R.get() == SubRegion; - }) == children.end() && + assert(llvm::find_if(*this, + [&](const std::unique_ptr<RegionT> &R) { + return R.get() == SubRegion; + }) == children.end() && "Subregion already exists!"); SubRegion->parent = static_cast<RegionT *>(this); @@ -402,7 +414,7 @@ typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) { assert(Child->parent == this && "Child is not a child of this region!"); Child->parent = nullptr; typename RegionSet::iterator I = - find_if(children, [&](const std::unique_ptr<RegionT> &R) { + llvm::find_if(children, [&](const std::unique_ptr<RegionT> &R) { return R.get() == Child; }); assert(I != children.end() && "Region does not exit. Unable to remove."); @@ -505,8 +517,7 @@ void RegionBase<Tr>::clearNodeCache() { // template <class Tr> -RegionInfoBase<Tr>::RegionInfoBase() - : TopLevelRegion(nullptr) {} +RegionInfoBase<Tr>::RegionInfoBase() = default; template <class Tr> RegionInfoBase<Tr>::~RegionInfoBase() { @@ -543,7 +554,8 @@ bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry, template <class Tr> bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const { assert(entry && exit && "entry and exit must not be null!"); - typedef typename DomFrontierT::DomSetType DST; + + using DST = typename DomFrontierT::DomSetType; DST *entrySuccs = &DF->find(entry)->second; @@ -689,7 +701,8 @@ void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry, template <class Tr> void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) { - typedef typename std::add_pointer<FuncT>::type FuncPtrT; + using FuncPtrT = typename std::add_pointer<FuncT>::type; + BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F); DomTreeNodeT *N = DT->getNode(entry); @@ -876,7 +889,7 @@ RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const { template <class Tr> void RegionInfoBase<Tr>::calculate(FuncT &F) { - typedef typename std::add_pointer<FuncT>::type FuncPtrT; + using FuncPtrT = typename std::add_pointer<FuncT>::type; // ShortCut a function where for every BB the exit of the largest region // starting with BB is stored. These regions can be threated as single BBS. @@ -892,4 +905,4 @@ void RegionInfoBase<Tr>::calculate(FuncT &F) { } // end namespace llvm -#endif +#endif // LLVM_ANALYSIS_REGIONINFOIMPL_H diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h index de2f3bf3f12b..4f823cc82210 100644 --- a/include/llvm/Analysis/RegionIterator.h +++ b/include/llvm/Analysis/RegionIterator.h @@ -8,17 +8,23 @@ //===----------------------------------------------------------------------===// // This file defines the iterators to iterate over the elements of a Region. //===----------------------------------------------------------------------===// + #ifndef LLVM_ANALYSIS_REGIONITERATOR_H #define LLVM_ANALYSIS_REGIONITERATOR_H +#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/IR/CFG.h" -#include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <iterator> +#include <type_traits> namespace llvm { + +class BasicBlock; + //===----------------------------------------------------------------------===// /// @brief Hierarchical RegionNode successor iterator. /// @@ -33,10 +39,9 @@ namespace llvm { template <class NodeRef, class BlockT, class RegionT> class RNSuccIterator : public std::iterator<std::forward_iterator_tag, NodeRef> { - typedef std::iterator<std::forward_iterator_tag, NodeRef> super; - - typedef GraphTraits<BlockT*> BlockTraits; - typedef typename BlockTraits::ChildIteratorType SuccIterTy; + using super = std::iterator<std::forward_iterator_tag, NodeRef>; + using BlockTraits = GraphTraits<BlockT *>; + using SuccIterTy = typename BlockTraits::ChildIteratorType; // The iterator works in two modes, bb mode or region mode. enum ItMode { @@ -92,16 +97,15 @@ class RNSuccIterator inline bool isExit(BlockT* BB) const { return getNode()->getParent()->getExit() == BB; } -public: - typedef RNSuccIterator<NodeRef, BlockT, RegionT> Self; - typedef typename super::value_type value_type; +public: + using Self = RNSuccIterator<NodeRef, BlockT, RegionT>; + using value_type = typename super::value_type; /// @brief Create begin iterator of a RegionNode. inline RNSuccIterator(NodeRef node) : Node(node, node->isSubRegion() ? ItRgBegin : ItBB), BItor(BlockTraits::child_begin(node->getEntry())) { - // Skip the exit block if (!isRegionMode()) while (BlockTraits::child_end(node->getEntry()) != BItor && isExit(*BItor)) @@ -153,7 +157,6 @@ public: } }; - //===----------------------------------------------------------------------===// /// @brief Flat RegionNode iterator. /// @@ -163,16 +166,16 @@ public: template <class NodeRef, class BlockT, class RegionT> class RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> : public std::iterator<std::forward_iterator_tag, NodeRef> { - typedef std::iterator<std::forward_iterator_tag, NodeRef> super; - typedef GraphTraits<BlockT*> BlockTraits; - typedef typename BlockTraits::ChildIteratorType SuccIterTy; + using super = std::iterator<std::forward_iterator_tag, NodeRef>; + using BlockTraits = GraphTraits<BlockT *>; + using SuccIterTy = typename BlockTraits::ChildIteratorType; NodeRef Node; SuccIterTy Itor; public: - typedef RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> Self; - typedef typename super::value_type value_type; + using Self = RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>; + using value_type = typename super::value_type; /// @brief Create the iterator from a RegionNode. /// @@ -255,8 +258,8 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) { #define RegionNodeGraphTraits(NodeT, BlockT, RegionT) \ template <> struct GraphTraits<NodeT *> { \ - typedef NodeT *NodeRef; \ - typedef RNSuccIterator<NodeRef, BlockT, RegionT> ChildIteratorType; \ + using NodeRef = NodeT *; \ + using ChildIteratorType = RNSuccIterator<NodeRef, BlockT, RegionT>; \ static NodeRef getEntryNode(NodeRef N) { return N; } \ static inline ChildIteratorType child_begin(NodeRef N) { \ return RNSuccIterator<NodeRef, BlockT, RegionT>(N); \ @@ -266,9 +269,9 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) { } \ }; \ template <> struct GraphTraits<FlatIt<NodeT *>> { \ - typedef NodeT *NodeRef; \ - typedef RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> \ - ChildIteratorType; \ + using NodeRef = NodeT *; \ + using ChildIteratorType = \ + RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>; \ static NodeRef getEntryNode(NodeRef N) { return N; } \ static inline ChildIteratorType child_begin(NodeRef N) { \ return RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>(N); \ @@ -280,7 +283,7 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) { #define RegionGraphTraits(RegionT, NodeT) \ template <> struct GraphTraits<RegionT *> : public GraphTraits<NodeT *> { \ - typedef df_iterator<NodeRef> nodes_iterator; \ + using nodes_iterator = df_iterator<NodeRef>; \ static NodeRef getEntryNode(RegionT *R) { \ return R->getNode(R->getEntry()); \ } \ @@ -294,9 +297,9 @@ inline RNSuccIterator<NodeRef, BlockT, RegionT> succ_end(NodeRef Node) { template <> \ struct GraphTraits<FlatIt<RegionT *>> \ : public GraphTraits<FlatIt<NodeT *>> { \ - typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, \ - GraphTraits<FlatIt<NodeRef>>> \ - nodes_iterator; \ + using nodes_iterator = \ + df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, \ + GraphTraits<FlatIt<NodeRef>>>; \ static NodeRef getEntryNode(RegionT *R) { \ return R->getBBNode(R->getEntry()); \ } \ @@ -315,17 +318,19 @@ RegionGraphTraits(Region, RegionNode); RegionGraphTraits(const Region, const RegionNode); template <> struct GraphTraits<RegionInfo*> - : public GraphTraits<FlatIt<RegionNode*> > { - typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, - GraphTraits<FlatIt<NodeRef>>> - nodes_iterator; + : public GraphTraits<FlatIt<RegionNode*>> { + using nodes_iterator = + df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, + GraphTraits<FlatIt<NodeRef>>>; static NodeRef getEntryNode(RegionInfo *RI) { - return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion()); + return GraphTraits<FlatIt<Region*>>::getEntryNode(RI->getTopLevelRegion()); } + static nodes_iterator nodes_begin(RegionInfo* RI) { return nodes_iterator::begin(getEntryNode(RI)); } + static nodes_iterator nodes_end(RegionInfo *RI) { return nodes_iterator::end(getEntryNode(RI)); } @@ -333,21 +338,23 @@ template <> struct GraphTraits<RegionInfo*> template <> struct GraphTraits<RegionInfoPass*> : public GraphTraits<RegionInfo *> { - typedef df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, - GraphTraits<FlatIt<NodeRef>>> - nodes_iterator; + using nodes_iterator = + df_iterator<NodeRef, df_iterator_default_set<NodeRef>, false, + GraphTraits<FlatIt<NodeRef>>>; static NodeRef getEntryNode(RegionInfoPass *RI) { return GraphTraits<RegionInfo*>::getEntryNode(&RI->getRegionInfo()); } + static nodes_iterator nodes_begin(RegionInfoPass* RI) { return GraphTraits<RegionInfo*>::nodes_begin(&RI->getRegionInfo()); } + static nodes_iterator nodes_end(RegionInfoPass *RI) { return GraphTraits<RegionInfo*>::nodes_end(&RI->getRegionInfo()); } }; -} // End namespace llvm +} // end namespace llvm -#endif +#endif // LLVM_ANALYSIS_REGIONITERATOR_H diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 002a3174fd19..c7accfae78b0 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -262,7 +262,7 @@ public: const SCEVConstant *getRHS() const { return RHS; } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVPredicate *P) { + static bool classof(const SCEVPredicate *P) { return P->getKind() == P_Equal; } }; @@ -360,7 +360,7 @@ public: bool isAlwaysTrue() const override; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVPredicate *P) { + static bool classof(const SCEVPredicate *P) { return P->getKind() == P_Wrap; } }; @@ -406,7 +406,7 @@ public: unsigned getComplexity() const override { return Preds.size(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVPredicate *P) { + static bool classof(const SCEVPredicate *P) { return P->getKind() == P_Union; } }; @@ -1197,20 +1197,8 @@ public: const SCEV *getConstant(const APInt &Val); const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty); - - typedef SmallDenseMap<std::pair<const SCEV *, Type *>, const SCEV *, 8> - ExtendCacheTy; - const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty); - const SCEV *getZeroExtendExprCached(const SCEV *Op, Type *Ty, - ExtendCacheTy &Cache); - const SCEV *getZeroExtendExprImpl(const SCEV *Op, Type *Ty, - ExtendCacheTy &Cache); - - const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty); - const SCEV *getSignExtendExprCached(const SCEV *Op, Type *Ty, - ExtendCacheTy &Cache); - const SCEV *getSignExtendExprImpl(const SCEV *Op, Type *Ty, - ExtendCacheTy &Cache); + const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); + const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty); const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 2c693bceb24d..56ddb5028d6d 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -46,7 +46,7 @@ namespace llvm { Type *getType() const { return V->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scConstant; } }; @@ -65,7 +65,7 @@ namespace llvm { Type *getType() const { return Ty; } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate || S->getSCEVType() == scZeroExtend || S->getSCEVType() == scSignExtend; @@ -82,7 +82,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scTruncate; } }; @@ -97,7 +97,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scZeroExtend; } }; @@ -112,7 +112,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scSignExtend; } }; @@ -167,7 +167,7 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr || S->getSCEVType() == scSMaxExpr || @@ -185,7 +185,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr || S->getSCEVType() == scSMaxExpr || @@ -217,7 +217,7 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr; } }; @@ -234,7 +234,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scMulExpr; } }; @@ -263,7 +263,7 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scUDivExpr; } }; @@ -345,7 +345,7 @@ namespace llvm { } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scAddRecExpr; } }; @@ -363,7 +363,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scSMaxExpr; } }; @@ -382,7 +382,7 @@ namespace llvm { public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scUMaxExpr; } }; @@ -428,7 +428,7 @@ namespace llvm { Type *getType() const { return getValPtr()->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEV *S) { + static bool classof(const SCEV *S) { return S->getSCEVType() == scUnknown; } }; diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index af2ebb7b6b44..68fbf640994c 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -216,9 +216,23 @@ public: /// other context they may not be folded. This routine can distinguish such /// cases. /// + /// \p Operands is a list of operands which can be a result of transformations + /// of the current operands. The number of the operands on the list must equal + /// to the number of the current operands the IR user has. Their order on the + /// list must be the same as the order of the current operands the IR user + /// has. + /// /// The returned cost is defined in terms of \c TargetCostConstants, see its /// comments for a detailed explanation of the cost values. - int getUserCost(const User *U) const; + int getUserCost(const User *U, ArrayRef<const Value *> Operands) const; + + /// \brief This is a helper function which calls the two-argument getUserCost + /// with \p Operands which are the current operands U has. + int getUserCost(const User *U) const { + SmallVector<const Value *, 4> Operands(U->value_op_begin(), + U->value_op_end()); + return getUserCost(U, Operands); + } /// \brief Return true if branch divergence exists. /// @@ -366,7 +380,8 @@ public: /// \brief Get target-customized preferences for the generic loop unrolling /// transformation. The caller will initialize UP with the current /// target-independent defaults. - void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const; + void getUnrollingPreferences(Loop *L, ScalarEvolution &, + UnrollingPreferences &UP) const; /// @} @@ -823,13 +838,15 @@ public: ArrayRef<const Value *> Arguments) = 0; virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JTSize) = 0; - virtual int getUserCost(const User *U) = 0; + virtual int + getUserCost(const User *U, ArrayRef<const Value *> Operands) = 0; virtual bool hasBranchDivergence() = 0; virtual bool isSourceOfDivergence(const Value *V) = 0; virtual bool isAlwaysUniform(const Value *V) = 0; virtual unsigned getFlatAddressSpace() = 0; virtual bool isLoweredToCall(const Function *F) = 0; - virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0; + virtual void getUnrollingPreferences(Loop *L, ScalarEvolution &, + UnrollingPreferences &UP) = 0; virtual bool isLegalAddImmediate(int64_t Imm) = 0; virtual bool isLegalICmpImmediate(int64_t Imm) = 0; virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, @@ -998,7 +1015,9 @@ public: ArrayRef<const Value *> Arguments) override { return Impl.getIntrinsicCost(IID, RetTy, Arguments); } - int getUserCost(const User *U) override { return Impl.getUserCost(U); } + int getUserCost(const User *U, ArrayRef<const Value *> Operands) override { + return Impl.getUserCost(U, Operands); + } bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); } bool isSourceOfDivergence(const Value *V) override { return Impl.isSourceOfDivergence(V); @@ -1015,8 +1034,9 @@ public: bool isLoweredToCall(const Function *F) override { return Impl.isLoweredToCall(F); } - void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) override { - return Impl.getUnrollingPreferences(L, UP); + void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, + UnrollingPreferences &UP) override { + return Impl.getUnrollingPreferences(L, SE, UP); } bool isLegalAddImmediate(int64_t Imm) override { return Impl.isLegalAddImmediate(Imm); diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 24ac3b1213e1..0246fc1c02cc 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -217,7 +217,8 @@ public: return true; } - void getUnrollingPreferences(Loop *, TTI::UnrollingPreferences &) {} + void getUnrollingPreferences(Loop *, ScalarEvolution &, + TTI::UnrollingPreferences &) {} bool isLegalAddImmediate(int64_t Imm) { return false; } @@ -684,14 +685,14 @@ public: return static_cast<T *>(this)->getIntrinsicCost(IID, RetTy, ParamTys); } - unsigned getUserCost(const User *U) { + unsigned getUserCost(const User *U, ArrayRef<const Value *> Operands) { if (isa<PHINode>(U)) return TTI::TCC_Free; // Model all PHI nodes as free. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { - SmallVector<Value *, 4> Indices(GEP->idx_begin(), GEP->idx_end()); - return static_cast<T *>(this)->getGEPCost( - GEP->getSourceElementType(), GEP->getPointerOperand(), Indices); + return static_cast<T *>(this)->getGEPCost(GEP->getSourceElementType(), + GEP->getPointerOperand(), + Operands.drop_front()); } if (auto CS = ImmutableCallSite(U)) { diff --git a/include/llvm/BinaryFormat/COFF.h b/include/llvm/BinaryFormat/COFF.h index df173a80e09b..b395db6eaa83 100644 --- a/include/llvm/BinaryFormat/COFF.h +++ b/include/llvm/BinaryFormat/COFF.h @@ -382,7 +382,7 @@ enum RelocationTypesARM64 { IMAGE_REL_ARM64_ADDR32 = 0x0001, IMAGE_REL_ARM64_ADDR32NB = 0x0002, IMAGE_REL_ARM64_BRANCH26 = 0x0003, - IMAGE_REL_ARM64_PAGEBASE_REL2 = 0x0004, + IMAGE_REL_ARM64_PAGEBASE_REL21 = 0x0004, IMAGE_REL_ARM64_REL21 = 0x0005, IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006, IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007, diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index ab927565d05d..80456a0808f2 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/include/llvm/BinaryFormat/Dwarf.h @@ -62,6 +62,9 @@ enum LLVMConstants : uint32_t { const uint32_t DW_CIE_ID = UINT32_MAX; const uint64_t DW64_CIE_ID = UINT64_MAX; +// Identifier of an invalid DIE offset in the .debug_info section. +const uint32_t DW_INVALID_OFFSET = UINT32_MAX; + enum Tag : uint16_t { #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID, #include "llvm/BinaryFormat/Dwarf.def" diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 470c20ddc7d9..eef473b20dde 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -112,6 +112,11 @@ struct WasmRelocation { int64_t Addend; // A value to add to the symbol. }; +struct WasmLinkingData { + uint32_t DataSize; + uint32_t DataAlignment; +}; + enum : unsigned { WASM_SEC_CUSTOM = 0, // Custom / User-defined section WASM_SEC_TYPE = 1, // Function signature declarations @@ -175,8 +180,10 @@ enum class ValType { // Linking metadata kinds. enum : unsigned { - WASM_STACK_POINTER = 0x1, - WASM_SYMBOL_INFO = 0x2, + WASM_STACK_POINTER = 0x1, + WASM_SYMBOL_INFO = 0x2, + WASM_DATA_SIZE = 0x3, + WASM_DATA_ALIGNMENT = 0x4, }; enum : unsigned { diff --git a/include/llvm/Bitcode/BitcodeReader.h b/include/llvm/Bitcode/BitcodeReader.h index 0e17e9a0a278..160ddad5761f 100644 --- a/include/llvm/Bitcode/BitcodeReader.h +++ b/include/llvm/Bitcode/BitcodeReader.h @@ -111,9 +111,14 @@ namespace llvm { struct BitcodeFileContents { std::vector<BitcodeModule> Mods; + StringRef Symtab, StrtabForSymtab; }; - /// Returns the contents of a bitcode file. + /// Returns the contents of a bitcode file. This includes the raw contents of + /// the symbol table embedded in the bitcode file. Clients which require a + /// symbol table should prefer to use irsymtab::read instead of this function + /// because it creates a reader for the irsymtab and handles upgrading bitcode + /// files without a symbol table or with an old symbol table. Expected<BitcodeFileContents> getBitcodeFileContents(MemoryBufferRef Buffer); /// Returns a list of modules in the specified bitcode buffer. diff --git a/include/llvm/Bitcode/BitcodeWriter.h b/include/llvm/Bitcode/BitcodeWriter.h index 7c3c4b2e0cbd..f8b7fb341e88 100644 --- a/include/llvm/Bitcode/BitcodeWriter.h +++ b/include/llvm/Bitcode/BitcodeWriter.h @@ -28,18 +28,34 @@ namespace llvm { std::unique_ptr<BitstreamWriter> Stream; StringTableBuilder StrtabBuilder{StringTableBuilder::RAW}; - bool WroteStrtab = false; + + // Owns any strings created by the irsymtab writer until we create the + // string table. + BumpPtrAllocator Alloc; + + bool WroteStrtab = false, WroteSymtab = false; void writeBlob(unsigned Block, unsigned Record, StringRef Blob); + std::vector<Module *> Mods; + public: /// Create a BitcodeWriter that writes to Buffer. BitcodeWriter(SmallVectorImpl<char> &Buffer); ~BitcodeWriter(); + /// Attempt to write a symbol table to the bitcode file. This must be called + /// at most once after all modules have been written. + /// + /// A reader does not require a symbol table to interpret a bitcode file; + /// the symbol table is needed only to improve link-time performance. So + /// this function may decide not to write a symbol table. It may so decide + /// if, for example, the target is unregistered or the IR is malformed. + void writeSymtab(); + /// Write the bitcode file's string table. This must be called exactly once - /// after all modules have been written. + /// after all modules and the optional symbol table have been written. void writeStrtab(); /// Copy the string table for another module into this bitcode file. This diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 4e3e177cac8f..5435e48ff424 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -22,7 +22,7 @@ namespace llvm { namespace bitc { -// The only top-level block types are MODULE, IDENTIFICATION and STRTAB. +// The only top-level block types are MODULE, IDENTIFICATION, STRTAB and SYMTAB. enum BlockIDs { // Blocks MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, @@ -57,6 +57,8 @@ enum BlockIDs { STRTAB_BLOCK_ID, FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID, + + SYMTAB_BLOCK_ID, }; /// Identification block contains a string that describes the producer details, @@ -571,6 +573,10 @@ enum StrtabCodes { STRTAB_BLOB = 1, }; +enum SymtabCodes { + SYMTAB_BLOB = 1, +}; + } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index 5eb7a0f61eec..a740df96899d 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -277,7 +277,8 @@ public: unsigned getInliningThresholdMultiplier() { return 1; } - void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP) { + void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, + TTI::UnrollingPreferences &UP) { // This unrolling functionality is target independent, but to provide some // motivation for its intended use, for x86: diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h index 3e9a9d514cb8..e7ce1946889e 100644 --- a/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering --*- C++ -*-===// +//===- llvm/CodeGen/GlobalISel/CallLowering.h - Call lowering ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,21 +15,31 @@ #ifndef LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H #define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/CodeGen/CallingConvLower.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/IR/Function.h" +#include "llvm/CodeGen/MachineValueType.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetCallingConv.h" +#include <cstdint> +#include <functional> namespace llvm { -// Forward declarations. + +class DataLayout; +class Function; class MachineIRBuilder; class MachineOperand; +struct MachinePointerInfo; +class MachineRegisterInfo; class TargetLowering; +class Type; class Value; class CallLowering { const TargetLowering *TLI; + public: struct ArgInfo { unsigned Reg; @@ -49,6 +59,12 @@ public: /// arugment should go, exactly what happens can vary slightly. This /// class abstracts the differences. struct ValueHandler { + ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, + CCAssignFn *AssignFn) + : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn) {} + + virtual ~ValueHandler() = default; + /// Materialize a VReg containing the address of the specified /// stack-based object. This is either based on a FrameIndex or /// direct SP manipulation, depending on the context. \p MPO @@ -89,12 +105,6 @@ public: return AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State); } - ValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - CCAssignFn *AssignFn) - : MIRBuilder(MIRBuilder), MRI(MRI), AssignFn(AssignFn) {} - - virtual ~ValueHandler() {} - MachineIRBuilder &MIRBuilder; MachineRegisterInfo &MRI; CCAssignFn *AssignFn; @@ -112,7 +122,6 @@ protected: return static_cast<const XXXTargetLowering *>(TLI); } - template <typename FuncInfoTy> void setArgFlags(ArgInfo &Arg, unsigned OpNum, const DataLayout &DL, const FuncInfoTy &FuncInfo) const; @@ -126,7 +135,7 @@ protected: public: CallLowering(const TargetLowering *TLI) : TLI(TLI) {} - virtual ~CallLowering() {} + virtual ~CallLowering() = default; /// This hook must be implemented to lower outgoing return values, described /// by \p Val, into the specified virtual register \p VReg. @@ -200,6 +209,7 @@ public: unsigned ResReg, ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const; }; -} // End namespace llvm. -#endif +} // end namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index e292e8913db0..7061c014d9b7 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ---*- C++ -*-===// +//===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,24 +19,33 @@ #ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H -#include "Types.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/GlobalISel/Types.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/IR/Intrinsics.h" +#include <memory> +#include <utility> namespace llvm { -// Forward declarations. + +class AllocaInst; class BasicBlock; +class CallInst; class CallLowering; class Constant; +class DataLayout; class Instruction; class MachineBasicBlock; class MachineFunction; class MachineInstr; -class OptimizationRemarkEmitter; class MachineRegisterInfo; +class OptimizationRemarkEmitter; +class PHINode; class TargetPassConfig; +class User; +class Value; // Technically the pass should run on an hypothetical MachineModule, // since it should translate Global into some sort of MachineGlobal. @@ -53,6 +62,7 @@ public: private: /// Interface used to lower the everything related to calls. const CallLowering *CLI; + /// Mapping of the values of the current LLVM IR function /// to the related virtual registers. ValueToVReg ValToVReg; @@ -67,7 +77,7 @@ private: // a mapping between the edges arriving at the BasicBlock to the corresponding // created MachineBasicBlocks. Some BasicBlocks that get translated to a // single MachineBasicBlock may also end up in this Map. - typedef std::pair<const BasicBlock *, const BasicBlock *> CFGEdge; + using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>; DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds; // List of stubbed PHI instructions, for values and basic blocks to be filled @@ -165,7 +175,6 @@ private: return translateCompare(U, MIRBuilder); } - /// Add remaining operands onto phis we've translated. Executed after all /// MachineBasicBlocks for the function have been created. void finishPendingPhis(); @@ -356,7 +365,7 @@ private: MachineFunction *MF; /// MachineRegisterInfo used to create virtual registers. - MachineRegisterInfo *MRI; + MachineRegisterInfo *MRI = nullptr; const DataLayout *DL; @@ -430,5 +439,6 @@ public: bool runOnMachineFunction(MachineFunction &MF) override; }; -} // End namespace llvm. -#endif +} // end namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index b3ef7c2dc185..ec60123e54b1 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -1,4 +1,4 @@ -//==-- llvm/CodeGen/GlobalISel/InstructionSelector.h -------------*- C++ -*-==// +//===- llvm/CodeGen/GlobalISel/InstructionSelector.h ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,15 +16,16 @@ #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H -#include "llvm/ADT/Optional.h" #include <bitset> +#include <cstddef> #include <cstdint> #include <functional> +#include <initializer_list> namespace llvm { + class MachineInstr; class MachineInstrBuilder; -class MachineFunction; class MachineOperand; class MachineRegisterInfo; class RegisterBankInfo; @@ -60,7 +61,7 @@ public: /// Provides the logic to select generic machine instructions. class InstructionSelector { public: - virtual ~InstructionSelector() {} + virtual ~InstructionSelector() = default; /// Select the (possibly generic) instruction \p I to only use target-specific /// opcodes. It is OK to insert multiple instructions, but they cannot be @@ -76,7 +77,7 @@ public: virtual bool select(MachineInstr &I) const = 0; protected: - typedef std::function<void(MachineInstrBuilder &)> ComplexRendererFn; + using ComplexRendererFn = std::function<void(MachineInstrBuilder &)>; InstructionSelector(); @@ -110,6 +111,6 @@ protected: bool isObviouslySafeToFold(MachineInstr &MI) const; }; -} // End namespace llvm. +} // end namespace llvm -#endif +#endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index 21354ae20ed1..c259e93fdd36 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -1,4 +1,4 @@ -//==-- llvm/CodeGen/GlobalISel/LegalizerInfo.h -------------------*- C++ -*-==// +//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,33 +12,36 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H -#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZER_H +#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H +#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H #include "llvm/ADT/DenseMap.h" -#include "llvm/CodeGen/LowLevelType.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/LowLevelTypeImpl.h" #include "llvm/Target/TargetOpcodes.h" - #include <cstdint> -#include <functional> +#include <cassert> +#include <tuple> +#include <utility> namespace llvm { -class LLVMContext; + class MachineInstr; class MachineIRBuilder; class MachineRegisterInfo; -class Type; -class VectorType; /// Legalization is decided based on an instruction's opcode, which type slot /// we're considering, and what the existing type is. These aspects are gathered /// together for convenience in the InstrAspect class. struct InstrAspect { unsigned Opcode; - unsigned Idx; + unsigned Idx = 0; LLT Type; - InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Idx(0), Type(Type) {} + InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {} InstrAspect(unsigned Opcode, unsigned Idx, LLT Type) : Opcode(Opcode), Idx(Idx), Type(Type) {} @@ -104,6 +107,19 @@ public: /// before any query is made or incorrect results may be returned. void computeTables(); + static bool needsLegalizingToDifferentSize(const LegalizeAction Action) { + switch (Action) { + case NarrowScalar: + case WidenScalar: + case FewerElements: + case MoreElements: + case Unsupported: + return true; + default: + return false; + } + } + /// More friendly way to set an action for common types that have an LLT /// representation. void setAction(const InstrAspect &Aspect, LegalizeAction Action) { @@ -125,7 +141,6 @@ public: ScalarInVectorActions[std::make_pair(Opcode, ScalarTy)] = Action; } - /// Determine what action should be taken to legalize the given generic /// instruction opcode, type-index and type. Requires computeTables to have /// been called. @@ -145,8 +160,8 @@ public: /// Iterate the given function (typically something like doubling the width) /// on Ty until we find a legal type for this operation. - Optional<LLT> findLegalType(const InstrAspect &Aspect, - function_ref<LLT(LLT)> NextType) const { + Optional<LLT> findLegalizableSize(const InstrAspect &Aspect, + function_ref<LLT(LLT)> NextType) const { LegalizeAction Action; const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx]; LLT Ty = Aspect.Type; @@ -158,10 +173,9 @@ public: if (DefaultIt == DefaultActions.end()) return None; Action = DefaultIt->second; - } - else + } else Action = ActionIt->second; - } while(Action != Legal); + } while (needsLegalizingToDifferentSize(Action)); return Ty; } @@ -203,18 +217,17 @@ private: static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START; static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END; - typedef DenseMap<LLT, LegalizeAction> TypeMap; - typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap; + using TypeMap = DenseMap<LLT, LegalizeAction>; + using SIVActionMap = DenseMap<std::pair<unsigned, LLT>, LegalizeAction>; SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1]; SIVActionMap ScalarInVectorActions; DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts; DenseMap<unsigned, LegalizeAction> DefaultActions; - bool TablesInitialized; + bool TablesInitialized = false; }; +} // end namespace llvm -} // End namespace llvm. - -#endif +#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H diff --git a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h index f610bc02b6f2..676955c33fe9 100644 --- a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -1,4 +1,4 @@ -//== llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector -*- C++ -*-==// +//=- llvm/CodeGen/GlobalISel/RegBankSelect.h - Reg Bank Selector --*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -64,20 +64,27 @@ #ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H #define LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include <cassert> +#include <cstdint> +#include <memory> namespace llvm { -// Forward declarations. + class BlockFrequency; -class MachineBranchProbabilityInfo; class MachineBlockFrequencyInfo; +class MachineBranchProbabilityInfo; +class MachineOperand; class MachineRegisterInfo; +class Pass; +class raw_ostream; class TargetPassConfig; class TargetRegisterInfo; -class raw_ostream; /// This pass implements the reg bank selector pass used in the GlobalISel /// pipeline. At the end of this pass, all register operands have been assigned @@ -105,6 +112,7 @@ public: protected: /// Tell if the insert point has already been materialized. bool WasMaterialized = false; + /// Materialize the insertion point. /// /// If isSplit() is true, this involves actually splitting @@ -128,7 +136,7 @@ public: virtual MachineBasicBlock::iterator getPointImpl() = 0; public: - virtual ~InsertPoint() {} + virtual ~InsertPoint() = default; /// The first call to this method will cause the splitting to /// happen if need be, then sub sequent calls just return @@ -197,6 +205,7 @@ public: private: /// Insertion point. MachineInstr &Instr; + /// Does the insertion point is before or after Instr. bool Before; @@ -216,6 +225,7 @@ public: public: /// Create an insertion point before (\p Before=true) or after \p Instr. InstrInsertPoint(MachineInstr &Instr, bool Before = true); + bool isSplit() const override; uint64_t frequency(const Pass &P) const override; @@ -228,6 +238,7 @@ public: private: /// Insertion point. MachineBasicBlock &MBB; + /// Does the insertion point is at the beginning or end of MBB. bool Beginning; @@ -252,6 +263,7 @@ public: assert((Beginning || MBB.getFirstTerminator() == MBB.end()) && "Invalid end point"); } + bool isSplit() const override { return false; } uint64_t frequency(const Pass &P) const override; bool canMaterialize() const override { return true; }; @@ -262,10 +274,12 @@ public: private: /// Source of the edge. MachineBasicBlock &Src; + /// Destination of the edge. /// After the materialization is done, this hold the basic block /// that resulted from the splitting. MachineBasicBlock *DstOrSplit; + /// P is used to update the analysis passes as applicable. Pass &P; @@ -286,9 +300,11 @@ public: public: EdgeInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst, Pass &P) : InsertPoint(), Src(Src), DstOrSplit(&Dst), P(P) {} + bool isSplit() const override { return Src.succ_size() > 1 && DstOrSplit->pred_size() > 1; } + uint64_t frequency(const Pass &P) const override; bool canMaterialize() const override; }; @@ -311,9 +327,9 @@ public: /// \name Convenient types for a list of insertion points. /// @{ - typedef SmallVector<std::unique_ptr<InsertPoint>, 2> InsertionPoints; - typedef InsertionPoints::iterator insertpt_iterator; - typedef InsertionPoints::const_iterator const_insertpt_iterator; + using InsertionPoints = SmallVector<std::unique_ptr<InsertPoint>, 2>; + using insertpt_iterator = InsertionPoints::iterator; + using const_insertpt_iterator = InsertionPoints::const_iterator; /// @} private: @@ -324,7 +340,7 @@ public: /// Are all the insert points materializeable? bool CanMaterialize; /// Is there any of the insert points needing splitting? - bool HasSplit; + bool HasSplit = false; /// Insertion point for the repair code. /// The repairing code needs to happen just before these points. InsertionPoints InsertPoints; @@ -407,10 +423,10 @@ private: private: /// Cost of the local instructions. /// This cost is free of basic block frequency. - uint64_t LocalCost; + uint64_t LocalCost = 0; /// Cost of the non-local instructions. /// This cost should include the frequency of the related blocks. - uint64_t NonLocalCost; + uint64_t NonLocalCost = 0; /// Frequency of the block where the local instructions live. uint64_t LocalFreq; @@ -468,22 +484,22 @@ private: /// Interface to the target lowering info related /// to register banks. - const RegisterBankInfo *RBI; + const RegisterBankInfo *RBI = nullptr; /// MRI contains all the register class/bank information that this /// pass uses and updates. - MachineRegisterInfo *MRI; + MachineRegisterInfo *MRI = nullptr; /// Information on the register classes for the current function. - const TargetRegisterInfo *TRI; + const TargetRegisterInfo *TRI = nullptr; /// Get the frequency of blocks. /// This is required for non-fast mode. - MachineBlockFrequencyInfo *MBFI; + MachineBlockFrequencyInfo *MBFI = nullptr; /// Get the frequency of the edges. /// This is required for non-fast mode. - MachineBranchProbabilityInfo *MBPI; + MachineBranchProbabilityInfo *MBPI = nullptr; /// Current optimization remark emitter. Used to report failures. std::unique_ptr<MachineOptimizationRemarkEmitter> MORE; @@ -644,6 +660,6 @@ public: bool runOnMachineFunction(MachineFunction &MF) override; }; -} // End namespace llvm. +} // end namespace llvm -#endif +#endif // LLVM_CODEGEN_GLOBALISEL_REGBANKSELECT_H diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index e3549d8988cd..60905c7ec226 100644 --- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -1,4 +1,4 @@ -//==-- llvm/CodeGen/GlobalISel/RegisterBankInfo.h ----------------*- C++ -*-==// +//===- llvm/CodeGen/GlobalISel/RegisterBankInfo.h ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,26 +12,27 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H -#define LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H +#ifndef LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H +#define LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H -#include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/GlobalISel/RegisterBank.h" -#include "llvm/CodeGen/MachineValueType.h" // For SimpleValueType. +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" - #include <cassert> -#include <memory> // For unique_ptr. +#include <initializer_list> +#include <memory> namespace llvm { + class MachineInstr; class MachineRegisterInfo; +class raw_ostream; +class RegisterBank; class TargetInstrInfo; +class TargetRegisterClass; class TargetRegisterInfo; -class raw_ostream; /// Holds all the information related to register banks. class RegisterBankInfo { @@ -48,10 +49,12 @@ public: /// original value. The bits are counted from less significant /// bits to most significant bits. unsigned StartIdx; + /// Length of this mapping in bits. This is how many bits this /// partial mapping covers in the original value: /// from StartIdx to StartIdx + Length -1. unsigned Length; + /// Register bank where the partial value lives. const RegisterBank *RegBank; @@ -180,13 +183,16 @@ public: /// Identifier of the mapping. /// This is used to communicate between the target and the optimizers /// which mapping should be realized. - unsigned ID; + unsigned ID = InvalidMappingID; + /// Cost of this mapping. - unsigned Cost; + unsigned Cost = 0; + /// Mapping of all the operands. const ValueMapping *OperandsMapping; + /// Number of operands. - unsigned NumOperands; + unsigned NumOperands = 0; const ValueMapping &getOperandMapping(unsigned i) { assert(i < getNumOperands() && "Out of bound operand"); @@ -213,7 +219,7 @@ public: /// Default constructor. /// Use this constructor to express that the mapping is invalid. - InstructionMapping() : ID(InvalidMappingID), Cost(0), NumOperands(0) {} + InstructionMapping() = default; /// Get the cost. unsigned getCost() const { return Cost; } @@ -264,7 +270,7 @@ public: /// Convenient type to represent the alternatives for mapping an /// instruction. /// \todo When we move to TableGen this should be an array ref. - typedef SmallVector<const InstructionMapping *, 4> InstructionMappings; + using InstructionMappings = SmallVector<const InstructionMapping *, 4>; /// Helper class used to get/create the virtual registers that will be used /// to replace the MachineOperand when applying a mapping. @@ -273,12 +279,16 @@ public: /// OpIdx-th operand starts. -1 means we do not have such mapping yet. /// Note: We use a SmallVector to avoid heap allocation for most cases. SmallVector<int, 8> OpToNewVRegIdx; + /// Hold the registers that will be used to map MI with InstrMapping. SmallVector<unsigned, 8> NewVRegs; + /// Current MachineRegisterInfo, used to create new virtual registers. MachineRegisterInfo &MRI; + /// Instruction being remapped. MachineInstr &MI; + /// New mapping of the instruction. const InstructionMapping &InstrMapping; @@ -373,6 +383,7 @@ public: protected: /// Hold the set of supported register banks. RegisterBank **RegBanks; + /// Total number of register banks. unsigned NumRegBanks; @@ -729,6 +740,7 @@ operator<<(raw_ostream &OS, const RegisterBankInfo::OperandsMapper &OpdMapper) { /// Hashing function for PartialMapping. /// It is required for the hashing of ValueMapping. hash_code hash_value(const RegisterBankInfo::PartialMapping &PartMapping); -} // End namespace llvm. -#endif +} // end namespace llvm + +#endif // LLVM_CODEGEN_GLOBALISEL_REGISTERBANKINFO_H diff --git a/include/llvm/CodeGen/GlobalISel/Types.h b/include/llvm/CodeGen/GlobalISel/Types.h index 7d974878d3b9..7b22e343a7f8 100644 --- a/include/llvm/CodeGen/GlobalISel/Types.h +++ b/include/llvm/CodeGen/GlobalISel/Types.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===// +//===- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,17 +16,19 @@ #define LLVM_CODEGEN_GLOBALISEL_TYPES_H #include "llvm/ADT/DenseMap.h" -#include "llvm/IR/Value.h" namespace llvm { +class Value; + /// Map a value to a virtual register. /// For now, we chose to map aggregate types to on single virtual /// register. This might be revisited if it turns out to be inefficient. /// PR26161 tracks that. /// Note: We need to expose this type to the target hooks for thing like /// ABI lowering that would be used during IRTranslation. -typedef DenseMap<const Value *, unsigned> ValueToVReg; +using ValueToVReg = DenseMap<const Value *, unsigned>; + +} // end namespace llvm -} // End namespace llvm. -#endif +#endif // LLVM_CODEGEN_GLOBALISEL_TYPES_H diff --git a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h index da8fdcdf5a33..6ad5de533d13 100644 --- a/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h +++ b/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h @@ -134,7 +134,7 @@ using MNV = DiagnosticInfoMIROptimization::MachineArgument; /// /// It allows reporting when optimizations are performed and when they are not /// along with the reasons for it. Hotness information of the corresponding -/// code region can be included in the remark if DiagnosticHotnessRequested is +/// code region can be included in the remark if DiagnosticsHotnessRequested is /// enabled in the LLVM context. class MachineOptimizationRemarkEmitter { public: diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index db914b1f8bc7..3aba0bba7d1a 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===// +//===- llvm/CodeGen/MachinePassRegistry.h -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,13 +18,13 @@ #ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H #define LLVM_CODEGEN_MACHINEPASSREGISTRY_H +#include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/CommandLine.h" namespace llvm { -typedef void *(*MachinePassCtor)(); - +using MachinePassCtor = void *(*)(); //===----------------------------------------------------------------------===// /// @@ -34,36 +34,30 @@ typedef void *(*MachinePassCtor)(); //===----------------------------------------------------------------------===// class MachinePassRegistryListener { virtual void anchor(); + public: - MachinePassRegistryListener() {} - virtual ~MachinePassRegistryListener() {} + MachinePassRegistryListener() = default; + virtual ~MachinePassRegistryListener() = default; + virtual void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) = 0; virtual void NotifyRemove(StringRef N) = 0; }; - //===----------------------------------------------------------------------===// /// /// MachinePassRegistryNode - Machine pass node stored in registration list. /// //===----------------------------------------------------------------------===// class MachinePassRegistryNode { - private: - - MachinePassRegistryNode *Next; // Next function pass in list. + MachinePassRegistryNode *Next = nullptr; // Next function pass in list. StringRef Name; // Name of function pass. StringRef Description; // Description string. MachinePassCtor Ctor; // Function pass creator. public: - MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C) - : Next(nullptr) - , Name(N) - , Description(D) - , Ctor(C) - {} + : Name(N), Description(D), Ctor(C) {} // Accessors MachinePassRegistryNode *getNext() const { return Next; } @@ -72,25 +66,20 @@ public: StringRef getDescription() const { return Description; } MachinePassCtor getCtor() const { return Ctor; } void setNext(MachinePassRegistryNode *N) { Next = N; } - }; - //===----------------------------------------------------------------------===// /// /// MachinePassRegistry - Track the registration of machine passes. /// //===----------------------------------------------------------------------===// class MachinePassRegistry { - private: - MachinePassRegistryNode *List; // List of registry nodes. MachinePassCtor Default; // Default function pass creator. - MachinePassRegistryListener* Listener;// Listener for list adds are removes. + MachinePassRegistryListener *Listener; // Listener for list adds are removes. public: - // NO CONSTRUCTOR - we don't want static constructor ordering to mess // with the registry. @@ -109,10 +98,8 @@ public: /// Remove - Removes a function pass from the registration list. /// void Remove(MachinePassRegistryNode *Node); - }; - //===----------------------------------------------------------------------===// /// /// RegisterPassParser class - Handle the addition of new machine passes. @@ -142,7 +129,6 @@ public: } // Implement the MachinePassRegistryListener callbacks. - // void NotifyAdd(StringRef N, MachinePassCtor C, StringRef D) override { this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D); } @@ -151,7 +137,6 @@ public: } }; - } // end namespace llvm -#endif +#endif // LLVM_CODEGEN_MACHINEPASSREGISTRY_H diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 34cbffa78203..8590b7a348cf 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -32,7 +32,7 @@ // // ScheduleDAGInstrs *<Target>PassConfig:: // createMachineScheduler(MachineSchedContext *C) { -// return new ScheduleDAGMI(C, CustomStrategy(C)); +// return new ScheduleDAGMILive(C, CustomStrategy(C)); // } // // The DAG builder can also be customized in a sense by adding DAG mutations diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index d991e4c216d9..0bdb38bfcbec 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -18,6 +18,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include <cassert> namespace llvm { @@ -232,8 +233,7 @@ namespace llvm { Any = 255 }; - SimpleValueType SimpleTy; - + SimpleValueType SimpleTy = INVALID_SIMPLE_VALUE_TYPE; // A class to represent the number of elements in a vector // @@ -270,7 +270,7 @@ namespace llvm { } }; - constexpr MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {} + constexpr MVT() = default; constexpr MVT(SimpleValueType SVT) : SimpleTy(SVT) {} bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; } @@ -780,7 +780,6 @@ namespace llvm { return getSizeInBits() <= VT.getSizeInBits(); } - static MVT getFloatingPointVT(unsigned BitWidth) { switch (BitWidth) { default: @@ -982,9 +981,12 @@ namespace llvm { /// A simple iterator over the MVT::SimpleValueType enum. struct mvt_iterator { SimpleValueType VT; + mvt_iterator(SimpleValueType VT) : VT(VT) {} + MVT operator*() const { return VT; } bool operator!=(const mvt_iterator &LHS) const { return VT != LHS.VT; } + mvt_iterator& operator++() { VT = (MVT::SimpleValueType)((int)VT + 1); assert((int)VT <= MVT::MAX_ALLOWED_VALUETYPE && @@ -992,8 +994,9 @@ namespace llvm { return *this; } }; + /// A range of the MVT::SimpleValueType enum. - typedef iterator_range<mvt_iterator> mvt_range; + using mvt_range = iterator_range<mvt_iterator>; public: /// SimpleValueType Iteration @@ -1001,32 +1004,39 @@ namespace llvm { static mvt_range all_valuetypes() { return mvt_range(MVT::FIRST_VALUETYPE, MVT::LAST_VALUETYPE); } + static mvt_range integer_valuetypes() { return mvt_range(MVT::FIRST_INTEGER_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_INTEGER_VALUETYPE + 1)); } + static mvt_range fp_valuetypes() { return mvt_range(MVT::FIRST_FP_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_FP_VALUETYPE + 1)); } + static mvt_range vector_valuetypes() { return mvt_range(MVT::FIRST_VECTOR_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_VECTOR_VALUETYPE + 1)); } + static mvt_range integer_vector_valuetypes() { return mvt_range( MVT::FIRST_INTEGER_VECTOR_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_INTEGER_VECTOR_VALUETYPE + 1)); } + static mvt_range fp_vector_valuetypes() { return mvt_range( MVT::FIRST_FP_VECTOR_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_FP_VECTOR_VALUETYPE + 1)); } + static mvt_range integer_scalable_vector_valuetypes() { return mvt_range(MVT::FIRST_INTEGER_SCALABLE_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_INTEGER_SCALABLE_VALUETYPE + 1)); } + static mvt_range fp_scalable_vector_valuetypes() { return mvt_range(MVT::FIRST_FP_SCALABLE_VALUETYPE, (MVT::SimpleValueType)(MVT::LAST_FP_SCALABLE_VALUETYPE + 1)); @@ -1034,6 +1044,6 @@ namespace llvm { /// @} }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_CODEGEN_MACHINEVALUETYPE_H diff --git a/include/llvm/CodeGen/MacroFusion.h b/include/llvm/CodeGen/MacroFusion.h index 473784bc5841..dc105fdc68fd 100644 --- a/include/llvm/CodeGen/MacroFusion.h +++ b/include/llvm/CodeGen/MacroFusion.h @@ -1,4 +1,4 @@ -//===- MacroFusion.h - Macro Fusion ------------------------===// +//===- MacroFusion.h - Macro Fusion -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,19 +12,26 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_CODEGEN_MACROFUSION_H +#define LLVM_CODEGEN_MACROFUSION_H + #include <functional> -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/CodeGen/MachineScheduler.h" +#include <memory> namespace llvm { +class MachineInstr; +class ScheduleDAGMutation; +class TargetInstrInfo; +class TargetSubtargetInfo; + /// \brief Check if the instr pair, FirstMI and SecondMI, should be fused /// together. Given SecondMI, when FirstMI is unspecified, then check if /// SecondMI may be part of a fused pair at all. -typedef std::function<bool(const TargetInstrInfo &TII, - const TargetSubtargetInfo &TSI, - const MachineInstr *FirstMI, - const MachineInstr &SecondMI)> ShouldSchedulePredTy; +using ShouldSchedulePredTy = std::function<bool(const TargetInstrInfo &TII, + const TargetSubtargetInfo &TSI, + const MachineInstr *FirstMI, + const MachineInstr &SecondMI)>; /// \brief Create a DAG scheduling mutation to pair instructions back to back /// for instructions that benefit according to the target-specific @@ -39,3 +46,5 @@ std::unique_ptr<ScheduleDAGMutation> createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); } // end namespace llvm + +#endif // LLVM_CODEGEN_MACROFUSION_H diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index 681ccb4b997c..f5aedb07e4d2 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -94,7 +94,7 @@ public: explicit FixedStackPseudoSourceValue(int FI) : PseudoSourceValue(FixedStack), FI(FI) {} - static inline bool classof(const PseudoSourceValue *V) { + static bool classof(const PseudoSourceValue *V) { return V->kind() == FixedStack; } @@ -126,7 +126,7 @@ class GlobalValuePseudoSourceValue : public CallEntryPseudoSourceValue { public: GlobalValuePseudoSourceValue(const GlobalValue *GV); - static inline bool classof(const PseudoSourceValue *V) { + static bool classof(const PseudoSourceValue *V) { return V->kind() == GlobalValueCallEntry; } @@ -140,7 +140,7 @@ class ExternalSymbolPseudoSourceValue : public CallEntryPseudoSourceValue { public: ExternalSymbolPseudoSourceValue(const char *ES); - static inline bool classof(const PseudoSourceValue *V) { + static bool classof(const PseudoSourceValue *V) { return V->kind() == ExternalSymbolCallEntry; } diff --git a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h index d82ab7d647e7..2107e5a31381 100644 --- a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h +++ b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h @@ -57,7 +57,7 @@ public: int64_t &Off); /// Parses tree in Ptr for base, index, offset addresses. - static BaseIndexOffset match(SDValue Ptr); + static BaseIndexOffset match(SDValue Ptr, const SelectionDAG &DAG); }; } // namespace llvm diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index af418d3050e4..d9f8af0e21d1 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1743,7 +1743,7 @@ public: bool isConstant() const; - static inline bool classof(const SDNode *N) { + static bool classof(const SDNode *N) { return N->getOpcode() == ISD::BUILD_VECTOR; } }; diff --git a/include/llvm/CodeGen/TargetPassConfig.h b/include/llvm/CodeGen/TargetPassConfig.h index c109b7489cca..aaf0ab5d5481 100644 --- a/include/llvm/CodeGen/TargetPassConfig.h +++ b/include/llvm/CodeGen/TargetPassConfig.h @@ -1,4 +1,4 @@ -//===-- TargetPassConfig.h - Code Generation pass options -------*- C++ -*-===// +//===- TargetPassConfig.h - Code Generation pass options --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,19 +16,23 @@ #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" +#include <cassert> #include <string> namespace llvm { -class PassConfigImpl; -class ScheduleDAGInstrs; class LLVMTargetMachine; struct MachineSchedContext; +class PassConfigImpl; +class ScheduleDAGInstrs; // The old pass manager infrastructure is hidden in a legacy namespace now. namespace legacy { + class PassManagerBase; -} + +} // end namespace legacy + using legacy::PassManagerBase; /// Discriminated union of Pass ID types. @@ -50,10 +54,11 @@ class IdentifyingPassPtr { AnalysisID ID; Pass *P; }; - bool IsInstance; + bool IsInstance = false; + public: - IdentifyingPassPtr() : P(nullptr), IsInstance(false) {} - IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {} + IdentifyingPassPtr() : P(nullptr) {} + IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr) {} IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {} bool isValid() const { return P; } @@ -63,6 +68,7 @@ public: assert(!IsInstance && "Not a Pass ID"); return ID; } + Pass *getInstance() const { assert(IsInstance && "Not a Pass Instance"); return P; @@ -93,31 +99,30 @@ public: static char PostRAMachineLICMID; private: - PassManagerBase *PM; + PassManagerBase *PM = nullptr; AnalysisID StartBefore = nullptr; AnalysisID StartAfter = nullptr; AnalysisID StopBefore = nullptr; AnalysisID StopAfter = nullptr; - bool Started; - bool Stopped; - bool AddingMachinePasses; + bool Started = true; + bool Stopped = false; + bool AddingMachinePasses = false; protected: LLVMTargetMachine *TM; - PassConfigImpl *Impl; // Internal data structures - bool Initialized; // Flagged after all passes are configured. + PassConfigImpl *Impl = nullptr; // Internal data structures + bool Initialized = false; // Flagged after all passes are configured. // Target Pass Options // Targets provide a default setting, user flags override. - // - bool DisableVerify; + bool DisableVerify = false; /// Default setting for -enable-tail-merge on this target. - bool EnableTailMerge; + bool EnableTailMerge = true; /// Require processing of functions such that callees are generated before /// callers. - bool RequireCodeGenSCCOrder; + bool RequireCodeGenSCCOrder = false; /// Add the actual instruction selection passes. This does not include /// preparation passes on IR. @@ -296,7 +301,6 @@ public: /// printAndVerify - Add a pass to dump then verify the machine function, if /// those steps are enabled. - /// void printAndVerify(const std::string &Banner); /// Add a pass to print the machine function if printing is enabled. @@ -430,4 +434,4 @@ protected: } // end namespace llvm -#endif +#endif // LLVM_CODEGEN_TARGETPASSCONFIG_H diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index b404b4ca701f..40d501edde10 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -17,7 +17,10 @@ #define LLVM_CODEGEN_VALUETYPES_H #include "llvm/CodeGen/MachineValueType.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" #include <cassert> +#include <cstdint> #include <string> namespace llvm { @@ -30,13 +33,13 @@ namespace llvm { /// can represent. struct EVT { private: - MVT V; - Type *LLVMTy; + MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE; + Type *LLVMTy = nullptr; public: - constexpr EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {} - constexpr EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {} - constexpr EVT(MVT S) : V(S), LLVMTy(nullptr) {} + constexpr EVT() = default; + constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {} + constexpr EVT(MVT S) : V(S) {} bool operator==(EVT VT) const { return !(*this != VT); @@ -246,7 +249,6 @@ namespace llvm { return getSizeInBits() <= VT.getSizeInBits(); } - /// Return the SimpleValueType held in the specified simple EVT. MVT getSimpleVT() const { assert(isSimple() && "Expected a SimpleValueType!"); @@ -430,6 +432,6 @@ namespace llvm { unsigned getExtendedSizeInBits() const LLVM_READONLY; }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_CODEGEN_VALUETYPES_H diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h index b2d3f5ea34a8..7c8cd121751a 100644 --- a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h @@ -25,7 +25,9 @@ public: CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks); Error visitSymbolRecord(CVSymbol &Record); + Error visitSymbolRecord(CVSymbol &Record, uint32_t Offset); Error visitSymbolStream(const CVSymbolArray &Symbols); + Error visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset); private: SymbolVisitorCallbacks &Callbacks; diff --git a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h index 9fc90f13d347..78b284563afd 100644 --- a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h @@ -12,13 +12,19 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/Endian.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { + namespace codeview { class DebugStringTableSubsection; @@ -28,24 +34,22 @@ struct FileChecksumEntry { FileChecksumKind Kind; // The type of checksum. ArrayRef<uint8_t> Checksum; // The bytes of the checksum. }; -} -} -namespace llvm { +} // end namespace codeview + template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> { public: - typedef void ContextType; + using ContextType = void; Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::FileChecksumEntry &Item); }; -} -namespace llvm { namespace codeview { + class DebugChecksumsSubsectionRef final : public DebugSubsectionRef { - typedef VarStreamArray<codeview::FileChecksumEntry> FileChecksumArray; - typedef FileChecksumArray::Iterator Iterator; + using FileChecksumArray = VarStreamArray<codeview::FileChecksumEntry>; + using Iterator = FileChecksumArray::Iterator; public: DebugChecksumsSubsectionRef() @@ -89,10 +93,12 @@ private: DenseMap<uint32_t, uint32_t> OffsetMap; uint32_t SerializedSize = 0; - llvm::BumpPtrAllocator Storage; + BumpPtrAllocator Storage; std::vector<FileChecksumEntry> Checksums; }; -} -} -#endif +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h b/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h index f755b23422c7..2f9e9814d998 100644 --- a/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugCrossExSubsection.h @@ -10,18 +10,21 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H #define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/Endian.h" - +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Error.h" +#include <cstdint> #include <map> namespace llvm { namespace codeview { + class DebugCrossModuleExportsSubsectionRef final : public DebugSubsectionRef { - typedef FixedStreamArray<CrossModuleExport> ReferenceArray; - typedef ReferenceArray::Iterator Iterator; + using ReferenceArray = FixedStreamArray<CrossModuleExport>; + using Iterator = ReferenceArray::Iterator; public: DebugCrossModuleExportsSubsectionRef() @@ -58,7 +61,8 @@ public: private: std::map<uint32_t, uint32_t> Mappings; }; -} -} -#endif +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSEXSUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h b/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h index ea3a9a43d50b..8be7ef265c82 100644 --- a/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h @@ -11,38 +11,43 @@ #define LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { + namespace codeview { struct CrossModuleImportItem { const CrossModuleImport *Header = nullptr; - llvm::FixedStreamArray<support::ulittle32_t> Imports; + FixedStreamArray<support::ulittle32_t> Imports; }; -} -} -namespace llvm { +} // end namespace codeview + template <> struct VarStreamArrayExtractor<codeview::CrossModuleImportItem> { public: - typedef void ContextType; + using ContextType = void; Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::CrossModuleImportItem &Item); }; -} -namespace llvm { namespace codeview { + class DebugStringTableSubsection; class DebugCrossModuleImportsSubsectionRef final : public DebugSubsectionRef { - typedef VarStreamArray<CrossModuleImportItem> ReferenceArray; - typedef ReferenceArray::Iterator Iterator; + using ReferenceArray = VarStreamArray<CrossModuleImportItem>; + using Iterator = ReferenceArray::Iterator; public: DebugCrossModuleImportsSubsectionRef() @@ -82,7 +87,9 @@ private: DebugStringTableSubsection &Strings; StringMap<std::vector<support::ulittle32_t>> Mappings; }; -} -} -#endif +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGCROSSIMPSUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h index 7484af663105..b88c0eae1de2 100644 --- a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h @@ -7,19 +7,26 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_BUGINLINEELINESSUBSECTION_H -#define LLVM_DEBUGINFO_CODEVIEW_BUGINLINEELINESSUBSECTION_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { + namespace codeview { -class DebugInlineeLinesSubsectionRef; class DebugChecksumsSubsection; enum class InlineeLinesSignature : uint32_t { @@ -40,18 +47,21 @@ struct InlineeSourceLine { const InlineeSourceLineHeader *Header; FixedStreamArray<support::ulittle32_t> ExtraFiles; }; -} + +} // end namespace codeview template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> { Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::InlineeSourceLine &Item); + bool HasExtraFiles = false; }; namespace codeview { + class DebugInlineeLinesSubsectionRef final : public DebugSubsectionRef { - typedef VarStreamArray<InlineeSourceLine> LinesArray; - typedef LinesArray::Iterator Iterator; + using LinesArray = VarStreamArray<InlineeSourceLine>; + using Iterator = LinesArray::Iterator; public: DebugInlineeLinesSubsectionRef(); @@ -99,13 +109,13 @@ public: private: DebugChecksumsSubsection &Checksums; - bool HasExtraFiles = false; uint32_t ExtraFileCount = 0; - std::vector<Entry> Entries; }; -} -} -#endif +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGINLINEELINESSUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h index f1feb1336cc5..53044b6c3dc8 100644 --- a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h @@ -1,4 +1,4 @@ -//===- DebugLinesSubsection.h --------------------------------*- C++ -*-===// +//===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,20 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H -#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { namespace codeview { @@ -72,8 +78,9 @@ public: class DebugLinesSubsectionRef final : public DebugSubsectionRef { friend class LineColumnExtractor; - typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray; - typedef LineInfoArray::Iterator Iterator; + + using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>; + using Iterator = LineInfoArray::Iterator; public: DebugLinesSubsectionRef(); @@ -130,14 +137,14 @@ public: private: DebugChecksumsSubsection &Checksums; - uint32_t RelocOffset = 0; uint16_t RelocSegment = 0; uint32_t CodeSize = 0; LineFlags Flags = LF_None; std::vector<Block> Blocks; }; -} -} -#endif +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h index be0a2344965b..7f0f10e4fbfa 100644 --- a/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h @@ -12,17 +12,15 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" - -#include <stdint.h> +#include <cstdint> namespace llvm { class BinaryStreamReader; -class BinaryStreamRef; -class BinaryStreamWriter; namespace codeview { @@ -83,7 +81,9 @@ private: StringMap<uint32_t> Strings; uint32_t StringSize = 1; }; -} -} -#endif +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h index ee17b47d8e63..fc0cf0d1d90e 100644 --- a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h +++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h @@ -1,4 +1,4 @@ -//===- DebugSubsection.h ------------------------------------*- C++ -*-===// +//===- DebugSubsectionRecord.h ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H -#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamRef.h" -#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include "llvm/Support/MathExtras.h" +#include <cstdint> +#include <memory> namespace llvm { + +class BinaryStreamWriter; + namespace codeview { class DebugSubsection; @@ -42,8 +47,8 @@ public: BinaryStreamRef getRecordData() const; private: - CodeViewContainer Container; - DebugSubsectionKind Kind; + CodeViewContainer Container = CodeViewContainer::ObjectFile; + DebugSubsectionKind Kind = DebugSubsectionKind::None; BinaryStreamRef Data; }; @@ -71,7 +76,7 @@ private: CodeViewContainer Container; }; -} // namespace codeview +} // end namespace codeview template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> { Error operator()(BinaryStreamRef Stream, uint32_t &Length, @@ -88,8 +93,11 @@ template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> { }; namespace codeview { -typedef VarStreamArray<DebugSubsectionRecord> DebugSubsectionArray; -} -} // namespace llvm -#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H +using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>; + +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H diff --git a/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h b/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h index ad58a293cb09..a4c04b55eb4c 100644 --- a/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h @@ -10,17 +10,23 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamArray.h" -#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { + +class BinaryStreamReader; + namespace codeview { class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef { public: - typedef FixedStreamArray<support::ulittle32_t> ArrayType; + using ArrayType = FixedStreamArray<support::ulittle32_t>; DebugSymbolRVASubsectionRef(); @@ -53,7 +59,9 @@ public: private: std::vector<support::ulittle32_t> RVAs; }; -} // namespace codeview -} // namespace llvm -#endif +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H diff --git a/include/llvm/DebugInfo/CodeView/EnumTables.h b/include/llvm/DebugInfo/CodeView/EnumTables.h index 5d54bb4cca84..ee0f0f7c6023 100644 --- a/include/llvm/DebugInfo/CodeView/EnumTables.h +++ b/include/llvm/DebugInfo/CodeView/EnumTables.h @@ -1,4 +1,4 @@ -//===- EnumTables.h Enum to string conversion tables ------------*- C++ -*-===// +//===- EnumTables.h - Enum to string conversion tables ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,11 +14,11 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/Support/ScopedPrinter.h" - -#include <stdint.h> +#include <cstdint> namespace llvm { namespace codeview { + ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames(); ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames(); ArrayRef<EnumEntry<uint16_t>> getRegisterNames(); @@ -38,7 +38,8 @@ ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames(); ArrayRef<EnumEntry<uint16_t>> getTrampolineNames(); ArrayRef<EnumEntry<COFF::SectionCharacteristics>> getImageSectionCharacteristicNames(); -} // namespace codeview -} // namespace llvm + +} // end namespace codeview +} // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H diff --git a/include/llvm/DebugInfo/CodeView/Formatters.h b/include/llvm/DebugInfo/CodeView/Formatters.h index 1fbb0dd6f9b0..0842c1e373db 100644 --- a/include/llvm/DebugInfo/CodeView/Formatters.h +++ b/include/llvm/DebugInfo/CodeView/Formatters.h @@ -14,21 +14,27 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/FormatAdapters.h" -#include "llvm/Support/FormatProviders.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include <cstdint> namespace llvm { + namespace codeview { + namespace detail { -class GuidAdapter final : public llvm::FormatAdapter<ArrayRef<uint8_t>> { + +class GuidAdapter final : public FormatAdapter<ArrayRef<uint8_t>> { ArrayRef<uint8_t> Guid; public: explicit GuidAdapter(ArrayRef<uint8_t> Guid); explicit GuidAdapter(StringRef Guid); - void format(llvm::raw_ostream &Stream, StringRef Style); + + void format(raw_ostream &Stream, StringRef Style) override ; }; -} + +} // end namespace detail inline detail::GuidAdapter fmt_guid(StringRef Item) { return detail::GuidAdapter(Item); @@ -37,11 +43,12 @@ inline detail::GuidAdapter fmt_guid(StringRef Item) { inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) { return detail::GuidAdapter(Item); } -} + +} // end namespace codeview template <> struct format_provider<codeview::TypeIndex> { public: - static void format(const codeview::TypeIndex &V, llvm::raw_ostream &Stream, + static void format(const codeview::TypeIndex &V, raw_ostream &Stream, StringRef Style) { if (V.isNoneType()) Stream << "<no type>"; @@ -52,6 +59,7 @@ public: } } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H diff --git a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h index 8b1540abf903..cc0c24301d49 100644 --- a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h +++ b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h @@ -1,4 +1,4 @@ -//===- LazyRandomTypeCollection.h ---------------------------- *- C++ --*-===// +//===- LazyRandomTypeCollection.h -------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,12 +10,18 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H #define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/TypeCollection.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Error.h" #include "llvm/Support/StringSaver.h" +#include <cstdint> +#include <vector> namespace llvm { namespace codeview { @@ -43,7 +49,8 @@ namespace codeview { /// into M chunks of roughly equal size, this yields a worst case lookup time /// of O(N/M) and an amortized time of O(1). class LazyRandomTypeCollection : public TypeCollection { - typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray; + using PartialOffsetArray = FixedStreamArray<TypeIndexOffset>; + struct CacheEntry { CVType Type; uint32_t Offset; diff --git a/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h b/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h index 708b317164fc..1a8388224665 100644 --- a/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h +++ b/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h @@ -7,23 +7,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H -#define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H +#define LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" - #include <memory> namespace llvm { namespace codeview { -class DebugSubsectionRecord; -class DebugChecksumsSubsectionRef; -class DebugStringTableSubsectionRef; -class DebugChecksumsSubsection; -class DebugStringTableSubsection; - class StringsAndChecksumsRef { public: // If no subsections are known about initially, we find as much as we can. @@ -83,8 +78,9 @@ class StringsAndChecksums { public: using StringsPtr = std::shared_ptr<DebugStringTableSubsection>; using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>; + // If no subsections are known about initially, we find as much as we can. - StringsAndChecksums() {} + StringsAndChecksums() = default; void setStrings(const StringsPtr &SP) { Strings = SP; } void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; } @@ -100,7 +96,7 @@ private: ChecksumsPtr Checksums; }; -} // namespace codeview -} // namespace llvm +} // end namespace codeview +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_CODEVIEW_STRINGSANDCHECKSUMS_H diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index 7080b0480757..5b6599d8c1db 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -51,6 +51,10 @@ public: CodeViewContainer Container) : Delegate(Delegate), Container(Container) {} + Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override { + return visitSymbolBegin(Record); + } + Error visitSymbolBegin(CVSymbol &Record) override { assert(!Mapping && "Already in a symbol mapping!"); Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container); diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 1cf77fcdecbe..7941af8be8af 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -21,8 +21,6 @@ #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include <cstddef> #include <cstdint> #include <vector> @@ -35,6 +33,7 @@ protected: public: SymbolRecordKind getKind() const { return Kind; } + SymbolRecordKind Kind; }; @@ -153,6 +152,7 @@ public: : SymbolRecord(Kind), RecordOffset(RecordOffset) {} std::vector<TypeIndex> Indices; + uint32_t RecordOffset; }; @@ -165,8 +165,8 @@ struct BinaryAnnotationIterator { int32_t S1; }; - BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {} BinaryAnnotationIterator() = default; + BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {} BinaryAnnotationIterator(const BinaryAnnotationIterator &Other) : Data(Other.Data) {} @@ -342,9 +342,9 @@ public: : SymbolRecord(SymbolRecordKind::InlineSiteSym), RecordOffset(RecordOffset) {} - llvm::iterator_range<BinaryAnnotationIterator> annotations() const { - return llvm::make_range(BinaryAnnotationIterator(AnnotationData), - BinaryAnnotationIterator()); + iterator_range<BinaryAnnotationIterator> annotations() const { + return make_range(BinaryAnnotationIterator(AnnotationData), + BinaryAnnotationIterator()); } uint32_t Parent; @@ -479,6 +479,7 @@ public: ulittle16_t Register; ulittle16_t MayHaveNoName; }; + explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} DefRangeRegisterSym(uint32_t RecordOffset) : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), @@ -501,6 +502,7 @@ public: ulittle16_t MayHaveNoName; ulittle32_t OffsetInParent; }; + explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} DefRangeSubfieldRegisterSym(uint32_t RecordOffset) @@ -546,6 +548,7 @@ public: ulittle16_t Flags; little32_t BasePointerOffset; }; + explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} explicit DefRangeRegisterRelSym(uint32_t RecordOffset) : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), @@ -935,8 +938,8 @@ public: uint32_t RecordOffset; }; -typedef CVRecord<SymbolKind> CVSymbol; -typedef VarStreamArray<CVSymbol> CVSymbolArray; +using CVSymbol = CVRecord<SymbolKind>; +using CVSymbolArray = VarStreamArray<CVSymbol>; } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h index 42adbdb4e20f..b63ced5217b4 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h @@ -1,4 +1,4 @@ -//===- symbolSerializer.h ---------------------------------------*- C++ -*-===// +//===- SymbolSerializer.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,21 +10,20 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> namespace llvm { -class BinaryStreamWriter; namespace codeview { class SymbolSerializer : public SymbolVisitorCallbacks { @@ -45,6 +44,8 @@ class SymbolSerializer : public SymbolVisitorCallbacks { } public: + SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container); + template <typename SymType> static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage, CodeViewContainer Container) { @@ -57,13 +58,11 @@ public: return Result; } - SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container); - - virtual Error visitSymbolBegin(CVSymbol &Record) override; - virtual Error visitSymbolEnd(CVSymbol &Record) override; + Error visitSymbolBegin(CVSymbol &Record) override; + Error visitSymbolEnd(CVSymbol &Record) override; #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ - virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \ + Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \ return visitKnownRecordImpl(CVR, Record); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) @@ -75,7 +74,8 @@ private: return Mapping.visitKnownRecord(CVR, Record); } }; -} -} -#endif +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h index 5f4205bd6e08..e29511a67b7f 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h @@ -30,6 +30,14 @@ public: return Error::success(); } + Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override { + for (auto Visitor : Pipeline) { + if (auto EC = Visitor->visitSymbolBegin(Record, Offset)) + return EC; + } + return Error::success(); + } + Error visitSymbolBegin(CVSymbol &Record) override { for (auto Visitor : Pipeline) { if (auto EC = Visitor->visitSymbolBegin(Record)) diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h index 2ef7eabdaa9d..0816f7c62656 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h @@ -29,8 +29,10 @@ public: /// Paired begin/end actions for all symbols. Receives all record data, /// including the fixed-length record prefix. visitSymbolBegin() should - /// return - /// the type of the Symbol, or an error if it cannot be determined. + /// return the type of the Symbol, or an error if it cannot be determined. + virtual Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) { + return Error::success(); + } virtual Error visitSymbolBegin(CVSymbol &Record) { return Error::success(); } virtual Error visitSymbolEnd(CVSymbol &Record) { return Error::success(); } diff --git a/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h index c393b42cd27c..afe8942159e8 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h @@ -28,6 +28,8 @@ void discoverTypeIndices(ArrayRef<uint8_t> RecordData, SmallVectorImpl<TiReference> &Refs); void discoverTypeIndices(const CVType &Type, SmallVectorImpl<TiReference> &Refs); +void discoverTypeIndices(const CVType &Type, + SmallVectorImpl<TypeIndex> &Indices); /// Discover type indices in symbol records. Returns false if this is an unknown /// record. diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 3a64a437aa4d..2efeb1b3cefd 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -15,6 +15,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" @@ -25,31 +26,30 @@ #include <vector> namespace llvm { - -class BinaryStreamReader; - namespace codeview { using support::little32_t; using support::ulittle16_t; using support::ulittle32_t; -typedef CVRecord<TypeLeafKind> CVType; -typedef RemappedRecord<TypeLeafKind> RemappedType; +using CVType = CVRecord<TypeLeafKind>; +using RemappedType = RemappedRecord<TypeLeafKind>; struct CVMemberRecord { TypeLeafKind Kind; ArrayRef<uint8_t> Data; }; -typedef VarStreamArray<CVType> CVTypeArray; -typedef iterator_range<CVTypeArray::Iterator> CVTypeRange; +using CVTypeArray = VarStreamArray<CVType>; +using CVTypeRange = iterator_range<CVTypeArray::Iterator>; /// Equvalent to CV_fldattr_t in cvinfo.h. struct MemberAttributes { uint16_t Attrs = 0; + enum { MethodKindShift = 2, }; + MemberAttributes() = default; explicit MemberAttributes(MemberAccess Access) @@ -226,6 +226,7 @@ public: TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } + TypeIndex ClassType; TypeIndex FunctionType; StringRef Name; @@ -330,7 +331,6 @@ public: TypeIndex ReferentType; uint32_t Attrs; - Optional<MemberPointerInfo> MemberInfo; private: @@ -490,6 +490,7 @@ public: UnderlyingType(UnderlyingType) {} TypeIndex getUnderlyingType() const { return UnderlyingType; } + TypeIndex UnderlyingType; }; @@ -505,6 +506,7 @@ public: TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } uint8_t getBitSize() const { return BitSize; } + TypeIndex Type; uint8_t BitSize; uint8_t BitOffset; @@ -527,6 +529,7 @@ public: } uint32_t getEntryCount() const { return getSlots().size(); } + ArrayRef<VFTableSlotKind> SlotsRef; std::vector<VFTableSlotKind> Slots; }; @@ -541,9 +544,7 @@ public: Name(Name) {} StringRef getGuid() const { return Guid; } - uint32_t getAge() const { return Age; } - StringRef getName() const { return Name; } StringRef Guid; @@ -560,8 +561,8 @@ public: : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {} TypeIndex getId() const { return Id; } - StringRef getString() const { return String; } + TypeIndex Id; StringRef String; }; @@ -576,9 +577,7 @@ public: FunctionType(FunctionType), Name(Name) {} TypeIndex getParentScope() const { return ParentScope; } - TypeIndex getFunctionType() const { return FunctionType; } - StringRef getName() const { return Name; } TypeIndex ParentScope; @@ -635,6 +634,7 @@ public: ArgIndices(ArgIndices.begin(), ArgIndices.end()) {} ArrayRef<TypeIndex> getArgs() const { return ArgIndices; } + SmallVector<TypeIndex, 4> ArgIndices; }; @@ -656,6 +656,7 @@ public: TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } uint32_t getVFPtrOffset() const { return VFPtrOffset; } StringRef getName() const { return makeArrayRef(MethodNames).front(); } + ArrayRef<StringRef> getMethodNames() const { return makeArrayRef(MethodNames).drop_front(); } @@ -707,6 +708,7 @@ public: : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {} ArrayRef<OneMethodRecord> getMethods() const { return Methods; } + std::vector<OneMethodRecord> Methods; }; @@ -723,6 +725,7 @@ public: uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } StringRef getName() const { return Name; } + uint16_t NumOverloads; TypeIndex MethodList; StringRef Name; @@ -874,7 +877,6 @@ public: }; } // end namespace codeview - } // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index 988a2d4aa834..0e734a8170bd 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -10,19 +10,25 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H #define LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamWriter.h" - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" +#include <cassert> +#include <cstdint> +#include <memory> +#include <vector> namespace llvm { - namespace codeview { class TypeHasher; @@ -46,7 +52,7 @@ class TypeSerializer : public TypeVisitorCallbacks { } }; - typedef SmallVector<MutableArrayRef<uint8_t>, 2> MutableRecordList; + using MutableRecordList = SmallVector<MutableArrayRef<uint8_t>, 2>; static constexpr uint8_t ContinuationLength = 8; BumpPtrAllocator &RecordStorage; @@ -82,7 +88,7 @@ class TypeSerializer : public TypeVisitorCallbacks { public: explicit TypeSerializer(BumpPtrAllocator &Storage, bool Hash = true); - ~TypeSerializer(); + ~TypeSerializer() override; void reset(); @@ -146,7 +152,8 @@ private: return Error::success(); } }; -} -} -#endif +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZER_H diff --git a/include/llvm/DebugInfo/CodeView/TypeServerHandler.h b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h index 35f06eaf6eb4..e96baad9ceae 100644 --- a/include/llvm/DebugInfo/CodeView/TypeServerHandler.h +++ b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h @@ -10,16 +10,17 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H #define LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H -#include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/Error.h" namespace llvm { namespace codeview { + +class TypeServer2Record; class TypeVisitorCallbacks; class TypeServerHandler { public: - virtual ~TypeServerHandler() {} + virtual ~TypeServerHandler() = default; /// Handle a TypeServer record. If the implementation returns true /// the record will not be processed by the top-level visitor. If @@ -30,7 +31,8 @@ public: return false; } }; -} -} -#endif +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 8bde63efe188..eb6d0f541c1e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -12,8 +12,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" -#include "llvm/Support/DataExtractor.h" #include <cstdint> #include <utility> @@ -41,20 +41,31 @@ class DWARFAcceleratorTable { struct Header Hdr; struct HeaderData HdrData; - DataExtractor AccelSection; + DWARFDataExtractor AccelSection; DataExtractor StringSection; - const RelocAddrMap& Relocs; public: - DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection, - const RelocAddrMap &Relocs) - : AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {} + DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection, + DataExtractor StringSection) + : AccelSection(AccelSection), StringSection(StringSection) {} bool extract(); uint32_t getNumBuckets(); uint32_t getNumHashes(); uint32_t getSizeHdr(); uint32_t getHeaderDataLength(); + ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc(); + bool validateForms(); + + /// Return information related to the DWARF DIE we're looking for when + /// performing a lookup by name. + /// + /// \param HashDataOffset an offset into the hash data table + /// \returns DIEOffset the offset into the .debug_info section for the DIE + /// related to the input hash data offset. Currently this function returns + /// only the DIEOffset but it can be modified to return more data regarding + /// the DIE + uint32_t readAtoms(uint32_t &HashDataOffset); void dump(raw_ostream &OS) const; }; diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index b4e4721e3d51..a18adf87bf8e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -20,8 +20,8 @@ public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, StringRef LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, + const DWARFSection *AOS, const DWARFSection &LS, bool LE, + bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 4bf34d52bcba..739aa1f9ee74 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -45,12 +45,6 @@ class DataExtractor; class MemoryBuffer; class raw_ostream; -/// Reads a value from data extractor and applies a relocation to the result if -/// one exists for the given offset. -uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size, - uint32_t *Off, const RelocAddrMap *Relocs, - uint64_t *SecNdx = nullptr); - /// DWARFContext /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through pure virtual @@ -289,6 +283,11 @@ private: DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); }; +/// Used as a return value for a error callback passed to DWARF context. +/// Callback should return Halt if client application wants to stop +/// object parsing, or should return Continue otherwise. +enum class ErrorPolicy { Halt, Continue }; + /// DWARFContextInMemory is the simplest possible implementation of a /// DWARFContext. It assumes all content is available in memory and stores /// pointers to it. @@ -346,9 +345,14 @@ class DWARFContextInMemory : public DWARFContext { Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, StringRef &Data); + /// Function used to handle default error reporting policy. Prints a error + /// message and returns Continue, so DWARF context ignores the error. + static ErrorPolicy defaultErrorHandler(Error E); + public: - DWARFContextInMemory(const object::ObjectFile &Obj, - const LoadedObjectInfo *L = nullptr); + DWARFContextInMemory( + const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, + function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler); DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize, diff --git a/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h new file mode 100644 index 000000000000..ef4360f66621 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h @@ -0,0 +1,48 @@ +//===- DWARFDataExtractor.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H +#define LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H + +#include "llvm/DebugInfo/DWARF/DWARFSection.h" +#include "llvm/Support/DataExtractor.h" + +namespace llvm { + +/// A DataExtractor (typically for an in-memory copy of an object-file section) +/// plus a relocation map for that section, if there is one. +class DWARFDataExtractor : public DataExtractor { + const RelocAddrMap *RelocMap = nullptr; +public: + /// Constructor for the normal case of extracting data from a DWARF section. + /// The DWARFSection's lifetime must be at least as long as the extractor's. + DWARFDataExtractor(const DWARFSection &Section, bool IsLittleEndian, + uint8_t AddressSize) + : DataExtractor(Section.Data, IsLittleEndian, AddressSize), + RelocMap(&Section.Relocs) {} + + /// Constructor for cases when there are no relocations. + DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) + : DataExtractor(Data, IsLittleEndian, AddressSize) {} + + /// Extracts a value and applies a relocation to the result if + /// one exists for the given offset. + uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off, + uint64_t *SectionIndex = nullptr) const; + + /// Extracts an address-sized value and applies a relocation to the result if + /// one exists for the given offset. + uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const { + return getRelocatedValue(getAddressSize(), Off, SecIx); + } +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h index 5c591b3de491..88c8f57bc33c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -12,6 +12,7 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include <cstdint> namespace llvm { @@ -40,8 +41,7 @@ public: /// High performance extraction should use this call. bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, - const DataExtractor &DebugInfoData, - uint32_t UEndOffset, + const DWARFDataExtractor &DebugInfoData, uint32_t UEndOffset, uint32_t Depth); uint32_t getOffset() const { return Offset; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 4d624812f186..0c8f98aa62f9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -12,9 +12,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" -#include "llvm/Support/DataExtractor.h" #include <cstdint> #include <map> #include <string> @@ -26,9 +26,6 @@ class raw_ostream; class DWARFDebugLine { public: - DWARFDebugLine(const RelocAddrMap *LineInfoRelocMap) - : RelocMap(LineInfoRelocMap) {} - struct FileNameEntry { FileNameEntry() = default; @@ -98,7 +95,7 @@ public: void clear(); void dump(raw_ostream &OS) const; - bool parse(DataExtractor DebugLineData, uint32_t *OffsetPtr); + bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr); }; /// Standard .debug_line state machine structure. @@ -220,8 +217,7 @@ public: void clear(); /// Parse prologue and all rows. - bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap, - uint32_t *OffsetPtr); + bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr); using RowVector = std::vector<Row>; using RowIter = RowVector::const_iterator; @@ -238,7 +234,7 @@ public: }; const LineTable *getLineTable(uint32_t Offset) const; - const LineTable *getOrParseLineTable(DataExtractor DebugLineData, + const LineTable *getOrParseLineTable(const DWARFDataExtractor &DebugLineData, uint32_t Offset); private: @@ -261,7 +257,6 @@ private: using LineTableIter = LineTableMapTy::iterator; using LineTableConstIter = LineTableMapTy::const_iterator; - const RelocAddrMap *RelocMap; LineTableMapTy LineTableMap; }; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index 821da8f9b536..c2b8d0cd73d8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -11,8 +11,8 @@ #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H #include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" -#include "llvm/Support/DataExtractor.h" #include <cstdint> namespace llvm { @@ -45,18 +45,13 @@ class DWARFDebugLoc { /// the locations in which the variable is stored. LocationLists Locations; - /// A map used to resolve binary relocations. - const RelocAddrMap &RelocMap; - public: - DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {} - /// Print the location lists found within the debug_loc section. void dump(raw_ostream &OS) const; /// Parse the debug_loc section accessible via the 'data' parameter using the - /// specified address size to interpret the address ranges. - void parse(DataExtractor data, unsigned AddressSize); + /// address size also given in 'data' to interpret the address ranges. + void parse(const DWARFDataExtractor &data); }; class DWARFDebugLocDWO { diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index 49beec92ecc6..bcba14b1630d 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -10,8 +10,8 @@ #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" -#include "llvm/Support/DataExtractor.h" #include <cassert> #include <cstdint> #include <vector> @@ -79,7 +79,7 @@ public: void clear(); void dump(raw_ostream &OS) const; - bool extract(DataExtractor data, uint32_t *offset_ptr, const RelocAddrMap& Relocs); + bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr); const std::vector<RangeListEntry> &getEntries() { return Entries; } /// getAbsoluteRanges - Returns absolute address ranges defined by this range diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 78fa6639db08..008dba9b42ac 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -14,7 +14,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/Support/DataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include <cstdint> namespace llvm { @@ -105,14 +105,13 @@ public: /// Extracts a value in \p Data at offset \p *OffsetPtr. /// - /// The passed DWARFUnit is allowed to be nullptr, in which - /// case no relocation processing will be performed and some + /// The passed DWARFUnit is allowed to be nullptr, in which case some /// kind of forms that depend on Unit information are disallowed. - /// \param Data The DataExtractor to use. - /// \param OffsetPtr The offset within DataExtractor where the data starts. + /// \param Data The DWARFDataExtractor to use. + /// \param OffsetPtr The offset within \p Data where the data starts. /// \param U The optional DWARFUnit supplying information for some forms. /// \returns whether the extraction succeeded. - bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr, + bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, const DWARFUnit *U); bool isInlinedCStr() const { diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index 2041d40eb53a..4a5793ecb8fa 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -32,7 +32,7 @@ public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, - StringRef LS, bool LE, bool IsDWO, + const DWARFSection &LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index d7ccaf82bc9a..ea36ab7ab5b6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -58,7 +58,7 @@ protected: virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, StringRef LS, + const DWARFSection *AOS, const DWARFSection &LS, bool isLittleEndian, bool isDWO) = 0; }; @@ -91,7 +91,7 @@ private: void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, - StringRef LS, bool LE, bool IsDWO) override { + const DWARFSection &LS, bool LE, bool IsDWO) override { if (Parsed) return; const auto &Index = getDWARFUnitIndex(Context, UnitType::Section); @@ -118,7 +118,7 @@ class DWARFUnit { const DWARFDebugAbbrev *Abbrev; const DWARFSection *RangeSection; uint32_t RangeSectionBase; - StringRef LineSection; + const DWARFSection &LineSection; StringRef StringSection; const DWARFSection &StringOffsetSection; uint64_t StringOffsetSectionBase = 0; @@ -166,15 +166,16 @@ protected: public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, - const DWARFSection &SOS, const DWARFSection *AOS, StringRef LS, - bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, + const DWARFSection &SOS, const DWARFSection *AOS, + const DWARFSection &LS, bool LE, bool IsDWO, + const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry = nullptr); virtual ~DWARFUnit(); DWARFContext& getContext() const { return Context; } - StringRef getLineSection() const { return LineSection; } + const DWARFSection &getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } const DWARFSection &getStringOffsetSection() const { return StringOffsetSection; @@ -194,13 +195,11 @@ public: } bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; - // FIXME: Result should be uint64_t in DWARF64. bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const; - uint64_t getStringOffsetSectionRelocation(uint32_t Index) const; - DataExtractor getDebugInfoExtractor() const { - return DataExtractor(InfoSection.Data, isLittleEndian, - getAddressByteSize()); + DWARFDataExtractor getDebugInfoExtractor() const { + return DWARFDataExtractor(InfoSection, isLittleEndian, + getAddressByteSize()); } DataExtractor getStringExtractor() const { diff --git a/include/llvm/DebugInfo/PDB/IPDBDataStream.h b/include/llvm/DebugInfo/PDB/IPDBDataStream.h index 9594dc1591a7..67b5a06d7c59 100644 --- a/include/llvm/DebugInfo/PDB/IPDBDataStream.h +++ b/include/llvm/DebugInfo/PDB/IPDBDataStream.h @@ -1,4 +1,4 @@ -//===- IPDBDataStream.h - base interface for child enumerator -*- C++ ---*-===// +//===- IPDBDataStream.h - base interface for child enumerator ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,9 +10,10 @@ #ifndef LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H #define LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H -#include "PDBTypes.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include <cstdint> +#include <string> namespace llvm { namespace pdb { @@ -22,18 +23,19 @@ namespace pdb { /// stream type. class IPDBDataStream { public: - typedef llvm::SmallVector<uint8_t, 32> RecordType; + using RecordType = SmallVector<uint8_t, 32>; virtual ~IPDBDataStream(); virtual uint32_t getRecordCount() const = 0; virtual std::string getName() const = 0; - virtual llvm::Optional<RecordType> getItemAtIndex(uint32_t Index) const = 0; + virtual Optional<RecordType> getItemAtIndex(uint32_t Index) const = 0; virtual bool getNext(RecordType &Record) = 0; virtual void reset() = 0; virtual IPDBDataStream *clone() const = 0; }; -} -} -#endif +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_IPDBDATASTREAM_H diff --git a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h index e48dc250822e..b6b7d95f6282 100644 --- a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h +++ b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h @@ -18,8 +18,8 @@ namespace pdb { template <typename ChildType> class IPDBEnumChildren { public: - typedef std::unique_ptr<ChildType> ChildTypePtr; - typedef IPDBEnumChildren<ChildType> MyType; + using ChildTypePtr = std::unique_ptr<ChildType>; + using MyType = IPDBEnumChildren<ChildType>; virtual ~IPDBEnumChildren() = default; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h index 2885081628f6..5f6e7ab92a96 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h @@ -7,22 +7,23 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H -#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H +#define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" -#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include <cstddef> #include <cstdint> +#include <iterator> #include <vector> namespace llvm { -namespace codeview {} namespace pdb { class DbiModuleList; @@ -31,9 +32,9 @@ struct FileInfoSubstreamHeader; class DbiModuleSourceFilesIterator : public iterator_facade_base<DbiModuleSourceFilesIterator, std::random_access_iterator_tag, StringRef> { - typedef iterator_facade_base<DbiModuleSourceFilesIterator, - std::random_access_iterator_tag, StringRef> - BaseType; + using BaseType = + iterator_facade_base<DbiModuleSourceFilesIterator, + std::random_access_iterator_tag, StringRef>; public: DbiModuleSourceFilesIterator(const DbiModuleList &Modules, uint32_t Modi, @@ -110,7 +111,8 @@ private: BinaryStreamRef FileInfoSubstream; BinaryStreamRef NamesBuffer; }; -} -} -#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H
\ No newline at end of file +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULELIST_H diff --git a/include/llvm/DebugInfo/PDB/Native/Hash.h b/include/llvm/DebugInfo/PDB/Native/Hash.h index 0340554d7b0b..1f11d43ecdd4 100644 --- a/include/llvm/DebugInfo/PDB/Native/Hash.h +++ b/include/llvm/DebugInfo/PDB/Native/Hash.h @@ -7,19 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_HASH_H -#define LLVM_DEBUGINFO_PDB_RAW_HASH_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_HASH_H +#define LLVM_DEBUGINFO_PDB_NATIVE_HASH_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include <stdint.h> +#include <cstdint> namespace llvm { namespace pdb { + uint32_t hashStringV1(StringRef Str); uint32_t hashStringV2(StringRef Str); uint32_t hashBufferV8(ArrayRef<uint8_t> Data); -} -} -#endif +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_HASH_H diff --git a/include/llvm/DebugInfo/PDB/Native/HashTable.h b/include/llvm/DebugInfo/PDB/Native/HashTable.h index 46eefa968e52..05c70c4f2175 100644 --- a/include/llvm/DebugInfo/PDB/Native/HashTable.h +++ b/include/llvm/DebugInfo/PDB/Native/HashTable.h @@ -7,36 +7,36 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_HASHTABLE_H -#define LLVM_DEBUGINFO_PDB_RAW_HASHTABLE_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H +#define LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SparseBitVector.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" -#include "llvm/Support/BinaryStreamArray.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" -#include "llvm/Support/MathExtras.h" - #include <cstdint> +#include <iterator> #include <utility> +#include <vector> namespace llvm { + +class BinaryStreamReader; +class BinaryStreamWriter; + namespace pdb { class HashTableIterator; class HashTable { friend class HashTableIterator; + struct Header { support::ulittle32_t Size; support::ulittle32_t Capacity; }; - typedef std::vector<std::pair<uint32_t, uint32_t>> BucketList; + using BucketList = std::vector<std::pair<uint32_t, uint32_t>>; public: HashTable(); @@ -63,6 +63,7 @@ public: protected: bool isPresent(uint32_t K) const { return Present.test(K); } bool isDeleted(uint32_t K) const { return Deleted.test(K); } + BucketList Buckets; mutable SparseBitVector<> Present; mutable SparseBitVector<> Deleted; @@ -81,6 +82,7 @@ class HashTableIterator : public iterator_facade_base<HashTableIterator, std::forward_iterator_tag, std::pair<uint32_t, uint32_t>> { friend class HashTable; + HashTableIterator(const HashTable &Map, uint32_t Index, bool IsEnd); public: @@ -101,6 +103,7 @@ private: }; } // end namespace pdb + } // end namespace llvm -#endif // LLVM_DEBUGINFO_PDB_RAW_HASHTABLE_H +#endif // LLVM_DEBUGINFO_PDB_NATIVE_HASHTABLE_H diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index 5565cd5582bc..f413fd1b336e 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -1,4 +1,4 @@ -//===- ModuleDebugStream.h - PDB Module Info Stream Access ----------------===// +//===- ModuleDebugStream.h - PDB Module Info Stream Access ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,26 +7,26 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H -#define LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H +#define LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H #include "llvm/ADT/iterator_range.h" -#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" +#include <cstdint> +#include <memory> namespace llvm { namespace pdb { -class PDBFile; + class DbiModuleDescriptor; class ModuleDebugStreamRef { - typedef codeview::DebugSubsectionArray::Iterator DebugSubsectionIterator; + using DebugSubsectionIterator = codeview::DebugSubsectionArray::Iterator; public: ModuleDebugStreamRef(const DbiModuleDescriptor &Module, @@ -50,7 +50,7 @@ public: ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default; - llvm::iterator_range<DebugSubsectionIterator> subsections() const; + iterator_range<DebugSubsectionIterator> subsections() const; bool hasDebugSubsections() const; @@ -75,7 +75,8 @@ private: codeview::DebugSubsectionArray Subsections; }; -} -} -#endif +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_MODULEDEBUGSTREAM_H diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h +++ /dev/null diff --git a/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h index d4206503e7dc..25f66240a6a2 100644 --- a/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h +++ b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h @@ -7,27 +7,31 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBNAMEDSTREAMMAP_H -#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEDSTREAMMAP_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/PDB/Native/HashTable.h" #include "llvm/Support/Error.h" #include <cstdint> namespace llvm { + class BinaryStreamReader; class BinaryStreamWriter; namespace pdb { -class NamedStreamMapBuilder; + class NamedStreamMap { + friend class NamedStreamMapBuilder; + struct FinalizationInfo { uint32_t StringDataBytes = 0; uint32_t SerializedLength = 0; }; - friend NamedStreamMapBuilder; public: NamedStreamMap(); @@ -50,6 +54,7 @@ private: }; } // end namespace pdb + } // end namespace llvm -#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEDSTREAMMAP_H +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NAMEDSTREAMMAP_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index 5e4aaafff1a9..a24a972879d2 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -1,4 +1,4 @@ -//===- NativeRawSymbol.h - Native implementation of IPDBRawSymbol - C++ -*-===// +//==- NativeRawSymbol.h - Native implementation of IPDBRawSymbol -*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -11,6 +11,8 @@ #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" +#include <cstdint> +#include <memory> namespace llvm { namespace pdb { @@ -36,7 +38,7 @@ public: std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const override; - void getDataBytes(llvm::SmallVector<uint8_t, 32> &Bytes) const override; + void getDataBytes(SmallVector<uint8_t, 32> &Bytes) const override; void getFrontEndVersion(VersionInfo &Version) const override; void getBackEndVersion(VersionInfo &Version) const override; PDB_MemberAccess getAccess() const override; @@ -206,7 +208,7 @@ protected: uint32_t SymbolId; }; -} -} +} // end namespace pdb +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index bbe207738e02..dd40874dc5f2 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -7,11 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_RAWSESSION_H -#define LLVM_DEBUGINFO_PDB_RAW_RAWSESSION_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" @@ -30,6 +32,9 @@ public: static Error createFromExe(StringRef Path, std::unique_ptr<IPDBSession> &Session); + std::unique_ptr<PDBSymbolCompiland> + createCompilandSymbol(DbiModuleDescriptor MI); + uint64_t getLoadAddress() const override; void setLoadAddress(uint64_t Address) override; std::unique_ptr<PDBSymbolExe> getGlobalScope() override; @@ -71,6 +76,7 @@ public: private: std::unique_ptr<PDBFile> Pdb; std::unique_ptr<BumpPtrAllocator> Allocator; + std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache; }; } } diff --git a/include/llvm/DebugInfo/PDB/PDB.h b/include/llvm/DebugInfo/PDB/PDB.h index 1f5a066b9a1b..9f9da39ca6cc 100644 --- a/include/llvm/DebugInfo/PDB/PDB.h +++ b/include/llvm/DebugInfo/PDB/PDB.h @@ -10,21 +10,23 @@ #ifndef LLVM_DEBUGINFO_PDB_PDB_H #define LLVM_DEBUGINFO_PDB_PDB_H -#include "PDBTypes.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/Error.h" #include <memory> -#include <system_error> namespace llvm { -class StringRef; - namespace pdb { +class IPDBSession; + Error loadDataForPDB(PDB_ReaderType Type, StringRef Path, std::unique_ptr<IPDBSession> &Session); Error loadDataForEXE(PDB_ReaderType Type, StringRef Path, std::unique_ptr<IPDBSession> &Session); -} -} -#endif + +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_PDB_H diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index fc5787556a6d..3a38f21b94c8 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -1,4 +1,4 @@ -//===- PDBExtras.h - helper functions and classes for PDBs -------*- C++-*-===// +//===- PDBExtras.h - helper functions and classes for PDBs ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,15 +10,17 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBEXTRAS_H #define LLVM_DEBUGINFO_PDB_PDBEXTRAS_H -#include "PDBTypes.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" #include <unordered_map> namespace llvm { +class raw_ostream; + namespace pdb { -typedef std::unordered_map<PDB_SymType, int> TagStats; + +using TagStats = std::unordered_map<PDB_SymType, int>; raw_ostream &operator<<(raw_ostream &OS, const PDB_VariantType &Value); raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv); @@ -37,7 +39,9 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine); raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version); raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats); -} -} -#endif +} // end namespace pdb + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_PDBEXTRAS_H diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index dd2fc4f2c55f..79ec7ce906d5 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -1,4 +1,4 @@ -//===- PDBTypes.h - Defines enums for various fields contained in PDB ---*-===// +//===- PDBTypes.h - Defines enums for various fields contained in PDB ----====// // // The LLVM Compiler Infrastructure // @@ -10,9 +10,10 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H #define LLVM_DEBUGINFO_PDB_PDBTYPES_H -#include "llvm/Config/llvm-config.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include <cstddef> #include <cstdint> #include <cstring> #include <functional> @@ -20,21 +21,11 @@ namespace llvm { namespace pdb { -class PDBSymDumper; -class PDBSymbol; - class IPDBDataStream; -template <class T> class IPDBEnumChildren; class IPDBLineNumber; -class IPDBRawSymbol; -class IPDBSession; class IPDBSourceFile; - -typedef IPDBEnumChildren<PDBSymbol> IPDBEnumSymbols; -typedef IPDBEnumChildren<IPDBSourceFile> IPDBEnumSourceFiles; -typedef IPDBEnumChildren<IPDBDataStream> IPDBEnumDataStreams; -typedef IPDBEnumChildren<IPDBLineNumber> IPDBEnumLineNumbers; - +class PDBSymDumper; +class PDBSymbol; class PDBSymbolExe; class PDBSymbolCompiland; class PDBSymbolCompilandDetails; @@ -67,6 +58,11 @@ class PDBSymbolTypeManaged; class PDBSymbolTypeDimension; class PDBSymbolUnknown; +using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>; +using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>; +using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>; +using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; + /// Specifies which PDB reader implementation is to be used. Only a value /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. enum class PDB_ReaderType { @@ -104,7 +100,7 @@ enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 }; /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx -typedef codeview::CPUType PDB_Cpu; +using PDB_Cpu = codeview::CPUType; enum class PDB_Machine { Invalid = 0xffff, @@ -135,12 +131,11 @@ enum class PDB_Machine { /// at the following locations: /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx -/// -typedef codeview::CallingConvention PDB_CallingConv; +using PDB_CallingConv = codeview::CallingConvention; /// These values correspond to the CV_CFL_LANG enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx -typedef codeview::SourceLanguage PDB_Lang; +using PDB_Lang = codeview::SourceLanguage; /// These values correspond to the DataKind enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx @@ -273,9 +268,9 @@ enum PDB_VariantType { }; struct Variant { - Variant() : Type(PDB_VariantType::Empty) {} + Variant() = default; - Variant(const Variant &Other) : Type(PDB_VariantType::Empty) { + Variant(const Variant &Other) { *this = Other; } @@ -284,7 +279,7 @@ struct Variant { delete[] Value.String; } - PDB_VariantType Type; + PDB_VariantType Type = PDB_VariantType::Empty; union { bool Bool; int8_t Int8; @@ -344,18 +339,20 @@ struct Variant { } }; +} // end namespace pdb } // end namespace llvm -} namespace std { + template <> struct hash<llvm::pdb::PDB_SymType> { - typedef llvm::pdb::PDB_SymType argument_type; - typedef std::size_t result_type; + using argument_type = llvm::pdb::PDB_SymType; + using result_type = std::size_t; result_type operator()(const argument_type &Arg) const { return std::hash<int>()(static_cast<int>(Arg)); } }; + } // end namespace std #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H diff --git a/include/llvm/DebugInfo/PDB/UDTLayout.h b/include/llvm/DebugInfo/PDB/UDTLayout.h index 6bc3660fbe51..c4234c191e21 100644 --- a/include/llvm/DebugInfo/PDB/UDTLayout.h +++ b/include/llvm/DebugInfo/PDB/UDTLayout.h @@ -10,30 +10,26 @@ #ifndef LLVM_DEBUGINFO_PDB_UDTLAYOUT_H #define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H -#include "PDBSymbol.h" -#include "PDBTypes.h" - #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" - -#include <list> +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include <cstdint> #include <memory> +#include <string> +#include <vector> namespace llvm { - -class raw_ostream; - namespace pdb { -class PDBSymTypeBaseClass; -class PDBSymbolData; -class PDBSymbolTypeUDT; -class PDBSymbolTypeVTable; - -class ClassLayout; class BaseClassLayout; -class LayoutItemBase; +class ClassLayout; class UDTLayoutBase; class LayoutItemBase { @@ -41,7 +37,7 @@ public: LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol, const std::string &Name, uint32_t OffsetInParent, uint32_t Size, bool IsElided); - virtual ~LayoutItemBase() {} + virtual ~LayoutItemBase() = default; uint32_t deepPaddingSize() const; virtual uint32_t immediatePadding() const { return 0; } @@ -79,7 +75,8 @@ public: VBPtrLayoutItem(const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset, uint32_t Size); - virtual bool isVBPtr() const { return true; } + + bool isVBPtr() const override { return true; } private: std::unique_ptr<PDBSymbolTypeBuiltin> Type; @@ -120,17 +117,12 @@ public: bool IsElided); uint32_t tailPadding() const override; - ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; } - ArrayRef<BaseClassLayout *> bases() const { return AllBases; } ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; } ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; } - uint32_t directVirtualBaseCount() const { return DirectVBaseCount; } - ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; } - ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; } protected: @@ -183,7 +175,8 @@ private: std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage; const PDBSymbolTypeUDT &UDT; }; -} -} // namespace llvm + +} // end namespace pdb +} // end namespace llvm #endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 8e9be6b6f4fe..cf6556a33bbd 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -15,9 +15,11 @@ #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include <memory> #include <string> namespace llvm { +class Module; namespace orc { /// @brief IR mutating layer. diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 3efcc637b6ed..497dca44547c 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -120,7 +120,7 @@ public: bool hasAttribute(Attribute::AttrKind Kind) const; /// Method for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == ArgumentVal; } }; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 7a35afcbafc3..6714f2c97473 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -326,7 +326,7 @@ public: ValueSymbolTable *getValueSymbolTable(); /// \brief Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::BasicBlockVal; } diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h index 82afd9a2691f..9daeac6ad6e7 100644 --- a/include/llvm/IR/Constant.h +++ b/include/llvm/IR/Constant.h @@ -116,7 +116,7 @@ public: void destroyConstant(); //// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() >= ConstantFirstVal && V->getValueID() <= ConstantLastVal; } diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index 003a6d5d075d..8b3a90fa065b 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -842,7 +842,7 @@ public: BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == BlockAddressVal; } }; @@ -1217,7 +1217,7 @@ public: Instruction *getAsInstruction(); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == ConstantExprVal; } diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index a92321a44511..6e5e085873ab 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -89,7 +89,7 @@ public: bool isPowerOf2ByteWidth() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == IntegerTyID; } }; @@ -139,7 +139,7 @@ public: unsigned getNumParams() const { return NumContainedTys - 1; } /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == FunctionTyID; } }; @@ -171,7 +171,7 @@ public: bool indexValid(unsigned Idx) const; /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || T->getTypeID() == VectorTyID; @@ -317,7 +317,7 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == StructTyID; } }; @@ -360,7 +360,7 @@ public: Type *getElementType() const { return ContainedType; } /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == VectorTyID; } }; @@ -380,7 +380,7 @@ public: static bool isValidElementType(Type *ElemTy); /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == ArrayTyID; } }; @@ -454,7 +454,7 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == VectorTyID; } }; @@ -495,7 +495,7 @@ public: inline unsigned getAddressSpace() const { return getSubclassData(); } /// Implement support type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const Type *T) { + static bool classof(const Type *T) { return T->getTypeID() == PointerTyID; } }; diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 9be6acc33591..e10d14c19793 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -36,12 +36,22 @@ class raw_ostream; extern template class DomTreeNodeBase<BasicBlock>; extern template class DominatorTreeBase<BasicBlock>; +namespace DomTreeBuilder { extern template void Calculate<Function, BasicBlock *>( DominatorTreeBaseByGraphTraits<GraphTraits<BasicBlock *>> &DT, Function &F); + extern template void Calculate<Function, Inverse<BasicBlock *>>( DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT, Function &F); +extern template bool Verify<BasicBlock *>( + const DominatorTreeBaseByGraphTraits<GraphTraits<BasicBlock *>> &DT); + +extern template bool Verify<Inverse<BasicBlock *>>( + const DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> + &DT); +} // namespace DomTreeBuilder + using DomTreeNode = DomTreeNodeBase<BasicBlock>; class BasicBlockEdge { diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 3496806d9362..75fccc135dae 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -671,7 +671,7 @@ public: void viewCFGOnly() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal; } diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index d4bf0d7e1ed4..450583baaa3c 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -88,7 +88,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::GlobalAliasVal; } }; diff --git a/include/llvm/IR/GlobalIFunc.h b/include/llvm/IR/GlobalIFunc.h index d90c7c78ed26..ef51315a6f5d 100644 --- a/include/llvm/IR/GlobalIFunc.h +++ b/include/llvm/IR/GlobalIFunc.h @@ -70,7 +70,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::GlobalIFuncVal; } }; diff --git a/include/llvm/IR/GlobalIndirectSymbol.h b/include/llvm/IR/GlobalIndirectSymbol.h index 212703af7101..22c00686c549 100644 --- a/include/llvm/IR/GlobalIndirectSymbol.h +++ b/include/llvm/IR/GlobalIndirectSymbol.h @@ -75,7 +75,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::GlobalAliasVal || V->getValueID() == Value::GlobalIFuncVal; } diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index fc38f698027b..278b193567f1 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -155,7 +155,7 @@ protected: public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal; } diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index 8255a4f298c0..34ace6f2b4f4 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -241,7 +241,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; } }; diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 7f03fcd19b65..59874b05b0ce 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -183,7 +183,7 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() == Value::InlineAsmVal; } diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 76524b412456..d749077fd34a 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -73,10 +73,10 @@ public: void setSuccessor(unsigned idx, BasicBlock *B); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->isTerminator(); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -298,14 +298,14 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || I->getOpcode() == Instruction::ExtractValue || (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -532,10 +532,10 @@ public: bool swapOperands(); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->isBinaryOp(); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -833,10 +833,10 @@ public: static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->isCast(); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -1062,11 +1062,11 @@ public: static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp || I->getOpcode() == Instruction::FCmp; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -1152,8 +1152,8 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { return I->isFuncletPad(); } - static inline bool classof(const Value *V) { + static bool classof(const Instruction *I) { return I->isFuncletPad(); } + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index d8db29e15886..8dc02111b866 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -556,7 +556,7 @@ public: /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return V->getValueID() >= Value::InstructionVal; } diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index e1620b3e7df5..dc5f37450b48 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -145,10 +145,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Alloca); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -284,10 +284,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -408,10 +408,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -483,10 +483,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Fence; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -639,10 +639,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicCmpXchg; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -788,10 +788,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -1048,10 +1048,10 @@ public: bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::GetElementPtr); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -1226,10 +1226,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ICmp; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -1334,10 +1334,10 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::FCmp; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -1873,10 +1873,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -2011,10 +2011,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Select; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2057,10 +2057,10 @@ public: static unsigned getPointerOperandIndex() { return 0U; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == VAArg; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2114,10 +2114,10 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractElement; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2177,10 +2177,10 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertElement; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2276,10 +2276,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2376,10 +2376,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ExtractValue; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2507,10 +2507,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::InsertValue; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2747,10 +2747,10 @@ public: bool hasConstantOrUndefValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::PHI; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -2856,10 +2856,10 @@ public: void reserveClauses(unsigned Size) { growOperands(Size); } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::LandingPad; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -2930,10 +2930,10 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Ret); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -3046,10 +3046,10 @@ public: void swapSuccessors(); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Br); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -3403,10 +3403,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Switch; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -3501,10 +3501,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::IndirectBr; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -3977,10 +3977,10 @@ public: unsigned getNumSuccessors() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::Invoke); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -4072,10 +4072,10 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Resume; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -4260,10 +4260,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchSwitch; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4306,10 +4306,10 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CleanupPad; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4356,10 +4356,10 @@ public: } /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::CatchPad; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4420,10 +4420,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CatchRet); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -4516,10 +4516,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CleanupRet); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -4577,10 +4577,10 @@ public: unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Unreachable; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } @@ -4627,10 +4627,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Trunc; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4666,10 +4666,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == ZExt; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4705,10 +4705,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == SExt; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4744,10 +4744,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == FPTrunc; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4783,10 +4783,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == FPExt; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4822,10 +4822,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == UIToFP; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4861,10 +4861,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == SIToFP; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4900,10 +4900,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == FPToUI; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4939,10 +4939,10 @@ public: ); /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == FPToSI; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -4982,10 +4982,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == IntToPtr; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -5033,10 +5033,10 @@ public: } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == PtrToInt; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -5072,10 +5072,10 @@ public: ); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == BitCast; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } }; @@ -5112,10 +5112,10 @@ public: ); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == AddrSpaceCast; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) && classof(cast<Instruction>(V)); } diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index e0dd3ca7d01e..944af57a7800 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -53,12 +53,12 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CallInst *I) { + static bool classof(const CallInst *I) { if (const Function *CF = I->getCalledFunction()) return CF->isIntrinsic(); return false; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<CallInst>(V) && classof(cast<CallInst>(V)); } }; @@ -72,7 +72,7 @@ namespace llvm { Value *getVariableLocation(bool AllowNullOp = true) const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::dbg_declare: case Intrinsic::dbg_value: @@ -80,7 +80,7 @@ namespace llvm { default: return false; } } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -107,10 +107,10 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_declare; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -144,10 +144,10 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::dbg_value; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -176,7 +176,7 @@ namespace llvm { ExceptionBehavior getExceptionBehavior() const; // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::experimental_constrained_fadd: case Intrinsic::experimental_constrained_fsub: @@ -199,7 +199,7 @@ namespace llvm { default: return false; } } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -288,10 +288,10 @@ namespace llvm { setArgOperand(ARG_ELEMENTSIZE, V); } - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -358,7 +358,7 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { switch (I->getIntrinsicID()) { case Intrinsic::memcpy: case Intrinsic::memmove: @@ -367,7 +367,7 @@ namespace llvm { default: return false; } } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -387,10 +387,10 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memset; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -419,11 +419,11 @@ namespace llvm { } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy || I->getIntrinsicID() == Intrinsic::memmove; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -432,10 +432,10 @@ namespace llvm { class MemCpyInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memcpy; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -444,10 +444,10 @@ namespace llvm { class MemMoveInst : public MemTransferInst { public: // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::memmove; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -455,10 +455,10 @@ namespace llvm { /// This represents the llvm.va_start intrinsic. class VAStartInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::vastart; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -468,10 +468,10 @@ namespace llvm { /// This represents the llvm.va_end intrinsic. class VAEndInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::vaend; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -481,10 +481,10 @@ namespace llvm { /// This represents the llvm.va_copy intrinsic. class VACopyInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::vacopy; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -495,10 +495,10 @@ namespace llvm { /// This represents the llvm.instrprof_increment intrinsic. class InstrProfIncrementInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::instrprof_increment; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -524,10 +524,10 @@ namespace llvm { class InstrProfIncrementInstStep : public InstrProfIncrementInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; @@ -535,10 +535,10 @@ namespace llvm { /// This represents the llvm.instrprof_value_profile intrinsic. class InstrProfValueProfileInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index 3a0957dfa39b..640ef627bc46 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -19,4 +19,8 @@ let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.". def int_wasm_current_memory : Intrinsic<[llvm_anyint_ty], [], [IntrReadMem]>; def int_wasm_grow_memory : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], []>; +// Exception handling intrinsics +def int_wasm_throw: Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], [Throws]>; +def int_wasm_rethrow: Intrinsic<[], [], [Throws]>; + } diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index ad011fb72e6a..b27abad618c9 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -188,10 +188,19 @@ public: /// \brief Return if a code hotness metric should be included in optimization /// diagnostics. - bool getDiagnosticHotnessRequested() const; + bool getDiagnosticsHotnessRequested() const; /// \brief Set if a code hotness metric should be included in optimization /// diagnostics. - void setDiagnosticHotnessRequested(bool Requested); + void setDiagnosticsHotnessRequested(bool Requested); + + /// \brief Return the minimum hotness value a diagnostic would need in order + /// to be included in optimization diagnostics. If there is no minimum, this + /// returns None. + uint64_t getDiagnosticsHotnessThreshold() const; + + /// \brief Set the minimum hotness value a diagnostic needs in order to be + /// included in optimization diagnostics. + void setDiagnosticsHotnessThreshold(uint64_t Threshold); /// \brief Return the YAML file used by the backend to save optimization /// diagnostics. If null, diagnostics are not saved in a file but only diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h index fd9d468b06cb..4cec08196408 100644 --- a/include/llvm/IR/LegacyPassNameParser.h +++ b/include/llvm/IR/LegacyPassNameParser.h @@ -81,15 +81,15 @@ public: // default implementation to sort the table before we print... void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override { PassNameParser *PNP = const_cast<PassNameParser*>(this); - array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan); + array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValCompare); cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth); } private: - // ValLessThan - Provide a sorting comparator for Values elements... - static int ValLessThan(const PassNameParser::OptionInfo *VT1, - const PassNameParser::OptionInfo *VT2) { - return VT1->Name < VT2->Name; + // ValCompare - Provide a sorting comparator for Values elements... + static int ValCompare(const PassNameParser::OptionInfo *VT1, + const PassNameParser::OptionInfo *VT2) { + return VT1->Name.compare(VT2->Name); } }; diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 80ed44be43eb..3462cc02fd27 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -660,6 +660,19 @@ struct AAMDNodes { /// \brief The tag specifying the noalias scope. MDNode *NoAlias; + + /// \brief Given two sets of AAMDNodes that apply to the same pointer, + /// give the best AAMDNodes that are compatible with both (i.e. a set of + /// nodes whose allowable aliasing conclusions are a subset of those + /// allowable by both of the inputs). However, for efficiency + /// reasons, do not create any new MDNodes. + AAMDNodes intersect(const AAMDNodes &Other) { + AAMDNodes Result; + Result.TBAA = Other.TBAA == TBAA ? TBAA : nullptr; + Result.Scope = Other.Scope == Scope ? Scope : nullptr; + Result.NoAlias = Other.NoAlias == NoAlias ? NoAlias : nullptr; + return Result; + } }; // Specialize DenseMapInfo for AAMDNodes. diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h index 5d7b8b997d37..7f6cb5bee5a6 100644 --- a/include/llvm/IR/ModuleSummaryIndexYAML.h +++ b/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -140,8 +140,6 @@ struct FunctionSummaryYaml { } // End yaml namespace } // End llvm namespace -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) - namespace llvm { namespace yaml { @@ -188,7 +186,6 @@ template <> struct MappingTraits<FunctionSummaryYaml> { LLVM_YAML_IS_STRING_MAP(TypeIdSummary) LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string) namespace llvm { namespace yaml { diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index c7f4697e93e7..9df6bfc54cd4 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -54,9 +54,9 @@ public: return Instruction::UserOp1; } - static inline bool classof(const Instruction *) { return true; } - static inline bool classof(const ConstantExpr *) { return true; } - static inline bool classof(const Value *V) { + static bool classof(const Instruction *) { return true; } + static bool classof(const ConstantExpr *) { return true; } + static bool classof(const Value *V) { return isa<Instruction>(V) || isa<ConstantExpr>(V); } }; @@ -97,19 +97,19 @@ public: return (SubclassOptionalData & NoSignedWrap) != 0; } - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub || I->getOpcode() == Instruction::Mul || I->getOpcode() == Instruction::Shl; } - static inline bool classof(const ConstantExpr *CE) { + static bool classof(const ConstantExpr *CE) { return CE->getOpcode() == Instruction::Add || CE->getOpcode() == Instruction::Sub || CE->getOpcode() == Instruction::Mul || CE->getOpcode() == Instruction::Shl; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } @@ -144,13 +144,13 @@ public: OpC == Instruction::LShr; } - static inline bool classof(const ConstantExpr *CE) { + static bool classof(const ConstantExpr *CE) { return isPossiblyExactOpcode(CE->getOpcode()); } - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return isPossiblyExactOpcode(I->getOpcode()); } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } @@ -324,17 +324,17 @@ public: /// precision. float getFPAccuracy() const; - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getType()->isFPOrFPVectorTy() || I->getOpcode() == Instruction::FCmp; } - static inline bool classof(const ConstantExpr *CE) { + static bool classof(const ConstantExpr *CE) { return CE->getType()->isFPOrFPVectorTy() || CE->getOpcode() == Instruction::FCmp; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } @@ -344,13 +344,13 @@ public: template<typename SuperClass, unsigned Opc> class ConcreteOperator : public SuperClass { public: - static inline bool classof(const Instruction *I) { + static bool classof(const Instruction *I) { return I->getOpcode() == Opc; } - static inline bool classof(const ConstantExpr *CE) { + static bool classof(const ConstantExpr *CE) { return CE->getOpcode() == Opc; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 9e9c8ac75d2a..5b69e7855cc7 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -378,7 +378,7 @@ struct bind_const_intval_ty { template <typename ITy> bool match(ITy *V) { if (const auto *CV = dyn_cast<ConstantInt>(V)) - if (CV->getBitWidth() <= 64) { + if (CV->getValue().ule(UINT64_MAX)) { VR = CV->getZExtValue(); return true; } @@ -399,10 +399,7 @@ struct specific_intval { if (const auto *C = dyn_cast<Constant>(V)) CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()); - if (CI && CI->getBitWidth() <= 64) - return CI->getZExtValue() == Val; - - return false; + return CI && CI->getValue() == Val; } }; @@ -1363,6 +1360,11 @@ m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { // Helper intrinsic matching specializations. template <typename Opnd0> +inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) { + return m_Intrinsic<Intrinsic::bitreverse>(Op0); +} + +template <typename Opnd0> inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BSwap(const Opnd0 &Op0) { return m_Intrinsic<Intrinsic::bswap>(Op0); } diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 630f30667272..ad9537e9762e 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -329,12 +329,12 @@ public: /// Currently, the only projections available are gc.result and gc.relocate. class GCProjectionInst : public IntrinsicInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate || I->getIntrinsicID() == Intrinsic::experimental_gc_result; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -373,11 +373,11 @@ public: /// Represents calls to the gc.relocate intrinsic. class GCRelocateInst : public GCProjectionInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -408,11 +408,11 @@ public: /// Represents calls to the gc.result intrinsic. class GCResultInst : public GCProjectionInst { public: - static inline bool classof(const IntrinsicInst *I) { + static bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::experimental_gc_result; } - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } }; diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 109a3d5e7be8..4dfa19cf241f 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -288,7 +288,7 @@ public: void replaceUsesOfWith(Value *From, Value *To); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Value *V) { + static bool classof(const Value *V) { return isa<Instruction>(V) || isa<Constant>(V); } }; diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index a52fa3b542a5..aab14070dbda 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -70,7 +70,6 @@ void initializeAlwaysInlinerLegacyPassPass(PassRegistry&); void initializeArgPromotionPass(PassRegistry&); void initializeAssumptionCacheTrackerPass(PassRegistry&); void initializeAtomicExpandPass(PassRegistry&); -void initializeBBVectorizePass(PassRegistry&); void initializeBDCELegacyPassPass(PassRegistry&); void initializeBarrierNoopPass(PassRegistry&); void initializeBasicAAWrapperPassPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index c309ddbe2f02..d07c15c1013b 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -195,7 +195,6 @@ namespace { (void) llvm::createLoopVectorizePass(); (void) llvm::createSLPVectorizerPass(); (void) llvm::createLoadStoreVectorizerPass(); - (void) llvm::createBBVectorizePass(); (void) llvm::createPartiallyInlineLibCallsPass(); (void) llvm::createScalarizerPass(); (void) llvm::createSeparateConstOffsetFromGEPPass(); diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index a270973204f2..c9c43a22da5d 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -60,11 +60,12 @@ public: /// Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; - /// Target hook to adjust the literal value of a fixup if necessary. - /// IsResolved signals whether the caller believes a relocation is needed; the - /// target can modify the value. The default does nothing. - virtual void processFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, bool &IsResolved) {} + /// Hook to check if a relocation is needed for some target specific reason. + virtual bool shouldForceRelocation(const MCAssembler &Asm, + const MCFixup &Fixup, + const MCValue &Target) { + return false; + } /// Apply the \p Value for given \p Fixup into the provided data fragment, at /// the offset specified by the fixup and following the fixup kind as diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 6e14cefaa0ab..198a08b5f539 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -13,6 +13,7 @@ namespace llvm { class MCAsmBackend; +class MCContext; class MCFixup; class MCObjectWriter; class MCValue; diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 6c5fb9d5c92b..e56e8e464de3 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -253,7 +253,7 @@ public: } // Cast methods. - static inline bool classof(Binary const *v) { + static bool classof(Binary const *v) { return v->isArchive(); } diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index bf0172822d3f..78e0b5f6ed30 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -1026,7 +1026,7 @@ public: bool isRelocatableObject() const override; bool is64() const { return PE32PlusHeader; } - static inline bool classof(const Binary *v) { return v->isCOFF(); } + static bool classof(const Binary *v) { return v->isCOFF(); } }; // The iterator for the import directory table. diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index 78044a2832fa..060f965233e1 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -33,7 +33,7 @@ public: COFFImportFile(MemoryBufferRef Source) : SymbolicFile(ID_COFFImportFile, Source) {} - static inline bool classof(Binary const *V) { return V->isCOFFImportFile(); } + static bool classof(Binary const *V) { return V->isCOFFImportFile(); } void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; } diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 2ba3b13f49da..73011f6f9fe1 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -70,7 +70,7 @@ public: elf_symbol_iterator_range symbols() const; - static inline bool classof(const Binary *v) { return v->isELF(); } + static bool classof(const Binary *v) { return v->isELF(); } SubtargetFeatures getFeatures() const override; @@ -389,7 +389,7 @@ public: const ELFFile<ELFT> *getELFFile() const { return &EF; } bool isDyldType() const { return isDyldELFObject; } - static inline bool classof(const Binary *v) { + static bool classof(const Binary *v) { return v->getType() == getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits); } diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index 3bce7813ee93..9a696bffd1f0 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -46,7 +46,7 @@ public: StringRef getTargetTriple() const; - static inline bool classof(const Binary *v) { + static bool classof(const Binary *v) { return v->isIR(); } diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index 502f133d307d..824a67a672fa 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -124,6 +124,18 @@ struct Uncommon { }; struct Header { + /// Version number of the symtab format. This number should be incremented + /// when the format changes, but it does not need to be incremented if a + /// change to LLVM would cause it to create a different symbol table. + Word Version; + enum { kCurrentVersion = 0 }; + + /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION). + /// Consumers should rebuild the symbol table from IR if the producer's + /// version does not match the consumer's version due to potential differences + /// in symbol table format, symbol enumeration order and so on. + Str Producer; + Range<Module> Modules; Range<Comdat> Comdats; Range<Symbol> Symbols; @@ -243,6 +255,8 @@ public: /// copied into an irsymtab::Symbol object. symbol_range symbols() const; + size_t getNumModules() const { return Modules.size(); } + /// Returns a slice of the symbol table for the I'th module in the file. /// The symbols enumerated by this method are ephemeral, but they can be /// copied into an irsymtab::Symbol object. diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index 8a6f0fc56971..72837d0970c4 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -154,7 +154,7 @@ public: uint32_t getNumberOfObjects() const { return NumberOfObjects; } // Cast methods. - static inline bool classof(Binary const *V) { + static bool classof(Binary const *V) { return V->isMachOUniversalBinary(); } diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 6b5b9d95fcf3..afcad3090703 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -313,7 +313,7 @@ public: return createObjectFile(Object, llvm::file_magic::unknown); } - static inline bool classof(const Binary *v) { + static bool classof(const Binary *v) { return v->isObject(); } diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 97eeba6611a2..5b9549bc3449 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -173,7 +173,7 @@ public: static Expected<OwningBinary<SymbolicFile>> createSymbolicFile(StringRef ObjectPath); - static inline bool classof(const Binary *v) { + static bool classof(const Binary *v) { return v->isSymbolic(); } }; diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 9d53131234f4..5c8445f10f44 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -100,6 +100,7 @@ public: const std::vector<wasm::WasmLimits>& memories() const { return Memories; } const std::vector<wasm::WasmGlobal>& globals() const { return Globals; } const std::vector<wasm::WasmExport>& exports() const { return Exports; } + const wasm::WasmLinkingData& linkingData() const { return LinkingData; } uint32_t getNumberOfSymbols() const { return Symbols.size(); @@ -214,6 +215,8 @@ private: std::vector<WasmSymbol> Symbols; ArrayRef<uint8_t> CodeSection; uint32_t StartFunction = -1; + bool HasLinkingSection = false; + wasm::WasmLinkingData LinkingData; StringMap<uint32_t> SymbolMap; }; diff --git a/include/llvm/ObjectYAML/COFFYAML.h b/include/llvm/ObjectYAML/COFFYAML.h index 719cb1acf6ef..bbceefac3d94 100644 --- a/include/llvm/ObjectYAML/COFFYAML.h +++ b/include/llvm/ObjectYAML/COFFYAML.h @@ -15,14 +15,18 @@ #define LLVM_OBJECTYAML_COFFYAML_H #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" #include "llvm/ObjectYAML/CodeViewYAMLTypes.h" #include "llvm/ObjectYAML/YAML.h" +#include <cstdint> +#include <vector> namespace llvm { namespace COFF { + inline Characteristics operator|(Characteristics a, Characteristics b) { uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b); return static_cast<Characteristics>(Ret); @@ -39,60 +43,67 @@ inline DLLCharacteristics operator|(DLLCharacteristics a, uint16_t Ret = static_cast<uint16_t>(a) | static_cast<uint16_t>(b); return static_cast<DLLCharacteristics>(Ret); } -} + +} // end namespace COFF // The structure of the yaml files is not an exact 1:1 match to COFF. In order // to use yaml::IO, we use these structures which are closer to the source. namespace COFFYAML { - LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType) - LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics) - LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType) - - struct Relocation { - uint32_t VirtualAddress; - uint16_t Type; - StringRef SymbolName; - }; - - struct Section { - COFF::section Header; - unsigned Alignment = 0; - yaml::BinaryRef SectionData; - std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS; - std::vector<CodeViewYAML::LeafRecord> DebugT; - std::vector<Relocation> Relocations; - StringRef Name; - Section(); - }; - - struct Symbol { - COFF::symbol Header; - COFF::SymbolBaseType SimpleType = COFF::IMAGE_SYM_TYPE_NULL; - COFF::SymbolComplexType ComplexType = COFF::IMAGE_SYM_DTYPE_NULL; - Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition; - Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol; - Optional<COFF::AuxiliaryWeakExternal> WeakExternal; - StringRef File; - Optional<COFF::AuxiliarySectionDefinition> SectionDefinition; - Optional<COFF::AuxiliaryCLRToken> CLRToken; - StringRef Name; - Symbol(); - }; - - struct PEHeader { - COFF::PE32Header Header; - Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES]; - }; - - struct Object { - Optional<PEHeader> OptionalHeader; - COFF::header Header; - std::vector<Section> Sections; - std::vector<Symbol> Symbols; - Object(); - }; -} -} + +LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType) + +struct Relocation { + uint32_t VirtualAddress; + uint16_t Type; + StringRef SymbolName; +}; + +struct Section { + COFF::section Header; + unsigned Alignment = 0; + yaml::BinaryRef SectionData; + std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS; + std::vector<CodeViewYAML::LeafRecord> DebugT; + std::vector<Relocation> Relocations; + StringRef Name; + + Section(); +}; + +struct Symbol { + COFF::symbol Header; + COFF::SymbolBaseType SimpleType = COFF::IMAGE_SYM_TYPE_NULL; + COFF::SymbolComplexType ComplexType = COFF::IMAGE_SYM_DTYPE_NULL; + Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition; + Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol; + Optional<COFF::AuxiliaryWeakExternal> WeakExternal; + StringRef File; + Optional<COFF::AuxiliarySectionDefinition> SectionDefinition; + Optional<COFF::AuxiliaryCLRToken> CLRToken; + StringRef Name; + + Symbol(); +}; + +struct PEHeader { + COFF::PE32Header Header; + Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES]; +}; + +struct Object { + Optional<PEHeader> OptionalHeader; + COFF::header Header; + std::vector<Section> Sections; + std::vector<Symbol> Symbols; + + Object(); +}; + +} // end namespace COFFYAML + +} // end namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) @@ -224,4 +235,4 @@ struct MappingTraits<COFFYAML::Object> { } // end namespace yaml } // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_COFFYAML_H diff --git a/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h b/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h index 8180e0fc83f4..d620008e22d2 100644 --- a/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h +++ b/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h @@ -1,4 +1,4 @@ -//===- CodeViewYAMLDebugSections.h - CodeView YAMLIO debug sections -------===// +//=- CodeViewYAMLDebugSections.h - CodeView YAMLIO debug sections -*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -15,27 +15,33 @@ #ifndef LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H #define LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" -#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <memory> +#include <vector> namespace llvm { namespace codeview { -class DebugStringTableSubsection; -class DebugStringTableSubsectionRef; -class DebugChecksumsSubsectionRef; -class DebugStringTableSubsection; -class DebugChecksumsSubsection; + class StringsAndChecksums; class StringsAndChecksumsRef; -} + +} // end namespace codeview + namespace CodeViewYAML { namespace detail { + struct YAMLSubsectionBase; -} + +} // end namespace detail struct YAMLFrameData { uint32_t RvaStart; @@ -87,7 +93,6 @@ struct SourceLineInfo { uint32_t RelocSegment; codeview::LineFlags Flags; uint32_t CodeSize; - std::vector<SourceLineBlock> Blocks; }; @@ -124,11 +129,12 @@ fromDebugS(ArrayRef<uint8_t> Data, const codeview::StringsAndChecksumsRef &SC); void initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC); -} // namespace CodeViewYAML -} // namespace llvm +} // end namespace CodeViewYAML + +} // end namespace llvm LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::YAMLDebugSubsection) LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::YAMLDebugSubsection) -#endif +#endif // LLVM_OBJECTYAML_CODEVIEWYAMLDEBUGSECTIONS_H diff --git a/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h b/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h index 9b411e8b074f..791193c78f19 100644 --- a/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h +++ b/include/llvm/ObjectYAML/CodeViewYAMLSymbols.h @@ -17,13 +17,18 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include <memory> namespace llvm { namespace CodeViewYAML { + namespace detail { + struct SymbolRecordBase; -} + +} // end namespace detail struct SymbolRecord { std::shared_ptr<detail::SymbolRecordBase> Symbol; @@ -31,13 +36,14 @@ struct SymbolRecord { codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, codeview::CodeViewContainer Container) const; + static Expected<SymbolRecord> fromCodeViewSymbol(codeview::CVSymbol Symbol); }; -} // namespace CodeViewYAML -} // namespace llvm +} // end namespace CodeViewYAML +} // end namespace llvm LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SymbolRecord) LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::SymbolRecord) -#endif +#endif // LLVM_OBJECTYAML_CODEVIEWYAMLSYMBOLS_H diff --git a/include/llvm/ObjectYAML/CodeViewYAMLTypes.h b/include/llvm/ObjectYAML/CodeViewYAMLTypes.h index e97d5f92bf7f..6746fd60b6cb 100644 --- a/include/llvm/ObjectYAML/CodeViewYAMLTypes.h +++ b/include/llvm/ObjectYAML/CodeViewYAMLTypes.h @@ -1,4 +1,4 @@ -//===- CodeViewYAMLTypes.h - CodeView YAMLIO Type Record implementation ---===// +//==- CodeViewYAMLTypes.h - CodeView YAMLIO Type implementation --*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -15,20 +15,31 @@ #ifndef LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H #define LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H -#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <memory> +#include <vector> namespace llvm { + namespace codeview { + class TypeTableBuilder; -} + +} // end namespace codeview + namespace CodeViewYAML { + namespace detail { + struct LeafRecordBase; struct MemberRecordBase; -} + +} // end namespace detail struct MemberRecord { std::shared_ptr<detail::MemberRecordBase> Member; @@ -44,8 +55,10 @@ struct LeafRecord { std::vector<LeafRecord> fromDebugT(ArrayRef<uint8_t> DebugT); ArrayRef<uint8_t> toDebugT(ArrayRef<LeafRecord>, BumpPtrAllocator &Alloc); -} // namespace CodeViewYAML -} // namespace llvm + +} // end namespace CodeViewYAML + +} // end namespace llvm LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord) LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord) @@ -53,4 +66,4 @@ LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord) LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::LeafRecord) LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::MemberRecord) -#endif +#endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H diff --git a/include/llvm/ObjectYAML/DWARFEmitter.h b/include/llvm/ObjectYAML/DWARFEmitter.h index ce231cc0ce68..0d7d8b4efbdf 100644 --- a/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/include/llvm/ObjectYAML/DWARFEmitter.h @@ -1,5 +1,4 @@ -//===--- DWARFEmitter.h - -------------------------------------------*- C++ -//-*-===// +//===--- DWARFEmitter.h - ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,6 +9,7 @@ /// \file /// \brief Common declarations for yaml2obj //===----------------------------------------------------------------------===// + #ifndef LLVM_OBJECTYAML_DWARFEMITTER_H #define LLVM_OBJECTYAML_DWARFEMITTER_H @@ -19,30 +19,31 @@ #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include <memory> -#include <vector> namespace llvm { + class raw_ostream; namespace DWARFYAML { + struct Data; struct PubSection; -void EmitDebugAbbrev(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); -void EmitDebugStr(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); +void EmitDebugAbbrev(raw_ostream &OS, const Data &DI); +void EmitDebugStr(raw_ostream &OS, const Data &DI); -void EmitDebugAranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); -void EmitPubSection(llvm::raw_ostream &OS, - const llvm::DWARFYAML::PubSection &Sect, +void EmitDebugAranges(raw_ostream &OS, const Data &DI); +void EmitPubSection(raw_ostream &OS, const PubSection &Sect, bool IsLittleEndian); -void EmitDebugInfo(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); -void EmitDebugLine(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); +void EmitDebugInfo(raw_ostream &OS, const Data &DI); +void EmitDebugLine(raw_ostream &OS, const Data &DI); Expected<StringMap<std::unique_ptr<MemoryBuffer>>> EmitDebugSections(StringRef YAMLString, bool IsLittleEndian = sys::IsLittleEndianHost); -} // namespace DWARFYAML -} // namespace llvm +} // end namespace DWARFYAML + +} // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_DWARFEMITTER_H diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h index 75e9112e121a..2162f0fef852 100644 --- a/include/llvm/ObjectYAML/DWARFYAML.h +++ b/include/llvm/ObjectYAML/DWARFYAML.h @@ -16,8 +16,11 @@ #ifndef LLVM_OBJECTYAML_DWARFYAML_H #define LLVM_OBJECTYAML_DWARFYAML_H +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <vector> namespace llvm { namespace DWARFYAML { @@ -76,13 +79,11 @@ struct PubEntry { }; struct PubSection { - PubSection() : IsGNUStyle(false) {} - InitialLength Length; uint16_t Version; uint32_t UnitOffset; uint32_t UnitSize; - bool IsGNUStyle; + bool IsGNUStyle = false; std::vector<PubEntry> Entries; }; @@ -158,12 +159,10 @@ struct Data { bool isEmpty() const; }; -} // namespace llvm::DWARFYAML -} // namespace llvm +} // end namespace DWARFYAML +} // end namespace llvm -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint8_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev) @@ -304,7 +303,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Constants> { } }; -} // namespace llvm::yaml -} // namespace llvm +} // end namespace yaml +} // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_DWARFYAML_H diff --git a/include/llvm/ObjectYAML/ELFYAML.h b/include/llvm/ObjectYAML/ELFYAML.h index 9d62ec27ad31..ed455311696e 100644 --- a/include/llvm/ObjectYAML/ELFYAML.h +++ b/include/llvm/ObjectYAML/ELFYAML.h @@ -16,8 +16,12 @@ #ifndef LLVM_OBJECTYAML_ELFYAML_H #define LLVM_OBJECTYAML_ELFYAML_H -#include "llvm/BinaryFormat/ELF.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <memory> +#include <vector> namespace llvm { namespace ELFYAML { @@ -66,6 +70,7 @@ struct FileHeader { ELF_EF Flags; llvm::yaml::Hex64 Entry; }; + struct Symbol { StringRef Name; ELF_STT Type; @@ -74,6 +79,7 @@ struct Symbol { llvm::yaml::Hex64 Size; uint8_t Other; }; + struct LocalGlobalWeakSymbols { std::vector<Symbol> Local; std::vector<Symbol> Global; @@ -100,13 +106,16 @@ struct Section { StringRef Link; StringRef Info; llvm::yaml::Hex64 AddressAlign; + Section(SectionKind Kind) : Kind(Kind) {} virtual ~Section(); }; struct RawContentSection : Section { yaml::BinaryRef Content; llvm::yaml::Hex64 Size; + RawContentSection() : Section(SectionKind::RawContent) {} + static bool classof(const Section *S) { return S->Kind == SectionKind::RawContent; } @@ -114,7 +123,9 @@ 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; } @@ -124,7 +135,9 @@ struct Group : Section { // Members of a group contain a flag and a list of section indices // that are part of the group. std::vector<SectionOrType> Members; + Group() : Section(SectionKind::Group) {} + static bool classof(const Section *S) { return S->Kind == SectionKind::Group; } @@ -136,9 +149,12 @@ struct Relocation { ELF_REL Type; StringRef Symbol; }; + struct RelocationSection : Section { std::vector<Relocation> Relocations; + RelocationSection() : Section(SectionKind::Relocation) {} + static bool classof(const Section *S) { return S->Kind == SectionKind::Relocation; } @@ -157,7 +173,9 @@ struct MipsABIFlags : Section { MIPS_AFL_ASE ASEs; MIPS_AFL_FLAGS1 Flags1; llvm::yaml::Hex32 Flags2; + MipsABIFlags() : Section(SectionKind::MipsABIFlags) {} + static bool classof(const Section *S) { return S->Kind == SectionKind::MipsABIFlags; } @@ -316,4 +334,4 @@ template <> struct MappingTraits<ELFYAML::SectionOrType> { } // end namespace yaml } // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_ELFYAML_H diff --git a/include/llvm/ObjectYAML/MachOYAML.h b/include/llvm/ObjectYAML/MachOYAML.h index 59aca9a1ddf2..305497b6aa6a 100644 --- a/include/llvm/ObjectYAML/MachOYAML.h +++ b/include/llvm/ObjectYAML/MachOYAML.h @@ -16,9 +16,13 @@ #ifndef LLVM_OBJECTYAML_MACHOYAML_H #define LLVM_OBJECTYAML_MACHOYAML_H +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/ObjectYAML/DWARFYAML.h" -#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <string> +#include <vector> namespace llvm { namespace MachOYAML { @@ -51,6 +55,7 @@ struct FileHeader { struct LoadCommand { virtual ~LoadCommand(); + llvm::MachO::macho_load_command Data; std::vector<Section> Sections; std::vector<MachO::build_tool_version> Tools; @@ -66,6 +71,7 @@ struct NListEntry { uint16_t n_desc; uint64_t n_value; }; + struct RebaseOpcode { MachO::RebaseOpcode Opcode; uint8_t Imm; @@ -81,15 +87,12 @@ struct BindOpcode { }; struct ExportEntry { - ExportEntry() - : TerminalSize(0), NodeOffset(0), Name(), Flags(0), Address(0), Other(0), - ImportName(), Children() {} - uint64_t TerminalSize; - uint64_t NodeOffset; + uint64_t TerminalSize = 0; + uint64_t NodeOffset = 0; std::string Name; - llvm::yaml::Hex64 Flags; - llvm::yaml::Hex64 Address; - llvm::yaml::Hex64 Other; + llvm::yaml::Hex64 Flags = 0; + llvm::yaml::Hex64 Address = 0; + llvm::yaml::Hex64 Other = 0; std::string ImportName; std::vector<MachOYAML::ExportEntry> Children; }; @@ -135,12 +138,11 @@ struct UniversalBinary { std::vector<Object> Slices; }; -} // namespace llvm::MachOYAML -} // namespace llvm +} // end namespace MachOYAML +} // end namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section) -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int64_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry) @@ -150,6 +152,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version) namespace llvm { + +class raw_ostream; + namespace yaml { template <> struct MappingTraits<MachOYAML::FileHeader> { @@ -251,22 +256,20 @@ template <> struct ScalarEnumerationTraits<MachO::BindOpcode> { }; // This trait is used for 16-byte chars in Mach structures used for strings -typedef char char_16[16]; +using char_16 = char[16]; template <> struct ScalarTraits<char_16> { - static void output(const char_16 &Val, void *, llvm::raw_ostream &Out); - + static void output(const char_16 &Val, void *, raw_ostream &Out); static StringRef input(StringRef Scalar, void *, char_16 &Val); static bool mustQuote(StringRef S); }; // This trait is used for UUIDs. It reads and writes them matching otool's // formatting style. -typedef uint8_t uuid_t[16]; +using uuid_t = uint8_t[16]; template <> struct ScalarTraits<uuid_t> { - static void output(const uuid_t &Val, void *, llvm::raw_ostream &Out); - + static void output(const uuid_t &Val, void *, raw_ostream &Out); static StringRef input(StringRef Scalar, void *, uuid_t &Val); static bool mustQuote(StringRef S); }; @@ -297,8 +300,8 @@ template <> struct MappingTraits<MachO::section_64> { static void mapping(IO &IO, MachO::section_64 &LoadCommand); }; -} // namespace llvm::yaml +} // end namespace yaml -} // namespace llvm +} // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_MACHOYAML_H diff --git a/include/llvm/ObjectYAML/ObjectYAML.h b/include/llvm/ObjectYAML/ObjectYAML.h index 36d6ed5417cf..00ce86430fca 100644 --- a/include/llvm/ObjectYAML/ObjectYAML.h +++ b/include/llvm/ObjectYAML/ObjectYAML.h @@ -15,10 +15,13 @@ #include "llvm/ObjectYAML/MachOYAML.h" #include "llvm/ObjectYAML/WasmYAML.h" #include "llvm/Support/YAMLTraits.h" +#include <memory> namespace llvm { namespace yaml { +class IO; + struct YamlObjectFile { std::unique_ptr<ELFYAML::Object> Elf; std::unique_ptr<COFFYAML::Object> Coff; @@ -31,7 +34,7 @@ template <> struct MappingTraits<YamlObjectFile> { static void mapping(IO &IO, YamlObjectFile &ObjectFile); }; -} // namespace yaml -} // namespace llvm +} // end namespace yaml +} // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_OBJECTYAML_H diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index 74f5664c43ac..6bf08d340eeb 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -16,8 +16,13 @@ #ifndef LLVM_OBJECTYAML_WASMYAML_H #define LLVM_OBJECTYAML_WASMYAML_H +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Casting.h" +#include <cstdint> +#include <memory> +#include <vector> namespace llvm { namespace WasmYAML { @@ -104,10 +109,8 @@ struct NameEntry { }; struct Signature { - Signature() : Form(wasm::WASM_TYPE_FUNC) {} - uint32_t Index; - SignatureForm Form; + SignatureForm Form = wasm::WASM_TYPE_FUNC; std::vector<ValueType> ParamTypes; ValueType ReturnType; }; @@ -128,6 +131,7 @@ struct Section { struct CustomSection : Section { explicit CustomSection(StringRef Name) : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_CUSTOM; } @@ -138,6 +142,7 @@ struct CustomSection : Section { struct NameSection : CustomSection { NameSection() : CustomSection("name") {} + static bool classof(const Section *S) { auto C = dyn_cast<CustomSection>(S); return C && C->Name == "name"; @@ -148,16 +153,20 @@ struct NameSection : CustomSection { struct LinkingSection : CustomSection { LinkingSection() : CustomSection("linking") {} + static bool classof(const Section *S) { auto C = dyn_cast<CustomSection>(S); return C && C->Name == "linking"; } std::vector<SymbolInfo> SymbolInfos; + uint32_t DataSize; + uint32_t DataAlignment; }; struct TypeSection : Section { TypeSection() : Section(wasm::WASM_SEC_TYPE) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_TYPE; } @@ -167,6 +176,7 @@ struct TypeSection : Section { struct ImportSection : Section { ImportSection() : Section(wasm::WASM_SEC_IMPORT) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_IMPORT; } @@ -176,6 +186,7 @@ struct ImportSection : Section { struct FunctionSection : Section { FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_FUNCTION; } @@ -185,6 +196,7 @@ struct FunctionSection : Section { struct TableSection : Section { TableSection() : Section(wasm::WASM_SEC_TABLE) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_TABLE; } @@ -194,6 +206,7 @@ struct TableSection : Section { struct MemorySection : Section { MemorySection() : Section(wasm::WASM_SEC_MEMORY) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_MEMORY; } @@ -203,6 +216,7 @@ struct MemorySection : Section { struct GlobalSection : Section { GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_GLOBAL; } @@ -212,6 +226,7 @@ struct GlobalSection : Section { struct ExportSection : Section { ExportSection() : Section(wasm::WASM_SEC_EXPORT) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_EXPORT; } @@ -221,6 +236,7 @@ struct ExportSection : Section { struct StartSection : Section { StartSection() : Section(wasm::WASM_SEC_START) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_START; } @@ -230,6 +246,7 @@ struct StartSection : Section { struct ElemSection : Section { ElemSection() : Section(wasm::WASM_SEC_ELEM) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_ELEM; } @@ -239,6 +256,7 @@ struct ElemSection : Section { struct CodeSection : Section { CodeSection() : Section(wasm::WASM_SEC_CODE) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_CODE; } @@ -248,6 +266,7 @@ struct CodeSection : Section { struct DataSection : Section { DataSection() : Section(wasm::WASM_SEC_DATA) {} + static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_DATA; } @@ -278,7 +297,6 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t) namespace llvm { namespace yaml { @@ -378,4 +396,4 @@ template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> { } // end namespace yaml } // end namespace llvm -#endif +#endif // LLVM_OBJECTYAML_WASMYAML_H diff --git a/include/llvm/ObjectYAML/YAML.h b/include/llvm/ObjectYAML/YAML.h index 7f6836809b6d..29151a269df0 100644 --- a/include/llvm/ObjectYAML/YAML.h +++ b/include/llvm/ObjectYAML/YAML.h @@ -10,10 +10,17 @@ #ifndef LLVM_OBJECTYAML_YAML_H #define LLVM_OBJECTYAML_YAML_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/YAMLTraits.h" +#include <cstdint> namespace llvm { + +class raw_ostream; + namespace yaml { + /// \brief Specialized YAMLIO scalar type for representing a binary blob. /// /// A typical use case would be to represent the content of a section in a @@ -56,18 +63,20 @@ namespace yaml { /// \endcode class BinaryRef { friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); + /// \brief Either raw binary data, or a string of hex bytes (must always /// be an even number of characters). ArrayRef<uint8_t> Data; + /// \brief Discriminator between the two states of the `Data` member. - bool DataIsHexString; + bool DataIsHexString = true; public: + BinaryRef() = default; BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {} BinaryRef(StringRef Data) - : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()), - DataIsHexString(true) {} - BinaryRef() : DataIsHexString(true) {} + : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()) {} + /// \brief The number of bytes that are represented by this BinaryRef. /// This is the number of bytes that writeAsBinary() will write. ArrayRef<uint8_t>::size_type binary_size() const { @@ -75,9 +84,11 @@ public: return Data.size() / 2; return Data.size(); } + /// \brief Write the contents (regardless of whether it is binary or a /// hex string) as binary to the given raw_ostream. void writeAsBinary(raw_ostream &OS) const; + /// \brief Write the contents (regardless of whether it is binary or a /// hex string) as hex to the given raw_ostream. /// @@ -94,10 +105,13 @@ inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) { } template <> struct ScalarTraits<BinaryRef> { - static void output(const BinaryRef &, void *, llvm::raw_ostream &); + static void output(const BinaryRef &, void *, raw_ostream &); static StringRef input(StringRef, void *, BinaryRef &); static bool mustQuote(StringRef S) { return needsQuotes(S); } }; -} -} -#endif + +} // end namespace yaml + +} // end namespace llvm + +#endif // LLVM_OBJECTYAML_YAML_H diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h index 12b05e4ff0c5..ff1958397331 100644 --- a/include/llvm/Passes/PassBuilder.h +++ b/include/llvm/Passes/PassBuilder.h @@ -31,8 +31,8 @@ class TargetMachine; struct PGOOptions { std::string ProfileGenFile = ""; std::string ProfileUseFile = ""; + std::string SampleProfileFile = ""; bool RunProfileGen = false; - bool SamplePGO = false; }; /// \brief This class provides access to building LLVM's passes. diff --git a/include/llvm/ProfileData/Coverage/CoverageMapping.h b/include/llvm/ProfileData/Coverage/CoverageMapping.h index 0ba792e8dc43..fa9a87aed680 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -168,13 +168,21 @@ class CounterExpressionBuilder { /// expression is added to the builder's collection of expressions. Counter get(const CounterExpression &E); + /// Represents a term in a counter expression tree. + struct Term { + unsigned CounterID; + int Factor; + + Term(unsigned CounterID, int Factor) + : CounterID(CounterID), Factor(Factor) {} + }; + /// \brief Gather the terms of the expression tree for processing. /// /// This collects each addition and subtraction referenced by the counter into /// a sequence that can be sorted and combined to build a simplified counter /// expression. - void extractTerms(Counter C, int Sign, - SmallVectorImpl<std::pair<unsigned, int>> &Terms); + void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms); /// \brief Simplifies the given expression tree /// by getting rid of algebraically redundant operations. @@ -443,20 +451,9 @@ public: /// \brief Load the coverage mapping using the given readers. static Expected<std::unique_ptr<CoverageMapping>> - load(CoverageMappingReader &CoverageReader, - IndexedInstrProfReader &ProfileReader); - - static Expected<std::unique_ptr<CoverageMapping>> load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders, IndexedInstrProfReader &ProfileReader); - /// \brief Load the coverage mapping from the given files. - static Expected<std::unique_ptr<CoverageMapping>> - load(StringRef ObjectFilename, StringRef ProfileFilename, - StringRef Arch = StringRef()) { - return load(ArrayRef<StringRef>(ObjectFilename), ProfileFilename, Arch); - } - static Expected<std::unique_ptr<CoverageMapping>> load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename, StringRef Arch = StringRef()); diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index 573ea90cfd00..a6b2850ccd22 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -598,6 +598,28 @@ struct InstrProfRecord { InstrProfRecord() = default; InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts) : Name(Name), Hash(Hash), Counts(std::move(Counts)) {} + InstrProfRecord(InstrProfRecord &&) = default; + InstrProfRecord(const InstrProfRecord &RHS) + : Name(RHS.Name), Hash(RHS.Hash), Counts(RHS.Counts), SIPE(RHS.SIPE), + ValueData(RHS.ValueData + ? llvm::make_unique<ValueProfData>(*RHS.ValueData) + : nullptr) {} + InstrProfRecord &operator=(InstrProfRecord &&) = default; + InstrProfRecord &operator=(const InstrProfRecord &RHS) { + Name = RHS.Name; + Hash = RHS.Hash; + Counts = RHS.Counts; + SIPE = RHS.SIPE; + if (!RHS.ValueData) { + ValueData = nullptr; + return *this; + } + if (!ValueData) + ValueData = llvm::make_unique<ValueProfData>(*RHS.ValueData); + else + *ValueData = *RHS.ValueData; + return *this; + } using ValueMapType = std::vector<std::pair<uint64_t, uint64_t>>; @@ -647,12 +669,9 @@ struct InstrProfRecord { /// Sort value profile data (per site) by count. void sortValueData() { - for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) { - std::vector<InstrProfValueSiteRecord> &SiteRecords = - getValueSitesForKind(Kind); - for (auto &SR : SiteRecords) + for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) + for (auto &SR : getValueSitesForKind(Kind)) SR.sortByCount(); - } } /// Clear value data entries and edge counters. @@ -662,36 +681,54 @@ struct InstrProfRecord { } /// Clear value data entries - void clearValueData() { - for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) - getValueSitesForKind(Kind).clear(); - } + void clearValueData() { ValueData = nullptr; } /// Get the error contained within the record's soft error counter. Error takeError() { return SIPE.takeError(); } private: - std::vector<InstrProfValueSiteRecord> IndirectCallSites; - std::vector<InstrProfValueSiteRecord> MemOPSizes; + struct ValueProfData { + std::vector<InstrProfValueSiteRecord> IndirectCallSites; + std::vector<InstrProfValueSiteRecord> MemOPSizes; + }; + std::unique_ptr<ValueProfData> ValueData; - const std::vector<InstrProfValueSiteRecord> & + MutableArrayRef<InstrProfValueSiteRecord> + getValueSitesForKind(uint32_t ValueKind) { + // Cast to /add/ const (should be an implicit_cast, ideally, if that's ever + // implemented in LLVM) to call the const overload of this function, then + // cast away the constness from the result. + auto AR = const_cast<const InstrProfRecord *>(this)->getValueSitesForKind( + ValueKind); + return makeMutableArrayRef( + const_cast<InstrProfValueSiteRecord *>(AR.data()), AR.size()); + } + ArrayRef<InstrProfValueSiteRecord> getValueSitesForKind(uint32_t ValueKind) const { + if (!ValueData) + return None; switch (ValueKind) { case IPVK_IndirectCallTarget: - return IndirectCallSites; + return ValueData->IndirectCallSites; case IPVK_MemOPSize: - return MemOPSizes; + return ValueData->MemOPSizes; default: llvm_unreachable("Unknown value kind!"); } - return IndirectCallSites; } std::vector<InstrProfValueSiteRecord> & - getValueSitesForKind(uint32_t ValueKind) { - return const_cast<std::vector<InstrProfValueSiteRecord> &>( - const_cast<const InstrProfRecord *>(this) - ->getValueSitesForKind(ValueKind)); + getOrCreateValueSitesForKind(uint32_t ValueKind) { + if (!ValueData) + ValueData = llvm::make_unique<ValueProfData>(); + switch (ValueKind) { + case IPVK_IndirectCallTarget: + return ValueData->IndirectCallSites; + case IPVK_MemOPSize: + return ValueData->MemOPSizes; + default: + llvm_unreachable("Unknown value kind!"); + } } // Map indirect call target name hash to name string. @@ -765,9 +802,9 @@ uint64_t InstrProfRecord::getValueForSite(InstrProfValueData Dest[], } void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) { - std::vector<InstrProfValueSiteRecord> &ValueSites = - getValueSitesForKind(ValueKind); - ValueSites.reserve(NumValueSites); + if (!NumValueSites) + return; + getOrCreateValueSitesForKind(ValueKind).reserve(NumValueSites); } inline support::endianness getHostEndianness() { diff --git a/include/llvm/Support/CMakeLists.txt b/include/llvm/Support/CMakeLists.txt index c58ccf216303..95752cf01856 100644 --- a/include/llvm/Support/CMakeLists.txt +++ b/include/llvm/Support/CMakeLists.txt @@ -9,25 +9,27 @@ function(find_first_existing_file out_var) endfunction() macro(find_first_existing_vc_file out_var path) - find_program(git_executable NAMES git git.exe git.cmd) - # Run from a subdirectory to force git to print an absolute path. - execute_process(COMMAND ${git_executable} rev-parse --git-dir - WORKING_DIRECTORY ${path}/cmake - RESULT_VARIABLE git_result - OUTPUT_VARIABLE git_dir - ERROR_QUIET) - if(git_result EQUAL 0) - string(STRIP "${git_dir}" git_dir) - set(${out_var} "${git_dir}/logs/HEAD") - # some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD - if (NOT EXISTS "${git_dir}/logs/HEAD") - file(WRITE "${git_dir}/logs/HEAD" "") + if ( LLVM_APPEND_VC_REV ) + find_program(git_executable NAMES git git.exe git.cmd) + # Run from a subdirectory to force git to print an absolute path. + execute_process(COMMAND ${git_executable} rev-parse --git-dir + WORKING_DIRECTORY ${path}/cmake + RESULT_VARIABLE git_result + OUTPUT_VARIABLE git_dir + ERROR_QUIET) + if(git_result EQUAL 0) + string(STRIP "${git_dir}" git_dir) + set(${out_var} "${git_dir}/logs/HEAD") + # some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD + if (NOT EXISTS "${git_dir}/logs/HEAD") + file(WRITE "${git_dir}/logs/HEAD" "") + endif() + else() + find_first_existing_file(${out_var} + "${path}/.svn/wc.db" # SVN 1.7 + "${path}/.svn/entries" # SVN 1.6 + ) endif() - else() - find_first_existing_file(${out_var} - "${path}/.svn/wc.db" # SVN 1.7 - "${path}/.svn/entries" # SVN 1.6 - ) endif() endmacro() diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h index 4ce65e7dc83c..35dc1ea7cf84 100644 --- a/include/llvm/Support/Errno.h +++ b/include/llvm/Support/Errno.h @@ -16,6 +16,7 @@ #include <cerrno> #include <string> +#include <type_traits> namespace llvm { namespace sys { @@ -29,6 +30,16 @@ std::string StrError(); /// Like the no-argument version above, but uses \p errnum instead of errno. std::string StrError(int errnum); +template <typename FailT, typename Fun, typename... Args> +inline auto RetryAfterSignal(const FailT &Fail, const Fun &F, + const Args &... As) -> decltype(F(As...)) { + decltype(F(As...)) Res; + do + Res = F(As...); + while (Res == Fail && errno == EINTR); + return Res; +} + } // namespace sys } // namespace llvm diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index 601633d41cff..394a45387d8a 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -58,40 +58,6 @@ template <typename GT> using DominatorTreeBaseByGraphTraits = typename detail::DominatorTreeBaseTraits<GT>::type; -/// \brief Base class that other, more interesting dominator analyses -/// inherit from. -template <class NodeT> class DominatorBase { -protected: - std::vector<NodeT *> Roots; - bool IsPostDominators; - - explicit DominatorBase(bool isPostDom) - : Roots(), IsPostDominators(isPostDom) {} - - DominatorBase(DominatorBase &&Arg) - : Roots(std::move(Arg.Roots)), IsPostDominators(Arg.IsPostDominators) { - Arg.Roots.clear(); - } - - DominatorBase &operator=(DominatorBase &&RHS) { - Roots = std::move(RHS.Roots); - IsPostDominators = RHS.IsPostDominators; - RHS.Roots.clear(); - return *this; - } - -public: - /// getRoots - Return the root blocks of the current CFG. This may include - /// multiple blocks if we are computing post dominators. For forward - /// dominators, this will always be a single block (the entry node). - /// - const std::vector<NodeT *> &getRoots() const { return Roots; } - - /// isPostDominator - Returns true if analysis based of postdoms - /// - bool isPostDominator() const { return IsPostDominators; } -}; - /// \brief Base class for the actual dominator tree node. template <class NodeT> class DomTreeNodeBase { friend struct PostDominatorTree; @@ -99,12 +65,14 @@ template <class NodeT> class DomTreeNodeBase { NodeT *TheBB; DomTreeNodeBase *IDom; + unsigned Level; std::vector<DomTreeNodeBase *> Children; mutable unsigned DFSNumIn = ~0; mutable unsigned DFSNumOut = ~0; public: - DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) : TheBB(BB), IDom(iDom) {} + DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) + : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {} using iterator = typename std::vector<DomTreeNodeBase *>::iterator; using const_iterator = @@ -117,6 +85,7 @@ template <class NodeT> class DomTreeNodeBase { NodeT *getBlock() const { return TheBB; } DomTreeNodeBase *getIDom() const { return IDom; } + unsigned getLevel() const { return Level; } const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; } @@ -134,6 +103,8 @@ template <class NodeT> class DomTreeNodeBase { if (getNumChildren() != Other->getNumChildren()) return true; + if (Level != Other->Level) return true; + SmallPtrSet<const NodeT *, 4> OtherChildren; for (const DomTreeNodeBase *I : *Other) { const NodeT *Nd = I->getBlock(); @@ -150,18 +121,19 @@ template <class NodeT> class DomTreeNodeBase { void setIDom(DomTreeNodeBase *NewIDom) { assert(IDom && "No immediate dominator?"); - if (IDom != NewIDom) { - typename std::vector<DomTreeNodeBase *>::iterator I = - find(IDom->Children, this); - assert(I != IDom->Children.end() && - "Not in immediate dominator children set!"); - // I am no longer your child... - IDom->Children.erase(I); + if (IDom == NewIDom) return; - // Switch to new dominator - IDom = NewIDom; - IDom->Children.push_back(this); - } + auto I = find(IDom->Children, this); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + + // Switch to new dominator + IDom = NewIDom; + IDom->Children.push_back(this); + + UpdateLevel(); } /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes @@ -177,6 +149,23 @@ private: return this->DFSNumIn >= other->DFSNumIn && this->DFSNumOut <= other->DFSNumOut; } + + void UpdateLevel() { + assert(IDom); + if (Level == IDom->Level + 1) return; + + SmallVector<DomTreeNodeBase *, 64> WorkStack = {this}; + + while (!WorkStack.empty()) { + DomTreeNodeBase *Current = WorkStack.pop_back_val(); + Current->Level = Current->IDom->Level + 1; + + for (DomTreeNodeBase *C : *Current) { + assert(C->IDom); + if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C); + } + } + } }; template <class NodeT> @@ -186,9 +175,10 @@ raw_ostream &operator<<(raw_ostream &O, const DomTreeNodeBase<NodeT> *Node) { else O << " <<exit node>>"; - O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; + O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} [" + << Node->getLevel() << "]\n"; - return O << "\n"; + return O; } template <class NodeT> @@ -201,40 +191,28 @@ void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &O, PrintDomTree<NodeT>(*I, O, Lev + 1); } +namespace DomTreeBuilder { +template <class NodeT> +struct SemiNCAInfo; + // The calculate routine is provided in a separate header but referenced here. template <class FuncT, class N> void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, FuncT &F); +// The verify function is provided in a separate header but referenced here. +template <class N> +bool Verify(const DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT); +} // namespace DomTreeBuilder + /// \brief Core dominator tree base class. /// /// This class is a generic template over graph nodes. It is instantiated for /// various graphs in the LLVM IR or in the code generator. -template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> { - bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, - const DomTreeNodeBase<NodeT> *B) const { - assert(A != B); - assert(isReachableFromEntry(B)); - assert(isReachableFromEntry(A)); - - const DomTreeNodeBase<NodeT> *IDom; - while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B) - B = IDom; // Walk up the tree - return IDom != nullptr; - } - - /// \brief Wipe this tree's state without releasing any resources. - /// - /// This is essentially a post-move helper only. It leaves the object in an - /// assignable and destroyable state, but otherwise invalid. - void wipe() { - DomTreeNodes.clear(); - IDoms.clear(); - Vertex.clear(); - Info.clear(); - RootNode = nullptr; - } +template <class NodeT> class DominatorTreeBase { + protected: + std::vector<NodeT *> Roots; + bool IsPostDominators; -protected: using DomTreeNodeMapType = DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>; DomTreeNodeMapType DomTreeNodes; @@ -242,117 +220,30 @@ protected: mutable bool DFSInfoValid = false; mutable unsigned int SlowQueries = 0; - // Information record used during immediate dominators computation. - struct InfoRec { - unsigned DFSNum = 0; - unsigned Parent = 0; - unsigned Semi = 0; - NodeT *Label = nullptr; - - InfoRec() = default; - }; - DenseMap<NodeT *, NodeT *> IDoms; + friend struct DomTreeBuilder::SemiNCAInfo<NodeT>; + using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo<NodeT>; - // Vertex - Map the DFS number to the NodeT* - std::vector<NodeT *> Vertex; - - // Info - Collection of information used during the computation of idoms. - DenseMap<NodeT *, InfoRec> Info; - - void reset() { - DomTreeNodes.clear(); - IDoms.clear(); - this->Roots.clear(); - Vertex.clear(); - RootNode = nullptr; - DFSInfoValid = false; - SlowQueries = 0; - } - - // NewBB is split and now it has one successor. Update dominator tree to - // reflect this change. - template <class N> - void Split(typename GraphTraits<N>::NodeRef NewBB) { - using GraphT = GraphTraits<N>; - using NodeRef = typename GraphT::NodeRef; - assert(std::distance(GraphT::child_begin(NewBB), - GraphT::child_end(NewBB)) == 1 && - "NewBB should have a single successor!"); - NodeRef NewBBSucc = *GraphT::child_begin(NewBB); - - std::vector<NodeRef> PredBlocks; - for (const auto &Pred : children<Inverse<N>>(NewBB)) - PredBlocks.push_back(Pred); - - assert(!PredBlocks.empty() && "No predblocks?"); - - bool NewBBDominatesNewBBSucc = true; - for (const auto &Pred : children<Inverse<N>>(NewBBSucc)) { - if (Pred != NewBB && !dominates(NewBBSucc, Pred) && - isReachableFromEntry(Pred)) { - NewBBDominatesNewBBSucc = false; - break; - } - } - - // Find NewBB's immediate dominator and create new dominator tree node for - // NewBB. - NodeT *NewBBIDom = nullptr; - unsigned i = 0; - for (i = 0; i < PredBlocks.size(); ++i) - if (isReachableFromEntry(PredBlocks[i])) { - NewBBIDom = PredBlocks[i]; - break; - } - - // It's possible that none of the predecessors of NewBB are reachable; - // in that case, NewBB itself is unreachable, so nothing needs to be - // changed. - if (!NewBBIDom) - return; - - for (i = i + 1; i < PredBlocks.size(); ++i) { - if (isReachableFromEntry(PredBlocks[i])) - NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]); - } - - // Create the new dominator tree node... and set the idom of NewBB. - DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom); - - // If NewBB strictly dominates other blocks, then it is now the immediate - // dominator of NewBBSucc. Update the dominator tree as appropriate. - if (NewBBDominatesNewBBSucc) { - DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc); - changeImmediateDominator(NewBBSuccNode, NewBBNode); - } - } - -public: - explicit DominatorTreeBase(bool isPostDom) - : DominatorBase<NodeT>(isPostDom) {} + public: + explicit DominatorTreeBase(bool isPostDom) : IsPostDominators(isPostDom) {} DominatorTreeBase(DominatorTreeBase &&Arg) - : DominatorBase<NodeT>( - std::move(static_cast<DominatorBase<NodeT> &>(Arg))), + : Roots(std::move(Arg.Roots)), + IsPostDominators(Arg.IsPostDominators), DomTreeNodes(std::move(Arg.DomTreeNodes)), RootNode(std::move(Arg.RootNode)), DFSInfoValid(std::move(Arg.DFSInfoValid)), - SlowQueries(std::move(Arg.SlowQueries)), IDoms(std::move(Arg.IDoms)), - Vertex(std::move(Arg.Vertex)), Info(std::move(Arg.Info)) { + SlowQueries(std::move(Arg.SlowQueries)) { Arg.wipe(); } DominatorTreeBase &operator=(DominatorTreeBase &&RHS) { - DominatorBase<NodeT>::operator=( - std::move(static_cast<DominatorBase<NodeT> &>(RHS))); + Roots = std::move(RHS.Roots); + IsPostDominators = RHS.IsPostDominators; DomTreeNodes = std::move(RHS.DomTreeNodes); RootNode = std::move(RHS.RootNode); DFSInfoValid = std::move(RHS.DFSInfoValid); SlowQueries = std::move(RHS.SlowQueries); - IDoms = std::move(RHS.IDoms); - Vertex = std::move(RHS.Vertex); - Info = std::move(RHS.Info); RHS.wipe(); return *this; } @@ -360,6 +251,16 @@ public: DominatorTreeBase(const DominatorTreeBase &) = delete; DominatorTreeBase &operator=(const DominatorTreeBase &) = delete; + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + const std::vector<NodeT *> &getRoots() const { return Roots; } + + /// isPostDominator - Returns true if analysis based of postdoms + /// + bool isPostDominator() const { return IsPostDominators; } + /// compare - Return false if the other dominator tree base matches this /// dominator tree base. Otherwise return true. bool compare(const DominatorTreeBase &Other) const { @@ -468,6 +369,13 @@ public: if (!isReachableFromEntry(A)) return false; + if (B->getIDom() == A) return true; + + if (A->getIDom() == B) return false; + + // A can only dominate B if it is higher in the tree. + if (A->getLevel() >= B->getLevel()) return false; + // Compare the result of the tree walk and the dfs numbers, if expensive // checks are enabled. #ifdef EXPENSIVE_CHECKS @@ -499,7 +407,7 @@ public: /// findNearestCommonDominator - Find nearest common dominator basic block /// for basic block A and B. If there is no such block then return NULL. - NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) { + NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) const { assert(A->getParent() == B->getParent() && "Two blocks are not in same function"); @@ -511,54 +419,24 @@ public: return &Entry; } - // If B dominates A then B is nearest common dominator. - if (dominates(B, A)) - return B; - - // If A dominates B then A is nearest common dominator. - if (dominates(A, B)) - return A; - DomTreeNodeBase<NodeT> *NodeA = getNode(A); DomTreeNodeBase<NodeT> *NodeB = getNode(B); - // If we have DFS info, then we can avoid all allocations by just querying - // it from each IDom. Note that because we call 'dominates' twice above, we - // expect to call through this code at most 16 times in a row without - // building valid DFS information. This is important as below is a *very* - // slow tree walk. - if (DFSInfoValid) { - DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); - while (IDomA) { - if (NodeB->DominatedBy(IDomA)) - return IDomA->getBlock(); - IDomA = IDomA->getIDom(); - } - return nullptr; - } - - // Collect NodeA dominators set. - SmallPtrSet<DomTreeNodeBase<NodeT> *, 16> NodeADoms; - NodeADoms.insert(NodeA); - DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); - while (IDomA) { - NodeADoms.insert(IDomA); - IDomA = IDomA->getIDom(); - } + if (!NodeA || !NodeB) return nullptr; - // Walk NodeB immediate dominators chain and find common dominator node. - DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom(); - while (IDomB) { - if (NodeADoms.count(IDomB) != 0) - return IDomB->getBlock(); + // Use level information to go up the tree until the levels match. Then + // continue going up til we arrive at the same node. + while (NodeA && NodeA != NodeB) { + if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB); - IDomB = IDomB->getIDom(); + NodeA = NodeA->IDom; } - return nullptr; + return NodeA ? NodeA->getBlock() : nullptr; } - const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) { + const NodeT *findNearestCommonDominator(const NodeT *A, + const NodeT *B) const { // Cast away the const qualifiers here. This is ok since // const is re-introduced on the return type. return findNearestCommonDominator(const_cast<NodeT *>(A), @@ -597,7 +475,6 @@ public: assert(!this->isPostDominator() && "Cannot change root of post-dominator tree"); DFSInfoValid = false; - auto &Roots = DominatorBase<NodeT>::Roots; DomTreeNodeBase<NodeT> *NewNode = (DomTreeNodes[BB] = llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, nullptr)).get(); if (Roots.empty()) { @@ -605,8 +482,10 @@ public: } else { assert(Roots.size() == 1); NodeT *OldRoot = Roots.front(); - DomTreeNodes[OldRoot] = - NewNode->addChild(std::move(DomTreeNodes[OldRoot])); + auto &OldNode = DomTreeNodes[OldRoot]; + OldNode = NewNode->addChild(std::move(DomTreeNodes[OldRoot])); + OldNode->IDom = NewNode; + OldNode->UpdateLevel(); Roots[0] = BB; } return RootNode = NewNode; @@ -673,45 +552,6 @@ public: if (getRootNode()) PrintDomTree<NodeT>(getRootNode(), O, 1); } -protected: - template <class GraphT> - friend typename GraphT::NodeRef - Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V, - unsigned LastLinked); - - template <class GraphT> - friend unsigned ReverseDFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef V, unsigned N); - - template <class GraphT> - friend unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef V, unsigned N); - - template <class FuncT, class N> - friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, - FuncT &F); - - DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) { - if (DomTreeNodeBase<NodeT> *Node = getNode(BB)) - return Node; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate dominator. - NodeT *IDom = getIDom(BB); - - assert(IDom || DomTreeNodes[nullptr]); - DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom); - - // Add a new tree node for this NodeT, and link it as a child of - // IDomNode - return (DomTreeNodes[BB] = IDomNode->addChild( - llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get(); - } - - NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); } - - void addRoot(NodeT *BB) { this->Roots.push_back(BB); } - public: /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking /// dominator tree in dfs order. @@ -767,23 +607,119 @@ public: template <class FT> void recalculate(FT &F) { using TraitsTy = GraphTraits<FT *>; reset(); - Vertex.push_back(nullptr); if (!this->IsPostDominators) { // Initialize root NodeT *entry = TraitsTy::getEntryNode(&F); addRoot(entry); - Calculate<FT, NodeT *>(*this, F); + DomTreeBuilder::Calculate<FT, NodeT *>(*this, F); } else { // Initialize the roots list for (auto *Node : nodes(&F)) if (TraitsTy::child_begin(Node) == TraitsTy::child_end(Node)) addRoot(Node); - Calculate<FT, Inverse<NodeT *>>(*this, F); + DomTreeBuilder::Calculate<FT, Inverse<NodeT *>>(*this, F); } } + + /// verify - check parent and sibling property + bool verify() const { + return this->isPostDominator() + ? DomTreeBuilder::Verify<Inverse<NodeT *>>(*this) + : DomTreeBuilder::Verify<NodeT *>(*this); + } + + protected: + void addRoot(NodeT *BB) { this->Roots.push_back(BB); } + + void reset() { + DomTreeNodes.clear(); + this->Roots.clear(); + RootNode = nullptr; + DFSInfoValid = false; + SlowQueries = 0; + } + + // NewBB is split and now it has one successor. Update dominator tree to + // reflect this change. + template <class N> + void Split(typename GraphTraits<N>::NodeRef NewBB) { + using GraphT = GraphTraits<N>; + using NodeRef = typename GraphT::NodeRef; + assert(std::distance(GraphT::child_begin(NewBB), + GraphT::child_end(NewBB)) == 1 && + "NewBB should have a single successor!"); + NodeRef NewBBSucc = *GraphT::child_begin(NewBB); + + std::vector<NodeRef> PredBlocks; + for (const auto &Pred : children<Inverse<N>>(NewBB)) + PredBlocks.push_back(Pred); + + assert(!PredBlocks.empty() && "No predblocks?"); + + bool NewBBDominatesNewBBSucc = true; + for (const auto &Pred : children<Inverse<N>>(NewBBSucc)) { + if (Pred != NewBB && !dominates(NewBBSucc, Pred) && + isReachableFromEntry(Pred)) { + NewBBDominatesNewBBSucc = false; + break; + } + } + + // Find NewBB's immediate dominator and create new dominator tree node for + // NewBB. + NodeT *NewBBIDom = nullptr; + unsigned i = 0; + for (i = 0; i < PredBlocks.size(); ++i) + if (isReachableFromEntry(PredBlocks[i])) { + NewBBIDom = PredBlocks[i]; + break; + } + + // It's possible that none of the predecessors of NewBB are reachable; + // in that case, NewBB itself is unreachable, so nothing needs to be + // changed. + if (!NewBBIDom) return; + + for (i = i + 1; i < PredBlocks.size(); ++i) { + if (isReachableFromEntry(PredBlocks[i])) + NewBBIDom = findNearestCommonDominator(NewBBIDom, PredBlocks[i]); + } + + // Create the new dominator tree node... and set the idom of NewBB. + DomTreeNodeBase<NodeT> *NewBBNode = addNewBlock(NewBB, NewBBIDom); + + // If NewBB strictly dominates other blocks, then it is now the immediate + // dominator of NewBBSucc. Update the dominator tree as appropriate. + if (NewBBDominatesNewBBSucc) { + DomTreeNodeBase<NodeT> *NewBBSuccNode = getNode(NewBBSucc); + changeImmediateDominator(NewBBSuccNode, NewBBNode); + } + } + + private: + bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, + const DomTreeNodeBase<NodeT> *B) const { + assert(A != B); + assert(isReachableFromEntry(B)); + assert(isReachableFromEntry(A)); + + const DomTreeNodeBase<NodeT> *IDom; + while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B) + B = IDom; // Walk up the tree + return IDom != nullptr; + } + + /// \brief Wipe this tree's state without releasing any resources. + /// + /// This is essentially a post-move helper only. It leaves the object in an + /// assignable and destroyable state, but otherwise invalid. + void wipe() { + DomTreeNodes.clear(); + RootNode = nullptr; + } }; // These two functions are declared out of line as a workaround for building diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h index 449c385bc86a..9edf03aa3621 100644 --- a/include/llvm/Support/GenericDomTreeConstruction.h +++ b/include/llvm/Support/GenericDomTreeConstruction.h @@ -10,10 +10,11 @@ /// /// Generic dominator tree construction - This file provides routines to /// construct immediate dominator information for a flow-graph based on the -/// algorithm described in this document: +/// Semi-NCA algorithm described in this dissertation: /// -/// A Fast Algorithm for Finding Dominators in a Flowgraph -/// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. +/// Linear-Time Algorithms for Dominators and Related Problems +/// Loukas Georgiadis, Princeton University, November 2005, pp. 21-23: +/// ftp://ftp.cs.princeton.edu/reports/2005/737.pdf /// /// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns /// out that the theoretically slower O(n*log(n)) implementation is actually @@ -29,256 +30,496 @@ #include "llvm/Support/GenericDomTree.h" namespace llvm { +namespace DomTreeBuilder { + +// Information record used by Semi-NCA during tree construction. +template <typename NodeT> +struct SemiNCAInfo { + using NodePtr = NodeT *; + using DomTreeT = DominatorTreeBase<NodeT>; + using TreeNodePtr = DomTreeNodeBase<NodeT> *; + + struct InfoRec { + unsigned DFSNum = 0; + unsigned Parent = 0; + unsigned Semi = 0; + NodePtr Label = nullptr; + NodePtr IDom = nullptr; + }; + + std::vector<NodePtr> NumToNode; + DenseMap<NodePtr, InfoRec> NodeToInfo; + + void clear() { + NumToNode.clear(); + NodeToInfo.clear(); + } + + NodePtr getIDom(NodePtr BB) const { + auto InfoIt = NodeToInfo.find(BB); + if (InfoIt == NodeToInfo.end()) return nullptr; -// External storage for depth first iterator that reuses the info lookup map -// domtree already has. We don't have a set, but a map instead, so we are -// converting the one argument insert calls. -template <class NodeRef, class InfoType> struct df_iterator_dom_storage { -public: - using BaseSet = DenseMap<NodeRef, InfoType>; - df_iterator_dom_storage(BaseSet &Storage) : Storage(Storage) {} - - using iterator = typename BaseSet::iterator; - std::pair<iterator, bool> insert(NodeRef N) { - return Storage.insert({N, InfoType()}); + return InfoIt->second.IDom; } - void completed(NodeRef) {} -private: - BaseSet &Storage; -}; + TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { + if (TreeNodePtr Node = DT.getNode(BB)) return Node; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate dominator. + NodePtr IDom = getIDom(BB); + + assert(IDom || DT.DomTreeNodes[nullptr]); + TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); -template <class GraphT> -unsigned ReverseDFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef V, unsigned N) { - df_iterator_dom_storage< - typename GraphT::NodeRef, - typename DominatorTreeBaseByGraphTraits<GraphT>::InfoRec> - DFStorage(DT.Info); - bool IsChildOfArtificialExit = (N != 0); - for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage); - I != E; ++I) { - typename GraphT::NodeRef BB = *I; - auto &BBInfo = DT.Info[BB]; - BBInfo.DFSNum = BBInfo.Semi = ++N; - BBInfo.Label = BB; - // Set the parent to the top of the visited stack. The stack includes us, - // and is 1 based, so we subtract to account for both of these. - if (I.getPathLength() > 1) - BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum; - DT.Vertex.push_back(BB); // Vertex[n] = V; - - if (IsChildOfArtificialExit) - BBInfo.Parent = 1; - - IsChildOfArtificialExit = false; + // Add a new tree node for this NodeT, and link it as a child of + // IDomNode + return (DT.DomTreeNodes[BB] = IDomNode->addChild( + llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) + .get(); } - return N; -} -template <class GraphT> -unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef V, unsigned N) { - df_iterator_dom_storage< - typename GraphT::NodeRef, - typename DominatorTreeBaseByGraphTraits<GraphT>::InfoRec> - DFStorage(DT.Info); - for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage); - I != E; ++I) { - typename GraphT::NodeRef BB = *I; - auto &BBInfo = DT.Info[BB]; - BBInfo.DFSNum = BBInfo.Semi = ++N; - BBInfo.Label = BB; - // Set the parent to the top of the visited stack. The stack includes us, - // and is 1 based, so we subtract to account for both of these. - if (I.getPathLength() > 1) - BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum; - DT.Vertex.push_back(BB); // Vertex[n] = V; + + // External storage for depth first iterator that reuses the info lookup map + // SemiNCAInfo already has. We don't have a set, but a map instead, so we are + // converting the one argument insert calls. + struct df_iterator_dom_storage { + public: + using BaseSet = decltype(NodeToInfo); + df_iterator_dom_storage(BaseSet &Storage) : Storage(Storage) {} + + using iterator = typename BaseSet::iterator; + std::pair<iterator, bool> insert(NodePtr N) { + return Storage.insert({N, InfoRec()}); + } + void completed(NodePtr) {} + + private: + BaseSet &Storage; + }; + + df_iterator_dom_storage getStorage() { return {NodeToInfo}; } + + unsigned runReverseDFS(NodePtr V, unsigned N) { + auto DFStorage = getStorage(); + + bool IsChildOfArtificialExit = (N != 0); + for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage); + I != E; ++I) { + NodePtr BB = *I; + auto &BBInfo = NodeToInfo[BB]; + BBInfo.DFSNum = BBInfo.Semi = ++N; + BBInfo.Label = BB; + // Set the parent to the top of the visited stack. The stack includes us, + // and is 1 based, so we subtract to account for both of these. + if (I.getPathLength() > 1) + BBInfo.Parent = NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum; + NumToNode.push_back(BB); // NumToNode[n] = V; + + if (IsChildOfArtificialExit) + BBInfo.Parent = 1; + + IsChildOfArtificialExit = false; + } + return N; } - return N; -} -template <class GraphT> -typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, - typename GraphT::NodeRef VIn, - unsigned LastLinked) { - using NodePtr = typename GraphT::NodeRef; + unsigned runForwardDFS(NodePtr V, unsigned N) { + auto DFStorage = getStorage(); + + for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage); + I != E; ++I) { + NodePtr BB = *I; + auto &BBInfo = NodeToInfo[BB]; + BBInfo.DFSNum = BBInfo.Semi = ++N; + BBInfo.Label = BB; + // Set the parent to the top of the visited stack. The stack includes us, + // and is 1 based, so we subtract to account for both of these. + if (I.getPathLength() > 1) + BBInfo.Parent = NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum; + NumToNode.push_back(BB); // NumToNode[n] = V; + } + return N; + } - auto &VInInfo = DT.Info[VIn]; - if (VInInfo.DFSNum < LastLinked) - return VIn; + NodePtr eval(NodePtr VIn, unsigned LastLinked) { + auto &VInInfo = NodeToInfo[VIn]; + if (VInInfo.DFSNum < LastLinked) + return VIn; - SmallVector<NodePtr, 32> Work; - SmallPtrSet<NodePtr, 32> Visited; + SmallVector<NodePtr, 32> Work; + SmallPtrSet<NodePtr, 32> Visited; - if (VInInfo.Parent >= LastLinked) - Work.push_back(VIn); + if (VInInfo.Parent >= LastLinked) + Work.push_back(VIn); - while (!Work.empty()) { - NodePtr V = Work.back(); - auto &VInfo = DT.Info[V]; - NodePtr VAncestor = DT.Vertex[VInfo.Parent]; + while (!Work.empty()) { + NodePtr V = Work.back(); + auto &VInfo = NodeToInfo[V]; + NodePtr VAncestor = NumToNode[VInfo.Parent]; - // Process Ancestor first - if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { - Work.push_back(VAncestor); - continue; + // Process Ancestor first + if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { + Work.push_back(VAncestor); + continue; + } + Work.pop_back(); + + // Update VInfo based on Ancestor info + if (VInfo.Parent < LastLinked) + continue; + + auto &VAInfo = NodeToInfo[VAncestor]; + NodePtr VAncestorLabel = VAInfo.Label; + NodePtr VLabel = VInfo.Label; + if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) + VInfo.Label = VAncestorLabel; + VInfo.Parent = VAInfo.Parent; } - Work.pop_back(); - - // Update VInfo based on Ancestor info - if (VInfo.Parent < LastLinked) - continue; - - auto &VAInfo = DT.Info[VAncestor]; - NodePtr VAncestorLabel = VAInfo.Label; - NodePtr VLabel = VInfo.Label; - if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) - VInfo.Label = VAncestorLabel; - VInfo.Parent = VAInfo.Parent; + + return VInInfo.Label; } - return VInInfo.Label; -} + template <typename NodeType> + void runSemiNCA(DomTreeT &DT, unsigned NumBlocks) { + unsigned N = 0; + NumToNode.push_back(nullptr); -template <class FuncT, class NodeT> -void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, - FuncT &F) { - using GraphT = GraphTraits<NodeT>; - using NodePtr = typename GraphT::NodeRef; - static_assert(std::is_pointer<NodePtr>::value, - "NodeRef should be pointer type"); - using NodeType = typename std::remove_pointer<NodePtr>::type; + bool MultipleRoots = (DT.Roots.size() > 1); + if (MultipleRoots) { + auto &BBInfo = NodeToInfo[nullptr]; + BBInfo.DFSNum = BBInfo.Semi = ++N; + BBInfo.Label = nullptr; - unsigned N = 0; - bool MultipleRoots = (DT.Roots.size() > 1); - if (MultipleRoots) { - auto &BBInfo = DT.Info[nullptr]; - BBInfo.DFSNum = BBInfo.Semi = ++N; - BBInfo.Label = nullptr; + NumToNode.push_back(nullptr); // NumToNode[n] = V; + } - DT.Vertex.push_back(nullptr); // Vertex[n] = V; - } + // Step #1: Number blocks in depth-first order and initialize variables used + // in later stages of the algorithm. + if (DT.isPostDominator()){ + for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size()); + i != e; ++i) + N = runReverseDFS(DT.Roots[i], N); + } else { + N = runForwardDFS(DT.Roots[0], N); + } - // Step #1: Number blocks in depth-first order and initialize variables used - // in later stages of the algorithm. - if (DT.isPostDominator()){ - for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size()); - i != e; ++i) - N = ReverseDFSPass<GraphT>(DT, DT.Roots[i], N); - } else { - N = DFSPass<GraphT>(DT, DT.Roots[0], N); - } + // It might be that some blocks did not get a DFS number (e.g., blocks of + // infinite loops). In these cases an artificial exit node is required. + MultipleRoots |= (DT.isPostDominator() && N != NumBlocks); - // it might be that some blocks did not get a DFS number (e.g., blocks of - // infinite loops). In these cases an artificial exit node is required. - MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F)); + // Initialize IDoms to spanning tree parents. + for (unsigned i = 1; i <= N; ++i) { + const NodePtr V = NumToNode[i]; + auto &VInfo = NodeToInfo[V]; + VInfo.IDom = NumToNode[VInfo.Parent]; + } - // When naively implemented, the Lengauer-Tarjan algorithm requires a separate - // bucket for each vertex. However, this is unnecessary, because each vertex - // is only placed into a single bucket (that of its semidominator), and each - // vertex's bucket is processed before it is added to any bucket itself. - // - // Instead of using a bucket per vertex, we use a single array Buckets that - // has two purposes. Before the vertex V with preorder number i is processed, - // Buckets[i] stores the index of the first element in V's bucket. After V's - // bucket is processed, Buckets[i] stores the index of the next element in the - // bucket containing V, if any. - SmallVector<unsigned, 32> Buckets; - Buckets.resize(N + 1); - for (unsigned i = 1; i <= N; ++i) - Buckets[i] = i; - - for (unsigned i = N; i >= 2; --i) { - NodePtr W = DT.Vertex[i]; - auto &WInfo = DT.Info[W]; - - // Step #2: Implicitly define the immediate dominator of vertices - for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { - NodePtr V = DT.Vertex[Buckets[j]]; - NodePtr U = Eval<GraphT>(DT, V, i + 1); - DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; + // Step #2: Calculate the semidominators of all vertices. + for (unsigned i = N; i >= 2; --i) { + NodePtr W = NumToNode[i]; + auto &WInfo = NodeToInfo[W]; + + // Initialize the semi dominator to point to the parent node. + WInfo.Semi = WInfo.Parent; + for (const auto &N : inverse_children<NodeType>(W)) + if (NodeToInfo.count(N)) { // Only if this predecessor is reachable! + unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; + if (SemiU < WInfo.Semi) + WInfo.Semi = SemiU; + } } - // Step #3: Calculate the semidominators of all vertices + // Step #3: Explicitly define the immediate dominator of each vertex. + // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). + // Note that the parents were stored in IDoms and later got invalidated + // during path compression in Eval. + for (unsigned i = 2; i <= N; ++i) { + const NodePtr W = NumToNode[i]; + auto &WInfo = NodeToInfo[W]; + const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; + NodePtr WIDomCandidate = WInfo.IDom; + while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) + WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; + + WInfo.IDom = WIDomCandidate; + } - // initialize the semi dominator to point to the parent node - WInfo.Semi = WInfo.Parent; - for (const auto &N : inverse_children<NodeT>(W)) - if (DT.Info.count(N)) { // Only if this predecessor is reachable! - unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi; - if (SemiU < WInfo.Semi) - WInfo.Semi = SemiU; - } + if (DT.Roots.empty()) return; - // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is - // necessarily parent(V). In this case, set idom(V) here and avoid placing - // V into a bucket. - if (WInfo.Semi == WInfo.Parent) { - DT.IDoms[W] = DT.Vertex[WInfo.Parent]; - } else { - Buckets[i] = Buckets[WInfo.Semi]; - Buckets[WInfo.Semi] = i; + // Add a node for the root. This node might be the actual root, if there is + // one exit block, or it may be the virtual exit (denoted by + // (BasicBlock *)0) which postdominates all real exits if there are multiple + // exit blocks, or an infinite loop. + NodePtr Root = !MultipleRoots ? DT.Roots[0] : nullptr; + + DT.RootNode = + (DT.DomTreeNodes[Root] = + llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) + .get(); + + // Loop over all of the reachable blocks in the function... + for (unsigned i = 2; i <= N; ++i) { + NodePtr W = NumToNode[i]; + + // Don't replace this with 'count', the insertion side effect is important + if (DT.DomTreeNodes[W]) + continue; // Haven't calculated this node yet? + + NodePtr ImmDom = getIDom(W); + + assert(ImmDom || DT.DomTreeNodes[nullptr]); + + // Get or calculate the node for the immediate dominator + TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + DT.DomTreeNodes[W] = IDomNode->addChild( + llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); } } - if (N >= 1) { - NodePtr Root = DT.Vertex[1]; - for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { - NodePtr V = DT.Vertex[Buckets[j]]; - DT.IDoms[V] = Root; - } + void doFullDFSWalk(const DomTreeT &DT) { + NumToNode.push_back(nullptr); + unsigned Num = 0; + for (auto *Root : DT.Roots) + if (!DT.isPostDominator()) + Num = runForwardDFS(Root, Num); + else + Num = runReverseDFS(Root, Num); } - // Step #4: Explicitly define the immediate dominator of each vertex - for (unsigned i = 2; i <= N; ++i) { - NodePtr W = DT.Vertex[i]; - NodePtr &WIDom = DT.IDoms[W]; - if (WIDom != DT.Vertex[DT.Info[W].Semi]) - WIDom = DT.IDoms[WIDom]; + static void PrintBlockOrNullptr(raw_ostream &O, NodePtr Obj) { + if (!Obj) + O << "nullptr"; + else + Obj->printAsOperand(O, false); } - if (DT.Roots.empty()) return; + // Checks if the tree contains all reachable nodes in the input graph. + bool verifyReachability(const DomTreeT &DT) { + clear(); + doFullDFSWalk(DT); - // Add a node for the root. This node might be the actual root, if there is - // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) - // which postdominates all real exits if there are multiple exit blocks, or - // an infinite loop. - NodePtr Root = !MultipleRoots ? DT.Roots[0] : nullptr; + for (auto &NodeToTN : DT.DomTreeNodes) { + const TreeNodePtr TN = NodeToTN.second.get(); + const NodePtr BB = TN->getBlock(); + if (!BB) continue; - DT.RootNode = - (DT.DomTreeNodes[Root] = - llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr)) - .get(); + if (NodeToInfo.count(BB) == 0) { + errs() << "DomTree node "; + PrintBlockOrNullptr(errs(), BB); + errs() << " not found by DFS walk!\n"; + errs().flush(); - // Loop over all of the reachable blocks in the function... - for (unsigned i = 2; i <= N; ++i) { - NodePtr W = DT.Vertex[i]; + return false; + } + } - // Don't replace this with 'count', the insertion side effect is important - if (DT.DomTreeNodes[W]) - continue; // Haven't calculated this node yet? + return true; + } - NodePtr ImmDom = DT.getIDom(W); + // Check if for every parent with a level L in the tree all of its children + // have level L + 1. + static bool VerifyLevels(const DomTreeT &DT) { + for (auto &NodeToTN : DT.DomTreeNodes) { + const TreeNodePtr TN = NodeToTN.second.get(); + const NodePtr BB = TN->getBlock(); + if (!BB) continue; + + const TreeNodePtr IDom = TN->getIDom(); + if (!IDom && TN->getLevel() != 0) { + errs() << "Node without an IDom "; + PrintBlockOrNullptr(errs(), BB); + errs() << " has a nonzero level " << TN->getLevel() << "!\n"; + errs().flush(); + + return false; + } - assert(ImmDom || DT.DomTreeNodes[nullptr]); + if (IDom && TN->getLevel() != IDom->getLevel() + 1) { + errs() << "Node "; + PrintBlockOrNullptr(errs(), BB); + errs() << " has level " << TN->getLevel() << " while it's IDom "; + PrintBlockOrNullptr(errs(), IDom->getBlock()); + errs() << " has level " << IDom->getLevel() << "!\n"; + errs().flush(); - // Get or calculate the node for the immediate dominator - DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom); + return false; + } + } - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - DT.DomTreeNodes[W] = IDomNode->addChild( - llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode)); + return true; + } + + // Checks if for every edge From -> To in the graph + // NCD(From, To) == IDom(To) or To. + bool verifyNCD(const DomTreeT &DT) { + clear(); + doFullDFSWalk(DT); + + for (auto &BlockToInfo : NodeToInfo) { + auto &Info = BlockToInfo.second; + + const NodePtr From = NumToNode[Info.Parent]; + if (!From) continue; + + const NodePtr To = BlockToInfo.first; + const TreeNodePtr ToTN = DT.getNode(To); + assert(ToTN); + + const NodePtr NCD = DT.findNearestCommonDominator(From, To); + const TreeNodePtr NCDTN = NCD ? DT.getNode(NCD) : nullptr; + const TreeNodePtr ToIDom = ToTN->getIDom(); + if (NCDTN != ToTN && NCDTN != ToIDom) { + errs() << "NearestCommonDominator verification failed:\n\tNCD(From:"; + PrintBlockOrNullptr(errs(), From); + errs() << ", To:"; + PrintBlockOrNullptr(errs(), To); + errs() << ") = "; + PrintBlockOrNullptr(errs(), NCD); + errs() << ",\t (should be To or IDom[To]: "; + PrintBlockOrNullptr(errs(), ToIDom ? ToIDom->getBlock() : nullptr); + errs() << ")\n"; + errs().flush(); + + return false; + } + } + + return true; + } + + // The below routines verify the correctness of the dominator tree relative to + // the CFG it's coming from. A tree is a dominator tree iff it has two + // properties, called the parent property and the sibling property. Tarjan + // and Lengauer prove (but don't explicitly name) the properties as part of + // the proofs in their 1972 paper, but the proofs are mostly part of proving + // things about semidominators and idoms, and some of them are simply asserted + // based on even earlier papers (see, e.g., lemma 2). Some papers refer to + // these properties as "valid" and "co-valid". See, e.g., "Dominators, + // directed bipolar orders, and independent spanning trees" by Loukas + // Georgiadis and Robert E. Tarjan, as well as "Dominator Tree Verification + // and Vertex-Disjoint Paths " by the same authors. + + // A very simple and direct explanation of these properties can be found in + // "An Experimental Study of Dynamic Dominators", found at + // https://arxiv.org/abs/1604.02711 + + // The easiest way to think of the parent property is that it's a requirement + // of being a dominator. Let's just take immediate dominators. For PARENT to + // be an immediate dominator of CHILD, all paths in the CFG must go through + // PARENT before they hit CHILD. This implies that if you were to cut PARENT + // out of the CFG, there should be no paths to CHILD that are reachable. If + // there are, then you now have a path from PARENT to CHILD that goes around + // PARENT and still reaches CHILD, which by definition, means PARENT can't be + // a dominator of CHILD (let alone an immediate one). + + // The sibling property is similar. It says that for each pair of sibling + // nodes in the dominator tree (LEFT and RIGHT) , they must not dominate each + // other. If sibling LEFT dominated sibling RIGHT, it means there are no + // paths in the CFG from sibling LEFT to sibling RIGHT that do not go through + // LEFT, and thus, LEFT is really an ancestor (in the dominator tree) of + // RIGHT, not a sibling. + + // It is possible to verify the parent and sibling properties in + // linear time, but the algorithms are complex. Instead, we do it in a + // straightforward N^2 and N^3 way below, using direct path reachability. + + + // Checks if the tree has the parent property: if for all edges from V to W in + // the input graph, such that V is reachable, the parent of W in the tree is + // an ancestor of V in the tree. + // + // This means that if a node gets disconnected from the graph, then all of + // the nodes it dominated previously will now become unreachable. + bool verifyParentProperty(const DomTreeT &DT) { + for (auto &NodeToTN : DT.DomTreeNodes) { + const TreeNodePtr TN = NodeToTN.second.get(); + const NodePtr BB = TN->getBlock(); + if (!BB || TN->getChildren().empty()) continue; + + clear(); + NodeToInfo.insert({BB, {}}); + doFullDFSWalk(DT); + + for (TreeNodePtr Child : TN->getChildren()) + if (NodeToInfo.count(Child->getBlock()) != 0) { + errs() << "Child "; + PrintBlockOrNullptr(errs(), Child->getBlock()); + errs() << " reachable after its parent "; + PrintBlockOrNullptr(errs(), BB); + errs() << " is removed!\n"; + errs().flush(); + + return false; + } + } + + return true; } - // Free temporary memory used to construct idom's - DT.IDoms.clear(); - DT.Info.clear(); - DT.Vertex.clear(); - DT.Vertex.shrink_to_fit(); + // Check if the tree has sibling property: if a node V does not dominate a + // node W for all siblings V and W in the tree. + // + // This means that if a node gets disconnected from the graph, then all of its + // siblings will now still be reachable. + bool verifySiblingProperty(const DomTreeT &DT) { + for (auto &NodeToTN : DT.DomTreeNodes) { + const TreeNodePtr TN = NodeToTN.second.get(); + const NodePtr BB = TN->getBlock(); + if (!BB || TN->getChildren().empty()) continue; + + const auto &Siblings = TN->getChildren(); + for (const TreeNodePtr N : Siblings) { + clear(); + NodeToInfo.insert({N->getBlock(), {}}); + doFullDFSWalk(DT); + + for (const TreeNodePtr S : Siblings) { + if (S == N) continue; + + if (NodeToInfo.count(S->getBlock()) == 0) { + errs() << "Node "; + PrintBlockOrNullptr(errs(), S->getBlock()); + errs() << " not reachable when its sibling "; + PrintBlockOrNullptr(errs(), N->getBlock()); + errs() << " is removed!\n"; + errs().flush(); + + return false; + } + } + } + } + + return true; + } +}; - DT.updateDFSNumbers(); +template <class FuncT, class NodeT> +void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, + FuncT &F) { + using NodePtr = typename GraphTraits<NodeT>::NodeRef; + static_assert(std::is_pointer<NodePtr>::value, + "NodePtr should be a pointer type"); + SemiNCAInfo<typename std::remove_pointer<NodePtr>::type> SNCA; + SNCA.template runSemiNCA<NodeT>(DT, GraphTraits<FuncT *>::size(&F)); } + +template <class NodeT> +bool Verify(const DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT) { + using NodePtr = typename GraphTraits<NodeT>::NodeRef; + static_assert(std::is_pointer<NodePtr>::value, + "NodePtr should be a pointer type"); + SemiNCAInfo<typename std::remove_pointer<NodePtr>::type> SNCA; + + return SNCA.verifyReachability(DT) && SNCA.VerifyLevels(DT) && + SNCA.verifyNCD(DT) && SNCA.verifyParentProperty(DT) && + SNCA.verifySiblingProperty(DT); } +} // namespace DomTreeBuilder +} // namespace llvm + #endif diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h index f29cc40ffdd5..72c28865ac57 100644 --- a/include/llvm/Support/TargetParser.h +++ b/include/llvm/Support/TargetParser.h @@ -17,6 +17,7 @@ // FIXME: vector is used because that's what clang uses for subtarget feature // lists, but SmallVector would probably be better +#include "llvm/ADT/Triple.h" #include <vector> namespace llvm { @@ -140,6 +141,8 @@ unsigned parseArchEndian(StringRef Arch); unsigned parseArchProfile(StringRef Arch); unsigned parseArchVersion(StringRef Arch); +StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU); + } // namespace ARM // FIXME:This should be made into class design,to avoid dupplication. diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index c196dd6c1ddc..549da3ccad51 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -188,7 +188,7 @@ public: NullNode(std::unique_ptr<Document> &D) : Node(NK_Null, D, StringRef(), StringRef()) {} - static inline bool classof(const Node *N) { return N->getType() == NK_Null; } + static bool classof(const Node *N) { return N->getType() == NK_Null; } }; /// \brief A scalar node is an opaque datum that can be presented as a @@ -220,7 +220,7 @@ public: /// This happens with escaped characters and multi-line literals. StringRef getValue(SmallVectorImpl<char> &Storage) const; - static inline bool classof(const Node *N) { + static bool classof(const Node *N) { return N->getType() == NK_Scalar; } @@ -254,7 +254,7 @@ public: /// \brief Gets the value of this node as a StringRef. StringRef getValue() const { return Value; } - static inline bool classof(const Node *N) { + static bool classof(const Node *N) { return N->getType() == NK_BlockScalar; } @@ -296,7 +296,7 @@ public: Val->skip(); } - static inline bool classof(const Node *N) { + static bool classof(const Node *N) { return N->getType() == NK_KeyValue; } @@ -419,7 +419,7 @@ public: void skip() override { yaml::skip(*this); } - static inline bool classof(const Node *N) { + static bool classof(const Node *N) { return N->getType() == NK_Mapping; } @@ -476,7 +476,7 @@ public: void skip() override { yaml::skip(*this); } - static inline bool classof(const Node *N) { + static bool classof(const Node *N) { return N->getType() == NK_Sequence; } @@ -502,7 +502,7 @@ public: StringRef getName() const { return Name; } Node *getTarget(); - static inline bool classof(const Node *N) { return N->getType() == NK_Alias; } + static bool classof(const Node *N) { return N->getType() == NK_Alias; } private: StringRef Name; diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 53618a56f853..15b3b11db045 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -180,17 +180,17 @@ struct BlockScalarTraits { /// to/from a YAML sequence. For example: /// /// template<> -/// struct SequenceTraits< std::vector<MyType>> { -/// static size_t size(IO &io, std::vector<MyType> &seq) { +/// struct SequenceTraits<MyContainer> { +/// static size_t size(IO &io, MyContainer &seq) { /// return seq.size(); /// } -/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) { +/// static MyType& element(IO &, MyContainer &seq, size_t index) { /// if ( index >= seq.size() ) /// seq.resize(index+1); /// return seq[index]; /// } /// }; -template<typename T> +template<typename T, typename EnableIf = void> struct SequenceTraits { // Must provide: // static size_t size(IO &io, T &seq); @@ -201,6 +201,14 @@ struct SequenceTraits { // static const bool flow = true; }; +/// This class should be specialized by any type for which vectors of that +/// type need to be converted to/from a YAML sequence. +template<typename T, typename EnableIf = void> +struct SequenceElementTraits { + // Must provide: + // static const bool flow; +}; + /// This class should be specialized by any type that needs to be converted /// to/from a list of YAML documents. template<typename T> @@ -1148,7 +1156,7 @@ private: HNode(Node *n) : _node(n) { } virtual ~HNode() = default; - static inline bool classof(const HNode *) { return true; } + static bool classof(const HNode *) { return true; } Node *_node; }; @@ -1159,11 +1167,9 @@ private: public: EmptyHNode(Node *n) : HNode(n) { } - static inline bool classof(const HNode *n) { - return NullNode::classof(n->_node); - } + static bool classof(const HNode *n) { return NullNode::classof(n->_node); } - static inline bool classof(const EmptyHNode *) { return true; } + static bool classof(const EmptyHNode *) { return true; } }; class ScalarHNode : public HNode { @@ -1174,12 +1180,12 @@ private: StringRef value() const { return _value; } - static inline bool classof(const HNode *n) { + static bool classof(const HNode *n) { return ScalarNode::classof(n->_node) || BlockScalarNode::classof(n->_node); } - static inline bool classof(const ScalarHNode *) { return true; } + static bool classof(const ScalarHNode *) { return true; } protected: StringRef _value; @@ -1191,11 +1197,11 @@ private: public: MapHNode(Node *n) : HNode(n) { } - static inline bool classof(const HNode *n) { + static bool classof(const HNode *n) { return MappingNode::classof(n->_node); } - static inline bool classof(const MapHNode *) { return true; } + static bool classof(const MapHNode *) { return true; } using NameToNode = StringMap<std::unique_ptr<HNode>>; @@ -1209,11 +1215,11 @@ private: public: SequenceHNode(Node *n) : HNode(n) { } - static inline bool classof(const HNode *n) { + static bool classof(const HNode *n) { return SequenceNode::classof(n->_node); } - static inline bool classof(const SequenceHNode *) { return true; } + static bool classof(const SequenceHNode *) { return true; } std::vector<std::unique_ptr<HNode>> Entries; }; @@ -1544,18 +1550,59 @@ operator<<(Output &yout, T &seq) { return yout; } -template <typename T> struct SequenceTraitsImpl { - using _type = typename T::value_type; +template <bool B> struct IsFlowSequenceBase {}; +template <> struct IsFlowSequenceBase<true> { static const bool flow = true; }; + +template <typename T, bool Flow> +struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> { +private: + using type = typename T::value_type; +public: static size_t size(IO &io, T &seq) { return seq.size(); } - static _type &element(IO &io, T &seq, size_t index) { + static type &element(IO &io, T &seq, size_t index) { if (index >= seq.size()) seq.resize(index + 1); return seq[index]; } }; +// Simple helper to check an expression can be used as a bool-valued template +// argument. +template <bool> struct CheckIsBool { static const bool value = true; }; + +// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have +// SequenceTraits that do the obvious thing. +template <typename T> +struct SequenceTraits<std::vector<T>, + typename std::enable_if<CheckIsBool< + SequenceElementTraits<T>::flow>::value>::type> + : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {}; +template <typename T, unsigned N> +struct SequenceTraits<SmallVector<T, N>, + typename std::enable_if<CheckIsBool< + SequenceElementTraits<T>::flow>::value>::type> + : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {}; + +// Sequences of fundamental types use flow formatting. +template <typename T> +struct SequenceElementTraits< + T, typename std::enable_if<std::is_fundamental<T>::value>::type> { + static const bool flow = true; +}; + +// Sequences of strings use block formatting. +template<> struct SequenceElementTraits<std::string> { + static const bool flow = false; +}; +template<> struct SequenceElementTraits<StringRef> { + static const bool flow = false; +}; +template<> struct SequenceElementTraits<std::pair<std::string, std::string>> { + static const bool flow = false; +}; + /// Implementation of CustomMappingTraits for std::map<std::string, T>. template <typename T> struct StdMapStringCustomMappingTraitsImpl { using map_type = std::map<std::string, T>; @@ -1573,42 +1620,29 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl { } // end namespace yaml } // end namespace llvm -/// Utility for declaring that a std::vector of a particular type -/// should be considered a YAML sequence. -#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \ +#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW) \ namespace llvm { \ namespace yaml { \ - template <> \ - struct SequenceTraits<std::vector<_type>> \ - : public SequenceTraitsImpl<std::vector<_type>> {}; \ - template <unsigned N> \ - struct SequenceTraits<SmallVector<_type, N>> \ - : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \ + static_assert( \ + !std::is_fundamental<TYPE>::value && \ + !std::is_same<TYPE, std::string>::value && \ + !std::is_same<TYPE, llvm::StringRef>::value, \ + "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \ + template <> struct SequenceElementTraits<TYPE> { \ + static const bool flow = FLOW; \ + }; \ } \ } /// Utility for declaring that a std::vector of a particular type +/// should be considered a YAML sequence. +#define LLVM_YAML_IS_SEQUENCE_VECTOR(type) \ + LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false) + +/// Utility for declaring that a std::vector of a particular type /// should be considered a YAML flow sequence. -/// We need to do a partial specialization on the vector version, not a full. -/// If this is a full specialization, the compiler is a bit too "smart" and -/// decides to warn on -Wunused-const-variable. This workaround can be -/// removed and we can do a full specialization on std::vector<T> once -/// PR28878 is fixed. -#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \ - namespace llvm { \ - namespace yaml { \ - template <unsigned N> \ - struct SequenceTraits<SmallVector<_type, N>> \ - : public SequenceTraitsImpl<SmallVector<_type, N>> { \ - static const bool flow = true; \ - }; \ - template <typename Allocator> \ - struct SequenceTraits<std::vector<_type, Allocator>> \ - : public SequenceTraitsImpl<std::vector<_type, Allocator>> { \ - static const bool flow = true; \ - }; \ - } \ - } +#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type) \ + LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true) #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \ namespace llvm { \ @@ -1655,10 +1689,10 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl { namespace yaml { \ template <unsigned N> \ struct DocumentListTraits<SmallVector<_type, N>> \ - : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \ + : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \ template <> \ struct DocumentListTraits<std::vector<_type>> \ - : public SequenceTraitsImpl<std::vector<_type>> {}; \ + : public SequenceTraitsImpl<std::vector<_type>, false> {}; \ } \ } diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index 9593d8bd7edb..e35bcb015d6a 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -49,6 +49,12 @@ def G_TRUNC : Instruction { let hasSideEffects = 0; } +def G_IMPLICIT_DEF : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins); + let hasSideEffects = 0; +} + def G_FRAME_INDEX : Instruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins unknown:$src2); @@ -416,6 +422,34 @@ def G_FPOW : Instruction { let hasSideEffects = 0; } +// Floating point base-e exponential of a value. +def G_FEXP : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = 0; +} + +// Floating point base-2 exponential of a value. +def G_FEXP2 : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = 0; +} + +// Floating point base-2 logarithm of a value. +def G_FLOG : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = 0; +} + +// Floating point base-2 logarithm of a value. +def G_FLOG2 : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Memory ops //------------------------------------------------------------------------------ diff --git a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index a06c67fe814c..3a3118139bcb 100644 --- a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -62,6 +62,8 @@ def : GINodeEquiv<G_FMUL, fmul>; def : GINodeEquiv<G_FDIV, fdiv>; def : GINodeEquiv<G_FREM, frem>; def : GINodeEquiv<G_FPOW, fpow>; +def : GINodeEquiv<G_FEXP2, fexp2>; +def : GINodeEquiv<G_FLOG2, flog2>; def : GINodeEquiv<G_BR, br>; // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 22dab2e82828..964d6314b127 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -2051,7 +2051,7 @@ public: /// this information should not be provided because it will generate more /// loads. virtual bool hasPairedLoad(EVT /*LoadedType*/, - unsigned & /*RequiredAligment*/) const { + unsigned & /*RequiredAlignment*/) const { return false; } @@ -2722,7 +2722,7 @@ public: // This transformation may not be desirable if it disrupts a particularly // auspicious target-specific tree (e.g. bitfield extraction in AArch64). // By default, it returns true. - virtual bool isDesirableToCommuteWithShift(const SDNode *N /*Op*/) const { + virtual bool isDesirableToCommuteWithShift(const SDNode *N) const { return true; } diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 836b11cf89c6..cadf86058f0c 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -222,6 +222,8 @@ HANDLE_TARGET_OPCODE(G_OR) HANDLE_TARGET_OPCODE(G_XOR) +HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF) + /// Generic instruction to materialize the address of an alloca or other /// stack-based object. HANDLE_TARGET_OPCODE(G_FRAME_INDEX) @@ -369,6 +371,18 @@ HANDLE_TARGET_OPCODE(G_FREM) /// Generic FP exponentiation. HANDLE_TARGET_OPCODE(G_FPOW) +/// Generic base-e exponential of a value. +HANDLE_TARGET_OPCODE(G_FEXP) + +/// Generic base-2 exponential of a value. +HANDLE_TARGET_OPCODE(G_FEXP2) + +/// Floating point base-e logarithm of a value. +HANDLE_TARGET_OPCODE(G_FLOG) + +/// Floating point base-2 logarithm of a value. +HANDLE_TARGET_OPCODE(G_FLOG2) + /// Generic FP negation. HANDLE_TARGET_OPCODE(G_FNEG) diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index db4bfb15f51d..276306f686ff 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -145,7 +145,6 @@ public: bool DisableTailCalls; bool DisableUnitAtATime; bool DisableUnrollLoops; - bool BBVectorize; bool SLPVectorize; bool LoopVectorize; bool RerollLoops; diff --git a/include/llvm/Transforms/SampleProfile.h b/include/llvm/Transforms/SampleProfile.h index 93fa9532cc3a..c984fe74ba93 100644 --- a/include/llvm/Transforms/SampleProfile.h +++ b/include/llvm/Transforms/SampleProfile.h @@ -21,6 +21,10 @@ namespace llvm { class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> { public: PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + SampleProfileLoaderPass(std::string File = "") : ProfileFileName(File) {} + +private: + std::string ProfileFileName; }; } // End llvm namespace diff --git a/include/llvm/Transforms/Scalar/ConstantHoisting.h b/include/llvm/Transforms/Scalar/ConstantHoisting.h index edc91add7a73..a2a9afc083a0 100644 --- a/include/llvm/Transforms/Scalar/ConstantHoisting.h +++ b/include/llvm/Transforms/Scalar/ConstantHoisting.h @@ -132,6 +132,8 @@ private: Instruction *Inst, unsigned Idx, ConstantInt *ConstInt); void collectConstantCandidates(ConstCandMapType &ConstCandMap, + Instruction *Inst, unsigned Idx); + void collectConstantCandidates(ConstCandMapType &ConstCandMap, Instruction *Inst); void collectConstantCandidates(Function &Fn); void findAndMakeBaseConstant(ConstCandVecType::iterator S, diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index 0397eb95e763..1344285917ba 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -184,9 +184,14 @@ public: /// Returns true if Phi is a first-order recurrence. A first-order recurrence /// is a non-reduction recurrence relation in which the value of the /// recurrence in the current loop iteration equals a value defined in the - /// previous iteration. - static bool isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop, - DominatorTree *DT); + /// previous iteration. \p SinkAfter includes pairs of instructions where the + /// first will be rescheduled to appear after the second if/when the loop is + /// vectorized. It may be augmented with additional pairs if needed in order + /// to handle Phi as a first-order recurrence. + static bool + isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop, + DenseMap<Instruction *, Instruction *> &SinkAfter, + DominatorTree *DT); RecurrenceKind getRecurrenceKind() { return Kind; } diff --git a/include/llvm/Transforms/Utils/OrderedInstructions.h b/include/llvm/Transforms/Utils/OrderedInstructions.h index 64c6bcb68b18..165d4bdaa6d4 100644 --- a/include/llvm/Transforms/Utils/OrderedInstructions.h +++ b/include/llvm/Transforms/Utils/OrderedInstructions.h @@ -46,7 +46,7 @@ public: /// i.e. If an instruction is deleted or added to the basic block, the user /// should call this function to invalidate the OrderedBasicBlock cache for /// this basic block. - void invalidateBlock(BasicBlock *BB) { OBBMap.erase(BB); } + void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); } }; } // end namespace llvm diff --git a/include/llvm/Transforms/Utils/PredicateInfo.h b/include/llvm/Transforms/Utils/PredicateInfo.h index 1322c686eb90..8150f1528397 100644 --- a/include/llvm/Transforms/Utils/PredicateInfo.h +++ b/include/llvm/Transforms/Utils/PredicateInfo.h @@ -74,6 +74,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Transforms/Utils/OrderedInstructions.h" #include <algorithm> #include <cassert> #include <cstddef> @@ -89,7 +90,6 @@ class Instruction; class MemoryAccess; class LLVMContext; class raw_ostream; -class OrderedBasicBlock; enum PredicateType { PT_Branch, PT_Assume, PT_Switch }; @@ -114,8 +114,9 @@ protected: class PredicateWithCondition : public PredicateBase { public: Value *Condition; - static inline bool classof(const PredicateBase *PB) { - return PB->Type == PT_Assume || PB->Type == PT_Branch || PB->Type == PT_Switch; + static bool classof(const PredicateBase *PB) { + return PB->Type == PT_Assume || PB->Type == PT_Branch || + PB->Type == PT_Switch; } protected: @@ -133,7 +134,7 @@ public: : PredicateWithCondition(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {} PredicateAssume() = delete; - static inline bool classof(const PredicateBase *PB) { + static bool classof(const PredicateBase *PB) { return PB->Type == PT_Assume; } }; @@ -146,7 +147,7 @@ public: BasicBlock *From; BasicBlock *To; PredicateWithEdge() = delete; - static inline bool classof(const PredicateBase *PB) { + static bool classof(const PredicateBase *PB) { return PB->Type == PT_Branch || PB->Type == PT_Switch; } @@ -166,7 +167,7 @@ public: : PredicateWithEdge(PT_Branch, Op, BranchBB, SplitBB, Condition), TrueEdge(TakenEdge) {} PredicateBranch() = delete; - static inline bool classof(const PredicateBase *PB) { + static bool classof(const PredicateBase *PB) { return PB->Type == PT_Branch; } }; @@ -182,7 +183,7 @@ public: SI->getCondition()), CaseValue(CaseValue), Switch(SI) {} PredicateSwitch() = delete; - static inline bool classof(const PredicateBase *PB) { + static bool classof(const PredicateBase *PB) { return PB->Type == PT_Switch; } }; @@ -244,6 +245,7 @@ private: Function &F; DominatorTree &DT; AssumptionCache &AC; + OrderedInstructions OI; // This maps from copy operands to Predicate Info. Note that it does not own // the Predicate Info, they belong to the ValueInfo structs in the ValueInfos // vector. @@ -256,8 +258,6 @@ private: // 0 is not a valid Value Info index, you can use DenseMap::lookup and tell // whether it returned a valid result. DenseMap<Value *, unsigned int> ValueInfoNums; - // OrderedBasicBlocks used during sorting uses - DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>> OBBMap; // The set of edges along which we can only handle phi uses, due to critical // edges. DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeUsesOnly; diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 0cc6b34d4593..45ef8246dcd1 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -116,7 +116,7 @@ static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) { /// - \a scheduleMapGlobalAliasee() /// - \a scheduleRemapFunction() /// -/// Sometimes a callback needs a diferent mapping context. Such a context can +/// Sometimes a callback needs a different mapping context. Such a context can /// be registered using \a registerAlternateMappingContext(), which takes an /// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to /// pass into the schedule*() functions. diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h index f734e299c6e9..19845e471e48 100644 --- a/include/llvm/Transforms/Vectorize.h +++ b/include/llvm/Transforms/Vectorize.h @@ -108,13 +108,6 @@ struct VectorizeConfig { //===----------------------------------------------------------------------===// // -// BBVectorize - A basic-block vectorization pass. -// -BasicBlockPass * -createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig()); - -//===----------------------------------------------------------------------===// -// // LoopVectorize - Create a loop vectorization pass. // Pass *createLoopVectorizePass(bool NoUnrolling = false, |