24 #define DEBUG_TYPE "ctor_utils"
30 void removeGlobalCtors(GlobalVariable *GCL,
const BitVector &CtorsToRemove) {
32 ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer());
33 SmallVector<Constant *, 10> CAList;
34 for (
unsigned I = 0,
E = OldCA->getNumOperands();
I <
E; ++
I)
35 if (!CtorsToRemove.test(
I))
36 CAList.push_back(OldCA->getOperand(
I));
44 if (CA->getType() == OldCA->getType()) {
45 GCL->setInitializer(CA);
51 new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(),
52 CA,
"", GCL->getThreadLocalMode());
53 GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV);
57 if (!GCL->use_empty()) {
59 if (V->getType() != GCL->getType())
63 GCL->eraseFromParent();
68 std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) {
69 if (GV->getInitializer()->isNullValue())
70 return std::vector<Function *>();
71 ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
72 std::vector<Function *> Result;
73 Result.reserve(CA->getNumOperands());
74 for (
auto &V : CA->operands()) {
75 ConstantStruct *CS = cast<ConstantStruct>(V);
76 Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
83 GlobalVariable *findGlobalCtors(Module &M) {
84 GlobalVariable *GV = M.getGlobalVariable(
"llvm.global_ctors");
90 if (!GV->hasUniqueInitializer())
93 if (isa<ConstantAggregateZero>(GV->getInitializer()))
95 ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
97 for (
auto &V : CA->operands()) {
98 if (isa<ConstantAggregateZero>(V))
100 ConstantStruct *CS = cast<ConstantStruct>(V);
101 if (isa<ConstantPointerNull>(CS->getOperand(1)))
105 if (!isa<Function>(CS->getOperand(1)))
109 ConstantInt *CI = cast<ConstantInt>(CS->getOperand(0));
110 if (CI->getZExtValue() != 65535)
126 std::vector<Function *> Ctors = parseGlobalCtors(GlobalCtors);
130 bool MadeChange =
false;
133 unsigned NumCtors = Ctors.size();
135 for (
unsigned i = 0;
i != Ctors.size() && NumCtors > 0; ++
i) {
142 DEBUG(
dbgs() <<
"Optimizing Global Constructor: " << *F <<
"\n");
149 if (ShouldRemove(F)) {
151 CtorsToRemove.
set(
i);
161 removeGlobalCtors(GlobalCtors, CtorsToRemove);
A Module instance is used to store all the information related to an LLVM module. ...
An efficient, type-erasing, non-owning reference to a callable.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Module.h This file contains the declarations for the Module class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
bool optimizeGlobalCtorsList(Module &M, function_ref< bool(Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it ret...