diff options
Diffstat (limited to 'lib/Transforms/Utils/CtorUtils.cpp')
-rw-r--r-- | lib/Transforms/Utils/CtorUtils.cpp | 71 |
1 files changed, 26 insertions, 45 deletions
diff --git a/lib/Transforms/Utils/CtorUtils.cpp b/lib/Transforms/Utils/CtorUtils.cpp index a359424..26875e8 100644 --- a/lib/Transforms/Utils/CtorUtils.cpp +++ b/lib/Transforms/Utils/CtorUtils.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/BitVector.h" #include "llvm/Transforms/Utils/CtorUtils.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" @@ -24,41 +25,22 @@ namespace llvm { namespace { -/// Given a specified llvm.global_ctors list, install the -/// specified array. -void installGlobalCtors(GlobalVariable *GCL, - const std::vector<Function *> &Ctors) { - // If we made a change, reassemble the initializer list. - Constant *CSVals[3]; - - StructType *StructTy = - cast<StructType>(GCL->getType()->getElementType()->getArrayElementType()); - - // Create the new init list. - std::vector<Constant *> CAList; - for (Function *F : Ctors) { - Type *Int32Ty = Type::getInt32Ty(GCL->getContext()); - if (F) { - CSVals[0] = ConstantInt::get(Int32Ty, 65535); - CSVals[1] = F; - } else { - CSVals[0] = ConstantInt::get(Int32Ty, 0x7fffffff); - CSVals[1] = Constant::getNullValue(StructTy->getElementType(1)); - } - // FIXME: Only allow the 3-field form in LLVM 4.0. - size_t NumElts = StructTy->getNumElements(); - if (NumElts > 2) - CSVals[2] = Constant::getNullValue(StructTy->getElementType(2)); - CAList.push_back( - ConstantStruct::get(StructTy, makeArrayRef(CSVals, NumElts))); - } - - // Create the array initializer. - Constant *CA = - ConstantArray::get(ArrayType::get(StructTy, CAList.size()), CAList); +/// Given a specified llvm.global_ctors list, remove the listed elements. +void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) { + // Filter out the initializer elements to remove. + ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer()); + SmallVector<Constant *, 10> CAList; + for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I) + if (!CtorsToRemove.test(I)) + CAList.push_back(OldCA->getOperand(I)); + + // Create the new array initializer. + ArrayType *ATy = + ArrayType::get(OldCA->getType()->getElementType(), CAList.size()); + Constant *CA = ConstantArray::get(ATy, CAList); // If we didn't change the number of elements, don't create a new GV. - if (CA->getType() == GCL->getInitializer()->getType()) { + if (CA->getType() == OldCA->getType()) { GCL->setInitializer(CA); return; } @@ -82,7 +64,7 @@ void installGlobalCtors(GlobalVariable *GCL, /// Given a llvm.global_ctors list that we can understand, /// return a list of the functions and null terminator as a vector. -std::vector<Function*> parseGlobalCtors(GlobalVariable *GV) { +std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) { if (GV->getInitializer()->isNullValue()) return std::vector<Function *>(); ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); @@ -147,17 +129,15 @@ bool optimizeGlobalCtorsList(Module &M, bool MadeChange = false; // Loop over global ctors, optimizing them when we can. - for (unsigned i = 0; i != Ctors.size(); ++i) { + unsigned NumCtors = Ctors.size(); + BitVector CtorsToRemove(NumCtors); + for (unsigned i = 0; i != Ctors.size() && NumCtors > 0; ++i) { Function *F = Ctors[i]; // Found a null terminator in the middle of the list, prune off the rest of // the list. - if (!F) { - if (i != Ctors.size() - 1) { - Ctors.resize(i + 1); - MadeChange = true; - } - break; - } + if (!F) + continue; + DEBUG(dbgs() << "Optimizing Global Constructor: " << *F << "\n"); // We cannot simplify external ctor functions. @@ -166,9 +146,10 @@ bool optimizeGlobalCtorsList(Module &M, // If we can evaluate the ctor at compile time, do. if (ShouldRemove(F)) { - Ctors.erase(Ctors.begin() + i); + Ctors[i] = nullptr; + CtorsToRemove.set(i); + NumCtors--; MadeChange = true; - --i; continue; } } @@ -176,7 +157,7 @@ bool optimizeGlobalCtorsList(Module &M, if (!MadeChange) return false; - installGlobalCtors(GlobalCtors, Ctors); + removeGlobalCtors(GlobalCtors, CtorsToRemove); return true; } |