/// Find the llvm.global_ctors list, verifying that all initializers have an /// init priority of 65535. static GlobalVariable *findGlobalCtors(Module &M) { GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); if (!GV) return nullptr; // Verify that the initializer is simple enough for us to handle. We are // only allowed to optimize the initializer if it is unique. if (!GV->hasUniqueInitializer()) return nullptr; if (isa<ConstantAggregateZero>(GV->getInitializer())) return GV; ConstantArray *CA = cast<ConstantArray>(GV->getInitializer()); for (auto &V : CA->operands()) { if (isa<ConstantAggregateZero>(V)) continue; ConstantStruct *CS = cast<ConstantStruct>(V); if (isa<ConstantPointerNull>(CS->getOperand(1))) continue; // Must have a function or null ptr. if (!isa<Function>(CS->getOperand(1))) return nullptr; // Init priority must be standard. ConstantInt *CI = cast<ConstantInt>(CS->getOperand(0)); if (CI->getZExtValue() != 65535) return nullptr; } return GV; }
/// Return true if this constant is simple enough for us to understand. In /// particular, if it is a cast to anything other than from one pointer type to /// another pointer type, we punt. We basically just support direct accesses to /// globals and GEP's of globals. This should be kept up to date with /// CommitValueTo. static bool isSimpleEnoughPointerToCommit(Constant *C) { // Conservatively, avoid aggregate types. This is because we don't // want to worry about them partially overlapping other stores. if (!cast<PointerType>(C->getType())->getElementType()->isSingleValueType()) return false; if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) // Do not allow weak/*_odr/linkonce linkage or external globals. return GV->hasUniqueInitializer(); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { // Handle a constantexpr gep. if (CE->getOpcode() == Instruction::GetElementPtr && isa<GlobalVariable>(CE->getOperand(0)) && cast<GEPOperator>(CE)->isInBounds()) { GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0)); // Do not allow weak/*_odr/linkonce/dllimport/dllexport linkage or // external globals. if (!GV->hasUniqueInitializer()) return false; // The first index must be zero. ConstantInt *CI = dyn_cast<ConstantInt>(*std::next(CE->op_begin())); if (!CI || !CI->isZero()) return false; // The remaining indices must be compile-time known integers within the // notional bounds of the corresponding static array types. if (!CE->isGEPWithNoNotionalOverIndexing()) return false; return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); // A constantexpr bitcast from a pointer to another pointer is a no-op, // and we know how to evaluate it by moving the bitcast from the pointer // operand to the value operand. } else if (CE->getOpcode() == Instruction::BitCast && isa<GlobalVariable>(CE->getOperand(0))) { // Do not allow weak/*_odr/linkonce/dllimport/dllexport linkage or // external globals. return cast<GlobalVariable>(CE->getOperand(0))->hasUniqueInitializer(); } } return false; }