Example #1
0
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
/// currently available via the gold plugin via -thinlto.
static int createCombinedFunctionIndex(StringRef Command) {
  LLVMContext Context;
  FunctionInfoIndex CombinedIndex;
  uint64_t NextModuleId = 0;
  for (auto &Filename : InputFilenames) {
    std::string Error;
    std::unique_ptr<FunctionInfoIndex> Index =
        getFunctionIndexForFile(Filename, Error, Context);
    if (!Index) {
      errs() << Command << ": error loading file '" << Filename
             << "': " << Error << "\n";
      return 1;
    }
    CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
  }
  std::error_code EC;
  assert(!OutputFilename.empty());
  raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
                    sys::fs::OpenFlags::F_None);
  if (EC) {
    errs() << Command << ": error opening the file '" << OutputFilename
           << ".thinlto.bc': " << EC.message() << "\n";
    return 1;
  }
  WriteFunctionSummaryToFile(CombinedIndex, OS);
  OS.close();
  return 0;
}
Example #2
0
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
/// currently available via the gold plugin via -thinlto.
static int createCombinedFunctionIndex(StringRef Command) {
  FunctionInfoIndex CombinedIndex;
  uint64_t NextModuleId = 0;
  for (auto &Filename : InputFilenames) {
    ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
        getFunctionIndexForFile(Filename, diagnosticHandler);
    if (std::error_code EC = IndexOrErr.getError()) {
      std::string Error = EC.message();
      errs() << Command << ": error loading file '" << Filename
             << "': " << Error << "\n";
      return 1;
    }
    std::unique_ptr<FunctionInfoIndex> Index = std::move(IndexOrErr.get());
    // Skip files without a function summary.
    if (!Index)
      continue;
    CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
  }
  std::error_code EC;
  assert(!OutputFilename.empty());
  raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
                    sys::fs::OpenFlags::F_None);
  if (EC) {
    errs() << Command << ": error opening the file '" << OutputFilename
           << ".thinlto.bc': " << EC.message() << "\n";
    return 1;
  }
  WriteFunctionSummaryToFile(CombinedIndex, OS);
  OS.close();
  return 0;
}
Example #3
0
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
/// currently available via the gold plugin via -thinlto.
static void createCombinedFunctionIndex() {
  FunctionInfoIndex CombinedIndex;
  uint64_t NextModuleId = 0;
  for (auto &Filename : InputFilenames) {
    CurrentActivity = "loading file '" + Filename + "'";
    ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
        llvm::getFunctionIndexForFile(Filename, diagnosticHandler);
    std::unique_ptr<FunctionInfoIndex> Index = std::move(IndexOrErr.get());
    CurrentActivity = "";
    // Skip files without a function summary.
    if (!Index)
      continue;
    CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
  }
  std::error_code EC;
  assert(!OutputFilename.empty());
  raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
                    sys::fs::OpenFlags::F_None);
  error(EC, "error opening the file '" + OutputFilename + ".thinlto.bc'");
  WriteFunctionSummaryToFile(CombinedIndex, OS);
  OS.close();
}
Example #4
0
/// gold informs us that all symbols have been read. At this point, we use
/// get_symbols to see if any of our definitions have been overridden by a
/// native object file. Then, perform optimization and codegen.
static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
  if (Modules.empty())
    return LDPS_OK;

  LLVMContext Context;
  Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true);

  // If we are doing ThinLTO compilation, simply build the combined
  // function index/summary and emit it. We don't need to parse the modules
  // and link them in this case.
  if (options::thinlto) {
    FunctionInfoIndex CombinedIndex;
    uint64_t NextModuleId = 0;
    for (claimed_file &F : Modules) {
      ld_plugin_input_file File;
      if (get_input_file(F.handle, &File) != LDPS_OK)
        message(LDPL_FATAL, "Failed to get file information");

      std::unique_ptr<FunctionInfoIndex> Index =
          getFunctionIndexForFile(F, File);

      // Skip files without a function summary.
      if (!Index)
        continue;

      CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
    }

    std::error_code EC;
    raw_fd_ostream OS(output_name + ".thinlto.bc", EC,
                      sys::fs::OpenFlags::F_None);
    if (EC)
      message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
              output_name.data(), EC.message().c_str());
    WriteFunctionSummaryToFile(CombinedIndex, OS);
    OS.close();

    cleanup_hook();
    exit(0);
  }

  std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
  Linker L(Combined.get());

  std::string DefaultTriple = sys::getDefaultTargetTriple();

  StringSet<> Internalize;
  StringSet<> Maybe;
  for (claimed_file &F : Modules) {
    ld_plugin_input_file File;
    if (get_input_file(F.handle, &File) != LDPS_OK)
      message(LDPL_FATAL, "Failed to get file information");
    std::unique_ptr<Module> M =
        getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe);
    if (!options::triple.empty())
      M->setTargetTriple(options::triple.c_str());
    else if (M->getTargetTriple().empty()) {
      M->setTargetTriple(DefaultTriple);
    }

    if (L.linkInModule(M.get()))
      message(LDPL_FATAL, "Failed to link module");
    if (release_input_file(F.handle) != LDPS_OK)
      message(LDPL_FATAL, "Failed to release file information");
  }

  for (const auto &Name : Internalize) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (GV)
      internalize(*GV);
  }

  for (const auto &Name : Maybe) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (!GV)
      continue;
    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
    if (canBeOmittedFromSymbolTable(GV))
      internalize(*GV);
  }

  if (options::TheOutputType == options::OT_DISABLE)
    return LDPS_OK;

  if (options::TheOutputType != options::OT_NORMAL) {
    std::string path;
    if (options::TheOutputType == options::OT_BC_ONLY)
      path = output_name;
    else
      path = output_name + ".bc";
    saveBCFile(path, *L.getModule());
    if (options::TheOutputType == options::OT_BC_ONLY)
      return LDPS_OK;
  }

  codegen(std::move(Combined));

  if (!options::extra_library_path.empty() &&
      set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
    message(LDPL_FATAL, "Unable to set the extra library path.");

  return LDPS_OK;
}