aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-01-24 19:17:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:24:44 +0000
commitab50317e96e57dee5b3ff4ad3f16f205b2a3359e (patch)
tree4b1f388eb6a07e574417aaacecd3ec4a83550718 /contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp
parent412542983a5ba62902141a8a7e155cceb9196a66 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/GlobalMerge.cpp167
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) {