コード例 #1
0
/// 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;
}
コード例 #2
0
/// Given a llvm.global_ctors list that we can understand,
/// return a list of the functions and null terminator as a vector.
static std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) {
  if (GV->getInitializer()->isNullValue())
    return std::vector<Function *>();
  ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
  std::vector<Function *> Result;
  Result.reserve(CA->getNumOperands());
  for (auto &V : CA->operands()) {
    ConstantStruct *CS = cast<ConstantStruct>(V);
    Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
  }
  return Result;
}
コード例 #3
0
ファイル: LTOCodeGenerator.cpp プロジェクト: Wilfred/llvm
// If a linkonce global is present in the MustPreserveSymbols, we need to make
// sure we honor this. To force the compiler to not drop it, we add it to the
// "llvm.compiler.used" global.
void LTOCodeGenerator::preserveDiscardableGVs(
    Module &TheModule,
    llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) {
  SetVector<Constant *> UsedValuesSet;
  if (GlobalVariable *LLVMUsed =
          TheModule.getGlobalVariable("llvm.compiler.used")) {
    ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
    for (auto &V : Inits->operands())
      UsedValuesSet.insert(cast<Constant>(&V));
    LLVMUsed->eraseFromParent();
  }
  llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
  auto mayPreserveGlobal = [&](GlobalValue &GV) {
    if (!GV.isDiscardableIfUnused() || GV.isDeclaration())
      return;
    if (!mustPreserveGV(GV))
      return;
    if (GV.hasAvailableExternallyLinkage()) {
      emitWarning(
          (Twine("Linker asked to preserve available_externally global: '") +
           GV.getName() + "'").str());
      return;
    }
    if (GV.hasInternalLinkage()) {
      emitWarning((Twine("Linker asked to preserve internal global: '") +
                   GV.getName() + "'").str());
      return;
    }
    UsedValuesSet.insert(ConstantExpr::getBitCast(&GV, i8PTy));
  };
  for (auto &GV : TheModule)
    mayPreserveGlobal(GV);
  for (auto &GV : TheModule.globals())
    mayPreserveGlobal(GV);
  for (auto &GV : TheModule.aliases())
    mayPreserveGlobal(GV);

  if (UsedValuesSet.empty())
    return;

  llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesSet.size());
  auto *LLVMUsed = new llvm::GlobalVariable(
      TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
      llvm::ConstantArray::get(ATy, UsedValuesSet.getArrayRef()),
      "llvm.compiler.used");
  LLVMUsed->setSection("llvm.metadata");
}