aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ModuleUtils.cpp
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2024-08-02 16:54:44 -0700
committerGitHub <noreply@github.com>2024-08-02 16:54:44 -0700
commit048cf8857e081fb80d5ac8b24a79f999d632141b (patch)
tree5bfa55b467705e3129b70fbd55726d038b921d61 /llvm/lib/Transforms/Utils/ModuleUtils.cpp
parenta0a9bf5152507beacd2a72dda42d054391494c4a (diff)
downloadllvm-048cf8857e081fb80d5ac8b24a79f999d632141b.zip
llvm-048cf8857e081fb80d5ac8b24a79f999d632141b.tar.gz
llvm-048cf8857e081fb80d5ac8b24a79f999d632141b.tar.bz2
[ModuleUtils] Add transformGlobal{C,D}tors (#101757)
For #101772
Diffstat (limited to 'llvm/lib/Transforms/Utils/ModuleUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ModuleUtils.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 1222791..309cf8e 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -79,6 +79,50 @@ void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *D
appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
}
+static void transformGlobalArray(StringRef ArrayName, Module &M,
+ const GlobalCtorTransformFn &Fn) {
+ GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName);
+ if (!GVCtor)
+ return;
+
+ IRBuilder<> IRB(M.getContext());
+ SmallVector<Constant *, 16> CurrentCtors;
+ bool Changed = false;
+ StructType *EltTy =
+ cast<StructType>(GVCtor->getValueType()->getArrayElementType());
+ if (Constant *Init = GVCtor->getInitializer()) {
+ CurrentCtors.reserve(Init->getNumOperands());
+ for (Value *OP : Init->operands()) {
+ Constant *C = cast<Constant>(OP);
+ Constant *NewC = Fn(C);
+ Changed |= (!NewC || NewC != C);
+ if (NewC)
+ CurrentCtors.push_back(NewC);
+ }
+ }
+ if (!Changed)
+ return;
+
+ GVCtor->eraseFromParent();
+
+ // Create a new initializer.
+ ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size());
+ Constant *NewInit = ConstantArray::get(AT, CurrentCtors);
+
+ // Create the new global variable and replace all uses of
+ // the old global variable with the new one.
+ (void)new GlobalVariable(M, NewInit->getType(), false,
+ GlobalValue::AppendingLinkage, NewInit, ArrayName);
+}
+
+void llvm::transformGlobalCtors(Module &M, const GlobalCtorTransformFn &Fn) {
+ transformGlobalArray("llvm.global_ctors", M, Fn);
+}
+
+void llvm::transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn) {
+ transformGlobalArray("llvm.global_dtors", M, Fn);
+}
+
static void collectUsedGlobals(GlobalVariable *GV,
SmallSetVector<Constant *, 16> &Init) {
if (!GV || !GV->hasInitializer())