summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp')
-rw-r--r--contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp57
1 files changed, 25 insertions, 32 deletions
diff --git a/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index 9ec28a3..eb91885 100644
--- a/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ModuleUtils.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
@@ -21,8 +20,8 @@
using namespace llvm;
-static void appendToGlobalArray(const char *Array,
- Module &M, Function *F, int Priority) {
+static void appendToGlobalArray(const char *Array, Module &M, Function *F,
+ int Priority, Constant *Data) {
IRBuilder<> IRB(M.getContext());
FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
@@ -31,15 +30,26 @@ static void appendToGlobalArray(const char *Array,
SmallVector<Constant *, 16> CurrentCtors;
StructType *EltTy;
if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
- // If there is a global_ctors array, use the existing struct type, which can
- // have 2 or 3 fields.
- ArrayType *ATy = cast<ArrayType>(GVCtor->getType()->getElementType());
- EltTy = cast<StructType>(ATy->getElementType());
+ ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType());
+ StructType *OldEltTy = cast<StructType>(ATy->getElementType());
+ // Upgrade a 2-field global array type to the new 3-field format if needed.
+ if (Data && OldEltTy->getNumElements() < 3)
+ EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
+ IRB.getInt8PtrTy(), nullptr);
+ else
+ EltTy = OldEltTy;
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)));
+ for (unsigned i = 0; i != n; ++i) {
+ auto Ctor = cast<Constant>(Init->getOperand(i));
+ if (EltTy != OldEltTy)
+ Ctor = ConstantStruct::get(
+ EltTy, Ctor->getAggregateElement((unsigned)0),
+ Ctor->getAggregateElement(1),
+ Constant::getNullValue(IRB.getInt8PtrTy()), nullptr);
+ CurrentCtors.push_back(Ctor);
+ }
}
GVCtor->eraseFromParent();
} else {
@@ -54,7 +64,8 @@ static void appendToGlobalArray(const char *Array,
CSVals[1] = F;
// FIXME: Drop support for the two element form in LLVM 4.0.
if (EltTy->getNumElements() >= 3)
- CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
+ CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())
+ : Constant::getNullValue(IRB.getInt8PtrTy());
Constant *RuntimeCtorInit =
ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
@@ -70,29 +81,12 @@ static void appendToGlobalArray(const char *Array,
GlobalValue::AppendingLinkage, NewInit, Array);
}
-void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) {
- appendToGlobalArray("llvm.global_ctors", M, F, Priority);
+void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
+ appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
}
-void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) {
- appendToGlobalArray("llvm.global_dtors", M, F, Priority);
-}
-
-GlobalVariable *
-llvm::collectUsedGlobalVariables(Module &M, SmallPtrSetImpl<GlobalValue *> &Set,
- bool CompilerUsed) {
- const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
- GlobalVariable *GV = M.getGlobalVariable(Name);
- if (!GV || !GV->hasInitializer())
- return GV;
-
- const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
- for (unsigned I = 0, E = Init->getNumOperands(); I != E; ++I) {
- Value *Op = Init->getOperand(I);
- GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases());
- Set.insert(G);
- }
- return GV;
+void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) {
+ appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
}
Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
@@ -132,4 +126,3 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
}
return std::make_pair(Ctor, InitFunction);
}
-
OpenPOWER on IntegriCloud