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:
Sam Clegg 2018-05-22 20:20:25 +00:00
parent a82ee182d4
commit 3ad27e92bc
11 changed files with 72 additions and 79 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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) + ".",
/*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<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)

View File

@ -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;
};
}

View File

@ -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)) {

View 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) {

View File

@ -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;
}

View File

@ -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>

View File

@ -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) {

View 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) {

View File

@ -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