diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index e57a71e49dd1..e6f9b513fedd 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -129,10 +129,10 @@ struct Configuration { Symbol *SEHCount = nullptr; // Used for /opt:lldlto=N - unsigned LTOOptLevel = 2; + unsigned LTOO = 2; // Used for /opt:lldltojobs=N - unsigned LTOJobs = 0; + unsigned ThinLTOJobs = 0; // Used for /opt:lldltopartitions=N unsigned LTOPartitions = 1; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 7a674989cb22..d0bd2b03ad58 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1086,12 +1086,12 @@ void LinkerDriver::link(ArrayRef ArgsArr) { TailMerge = 0; } else if (S.startswith("lldlto=")) { StringRef OptLevel = S.substr(7); - if (OptLevel.getAsInteger(10, Config->LTOOptLevel) || - Config->LTOOptLevel > 3) + if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3) 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); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index 56ca8c0bb88c..93f7ba3f9e4c 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/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 llvm::object; 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->LTOO; 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 @@ void BitcodeCompiler::add(BitcodeFile &F) { // 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 @@ std::vector BitcodeCompiler::compile() { 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 BitcodeCompiler::compile() { 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) diff --git a/lld/COFF/LTO.h b/lld/COFF/LTO.h index a444aa7ac4fe..f00924654780 100644 --- a/lld/COFF/LTO.h +++ b/lld/COFF/LTO.h @@ -48,7 +48,7 @@ public: private: std::unique_ptr LTOObj; - std::vector> Buff; + std::vector> Buf; std::vector> Files; }; } diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index f73d80c130f7..6b07c352688a 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -38,8 +38,9 @@ void SymbolTable::addFile(InputFile *File) { 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)) { diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp index 18affce4d5a6..6dacc2c850bc 100644 --- a/lld/Common/ErrorHandler.cpp +++ b/lld/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 @@ void lld::exitLld(int Val) { _exit(Val); } +void lld::diagnosticHandler(const DiagnosticInfo &DI) { + SmallString<128> S; + raw_svector_ostream OS(S); + DiagnosticPrinterRawOStream DP(OS); + DI.print(DP); + warn(S); +} + +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) { diff --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp index 1fac65b88ae8..36f4f77d8476 100644 --- a/lld/Common/Strings.cpp +++ b/lld/Common/Strings.cpp @@ -98,3 +98,12 @@ bool lld::isValidCIdentifier(StringRef S) { 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; +} diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index fb596d31e2b6..8e4fbe33fa68 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1017,8 +1017,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { 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 @@ template 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 @@ static Symbol *createBitcodeSymbol(const std::vector &KeptComdats, 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 diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 521657ea9c39..c47a5a8a2927 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -45,28 +45,6 @@ using namespace llvm::ELF; 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) { diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h index 8ae6f46ac59e..b6c78f1f1501 100644 --- a/lld/include/lld/Common/ErrorHandler.h +++ b/lld/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 @@ inline uint64_t errorCount() { return errorHandler().ErrorCount; } 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) { diff --git a/lld/include/lld/Common/Strings.h b/lld/include/lld/Common/Strings.h index 177cc15449f9..e17b25763781 100644 --- a/lld/include/lld/Common/Strings.h +++ b/lld/include/lld/Common/Strings.h @@ -26,6 +26,9 @@ llvm::Optional demangleMSVC(llvm::StringRef S); 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 @@ private: inline llvm::ArrayRef toArrayRef(llvm::StringRef S) { return {reinterpret_cast(S.data()), S.size()}; } -} +} // namespace lld #endif