forked from OSchip/llvm-project
Code cleanup in preparation for adding LTO for wasm. NFC.
- Move some common code into Common/rrorHandler.cpp and Common/Strings.h. - Don't use `fatal` when incompatible bitcode files are encountered. - Rename NameRef variable to just Name See D47162 Differential Revision: https://reviews.llvm.org/D47206 llvm-svn: 333021
This commit is contained in:
parent
a82ee182d4
commit
3ad27e92bc
|
@ -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;
|
||||
|
||||
|
|
|
@ -1086,12 +1086,12 @@ void LinkerDriver::link(ArrayRef<const char *> 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);
|
||||
|
|
|
@ -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<lto::LTO> 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) + ".",
|
||||
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<lto::LTO>(std::move(Conf), Backend,
|
||||
if (Config->ThinLTOJobs != 0)
|
||||
Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
|
||||
return llvm::make_unique<lto::LTO>(std::move(C), Backend,
|
||||
Config->LTOPartitions);
|
||||
}
|
||||
|
||||
|
@ -125,7 +105,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
|
|||
// and return the resulting objects.
|
||||
std::vector<StringRef> 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<StringRef> BitcodeCompiler::compile() {
|
|||
checkError(LTOObj->run(
|
||||
[&](size_t Task) {
|
||||
return llvm::make_unique<lto::NativeObjectStream>(
|
||||
llvm::make_unique<raw_svector_ostream>(Buff[Task]));
|
||||
llvm::make_unique<raw_svector_ostream>(Buf[Task]));
|
||||
},
|
||||
Cache));
|
||||
|
||||
|
@ -150,15 +130,15 @@ std::vector<StringRef> BitcodeCompiler::compile() {
|
|||
|
||||
std::vector<StringRef> 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<MemoryBuffer> &File : Files)
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
private:
|
||||
std::unique_ptr<llvm::lto::LTO> LTOObj;
|
||||
std::vector<SmallString<0>> Buff;
|
||||
std::vector<SmallString<0>> Buf;
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> Files;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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<ObjFile>(File)) {
|
||||
|
|
|
@ -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 <mutex>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <class ELFT>
|
|||
static Symbol *createBitcodeSymbol(const std::vector<bool> &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<bool> &KeptComdats,
|
|||
|
||||
int C = ObjSym.getComdatIndex();
|
||||
if (C != -1 && !KeptComdats[C])
|
||||
return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
|
||||
return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
|
||||
CanOmitFromDynSym, &F);
|
||||
|
||||
if (ObjSym.isUndefined())
|
||||
return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
|
||||
return Symtab->addUndefined<ELFT>(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 <class ELFT>
|
||||
|
|
|
@ -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<raw_fd_ostream> openFile(StringRef File) {
|
||||
|
|
|
@ -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 <class T> T check(ErrorOr<T> E) {
|
||||
|
|
|
@ -26,6 +26,9 @@ llvm::Optional<std::string> demangleMSVC(llvm::StringRef S);
|
|||
std::vector<uint8_t> 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<uint8_t> toArrayRef(llvm::StringRef S) {
|
||||
return {reinterpret_cast<const uint8_t *>(S.data()), S.size()};
|
||||
}
|
||||
}
|
||||
} // namespace lld
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue