Index: COFF/Config.h =================================================================== --- COFF/Config.h +++ COFF/Config.h @@ -132,7 +132,7 @@ unsigned LTOOptLevel = 2; // Used for /opt:lldltojobs=N - unsigned LTOJobs = 0; + unsigned ThinLTOJobs = 0; // Used for /opt:lldltopartitions=N unsigned LTOPartitions = 1; Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -1091,7 +1091,8 @@ error("/opt:lldlto: invalid optimization level: " + OptLevel); } else if (S.startswith("lldltojobs=")) { StringRef Jobs = S.substr(11); - if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0) + if (Jobs.getAsInteger(10, Config->ThinLTOJobs) || + Config->ThinLTOJobs == 0) error("/opt:lldltojobs: invalid job count: " + Jobs); } else if (S.startswith("lldltopartitions=")) { StringRef N = S.substr(17); Index: COFF/LTO.h =================================================================== --- COFF/LTO.h +++ COFF/LTO.h @@ -48,7 +48,7 @@ private: std::unique_ptr LTOObj; - std::vector> Buff; + std::vector> Buf; std::vector> Files; }; } Index: COFF/LTO.cpp =================================================================== --- COFF/LTO.cpp +++ COFF/LTO.cpp @@ -12,6 +12,7 @@ #include "InputFiles.h" #include "Symbols.h" #include "lld/Common/ErrorHandler.h" +#include "lld/Common/Strings.h" #include "lld/Common/TargetOptionsCommandFlags.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -40,53 +41,32 @@ using namespace lld; using namespace lld::coff; -static void diagnosticHandler(const DiagnosticInfo &DI) { - SmallString<128> ErrStorage; - raw_svector_ostream OS(ErrStorage); - DiagnosticPrinterRawOStream DP(OS); - DI.print(DP); - warn(ErrStorage); -} - -static void checkError(Error E) { - handleAllErrors(std::move(E), - [&](ErrorInfoBase &EIB) { error(EIB.message()); }); -} - -static void saveBuffer(StringRef Buffer, const Twine &Path) { - std::error_code EC; - raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); - if (EC) - error("cannot create " + Path + ": " + EC.message()); - OS << Buffer; -} - static std::unique_ptr createLTO() { - lto::Config Conf; - Conf.Options = InitTargetOptionsFromCodeGenFlags(); + lto::Config C; + C.Options = InitTargetOptionsFromCodeGenFlags(); // Always emit a section per function/datum with LTO. LLVM LTO should get most // of the benefit of linker GC, but there are still opportunities for ICF. - Conf.Options.FunctionSections = true; - Conf.Options.DataSections = true; + C.Options.FunctionSections = true; + C.Options.DataSections = true; // Use static reloc model on 32-bit x86 because it usually results in more // compact code, and because there are also known code generation bugs when // using the PIC model (see PR34306). if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386) - Conf.RelocModel = Reloc::Static; + C.RelocModel = Reloc::Static; else - Conf.RelocModel = Reloc::PIC_; - Conf.DisableVerify = true; - Conf.DiagHandler = diagnosticHandler; - Conf.OptLevel = Config->LTOOptLevel; + C.RelocModel = Reloc::PIC_; + C.DisableVerify = true; + C.DiagHandler = diagnosticHandler; + C.OptLevel = Config->LTOOptLevel; if (Config->SaveTemps) - checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".", - /*UseInputModulePath*/ true)); + checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".", + /*UseInputModulePath*/ true)); lto::ThinBackend Backend; - if (Config->LTOJobs != 0) - Backend = lto::createInProcessThinBackend(Config->LTOJobs); - return llvm::make_unique(std::move(Conf), Backend, + if (Config->ThinLTOJobs != 0) + Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); + return llvm::make_unique(std::move(C), Backend, Config->LTOPartitions); } @@ -125,7 +105,7 @@ // and return the resulting objects. std::vector BitcodeCompiler::compile() { unsigned MaxTasks = LTOObj->getMaxTasks(); - Buff.resize(MaxTasks); + Buf.resize(MaxTasks); Files.resize(MaxTasks); // The /lldltocache option specifies the path to a directory in which to cache @@ -141,7 +121,7 @@ checkError(LTOObj->run( [&](size_t Task) { return llvm::make_unique( - llvm::make_unique(Buff[Task])); + llvm::make_unique(Buf[Task])); }, Cache)); @@ -150,15 +130,15 @@ std::vector Ret; for (unsigned I = 0; I != MaxTasks; ++I) { - if (Buff[I].empty()) + if (Buf[I].empty()) continue; if (Config->SaveTemps) { if (I == 0) - saveBuffer(Buff[I], Config->OutputFile + ".lto.obj"); + saveBuffer(Buf[I], Config->OutputFile + ".lto.obj"); else - saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.obj"); + saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.obj"); } - Ret.emplace_back(Buff[I].data(), Buff[I].size()); + Ret.emplace_back(Buf[I].data(), Buf[I].size()); } for (std::unique_ptr &File : Files) Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -38,8 +38,9 @@ if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { Config->Machine = MT; } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { - fatal(toString(File) + ": machine type " + machineToStr(MT) + + error(toString(File) + ": machine type " + machineToStr(MT) + " conflicts with " + machineToStr(Config->Machine)); + return; } if (auto *F = dyn_cast(File)) { Index: Common/ErrorHandler.cpp =================================================================== --- Common/ErrorHandler.cpp +++ Common/ErrorHandler.cpp @@ -12,7 +12,8 @@ #include "lld/Common/Threads.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/Error.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include @@ -59,6 +60,19 @@ _exit(Val); } +void lld::diagnosticHandler(const DiagnosticInfo &DI) { + SmallString<128> ErrStorage; + raw_svector_ostream OS(ErrStorage); + DiagnosticPrinterRawOStream DP(OS); + DI.print(DP); + warn(ErrStorage); +} + +void lld::checkError(Error E) { + handleAllErrors(std::move(E), + [&](ErrorInfoBase &EIB) { error(EIB.message()); }); +} + void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { *ErrorOS << LogName << ": "; if (ColorDiagnostics) { Index: Common/Strings.cpp =================================================================== --- Common/Strings.cpp +++ Common/Strings.cpp @@ -98,3 +98,12 @@ std::all_of(S.begin() + 1, S.end(), [](char C) { return C == '_' || isAlnum(C); }); } + +// Write the contents of the a buffer to a file +void lld::saveBuffer(StringRef Buffer, const Twine &Path) { + std::error_code EC; + raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); + if (EC) + error("cannot create " + Path + ": " + EC.message()); + OS << Buffer; +} Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -196,7 +196,7 @@ uint64_t MaxPageSize; uint64_t ZStackSize; unsigned LTOPartitions; - unsigned LTOO; + unsigned LTOOptLevel; unsigned Optimize; unsigned ThinLTOJobs; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -711,7 +711,7 @@ Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager); Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager); Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); - Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); + Config->LTOOptLevel = args::getInteger(Args, OPT_lto_O, 2); Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile); Config->MapFile = Args.getLastArgValue(OPT_Map); @@ -785,7 +785,7 @@ } else if (S == "save-temps") { Config->SaveTemps = true; } else if (S.startswith("O")) { - Config->LTOO = parseInt(S.substr(1), Arg); + Config->LTOOptLevel = parseInt(S.substr(1), Arg); } else if (S.startswith("lto-partitions=")) { Config->LTOPartitions = parseInt(S.substr(15), Arg); } else if (S.startswith("jobs=")) { @@ -831,8 +831,8 @@ for (auto *Arg : Args.filtered(OPT_mllvm)) parseClangOption(Arg->getValue(), Arg->getSpelling()); - if (Config->LTOO > 3) - error("invalid optimization level for LTO: " + Twine(Config->LTOO)); + if (Config->LTOOptLevel > 3) + error("invalid optimization level for LTO: " + Twine(Config->LTOOptLevel)); if (Config->LTOPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (Config->ThinLTOJobs == 0) Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -1017,8 +1017,9 @@ case Triple::x86_64: return EM_X86_64; default: - fatal(Path + ": could not infer e_machine from bitcode target triple " + + error(Path + ": could not infer e_machine from bitcode target triple " + T.str()); + return EM_NONE; } } @@ -1065,7 +1066,7 @@ static Symbol *createBitcodeSymbol(const std::vector &KeptComdats, const lto::InputFile::Symbol &ObjSym, BitcodeFile &F) { - StringRef NameRef = Saver.save(ObjSym.getName()); + StringRef Name = Saver.save(ObjSym.getName()); uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL; uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE; @@ -1074,20 +1075,20 @@ int C = ObjSym.getComdatIndex(); if (C != -1 && !KeptComdats[C]) - return Symtab->addUndefined(NameRef, Binding, Visibility, Type, + return Symtab->addUndefined(Name, Binding, Visibility, Type, CanOmitFromDynSym, &F); if (ObjSym.isUndefined()) - return Symtab->addUndefined(NameRef, Binding, Visibility, Type, + return Symtab->addUndefined(Name, Binding, Visibility, Type, CanOmitFromDynSym, &F); if (ObjSym.isCommon()) - return Symtab->addCommon(NameRef, ObjSym.getCommonSize(), + return Symtab->addCommon(Name, ObjSym.getCommonSize(), ObjSym.getCommonAlignment(), Binding, Visibility, STT_OBJECT, F); - return Symtab->addBitcode(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, F); + return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym, + F); } template Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -45,28 +45,6 @@ using namespace lld; using namespace lld::elf; -// This is for use when debugging LTO. -static void saveBuffer(StringRef Buffer, const Twine &Path) { - std::error_code EC; - raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); - if (EC) - error("cannot create " + Path + ": " + EC.message()); - OS << Buffer; -} - -static void diagnosticHandler(const DiagnosticInfo &DI) { - SmallString<128> S; - raw_svector_ostream OS(S); - DiagnosticPrinterRawOStream DP(OS); - DI.print(DP); - warn(S); -} - -static void checkError(Error E) { - handleAllErrors(std::move(E), - [&](ErrorInfoBase &EIB) { error(EIB.message()); }); -} - // Creates an empty file to store a list of object files for final // linking of distributed ThinLTO. static std::unique_ptr openFile(StringRef File) { @@ -107,7 +85,7 @@ C.CodeModel = GetCodeModelFromCMModel(); C.DisableVerify = Config->DisableVerify; C.DiagHandler = diagnosticHandler; - C.OptLevel = Config->LTOO; + C.OptLevel = Config->LTOOptLevel; C.CPU = GetCPUStr(); // Set up a custom pipeline if we've been asked to. Index: include/lld/Common/ErrorHandler.h =================================================================== --- include/lld/Common/ErrorHandler.h +++ include/lld/Common/ErrorHandler.h @@ -34,6 +34,10 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FileOutputBuffer.h" +namespace llvm { +class DiagnosticInfo; +} + namespace lld { class ErrorHandler { @@ -74,6 +78,9 @@ LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); +void diagnosticHandler(const llvm::DiagnosticInfo &DI); +void checkError(Error E); + // check functions are convenient functions to strip errors // from error-or-value objects. template T check(ErrorOr E) { Index: include/lld/Common/Strings.h =================================================================== --- include/lld/Common/Strings.h +++ include/lld/Common/Strings.h @@ -26,6 +26,9 @@ std::vector parseHex(llvm::StringRef S); bool isValidCIdentifier(llvm::StringRef S); +// Write the contents of the a buffer to a file +void saveBuffer(llvm::StringRef Buffer, const llvm::Twine &Path); + // This class represents multiple glob patterns. class StringMatcher { public: @@ -41,6 +44,6 @@ inline llvm::ArrayRef toArrayRef(llvm::StringRef S) { return {reinterpret_cast(S.data()), S.size()}; } -} +} // namespace lld #endif