diff options
Diffstat (limited to 'tools/llvm-lto2/llvm-lto2.cpp')
-rw-r--r-- | tools/llvm-lto2/llvm-lto2.cpp | 124 |
1 files changed, 108 insertions, 16 deletions
diff --git a/tools/llvm-lto2/llvm-lto2.cpp b/tools/llvm-lto2/llvm-lto2.cpp index c09311a05b90..3d2643db85bd 100644 --- a/tools/llvm-lto2/llvm-lto2.cpp +++ b/tools/llvm-lto2/llvm-lto2.cpp @@ -21,12 +21,12 @@ #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/LTO/LTO.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Threading.h" using namespace llvm; using namespace lto; -using namespace object; static cl::opt<char> OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " @@ -90,11 +90,20 @@ static cl::opt<std::string> DefaultTriple( cl::desc( "Replace unspecified target triples in input files with this triple")); +static cl::opt<std::string> + OptRemarksOutput("pass-remarks-output", + cl::desc("YAML output file for optimization remarks")); + +static cl::opt<bool> OptRemarksWithHotness( + "pass-remarks-with-hotness", + cl::desc("Whether to include hotness informations in the remarks.\n" + "Has effect only if -pass-remarks-output is specified.")); + static void check(Error E, std::string Msg) { if (!E) return; handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { - errs() << "llvm-lto: " << Msg << ": " << EIB.message().c_str() << '\n'; + errs() << "llvm-lto2: " << Msg << ": " << EIB.message().c_str() << '\n'; }); exit(1); } @@ -117,12 +126,12 @@ template <typename T> static T check(ErrorOr<T> E, std::string Msg) { return T(); } -int main(int argc, char **argv) { - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmPrinters(); - InitializeAllAsmParsers(); +static int usage() { + errs() << "Available subcommands: dump-symtab run\n"; + return 1; +} +static int run(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "Resolution-based LTO test harness"); // FIXME: Workaround PR30396 which means that a symbol can appear @@ -148,9 +157,11 @@ int main(int argc, char **argv) { Res.FinalDefinitionInLinkageUnit = true; else if (C == 'x') Res.VisibleToRegularObj = true; - else + else { llvm::errs() << "invalid character " << C << " in resolution: " << R << '\n'; + return 1; + } } CommandLineResolutions[{FileName, SymbolName}].push_back(Res); } @@ -176,6 +187,10 @@ int main(int argc, char **argv) { check(Conf.addSaveTemps(OutputFilename + "."), "Config::addSaveTemps failed"); + // Optimization remarks. + Conf.RemarksFilename = OptRemarksOutput; + Conf.RemarksWithHotness = OptRemarksWithHotness; + // Run a custom pipeline, if asked for. Conf.OptPipeline = OptPipeline; Conf.AAPipeline = AAPipeline; @@ -199,6 +214,9 @@ int main(int argc, char **argv) { return 1; } + if (FileType.getNumOccurrences()) + Conf.CGFileType = FileType; + Conf.OverrideTriple = OverrideTriple; Conf.DefaultTriple = DefaultTriple; @@ -257,18 +275,92 @@ int main(int argc, char **argv) { return llvm::make_unique<lto::NativeObjectStream>(std::move(S)); }; - auto AddFile = [&](size_t Task, StringRef Path) { - auto ReloadedBufferOrErr = MemoryBuffer::getFile(Path); - if (auto EC = ReloadedBufferOrErr.getError()) - report_fatal_error(Twine("Can't reload cached file '") + Path + "': " + - EC.message() + "\n"); - - *AddStream(Task)->OS << (*ReloadedBufferOrErr)->getBuffer(); + auto AddBuffer = [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { + *AddStream(Task)->OS << MB->getBuffer(); }; NativeObjectCache Cache; if (!CacheDir.empty()) - Cache = localCache(CacheDir, AddFile); + Cache = check(localCache(CacheDir, AddBuffer), "failed to create cache"); check(Lto.run(AddStream, Cache), "LTO::run failed"); + return 0; +} + +static int dumpSymtab(int argc, char **argv) { + for (StringRef F : make_range(argv + 1, argv + argc)) { + std::unique_ptr<MemoryBuffer> MB = check(MemoryBuffer::getFile(F), F); + std::unique_ptr<InputFile> Input = + check(InputFile::create(MB->getMemBufferRef()), F); + + outs() << "target triple: " << Input->getTargetTriple() << '\n'; + Triple TT(Input->getTargetTriple()); + + outs() << "source filename: " << Input->getSourceFileName() << '\n'; + + if (TT.isOSBinFormatCOFF()) + outs() << "linker opts: " << Input->getCOFFLinkerOpts() << '\n'; + + std::vector<StringRef> ComdatTable = Input->getComdatTable(); + for (const InputFile::Symbol &Sym : Input->symbols()) { + switch (Sym.getVisibility()) { + case GlobalValue::HiddenVisibility: + outs() << 'H'; + break; + case GlobalValue::ProtectedVisibility: + outs() << 'P'; + break; + case GlobalValue::DefaultVisibility: + outs() << 'D'; + break; + } + + auto PrintBool = [&](char C, bool B) { outs() << (B ? C : '-'); }; + PrintBool('U', Sym.isUndefined()); + PrintBool('C', Sym.isCommon()); + PrintBool('W', Sym.isWeak()); + PrintBool('I', Sym.isIndirect()); + PrintBool('O', Sym.canBeOmittedFromSymbolTable()); + PrintBool('T', Sym.isTLS()); + PrintBool('X', Sym.isExecutable()); + outs() << ' ' << Sym.getName() << '\n'; + + if (Sym.isCommon()) + outs() << " size " << Sym.getCommonSize() << " align " + << Sym.getCommonAlignment() << '\n'; + + int Comdat = Sym.getComdatIndex(); + if (Comdat != -1) + outs() << " comdat " << ComdatTable[Comdat] << '\n'; + + if (TT.isOSBinFormatCOFF() && Sym.isWeak() && Sym.isIndirect()) + outs() << " fallback " << Sym.getCOFFWeakExternalFallback() << '\n'; + } + + outs() << '\n'; + } + + return 0; +} + +int main(int argc, char **argv) { + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + + // FIXME: This should use llvm::cl subcommands, but it isn't currently + // possible to pass an argument not associated with a subcommand to a + // subcommand (e.g. -lto-use-new-pm). + if (argc < 2) + return usage(); + + StringRef Subcommand = argv[1]; + // Ensure that argv[0] is correct after adjusting argv/argc. + argv[1] = argv[0]; + if (Subcommand == "dump-symtab") + return dumpSymtab(argc - 1, argv + 1); + if (Subcommand == "run") + return run(argc - 1, argv + 1); + return usage(); } |