diff options
author | Vitaly Buka <vitalybuka@google.com> | 2024-08-02 16:54:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 16:54:44 -0700 |
commit | 048cf8857e081fb80d5ac8b24a79f999d632141b (patch) | |
tree | 5bfa55b467705e3129b70fbd55726d038b921d61 /llvm/lib/Transforms/Utils/ModuleUtils.cpp | |
parent | a0a9bf5152507beacd2a72dda42d054391494c4a (diff) | |
download | llvm-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.cpp | 44 |
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()) |