diff options
author | Devang Patel <dpatel@apple.com> | 2011-10-31 23:58:51 +0000 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2011-11-14 09:11:32 -0800 |
commit | c3260988a8d234bd32d6fd4f121df783eb290d9a (patch) | |
tree | 4d016f734a236653c2d2a94ca6c7063d720ba972 /lib/Transforms/Utils | |
parent | 87011ab8c6918b3561c465b1aeb9a04e5cfb3aa9 (diff) | |
download | external_llvm-c3260988a8d234bd32d6fd4f121df783eb290d9a.tar.gz external_llvm-c3260988a8d234bd32d6fd4f121df783eb290d9a.tar.bz2 external_llvm-c3260988a8d234bd32d6fd4f121df783eb290d9a.zip |
Add utility to append a function to the list of global constructors.
Patch by Kostya Serebryany.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143405 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils')
-rw-r--r-- | lib/Transforms/Utils/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Transforms/Utils/ModuleUtils.cpp | 55 |
2 files changed, 56 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/CMakeLists.txt b/lib/Transforms/Utils/CMakeLists.txt index 7adc5f1ac2..6d5432d963 100644 --- a/lib/Transforms/Utils/CMakeLists.txt +++ b/lib/Transforms/Utils/CMakeLists.txt @@ -18,6 +18,7 @@ add_llvm_library(LLVMTransformUtils LowerInvoke.cpp LowerSwitch.cpp Mem2Reg.cpp + ModuleUtils.cpp PromoteMemoryToRegister.cpp SSAUpdater.cpp SimplifyCFG.cpp diff --git a/lib/Transforms/Utils/ModuleUtils.cpp b/lib/Transforms/Utils/ModuleUtils.cpp new file mode 100644 index 0000000000..db81de7b1d --- /dev/null +++ b/lib/Transforms/Utils/ModuleUtils.cpp @@ -0,0 +1,55 @@ +//===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This family of functions perform manipulations on Modules. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/Module.h" +#include "llvm/Support/IRBuilder.h" +using namespace llvm; + +void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) { + IRBuilder<> IRB(M.getContext()); + FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); + StructType *Ty = StructType::get( + IRB.getInt32Ty(), PointerType::getUnqual(FnTy), NULL); + + Constant *RuntimeCtorInit = ConstantStruct::get( + Ty, IRB.getInt32(Priority), F, NULL); + + // Get the current set of static global constructors and add the new ctor + // to the list. + SmallVector<Constant *, 16> CurrentCtors; + if (GlobalVariable * GVCtor = M.getNamedGlobal("llvm.global_ctors")) { + if (Constant *Init = GVCtor->getInitializer()) { + unsigned n = Init->getNumOperands(); + CurrentCtors.reserve(n + 1); + for (unsigned i = 0; i != n; ++i) + CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); + } + GVCtor->eraseFromParent(); + } + + CurrentCtors.push_back(RuntimeCtorInit); + + // Create a new initializer. + ArrayType *AT = ArrayType::get(RuntimeCtorInit->getType(), + 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, + "llvm.global_ctors"); +} |