aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Utils/CtorUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Utils/CtorUtils.cpp')
-rw-r--r--lib/Transforms/Utils/CtorUtils.cpp71
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;
}