diff options
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-gsymutil/Opts.td | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp | 47 | ||||
-rw-r--r-- | llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 77 | ||||
-rw-r--r-- | llvm/tools/llvm-link/llvm-link.cpp | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-profgen/PerfReader.cpp | 19 |
9 files changed, 132 insertions, 32 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp index 41d3615..5636782 100644 --- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp @@ -24,6 +24,8 @@ namespace llvm { namespace exegesis { +#include "RISCVGenExegesis.inc" + namespace { // Stores constant value to a general-purpose (integer) register. @@ -132,8 +134,7 @@ public: }; ExegesisRISCVTarget::ExegesisRISCVTarget() - : ExegesisTarget(ArrayRef<CpuAndPfmCounters>{}, - RISCV_MC::isOpcodeAvailable) {} + : ExegesisTarget(RISCVCpuPfmCounters, RISCV_MC::isOpcodeAvailable) {} bool ExegesisRISCVTarget::matchesArch(Triple::ArchType Arch) const { return Arch == Triple::riscv32 || Arch == Triple::riscv64; diff --git a/llvm/tools/llvm-gsymutil/Opts.td b/llvm/tools/llvm-gsymutil/Opts.td index d61b418..89cd3ce 100644 --- a/llvm/tools/llvm-gsymutil/Opts.td +++ b/llvm/tools/llvm-gsymutil/Opts.td @@ -17,7 +17,10 @@ defm convert : Eq<"convert", "Convert the specified file to the GSYM format.\nSupported files include ELF and mach-o files that will have their debug info (DWARF) and symbol table converted">; def merged_functions : - FF<"merged-functions", "Encode merged function information for functions in debug info that have matching address ranges.\nWithout this option one function per unique address range will be emitted.">; + FF<"merged-functions", "When used with --convert, encodes merged function information for functions in debug info that have matching address ranges.\n" + "Without this option one function per unique address range will be emitted.\n" + "When used with --address/--addresses-from-stdin, all merged functions for a particular address will be displayed.\n" + "Without this option only one function will be displayed.">; def dwarf_callsites : FF<"dwarf-callsites", "Load call site info from DWARF, if available">; defm callsites_yaml_file : Eq<"callsites-yaml-file", "Load call site info from YAML file. Useful for testing.">, Flags<[HelpHidden]>; diff --git a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp index aed4ae7..654da68 100644 --- a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp +++ b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp @@ -98,7 +98,7 @@ static uint64_t SegmentSize; static bool Quiet; static std::vector<uint64_t> LookupAddresses; static bool LookupAddressesFromStdin; -static bool StoreMergedFunctionInfo = false; +static bool UseMergedFunctions = false; static bool LoadDwarfCallSites = false; static std::string CallSiteYamlPath; @@ -181,7 +181,7 @@ static void parseArgs(int argc, char **argv) { } LookupAddressesFromStdin = Args.hasArg(OPT_addresses_from_stdin); - StoreMergedFunctionInfo = Args.hasArg(OPT_merged_functions); + UseMergedFunctions = Args.hasArg(OPT_merged_functions); if (Args.hasArg(OPT_callsites_yaml_file_EQ)) { CallSiteYamlPath = Args.getLastArgValue(OPT_callsites_yaml_file_EQ); @@ -380,7 +380,7 @@ static llvm::Error handleObjectFile(ObjectFile &Obj, const std::string &OutFile, // functions in the first FunctionInfo with that address range. Do this right // after loading the DWARF data so we don't have to deal with functions from // the symbol table. - if (StoreMergedFunctionInfo) + if (UseMergedFunctions) Gsym.prepareMergedFunctions(Out); // Get the UUID and convert symbol table to GSYM. @@ -508,24 +508,37 @@ static llvm::Error convertFileToGSYM(OutputAggregator &Out) { } static void doLookup(GsymReader &Gsym, uint64_t Addr, raw_ostream &OS) { - if (auto Result = Gsym.lookup(Addr)) { - // If verbose is enabled dump the full function info for the address. - if (Verbose) { - if (auto FI = Gsym.getFunctionInfo(Addr)) { - OS << "FunctionInfo for " << HEX64(Addr) << ":\n"; - Gsym.dump(OS, *FI); - OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; + if (UseMergedFunctions) { + if (auto Results = Gsym.lookupAll(Addr)) { + OS << "Found " << Results->size() << " functions at address " + << HEX64(Addr) << ":\n"; + for (size_t i = 0; i < Results->size(); ++i) { + OS << " " << Results->at(i); + + if (i != Results->size() - 1) + OS << "\n"; } } - OS << Result.get(); - } else { + } else { /* UseMergedFunctions == false */ + if (auto Result = Gsym.lookup(Addr)) { + // If verbose is enabled dump the full function info for the address. + if (Verbose) { + if (auto FI = Gsym.getFunctionInfo(Addr)) { + OS << "FunctionInfo for " << HEX64(Addr) << ":\n"; + Gsym.dump(OS, *FI); + OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; + } + } + OS << Result.get(); + } else { + if (Verbose) + OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; + OS << HEX64(Addr) << ": "; + logAllUnhandledErrors(Result.takeError(), OS, "error: "); + } if (Verbose) - OS << "\nLookupResult for " << HEX64(Addr) << ":\n"; - OS << HEX64(Addr) << ": "; - logAllUnhandledErrors(Result.takeError(), OS, "error: "); + OS << "\n"; } - if (Verbose) - OS << "\n"; } int llvm_gsymutil_main(int argc, char **argv, const llvm::ToolContext &) { diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp index 5271fdb..6db78926 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp @@ -66,6 +66,8 @@ static Expected<Symbol &> getCOFFStubTarget(LinkGraph &G, Block &B) { namespace llvm { Error registerCOFFGraphInfo(Session &S, LinkGraph &G) { + std::lock_guard<std::mutex> Lock(S.M); + auto FileName = sys::path::filename(G.getName()); if (S.FileInfos.count(FileName)) { return make_error<StringError>("When -check is passed, file names must be " diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp index a8c804a..6aa8941 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp @@ -101,6 +101,8 @@ static Error registerSymbol(LinkGraph &G, Symbol &Sym, Session::FileInfo &FI, namespace llvm { Error registerELFGraphInfo(Session &S, LinkGraph &G) { + std::lock_guard<std::mutex> Lock(S.M); + auto FileName = sys::path::filename(G.getName()); if (S.FileInfos.count(FileName)) { return make_error<StringError>("When -check is passed, file names must be " diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp index 2c60c80..2fc56c9 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp @@ -69,6 +69,8 @@ static Expected<Symbol &> getMachOStubTarget(LinkGraph &G, Block &B) { namespace llvm { Error registerMachOGraphInfo(Session &S, LinkGraph &G) { + std::lock_guard<std::mutex> Lock(S.M); + auto FileName = sys::path::filename(G.getName()); if (S.FileInfos.count(FileName)) { return make_error<StringError>("When -check is passed, file names must be " diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index 96a3e5b..963c363 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -91,6 +91,10 @@ static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore, cl::desc("input files"), cl::cat(JITLinkCategory)); +static cl::opt<size_t> MaterializationThreads( + "num-threads", cl::desc("Number of materialization threads to use"), + cl::init(std::numeric_limits<size_t>::max()), cl::cat(JITLinkCategory)); + static cl::list<std::string> LibrarySearchPaths("L", cl::desc("Add dir to the list of library search paths"), @@ -400,6 +404,7 @@ bool lazyLinkingRequested() { } static Error applyHarnessPromotions(Session &S, LinkGraph &G) { + std::lock_guard<std::mutex> Lock(S.M); // If this graph is part of the test harness there's nothing to do. if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName())) @@ -450,7 +455,11 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) { return Error::success(); } -static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) { +static void dumpSectionContents(raw_ostream &OS, Session &S, LinkGraph &G) { + std::lock_guard<std::mutex> Lock(S.M); + + outs() << "Relocated section contents for " << G.getName() << ":\n"; + constexpr orc::ExecutorAddrDiff DumpWidth = 16; static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two"); @@ -842,7 +851,7 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() { S.CreateMemoryManager = createSharedMemoryManager; return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>( - std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt), + std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads), std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]); #endif } @@ -984,10 +993,21 @@ Expected<std::unique_ptr<Session>> Session::Create(Triple TT, auto PageSize = sys::Process::getPageSize(); if (!PageSize) return PageSize.takeError(); + std::unique_ptr<TaskDispatcher> Dispatcher; + if (MaterializationThreads == 0) + Dispatcher = std::make_unique<InPlaceTaskDispatcher>(); + else { +#if LLVM_ENABLE_THREADS + Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>( + MaterializationThreads); +#else + llvm_unreachable("MaterializationThreads should be 0"); +#endif + } + EPC = std::make_unique<SelfExecutorProcessControl>( - std::make_shared<SymbolStringPool>(), - std::make_unique<InPlaceTaskDispatcher>(), std::move(TT), *PageSize, - createInProcessMemoryManager()); + std::make_shared<SymbolStringPool>(), std::move(Dispatcher), + std::move(TT), *PageSize, createInProcessMemoryManager()); } Error Err = Error::success(); @@ -1221,6 +1241,7 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) { if (ShowGraphsRegex) PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error { + std::lock_guard<std::mutex> Lock(M); // Print graph if ShowLinkGraphs is specified-but-empty, or if // it contains the given graph. if (ShowGraphsRegex->match(G.getName())) { @@ -1239,9 +1260,8 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) { [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); }); if (ShowRelocatedSectionContents) - PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error { - outs() << "Relocated section contents for " << G.getName() << ":\n"; - dumpSectionContents(outs(), G); + PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error { + dumpSectionContents(outs(), *this, G); return Error::success(); }); @@ -1613,6 +1633,46 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) { } } +#if LLVM_ENABLE_THREADS + if (MaterializationThreads == std::numeric_limits<size_t>::max()) { + if (auto HC = std::thread::hardware_concurrency()) + MaterializationThreads = HC; + else { + errs() << "Warning: std::thread::hardware_concurrency() returned 0, " + "defaulting to -num-threads=1.\n"; + MaterializationThreads = 1; + } + } +#else + if (MaterializationThreads.getNumOccurrences() && + MaterializationThreads != 0) { + errs() << "Warning: -num-threads was set, but LLVM was built with threads " + "disabled. Resetting to -num-threads=0\n"; + } + MaterializationThreads = 0; +#endif + + if (!!OutOfProcessExecutor.getNumOccurrences() || + !!OutOfProcessExecutorConnect.getNumOccurrences()) { + if (NoExec) + return make_error<StringError>("-noexec cannot be used with " + + OutOfProcessExecutor.ArgStr + " or " + + OutOfProcessExecutorConnect.ArgStr, + inconvertibleErrorCode()); + + if (MaterializationThreads == 0) + return make_error<StringError>("-threads=0 cannot be used with " + + OutOfProcessExecutor.ArgStr + " or " + + OutOfProcessExecutorConnect.ArgStr, + inconvertibleErrorCode()); + } + +#ifndef NDEBUG + if (DebugFlag && MaterializationThreads != 0) + errs() << "Warning: debugging output is not thread safe. " + "Use -num-threads=0 to stabilize output.\n"; +#endif // NDEBUG + // Only one of -oop-executor and -oop-executor-connect can be used. if (!!OutOfProcessExecutor.getNumOccurrences() && !!OutOfProcessExecutorConnect.getNumOccurrences()) @@ -2502,6 +2562,7 @@ int main(int argc, char *argv[]) { if (Timers) Timers->JITLinkTG.printAll(errs()); reportLLVMJITLinkError(EntryPoint.takeError()); + ExitOnErr(S->ES.endSession()); exit(1); } diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp index 34bb6ce..0f4a4d5 100644 --- a/llvm/tools/llvm-link/llvm-link.cpp +++ b/llvm/tools/llvm-link/llvm-link.cpp @@ -449,9 +449,8 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, } // Promotion - if (renameModuleForThinLTO(*M, *Index, - /*ClearDSOLocalOnDeclarations=*/false)) - return true; + renameModuleForThinLTO(*M, *Index, + /*ClearDSOLocalOnDeclarations=*/false); } if (Verbose) diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp index 111c546..ad113ed 100644 --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -42,6 +42,11 @@ static cl::opt<bool> cl::opt<bool> ShowDetailedWarning("show-detailed-warning", cl::desc("Show detailed warning message.")); +static cl::opt<int> CSProfMaxUnsymbolizedCtxDepth( + "csprof-max-unsymbolized-context-depth", cl::init(-1), + cl::desc("Keep the last K contexts while merging unsymbolized profile. -1 " + "means no depth limit.")); + extern cl::opt<std::string> PerfTraceFilename; extern cl::opt<bool> ShowDisassemblyOnly; extern cl::opt<bool> ShowSourceLocations; @@ -172,7 +177,19 @@ std::shared_ptr<AddrBasedCtxKey> AddressStack::getContextKey() { std::shared_ptr<AddrBasedCtxKey> KeyStr = std::make_shared<AddrBasedCtxKey>(); KeyStr->Context = Stack; CSProfileGenerator::compressRecursionContext<uint64_t>(KeyStr->Context); - CSProfileGenerator::trimContext<uint64_t>(KeyStr->Context); + // MaxContextDepth(--csprof-max-context-depth) is used to trim both symbolized + // and unsymbolized profile context. Sometimes we want to at least preserve + // the inlinings for the leaf frame(the profiled binary inlining), + // --csprof-max-context-depth may not be flexible enough, in this case, + // --csprof-max-unsymbolized-context-depth is used to limit the context for + // unsymbolized profile. If both are set, use the minimum of them. + int Depth = CSProfileGenerator::MaxContextDepth != -1 + ? CSProfileGenerator::MaxContextDepth + : KeyStr->Context.size(); + Depth = CSProfMaxUnsymbolizedCtxDepth != -1 + ? std::min(static_cast<int>(CSProfMaxUnsymbolizedCtxDepth), Depth) + : Depth; + CSProfileGenerator::trimContext<uint64_t>(KeyStr->Context, Depth); return KeyStr; } |