diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-24 19:17:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:24:44 +0000 |
commit | ab50317e96e57dee5b3ff4ad3f16f205b2a3359e (patch) | |
tree | 4b1f388eb6a07e574417aaacecd3ec4a83550718 /contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp | |
parent | 412542983a5ba62902141a8a7e155cceb9196a66 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp | 167 |
1 files changed, 85 insertions, 82 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp index 22b6d31d0634..a2b5cbf7bad9 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp @@ -60,6 +60,7 @@ // // ===---------------------------------------------------------------------===// +#include "llvm/CodeGen/GlobalMerge.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" @@ -137,88 +138,99 @@ STATISTIC(NumMerged, "Number of globals merged"); namespace { - class GlobalMerge : public FunctionPass { - const TargetMachine *TM = nullptr; - - // FIXME: Infer the maximum possible offset depending on the actual users - // (these max offsets are different for the users inside Thumb or ARM - // functions), see the code that passes in the offset in the ARM backend - // for more information. - unsigned MaxOffset; - - /// Whether we should try to optimize for size only. - /// Currently, this applies a dead simple heuristic: only consider globals - /// used in minsize functions for merging. - /// FIXME: This could learn about optsize, and be used in the cost model. - bool OnlyOptimizeForSize = false; - - /// Whether we should merge global variables that have external linkage. - bool MergeExternalGlobals = false; +class GlobalMergeImpl { + const TargetMachine *TM = nullptr; + GlobalMergeOptions Opt; + bool IsMachO = false; + +private: + bool doMerge(SmallVectorImpl<GlobalVariable *> &Globals, Module &M, + bool isConst, unsigned AddrSpace) const; + + /// Merge everything in \p Globals for which the corresponding bit + /// in \p GlobalSet is set. + bool doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, + const BitVector &GlobalSet, Module &M, bool isConst, + unsigned AddrSpace) const; + + /// Check if the given variable has been identified as must keep + /// \pre setMustKeepGlobalVariables must have been called on the Module that + /// contains GV + bool isMustKeepGlobalVariable(const GlobalVariable *GV) const { + return MustKeepGlobalVariables.count(GV); + } - bool IsMachO = false; + /// Collect every variables marked as "used" or used in a landing pad + /// instruction for this Module. + void setMustKeepGlobalVariables(Module &M); - bool doMerge(SmallVectorImpl<GlobalVariable*> &Globals, - Module &M, bool isConst, unsigned AddrSpace) const; + /// Collect every variables marked as "used" + void collectUsedGlobalVariables(Module &M, StringRef Name); - /// Merge everything in \p Globals for which the corresponding bit - /// in \p GlobalSet is set. - bool doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, - const BitVector &GlobalSet, Module &M, bool isConst, - unsigned AddrSpace) const; + /// Keep track of the GlobalVariable that must not be merged away + SmallSetVector<const GlobalVariable *, 16> MustKeepGlobalVariables; - /// Check if the given variable has been identified as must keep - /// \pre setMustKeepGlobalVariables must have been called on the Module that - /// contains GV - bool isMustKeepGlobalVariable(const GlobalVariable *GV) const { - return MustKeepGlobalVariables.count(GV); - } +public: + GlobalMergeImpl(const TargetMachine *TM, GlobalMergeOptions Opt) + : TM(TM), Opt(Opt) {} + bool run(Module &M); +}; - /// Collect every variables marked as "used" or used in a landing pad - /// instruction for this Module. - void setMustKeepGlobalVariables(Module &M); +class GlobalMerge : public FunctionPass { + const TargetMachine *TM = nullptr; + GlobalMergeOptions Opt; - /// Collect every variables marked as "used" - void collectUsedGlobalVariables(Module &M, StringRef Name); +public: + static char ID; // Pass identification, replacement for typeid. - /// Keep track of the GlobalVariable that must not be merged away - SmallSetVector<const GlobalVariable *, 16> MustKeepGlobalVariables; + explicit GlobalMerge() : FunctionPass(ID) { + Opt.MaxOffset = GlobalMergeMaxOffset; + initializeGlobalMergePass(*PassRegistry::getPassRegistry()); + } - public: - static char ID; // Pass identification, replacement for typeid. + explicit GlobalMerge(const TargetMachine *TM, unsigned MaximalOffset, + bool OnlyOptimizeForSize, bool MergeExternalGlobals) + : FunctionPass(ID), TM(TM) { + Opt.MaxOffset = MaximalOffset; + Opt.SizeOnly = OnlyOptimizeForSize; + Opt.MergeExternal = MergeExternalGlobals; + initializeGlobalMergePass(*PassRegistry::getPassRegistry()); + } - explicit GlobalMerge() - : FunctionPass(ID), MaxOffset(GlobalMergeMaxOffset) { - initializeGlobalMergePass(*PassRegistry::getPassRegistry()); - } + bool doInitialization(Module &M) override { + GlobalMergeImpl P(TM, Opt); + return P.run(M); + } + bool runOnFunction(Function &F) override { return false; } - explicit GlobalMerge(const TargetMachine *TM, unsigned MaximalOffset, - bool OnlyOptimizeForSize, bool MergeExternalGlobals) - : FunctionPass(ID), TM(TM), MaxOffset(MaximalOffset), - OnlyOptimizeForSize(OnlyOptimizeForSize), - MergeExternalGlobals(MergeExternalGlobals) { - initializeGlobalMergePass(*PassRegistry::getPassRegistry()); - } + StringRef getPassName() const override { return "Merge internal globals"; } - bool doInitialization(Module &M) override; - bool runOnFunction(Function &F) override; - bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + FunctionPass::getAnalysisUsage(AU); + } +}; - StringRef getPassName() const override { return "Merge internal globals"; } +} // end anonymous namespace - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - FunctionPass::getAnalysisUsage(AU); - } - }; +PreservedAnalyses GlobalMergePass::run(Module &M, ModuleAnalysisManager &) { + GlobalMergeImpl P(TM, Options); + bool Changed = P.run(M); + if (!Changed) + return PreservedAnalyses::all(); -} // end anonymous namespace + PreservedAnalyses PA; + PA.preserveSet<CFGAnalyses>(); + return PA; +} char GlobalMerge::ID = 0; INITIALIZE_PASS(GlobalMerge, DEBUG_TYPE, "Merge global variables", false, false) -bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals, - Module &M, bool isConst, unsigned AddrSpace) const { +bool GlobalMergeImpl::doMerge(SmallVectorImpl<GlobalVariable *> &Globals, + Module &M, bool isConst, + unsigned AddrSpace) const { auto &DL = M.getDataLayout(); // FIXME: Find better heuristics llvm::stable_sort( @@ -333,7 +345,7 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals, Function *ParentFn = I->getParent()->getParent(); // If we're only optimizing for size, ignore non-minsize functions. - if (OnlyOptimizeForSize && !ParentFn->hasMinSize()) + if (Opt.SizeOnly && !ParentFn->hasMinSize()) continue; size_t UGSIdx = GlobalUsesByFunction[ParentFn]; @@ -434,9 +446,9 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals, return Changed; } -bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, - const BitVector &GlobalSet, Module &M, bool isConst, - unsigned AddrSpace) const { +bool GlobalMergeImpl::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, + const BitVector &GlobalSet, Module &M, + bool isConst, unsigned AddrSpace) const { assert(Globals.size() > 1); Type *Int32Ty = Type::getInt32Ty(M.getContext()); @@ -467,7 +479,7 @@ bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, unsigned Padding = alignTo(MergedSize, Alignment) - MergedSize; MergedSize += Padding; MergedSize += DL.getTypeAllocSize(Ty); - if (MergedSize > MaxOffset) { + if (MergedSize > Opt.MaxOffset) { break; } if (Padding) { @@ -563,7 +575,7 @@ bool GlobalMerge::doMerge(const SmallVectorImpl<GlobalVariable *> &Globals, return Changed; } -void GlobalMerge::collectUsedGlobalVariables(Module &M, StringRef Name) { +void GlobalMergeImpl::collectUsedGlobalVariables(Module &M, StringRef Name) { // Extract global variables from llvm.used array const GlobalVariable *GV = M.getGlobalVariable(Name); if (!GV || !GV->hasInitializer()) return; @@ -577,7 +589,7 @@ void GlobalMerge::collectUsedGlobalVariables(Module &M, StringRef Name) { MustKeepGlobalVariables.insert(G); } -void GlobalMerge::setMustKeepGlobalVariables(Module &M) { +void GlobalMergeImpl::setMustKeepGlobalVariables(Module &M) { collectUsedGlobalVariables(M, "llvm.used"); collectUsedGlobalVariables(M, "llvm.compiler.used"); @@ -604,7 +616,7 @@ void GlobalMerge::setMustKeepGlobalVariables(Module &M) { } } -bool GlobalMerge::doInitialization(Module &M) { +bool GlobalMergeImpl::run(Module &M) { if (!EnableGlobalMerge) return false; @@ -632,7 +644,7 @@ bool GlobalMerge::doInitialization(Module &M) { if (TM && !TM->shouldAssumeDSOLocal(M, &GV)) continue; - if (!(MergeExternalGlobals && GV.hasExternalLinkage()) && + if (!(Opt.MergeExternal && GV.hasExternalLinkage()) && !GV.hasInternalLinkage()) continue; @@ -659,7 +671,7 @@ bool GlobalMerge::doInitialization(Module &M) { continue; Type *Ty = GV.getValueType(); - if (DL.getTypeAllocSize(Ty) < MaxOffset) { + if (DL.getTypeAllocSize(Ty) < Opt.MaxOffset) { if (TM && TargetLoweringObjectFile::getKindForGlobal(&GV, *TM).isBSS()) BSSGlobals[{AddressSpace, Section}].push_back(&GV); @@ -686,15 +698,6 @@ bool GlobalMerge::doInitialization(Module &M) { return Changed; } -bool GlobalMerge::runOnFunction(Function &F) { - return false; -} - -bool GlobalMerge::doFinalization(Module &M) { - MustKeepGlobalVariables.clear(); - return false; -} - Pass *llvm::createGlobalMergePass(const TargetMachine *TM, unsigned Offset, bool OnlyOptimizeForSize, bool MergeExternalByDefault) { |