diff options
Diffstat (limited to 'tools/gold/gold-plugin.cpp')
-rw-r--r-- | tools/gold/gold-plugin.cpp | 97 |
1 files changed, 73 insertions, 24 deletions
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index a9909a721c1b..724e93cb8c74 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -15,26 +15,28 @@ #include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/Linker/Linker.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Object/IRObjectFile.h" -#include "llvm/PassManager.h" -#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/GlobalStatus.h" @@ -89,6 +91,7 @@ namespace options { }; static bool generate_api_file = false; static OutputType TheOutputType = OT_NORMAL; + static unsigned OptLevel = 2; static std::string obj_path; static std::string extra_library_path; static std::string triple; @@ -122,6 +125,10 @@ namespace options { TheOutputType = OT_SAVE_TEMPS; } else if (opt == "disable-output") { TheOutputType = OT_DISABLE; + } else if (opt.size() == 2 && opt[0] == 'O') { + if (opt[1] < '0' || opt[1] > '3') + report_fatal_error("Optimization level must be between 0 and 3"); + OptLevel = opt[1] - '0'; } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -272,11 +279,11 @@ static bool shouldSkip(uint32_t Symflags) { } static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { - assert(DI.getSeverity() == DS_Error && "Only expecting errors"); - const auto &BDI = cast<BitcodeDiagnosticInfo>(DI); - std::error_code EC = BDI.getError(); - if (EC == BitcodeError::InvalidBitcodeSignature) - return; + if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) { + std::error_code EC = BDI->getError(); + if (EC == BitcodeError::InvalidBitcodeSignature) + return; + } std::string ErrStorage; { @@ -284,8 +291,21 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { DiagnosticPrinterRawOStream DP(OS); DI.print(DP); } - message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s", - ErrStorage.c_str()); + ld_plugin_level Level; + switch (DI.getSeverity()) { + case DS_Error: + message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s", + ErrStorage.c_str()); + llvm_unreachable("Fatal doesn't return."); + case DS_Warning: + Level = LDPL_WARNING; + break; + case DS_Note: + case DS_Remark: + Level = LDPL_INFO; + break; + } + message(Level, "LLVM gold plugin: %s", ErrStorage.c_str()); } /// Called by gold to see whether this file is one that our plugin can handle. @@ -560,7 +580,7 @@ static void freeSymName(ld_plugin_symbol &Sym) { static std::unique_ptr<Module> getModuleForFile(LLVMContext &Context, claimed_file &F, - off_t Filesize, raw_fd_ostream *ApiFile, + ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe) { if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK) @@ -570,7 +590,8 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, if (get_view(F.handle, &View) != LDPS_OK) message(LDPL_FATAL, "Failed to get a view of file"); - MemoryBufferRef BufferRef(StringRef((const char *)View, Filesize), ""); + MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize), + Info.name); ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr = object::IRObjectFile::create(BufferRef, Context); @@ -582,6 +603,9 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, Module &M = Obj.getModule(); + M.materializeMetadata(); + UpgradeDebugInfo(M); + SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); @@ -692,15 +716,21 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, } static void runLTOPasses(Module &M, TargetMachine &TM) { - PassManager passes; + if (const DataLayout *DL = TM.getDataLayout()) + M.setDataLayout(*DL); + + legacy::PassManager passes; + passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); + PassManagerBuilder PMB; - PMB.LibraryInfo = new TargetLibraryInfo(Triple(TM.getTargetTriple())); + PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())); PMB.Inliner = createFunctionInliningPass(); PMB.VerifyInput = true; PMB.VerifyOutput = true; PMB.LoopVectorize = true; PMB.SLPVectorize = true; - PMB.populateLTOPassManager(passes, &TM); + PMB.OptLevel = options::OptLevel; + PMB.populateLTOPassManager(passes); passes.run(M); } @@ -709,7 +739,7 @@ static void saveBCFile(StringRef Path, Module &M) { raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None); if (EC) message(LDPL_FATAL, "Failed to write the output file."); - WriteBitcodeToFile(&M, OS); + WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); } static void codegen(Module &M) { @@ -730,17 +760,31 @@ static void codegen(Module &M) { Features.AddFeature(A); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + CodeGenOpt::Level CGOptLevel; + switch (options::OptLevel) { + case 0: + CGOptLevel = CodeGenOpt::None; + break; + case 1: + CGOptLevel = CodeGenOpt::Less; + break; + case 2: + CGOptLevel = CodeGenOpt::Default; + break; + case 3: + CGOptLevel = CodeGenOpt::Aggressive; + break; + } std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine( TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, - CodeModel::Default, CodeGenOpt::Aggressive)); + CodeModel::Default, CGOptLevel)); runLTOPasses(M, *TM); if (options::TheOutputType == options::OT_SAVE_TEMPS) saveBCFile(output_name + ".opt.bc", M); - PassManager CodeGenPasses; - CodeGenPasses.add(new DataLayoutPass()); + legacy::PassManager CodeGenPasses; SmallString<128> Filename; int FD; @@ -760,9 +804,8 @@ static void codegen(Module &M) { { raw_fd_ostream OS(FD, true); - formatted_raw_ostream FOS(OS); - if (TM->addPassesToEmitFile(CodeGenPasses, FOS, + if (TM->addPassesToEmitFile(CodeGenPasses, OS, TargetMachine::CGFT_ObjectFile)) message(LDPL_FATAL, "Failed to setup codegen"); CodeGenPasses.run(M); @@ -785,6 +828,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { return LDPS_OK; LLVMContext Context; + Context.setDiagnosticHandler(diagnosticHandler, nullptr, true); + std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); Linker L(Combined.get()); @@ -797,8 +842,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { 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.filesize, ApiFile, - Internalize, Maybe); + getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe); if (!options::triple.empty()) M->setTargetTriple(options::triple.c_str()); else if (M->getTargetTriple().empty()) { @@ -865,8 +909,13 @@ static ld_plugin_status all_symbols_read_hook(void) { llvm_shutdown(); if (options::TheOutputType == options::OT_BC_ONLY || - options::TheOutputType == options::OT_DISABLE) + options::TheOutputType == options::OT_DISABLE) { + if (options::TheOutputType == options::OT_DISABLE) + // Remove the output file here since ld.bfd creates the output file + // early. + sys::fs::remove(output_name); exit(0); + } return Ret; } |