summaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
authorMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
committerMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
commit38500d63e14ce340236840f60d356cdefb56a52c (patch)
tree17edbec446ce9b50d2f215a483b83afb293a635d /llvm/tools
parent1a3d5daaef7a6a63448a497da3eff7fc9e23df26 (diff)
parent27f30029741ecf023baece7b3dde1ff9011ffefc (diff)
Merge branch 'main' into users/meinersbur/flang_runtime_split-headersusers/meinersbur/flang_runtime_split-headers
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/dsymutil/dsymutil.cpp38
-rw-r--r--llvm/tools/llc/llc.cpp4
-rw-r--r--llvm/tools/llvm-cgdata/llvm-cgdata.cpp14
-rw-r--r--llvm/tools/llvm-config/CMakeLists.txt4
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp26
-rw-r--r--llvm/tools/llvm-cov/CoverageSummaryInfo.cpp69
-rw-r--r--llvm/tools/llvm-cov/CoverageSummaryInfo.h45
-rw-r--r--llvm/tools/llvm-cov/CoverageViewOptions.h3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h14
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp138
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewText.cpp69
-rw-r--r--llvm/tools/llvm-cvtres/llvm-cvtres.cpp15
-rw-r--r--llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp14
-rw-r--r--llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp14
-rw-r--r--llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp14
-rw-r--r--llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp14
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp14
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp3
-rw-r--r--llvm/tools/llvm-exegesis/lib/CMakeLists.txt3
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp18
-rw-r--r--llvm/tools/llvm-exegesis/lib/MCInstrDescView.h11
-rw-r--r--llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt22
-rw-r--r--llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp272
-rw-r--r--llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp17
-rw-r--r--llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp12
-rw-r--r--llvm/tools/llvm-exegesis/llvm-exegesis.cpp33
-rw-r--r--llvm/tools/llvm-gsymutil/Opts.td1
-rw-r--r--llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp19
-rw-r--r--llvm/tools/llvm-ifs/llvm-ifs.cpp14
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp2
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp2
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp2
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp185
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.h40
-rw-r--r--llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp14
-rw-r--r--llvm/tools/llvm-lipo/llvm-lipo.cpp15
-rw-r--r--llvm/tools/llvm-mc/Disassembler.cpp36
-rw-r--r--llvm/tools/llvm-mc/Disassembler.h2
-rw-r--r--llvm/tools/llvm-mc/llvm-mc.cpp10
-rw-r--r--llvm/tools/llvm-ml/llvm-ml.cpp15
-rw-r--r--llvm/tools/llvm-mt/llvm-mt.cpp15
-rw-r--r--llvm/tools/llvm-nm/llvm-nm.cpp14
-rw-r--r--llvm/tools/llvm-objcopy/ObjcopyOptions.cpp59
-rw-r--r--llvm/tools/llvm-objdump/ELFDump.cpp1
-rw-r--r--llvm/tools/llvm-objdump/SourcePrinter.cpp3
-rw-r--r--llvm/tools/llvm-objdump/XCOFFDump.cpp1
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp44
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h2
-rw-r--r--llvm/tools/llvm-profdata/llvm-profdata.cpp82
-rw-r--r--llvm/tools/llvm-rc/llvm-rc.cpp32
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp1
-rw-r--r--llvm/tools/llvm-readobj/XCOFFDumper.cpp7
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp14
-rw-r--r--llvm/tools/llvm-readtapi/llvm-readtapi.cpp14
-rw-r--r--llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp2
-rw-r--r--llvm/tools/llvm-size/llvm-size.cpp16
-rw-r--r--llvm/tools/llvm-split/llvm-split.cpp6
-rw-r--r--llvm/tools/llvm-strings/llvm-strings.cpp14
-rw-r--r--llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp14
-rw-r--r--llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp14
-rw-r--r--llvm/tools/sancov/sancov.cpp14
61 files changed, 1092 insertions, 534 deletions
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 2ace7180b008..913077eb0b06 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -64,12 +64,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Options.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Options.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -80,7 +81,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class DsymutilOptTable : public opt::GenericOptTable {
public:
- DsymutilOptTable() : opt::GenericOptTable(InfoTable) {}
+ DsymutilOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // namespace
@@ -832,15 +834,15 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
return EXIT_FAILURE;
if (NeedsTempFiles) {
- const bool Fat64 = Options.LinkOpts.Fat64;
+ bool Fat64 = Options.LinkOpts.Fat64;
if (!Fat64) {
// Universal Mach-O files can't have an archicture slice that starts
// beyond the 4GB boundary. "lipo" can create a 64 bit universal
- // header, but not all tools can parse these files so we want to return
- // an error if the file can't be encoded as a file with a 32 bit
+ // header, but older tools may not support these files so we want to
+ // emit a warning if the file can't be encoded as a file with a 32 bit
// universal header. To detect this, we check the size of each
// architecture's skinny Mach-O file and add up the offsets. If they
- // exceed 4GB, then we return an error.
+ // exceed 4GB, we emit a warning.
// First we compute the right offset where the first architecture will
// fit followin the 32 bit universal header. The 32 bit universal header
@@ -859,13 +861,15 @@ int dsymutil_main(int argc, char **argv, const llvm::ToolContext &) {
if (!stat)
break;
if (FileOffset > UINT32_MAX) {
- WithColor::error()
- << formatv("the universal binary has a slice with a starting "
- "offset ({0:x}) that exceeds 4GB and will produce "
- "an invalid Mach-O file. Use the -fat64 flag to "
- "generate a universal binary with a 64-bit header "
- "but note that not all tools support this format.",
- FileOffset);
+ Fat64 = true;
+ WithColor::warning() << formatv(
+ "the universal binary has a slice with a starting offset "
+ "({0:x}) that exceeds 4GB. To avoid producing an invalid "
+ "Mach-O file, a universal binary with a 64-bit header will be "
+ "generated, which may not be supported by older tools. Use the "
+ "-fat64 flag to force a 64-bit header and silence this "
+ "warning.",
+ FileOffset);
return EXIT_FAILURE;
}
FileOffset += stat->getSize();
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 150dd50ef293..3694ff79b543 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -549,7 +549,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
TheTarget =
TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
if (!TheTarget) {
- WithColor::error(errs(), argv[0]) << Error;
+ WithColor::error(errs(), argv[0]) << Error << "\n";
exit(1);
}
@@ -592,7 +592,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
TheTarget =
TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
if (!TheTarget) {
- WithColor::error(errs(), argv[0]) << Error;
+ WithColor::error(errs(), argv[0]) << Error << "\n";
return 1;
}
diff --git a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
index d33459b194c9..9e3800f5bfbb 100644
--- a/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
+++ b/llvm/tools/llvm-cgdata/llvm-cgdata.cpp
@@ -51,12 +51,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -67,7 +68,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class CGDataOptTable : public opt::GenericOptTable {
public:
- CGDataOptTable() : GenericOptTable(InfoTable) {}
+ CGDataOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/llvm-config/CMakeLists.txt b/llvm/tools/llvm-config/CMakeLists.txt
index e02bda1ead50..02c2532dba77 100644
--- a/llvm/tools/llvm-config/CMakeLists.txt
+++ b/llvm/tools/llvm-config/CMakeLists.txt
@@ -89,7 +89,9 @@ if(LLVM_ENABLE_MODULES)
endif()
# Add the dependency on the generation step.
-add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.cpp ${BUILDVARIABLES_OBJPATH})
+set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.cpp
+ APPEND PROPERTY OBJECT_DEPENDS ${BUILDVARIABLES_OBJPATH}
+)
if(CMAKE_CROSSCOMPILING)
if (LLVM_NATIVE_TOOL_DIR AND NOT LLVM_CONFIG_PATH)
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index d06fd86fe52a..921f283deedc 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -1013,12 +1013,22 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
cl::desc("Show directory coverage"),
cl::cat(ViewCategory));
+ cl::opt<bool> ShowCreatedTime("show-created-time", cl::Optional,
+ cl::desc("Show created time for each page."),
+ cl::init(true), cl::cat(ViewCategory));
+
cl::opt<std::string> ShowOutputDirectory(
"output-dir", cl::init(""),
cl::desc("Directory in which coverage information is written out"));
cl::alias ShowOutputDirectoryA("o", cl::desc("Alias for --output-dir"),
cl::aliasopt(ShowOutputDirectory));
+ cl::opt<bool> BinaryCounters(
+ "binary-counters", cl::Optional,
+ cl::desc("Show binary counters (1/0) in lines and branches instead of "
+ "integer execution counts"),
+ cl::cat(ViewCategory));
+
cl::opt<uint32_t> TabSize(
"tab-size", cl::init(2),
cl::desc(
@@ -1096,6 +1106,7 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
ViewOpts.ShowDirectoryCoverage = ShowDirectoryCoverage;
ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
+ ViewOpts.BinaryCounters = BinaryCounters;
ViewOpts.TabSize = TabSize;
ViewOpts.ProjectTitle = ProjectTitle;
@@ -1112,12 +1123,15 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
return 1;
}
- auto ModifiedTime = Status.getLastModificationTime();
- std::string ModifiedTimeStr = to_string(ModifiedTime);
- size_t found = ModifiedTimeStr.rfind(':');
- ViewOpts.CreatedTimeStr = (found != std::string::npos)
- ? "Created: " + ModifiedTimeStr.substr(0, found)
- : "Created: " + ModifiedTimeStr;
+ if (ShowCreatedTime) {
+ auto ModifiedTime = Status.getLastModificationTime();
+ std::string ModifiedTimeStr = to_string(ModifiedTime);
+ size_t found = ModifiedTimeStr.rfind(':');
+ ViewOpts.CreatedTimeStr =
+ (found != std::string::npos)
+ ? "Created: " + ModifiedTimeStr.substr(0, found)
+ : "Created: " + ModifiedTimeStr;
+ }
auto Coverage = load();
if (!Coverage)
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 58e7918d3927..5c002a694f66 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -16,8 +16,9 @@
using namespace llvm;
using namespace coverage;
-static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
- const ArrayRef<CountedRegion> &Branches) {
+static auto sumBranches(const ArrayRef<CountedRegion> &Branches) {
+ size_t NumBranches = 0;
+ size_t CoveredBranches = 0;
for (const auto &BR : Branches) {
if (!BR.TrueFolded) {
// "True" Condition Branches.
@@ -32,20 +33,22 @@ static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
++CoveredBranches;
}
}
+ return BranchCoverageInfo(CoveredBranches, NumBranches);
}
-static void sumBranchExpansions(size_t &NumBranches, size_t &CoveredBranches,
- const CoverageMapping &CM,
- ArrayRef<ExpansionRecord> Expansions) {
+static BranchCoverageInfo
+sumBranchExpansions(const CoverageMapping &CM,
+ ArrayRef<ExpansionRecord> Expansions) {
+ BranchCoverageInfo BranchCoverage;
for (const auto &Expansion : Expansions) {
auto CE = CM.getCoverageForExpansion(Expansion);
- sumBranches(NumBranches, CoveredBranches, CE.getBranches());
- sumBranchExpansions(NumBranches, CoveredBranches, CM, CE.getExpansions());
+ BranchCoverage += sumBranches(CE.getBranches());
+ BranchCoverage += sumBranchExpansions(CM, CE.getExpansions());
}
+ return BranchCoverage;
}
-static std::pair<size_t, size_t>
-sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
+auto sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
size_t NumPairs = 0, CoveredPairs = 0;
for (const auto &Record : Records) {
const auto NumConditions = Record.getNumConditions();
@@ -56,15 +59,14 @@ sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
++CoveredPairs;
}
}
- return {NumPairs, CoveredPairs};
+ return MCDCCoverageInfo(CoveredPairs, NumPairs);
}
-FunctionCoverageSummary
-FunctionCoverageSummary::get(const CoverageMapping &CM,
- const coverage::FunctionRecord &Function) {
+static std::pair<RegionCoverageInfo, LineCoverageInfo>
+sumRegions(ArrayRef<CountedRegion> CodeRegions, const CoverageData &CD) {
// Compute the region coverage.
size_t NumCodeRegions = 0, CoveredRegions = 0;
- for (auto &CR : Function.CountedRegions) {
+ for (auto &CR : CodeRegions) {
if (CR.Kind != CounterMappingRegion::CodeRegion)
continue;
++NumCodeRegions;
@@ -74,7 +76,6 @@ FunctionCoverageSummary::get(const CoverageMapping &CM,
// Compute the line coverage
size_t NumLines = 0, CoveredLines = 0;
- CoverageData CD = CM.getCoverageForFunction(Function);
for (const auto &LCS : getLineCoverageStats(CD)) {
if (!LCS.isMapped())
continue;
@@ -83,20 +84,31 @@ FunctionCoverageSummary::get(const CoverageMapping &CM,
++CoveredLines;
}
+ return {RegionCoverageInfo(CoveredRegions, NumCodeRegions),
+ LineCoverageInfo(CoveredLines, NumLines)};
+}
+
+CoverageDataSummary::CoverageDataSummary(const CoverageData &CD,
+ ArrayRef<CountedRegion> CodeRegions) {
+ std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD);
+ BranchCoverage = sumBranches(CD.getBranches());
+ MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords());
+}
+
+FunctionCoverageSummary
+FunctionCoverageSummary::get(const CoverageMapping &CM,
+ const coverage::FunctionRecord &Function) {
+ CoverageData CD = CM.getCoverageForFunction(Function);
+
+ auto Summary =
+ FunctionCoverageSummary(Function.Name, Function.ExecutionCount);
+
+ Summary += CoverageDataSummary(CD, Function.CountedRegions);
+
// Compute the branch coverage, including branches from expansions.
- size_t NumBranches = 0, CoveredBranches = 0;
- sumBranches(NumBranches, CoveredBranches, CD.getBranches());
- sumBranchExpansions(NumBranches, CoveredBranches, CM, CD.getExpansions());
+ Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions());
- size_t NumPairs = 0, CoveredPairs = 0;
- std::tie(NumPairs, CoveredPairs) = sumMCDCPairs(CD.getMCDCRecords());
-
- return FunctionCoverageSummary(
- Function.Name, Function.ExecutionCount,
- RegionCoverageInfo(CoveredRegions, NumCodeRegions),
- LineCoverageInfo(CoveredLines, NumLines),
- BranchCoverageInfo(CoveredBranches, NumBranches),
- MCDCCoverageInfo(CoveredPairs, NumPairs));
+ return Summary;
}
FunctionCoverageSummary
@@ -111,8 +123,7 @@ FunctionCoverageSummary::get(const InstantiationGroup &Group,
<< Group.getColumn();
}
- FunctionCoverageSummary Summary(Name);
- Summary.ExecutionCount = Group.getTotalExecutionCount();
+ FunctionCoverageSummary Summary(Name, Group.getTotalExecutionCount());
Summary.RegionCoverage = Summaries[0].RegionCoverage;
Summary.LineCoverage = Summaries[0].LineCoverage;
Summary.BranchCoverage = Summaries[0].BranchCoverage;
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index 64c2c8406cf3..d9210676c41b 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -223,26 +223,32 @@ public:
}
};
-/// A summary of function's code coverage.
-struct FunctionCoverageSummary {
- std::string Name;
- uint64_t ExecutionCount;
+struct CoverageDataSummary {
RegionCoverageInfo RegionCoverage;
LineCoverageInfo LineCoverage;
BranchCoverageInfo BranchCoverage;
MCDCCoverageInfo MCDCCoverage;
- FunctionCoverageSummary(const std::string &Name)
- : Name(Name), ExecutionCount(0) {}
+ CoverageDataSummary() = default;
+ CoverageDataSummary(const coverage::CoverageData &CD,
+ ArrayRef<coverage::CountedRegion> CodeRegions);
- FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
- const RegionCoverageInfo &RegionCoverage,
- const LineCoverageInfo &LineCoverage,
- const BranchCoverageInfo &BranchCoverage,
- const MCDCCoverageInfo &MCDCCoverage)
- : Name(Name), ExecutionCount(ExecutionCount),
- RegionCoverage(RegionCoverage), LineCoverage(LineCoverage),
- BranchCoverage(BranchCoverage), MCDCCoverage(MCDCCoverage) {}
+ auto &operator+=(const CoverageDataSummary &RHS) {
+ RegionCoverage += RHS.RegionCoverage;
+ LineCoverage += RHS.LineCoverage;
+ BranchCoverage += RHS.BranchCoverage;
+ MCDCCoverage += RHS.MCDCCoverage;
+ return *this;
+ }
+};
+
+/// A summary of function's code coverage.
+struct FunctionCoverageSummary : CoverageDataSummary {
+ std::string Name;
+ uint64_t ExecutionCount;
+
+ FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount = 0)
+ : Name(Name), ExecutionCount(ExecutionCount) {}
/// Compute the code coverage summary for the given function coverage
/// mapping record.
@@ -257,12 +263,8 @@ struct FunctionCoverageSummary {
};
/// A summary of file's code coverage.
-struct FileCoverageSummary {
+struct FileCoverageSummary : CoverageDataSummary {
StringRef Name;
- RegionCoverageInfo RegionCoverage;
- LineCoverageInfo LineCoverage;
- BranchCoverageInfo BranchCoverage;
- MCDCCoverageInfo MCDCCoverage;
FunctionCoverageInfo FunctionCoverage;
FunctionCoverageInfo InstantiationCoverage;
@@ -270,11 +272,8 @@ struct FileCoverageSummary {
FileCoverageSummary(StringRef Name) : Name(Name) {}
FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
- RegionCoverage += RHS.RegionCoverage;
- LineCoverage += RHS.LineCoverage;
+ *static_cast<CoverageDataSummary *>(this) += RHS;
FunctionCoverage += RHS.FunctionCoverage;
- BranchCoverage += RHS.BranchCoverage;
- MCDCCoverage += RHS.MCDCCoverage;
InstantiationCoverage += RHS.InstantiationCoverage;
return *this;
}
diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h
index 6925cffd8246..81e69c3814e3 100644
--- a/llvm/tools/llvm-cov/CoverageViewOptions.h
+++ b/llvm/tools/llvm-cov/CoverageViewOptions.h
@@ -9,8 +9,8 @@
#ifndef LLVM_COV_COVERAGEVIEWOPTIONS_H
#define LLVM_COV_COVERAGEVIEWOPTIONS_H
-#include "llvm/Config/llvm-config.h"
#include "RenderingSupport.h"
+#include "llvm/Config/llvm-config.h"
#include <vector>
namespace llvm {
@@ -45,6 +45,7 @@ struct CoverageViewOptions {
bool SkipExpansions;
bool SkipFunctions;
bool SkipBranches;
+ bool BinaryCounters;
OutputFormat Format;
BranchOutputType ShowBranches;
std::string ShowOutputDirectory;
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index 2b1570d399dd..cff32b756ee3 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -180,6 +180,8 @@ class SourceCoverageView {
/// on display.
std::vector<InstantiationView> InstantiationSubViews;
+ bool BinaryCounters;
+
/// Get the first uncovered line number for the source file.
unsigned getFirstUncoveredLineNo();
@@ -266,6 +268,14 @@ protected:
/// digits.
static std::string formatCount(uint64_t N);
+ uint64_t BinaryCount(uint64_t N) const {
+ return (N && BinaryCounters ? 1 : N);
+ }
+
+ std::string formatBinaryCount(uint64_t N) const {
+ return formatCount(BinaryCount(N));
+ }
+
/// Check if region marker output is expected for a line.
bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const;
@@ -276,7 +286,9 @@ protected:
const CoverageViewOptions &Options,
CoverageData &&CoverageInfo)
: SourceName(SourceName), File(File), Options(Options),
- CoverageInfo(std::move(CoverageInfo)) {}
+ CoverageInfo(std::move(CoverageInfo)),
+ BinaryCounters(Options.BinaryCounters ||
+ CoverageInfo.getSingleByteCoverage()) {}
public:
static std::unique_ptr<SourceCoverageView>
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 0175deb1c848..c94d3853fc01 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -90,40 +90,38 @@ const char *BeginHeader =
const char *JSForCoverage =
R"javascript(
-
function next_uncovered(selector, reverse, scroll_selector) {
function visit_element(element) {
element.classList.add("seen");
element.classList.add("selected");
-
- if (!scroll_selector) {
- scroll_selector = "tr:has(.selected) td.line-number"
- }
-
- const scroll_to = document.querySelector(scroll_selector);
- if (scroll_to) {
- scroll_to.scrollIntoView({behavior: "smooth", block: "center", inline: "end"});
- }
-
+
+ if (!scroll_selector) {
+ scroll_selector = "tr:has(.selected) td.line-number"
+ }
+
+ const scroll_to = document.querySelector(scroll_selector);
+ if (scroll_to) {
+ scroll_to.scrollIntoView({behavior: "smooth", block: "center", inline: "end"});
+ }
}
-
+
function select_one() {
if (!reverse) {
const previously_selected = document.querySelector(".selected");
-
+
if (previously_selected) {
previously_selected.classList.remove("selected");
}
-
+
return document.querySelector(selector + ":not(.seen)");
- } else {
+ } else {
const previously_selected = document.querySelector(".selected");
-
+
if (previously_selected) {
previously_selected.classList.remove("selected");
previously_selected.classList.remove("seen");
}
-
+
const nodes = document.querySelectorAll(selector + ".seen");
if (nodes) {
const last = nodes[nodes.length - 1]; // last
@@ -133,54 +131,52 @@ function next_uncovered(selector, reverse, scroll_selector) {
}
}
}
-
+
function reset_all() {
if (!reverse) {
const all_seen = document.querySelectorAll(selector + ".seen");
-
+
if (all_seen) {
all_seen.forEach(e => e.classList.remove("seen"));
}
} else {
const all_seen = document.querySelectorAll(selector + ":not(.seen)");
-
+
if (all_seen) {
all_seen.forEach(e => e.classList.add("seen"));
}
}
-
+
}
-
+
const uncovered = select_one();
if (uncovered) {
visit_element(uncovered);
} else {
reset_all();
-
-
+
const uncovered = select_one();
-
+
if (uncovered) {
visit_element(uncovered);
}
}
}
-function next_line(reverse) {
+function next_line(reverse) {
next_uncovered("td.uncovered-line", reverse)
}
-function next_region(reverse) {
+function next_region(reverse) {
next_uncovered("span.red.region", reverse);
}
-function next_branch(reverse) {
+function next_branch(reverse) {
next_uncovered("span.red.branch", reverse);
}
document.addEventListener("keypress", function(event) {
- console.log(event);
const reverse = event.shiftKey;
if (event.code == "KeyL") {
next_line(reverse);
@@ -191,7 +187,6 @@ document.addEventListener("keypress", function(event) {
if (event.code == "KeyR") {
next_region(reverse);
}
-
});
)javascript";
@@ -1024,19 +1019,22 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L,
// Just consider the segments which start *and* end on this line.
for (unsigned I = 0, E = Segments.size() - 1; I < E; ++I) {
const auto *CurSeg = Segments[I];
+ auto CurSegCount = BinaryCount(CurSeg->Count);
+ auto LCSCount = BinaryCount(LCS.getExecutionCount());
if (!CurSeg->IsRegionEntry)
continue;
- if (CurSeg->Count == LCS.getExecutionCount())
+ if (CurSegCount == LCSCount)
continue;
Snippets[I + 1] =
- tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count),
- "tooltip-content"),
+ tag("div",
+ Snippets[I + 1] +
+ tag("span", formatCount(CurSegCount), "tooltip-content"),
"tooltip");
if (getOptions().Debug)
errs() << "Marker at " << CurSeg->Line << ":" << CurSeg->Col << " = "
- << formatCount(CurSeg->Count) << "\n";
+ << formatCount(CurSegCount) << "\n";
}
}
@@ -1056,7 +1054,7 @@ void SourceCoverageViewHTML::renderLineCoverageColumn(
raw_ostream &OS, const LineCoverageStats &Line) {
std::string Count;
if (Line.isMapped())
- Count = tag("pre", formatCount(Line.getExecutionCount()));
+ Count = tag("pre", formatBinaryCount(Line.getExecutionCount()));
std::string CoverageClass =
(Line.getExecutionCount() > 0)
? "covered-line"
@@ -1101,20 +1099,31 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
if (getOptions().Debug)
errs() << "Branch at line " << BRV.getLine() << '\n';
+ auto BranchCount = [&](StringRef Label, uint64_t Count, bool Folded,
+ double Total) {
+ if (Folded)
+ return std::string{"Folded"};
+
+ std::string Str;
+ raw_string_ostream OS(Str);
+
+ OS << tag("span", Label, (Count ? "None" : "red branch")) << ": ";
+ if (getOptions().ShowBranchCounts)
+ OS << tag("span", formatBinaryCount(Count),
+ (Count ? "covered-line" : "uncovered-line"));
+ else
+ OS << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%";
+
+ return Str;
+ };
+
OS << BeginExpansionDiv;
OS << BeginPre;
for (const auto &R : BRV.Regions) {
- // Calculate TruePercent and False Percent.
- double TruePercent = 0.0;
- double FalsePercent = 0.0;
- // FIXME: It may overflow when the data is too large, but I have not
- // encountered it in actual use, and not sure whether to use __uint128_t.
- uint64_t Total = R.ExecutionCount + R.FalseExecutionCount;
-
- if (!getOptions().ShowBranchCounts && Total != 0) {
- TruePercent = ((double)(R.ExecutionCount) / (double)Total) * 100.0;
- FalsePercent = ((double)(R.FalseExecutionCount) / (double)Total) * 100.0;
- }
+ // This can be `double` since it is only used as a denominator.
+ // FIXME: It is still inaccurate if Count is greater than (1LL << 53).
+ double Total =
+ static_cast<double>(R.ExecutionCount) + R.FalseExecutionCount;
// Display Line + Column.
std::string LineNoStr = utostr(uint64_t(R.LineStart));
@@ -1133,40 +1142,9 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
continue;
}
- // Display TrueCount or TruePercent.
- std::string TrueColor =
- (R.TrueFolded || R.ExecutionCount ? "None" : "red branch");
- std::string TrueCovClass =
- (R.TrueFolded || R.ExecutionCount > 0 ? "covered-line"
- : "uncovered-line");
-
- if (R.TrueFolded)
- OS << "Folded, ";
- else {
- OS << tag("span", "True", TrueColor) << ": ";
- if (getOptions().ShowBranchCounts)
- OS << tag("span", formatCount(R.ExecutionCount), TrueCovClass) << ", ";
- else
- OS << format("%0.2f", TruePercent) << "%, ";
- }
-
- // Display FalseCount or FalsePercent.
- std::string FalseColor =
- (R.FalseFolded || R.FalseExecutionCount ? "None" : "red branch");
- std::string FalseCovClass =
- (R.FalseFolded || R.FalseExecutionCount > 0 ? "covered-line"
- : "uncovered-line");
-
- if (R.FalseFolded)
- OS << "Folded]\n";
- else {
- OS << tag("span", "False", FalseColor) << ": ";
- if (getOptions().ShowBranchCounts)
- OS << tag("span", formatCount(R.FalseExecutionCount), FalseCovClass)
- << "]\n";
- else
- OS << format("%0.2f", FalsePercent) << "%]\n";
- }
+ OS << BranchCount("True", R.ExecutionCount, R.TrueFolded, Total) << ", "
+ << BranchCount("False", R.FalseExecutionCount, R.FalseFolded, Total)
+ << "]\n";
}
OS << EndPre;
OS << EndExpansionDiv;
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
index 444f33dac108..765f8bbbd8d1 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
@@ -216,7 +216,7 @@ void SourceCoverageViewText::renderLineCoverageColumn(
OS.indent(LineCoverageColumnWidth) << '|';
return;
}
- std::string C = formatCount(Line.getExecutionCount());
+ std::string C = formatBinaryCount(Line.getExecutionCount());
OS.indent(LineCoverageColumnWidth - C.size());
colored_ostream(OS, raw_ostream::MAGENTA,
Line.hasMultipleRegions() && getOptions().Colors)
@@ -263,7 +263,7 @@ void SourceCoverageViewText::renderRegionMarkers(raw_ostream &OS,
if (getOptions().Debug)
errs() << "Marker at " << S->Line << ":" << S->Col << " = "
- << formatCount(S->Count) << "\n";
+ << formatBinaryCount(S->Count) << "\n";
}
OS << '\n';
}
@@ -294,17 +294,32 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
if (getOptions().Debug)
errs() << "Branch at line " << BRV.getLine() << '\n';
+ auto BranchCount = [&](StringRef Label, uint64_t Count, bool Folded,
+ double Total) {
+ if (Folded)
+ return std::string{"Folded"};
+
+ std::string Str;
+ raw_string_ostream OS(Str);
+
+ colored_ostream(OS, raw_ostream::RED, getOptions().Colors && !Count,
+ /*Bold=*/false, /*BG=*/true)
+ << Label;
+
+ if (getOptions().ShowBranchCounts)
+ OS << ": " << formatBinaryCount(Count);
+ else
+ OS << ": " << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0))
+ << "%";
+
+ return Str;
+ };
+
for (const auto &R : BRV.Regions) {
- double TruePercent = 0.0;
- double FalsePercent = 0.0;
- // FIXME: It may overflow when the data is too large, but I have not
- // encountered it in actual use, and not sure whether to use __uint128_t.
- uint64_t Total = R.ExecutionCount + R.FalseExecutionCount;
-
- if (!getOptions().ShowBranchCounts && Total != 0) {
- TruePercent = ((double)(R.ExecutionCount) / (double)Total) * 100.0;
- FalsePercent = ((double)(R.FalseExecutionCount) / (double)Total) * 100.0;
- }
+ // This can be `double` since it is only used as a denominator.
+ // FIXME: It is still inaccurate if Count is greater than (1LL << 53).
+ double Total =
+ static_cast<double>(R.ExecutionCount) + R.FalseExecutionCount;
renderLinePrefix(OS, ViewDepth);
OS << " Branch (" << R.LineStart << ":" << R.ColumnStart << "): [";
@@ -314,33 +329,9 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
continue;
}
- if (R.TrueFolded)
- OS << "Folded, ";
- else {
- colored_ostream(OS, raw_ostream::RED,
- getOptions().Colors && !R.ExecutionCount,
- /*Bold=*/false, /*BG=*/true)
- << "True";
-
- if (getOptions().ShowBranchCounts)
- OS << ": " << formatCount(R.ExecutionCount) << ", ";
- else
- OS << ": " << format("%0.2f", TruePercent) << "%, ";
- }
-
- if (R.FalseFolded)
- OS << "Folded]\n";
- else {
- colored_ostream(OS, raw_ostream::RED,
- getOptions().Colors && !R.FalseExecutionCount,
- /*Bold=*/false, /*BG=*/true)
- << "False";
-
- if (getOptions().ShowBranchCounts)
- OS << ": " << formatCount(R.FalseExecutionCount) << "]\n";
- else
- OS << ": " << format("%0.2f", FalsePercent) << "%]\n";
- }
+ OS << BranchCount("True", R.ExecutionCount, R.TrueFolded, Total) << ", "
+ << BranchCount("False", R.FalseExecutionCount, R.FalseFolded, Total)
+ << "]\n";
}
}
diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
index 0c10769a9488..8ef8d6e239cf 100644
--- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
+++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
@@ -42,12 +42,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -58,7 +59,9 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class CvtResOptTable : public opt::GenericOptTable {
public:
- CvtResOptTable() : opt::GenericOptTable(InfoTable, true) {}
+ CvtResOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
+ true) {}
};
}
diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
index 41b379e8fd39..1467093e78c0 100644
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
@@ -31,12 +31,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \
- static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \
- NAME##_init, std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -47,7 +48,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class CxxfiltOptTable : public opt::GenericOptTable {
public:
- CxxfiltOptTable() : opt::GenericOptTable(InfoTable) {
+ CxxfiltOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
index 77862737bccd..934833bf6fe4 100644
--- a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
+++ b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
@@ -37,12 +37,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -53,7 +54,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class DebuginfodFindOptTable : public opt::GenericOptTable {
public:
- DebuginfodFindOptTable() : GenericOptTable(InfoTable) {}
+ DebuginfodFindOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp
index 44d656148a4e..2859a36c80b0 100644
--- a/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp
+++ b/llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp
@@ -36,12 +36,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -52,7 +53,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class DebuginfodOptTable : public opt::GenericOptTable {
public:
- DebuginfodOptTable() : GenericOptTable(InfoTable) {}
+ DebuginfodOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
index 7b777b1845f8..0180abb834f9 100644
--- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
+++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
@@ -38,12 +38,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Options.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Options.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -54,7 +55,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class DwarfutilOptTable : public opt::GenericOptTable {
public:
- DwarfutilOptTable() : opt::GenericOptTable(InfoTable) {}
+ DwarfutilOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // namespace
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 60a89cb13c57..e34fcadfde5f 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -47,12 +47,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -63,7 +64,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class DwpOptTable : public opt::GenericOptTable {
public:
- DwpOptTable() : GenericOptTable(InfoTable) {}
+ DwpOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 9116b5ced027..a7771b99e97b 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -422,8 +422,9 @@ private:
"Expected getcpu call to succeed.");
assert(static_cast<int>(CurrentCPU) == CPUToUse &&
"Expected current CPU to equal the CPU requested by the user");
-#endif // defined(__x86_64__) && defined(SYS_getcpu)
+#else
exit(ChildProcessExitCodeE::SetCPUAffinityFailed);
+#endif // defined(__x86_64__) && defined(SYS_getcpu)
}
Error createSubProcessAndRunBenchmark(
diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
index 414b49e5e021..d95c37ff5426 100644
--- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
+++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt
@@ -12,6 +12,9 @@ endif()
if (LLVM_TARGETS_TO_BUILD MATCHES "Mips")
list(APPEND LLVM_EXEGESIS_TARGETS "Mips")
endif()
+if(LLVM_TARGETS_TO_BUILD MATCHES "RISCV")
+ list(APPEND LLVM_EXEGESIS_TARGETS "RISCV")
+endif()
set(LLVM_EXEGESIS_TARGETS ${LLVM_EXEGESIS_TARGETS} PARENT_SCOPE)
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 9c926d1fc611..c9225e51213e 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -95,11 +95,12 @@ Instruction::Instruction(const MCInstrDesc *Description, StringRef Name,
const BitVector *ImplDefRegs,
const BitVector *ImplUseRegs,
const BitVector *AllDefRegs,
- const BitVector *AllUseRegs)
+ const BitVector *AllUseRegs,
+ const BitVector *NonMemoryRegs)
: Description(*Description), Name(Name), Operands(std::move(Operands)),
Variables(std::move(Variables)), ImplDefRegs(*ImplDefRegs),
ImplUseRegs(*ImplUseRegs), AllDefRegs(*AllDefRegs),
- AllUseRegs(*AllUseRegs) {}
+ AllUseRegs(*AllUseRegs), NonMemoryRegs(*NonMemoryRegs) {}
std::unique_ptr<Instruction>
Instruction::create(const MCInstrInfo &InstrInfo,
@@ -166,6 +167,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
BitVector ImplUseRegs = RATC.emptyRegisters();
BitVector AllDefRegs = RATC.emptyRegisters();
BitVector AllUseRegs = RATC.emptyRegisters();
+ BitVector NonMemoryRegs = RATC.emptyRegisters();
+
for (const auto &Op : Operands) {
if (Op.isReg()) {
const auto &AliasingBits = Op.getRegisterAliasing().aliasedBits();
@@ -177,6 +180,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
ImplDefRegs |= AliasingBits;
if (Op.isUse() && Op.isImplicit())
ImplUseRegs |= AliasingBits;
+ if (Op.isUse() && !Op.isMemory())
+ NonMemoryRegs |= AliasingBits;
}
}
// Can't use make_unique because constructor is private.
@@ -185,7 +190,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
std::move(Variables), BVC.getUnique(std::move(ImplDefRegs)),
BVC.getUnique(std::move(ImplUseRegs)),
BVC.getUnique(std::move(AllDefRegs)),
- BVC.getUnique(std::move(AllUseRegs))));
+ BVC.getUnique(std::move(AllUseRegs)),
+ BVC.getUnique(std::move(NonMemoryRegs))));
}
const Operand &Instruction::getPrimaryOperand(const Variable &Var) const {
@@ -240,6 +246,12 @@ bool Instruction::hasAliasingRegisters(
ForbiddenRegisters);
}
+bool Instruction::hasAliasingNotMemoryRegisters(
+ const BitVector &ForbiddenRegisters) const {
+ return anyCommonExcludingForbidden(AllDefRegs, NonMemoryRegs,
+ ForbiddenRegisters);
+}
+
bool Instruction::hasOneUseOrOneDef() const {
return AllDefRegs.count() || AllUseRegs.count();
}
diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
index f8ebc07d01f3..d7712e21c32c 100644
--- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
+++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
@@ -133,6 +133,12 @@ struct Instruction {
// aliasing Use and Def registers.
bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const;
+ // Whether this instruction is self aliasing through some registers.
+ // Repeating this instruction may execute sequentially by picking aliasing
+ // Def and Not Memory Use registers. It may also execute in parallel by
+ // picking non aliasing Def and Not Memory Use registers.
+ bool hasAliasingNotMemoryRegisters(const BitVector &ForbiddenRegisters) const;
+
// Whether this instruction's registers alias with OtherInstr's registers.
bool hasAliasingRegistersThrough(const Instruction &OtherInstr,
const BitVector &ForbiddenRegisters) const;
@@ -160,12 +166,15 @@ struct Instruction {
const BitVector &ImplUseRegs; // The set of aliased implicit use registers.
const BitVector &AllDefRegs; // The set of all aliased def registers.
const BitVector &AllUseRegs; // The set of all aliased use registers.
+ // The set of all aliased not memory use registers.
+ const BitVector &NonMemoryRegs;
+
private:
Instruction(const MCInstrDesc *Description, StringRef Name,
SmallVector<Operand, 8> Operands,
SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,
const BitVector *ImplUseRegs, const BitVector *AllDefRegs,
- const BitVector *AllUseRegs);
+ const BitVector *AllUseRegs, const BitVector *NonMemoryRegs);
};
// Instructions are expensive to instantiate. This class provides a cache of
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt
new file mode 100644
index 000000000000..489ac6d6e34b
--- /dev/null
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt
@@ -0,0 +1,22 @@
+include_directories(
+ ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV
+ ${LLVM_BINARY_DIR}/lib/Target/RISCV
+)
+
+set(LLVM_LINK_COMPONENTS
+ CodeGen
+ RISCV
+ Exegesis
+ Core
+ Support
+ )
+
+add_llvm_library(LLVMExegesisRISCV
+ DISABLE_LLVM_LINK_LLVM_DYLIB
+ STATIC
+ Target.cpp
+
+ DEPENDS
+ intrinsics_gen
+ RISCVCommonTableGen
+ )
diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
new file mode 100644
index 000000000000..41d361532908
--- /dev/null
+++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp
@@ -0,0 +1,272 @@
+//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../Target.h"
+
+#include "MCTargetDesc/RISCVBaseInfo.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "MCTargetDesc/RISCVMatInt.h"
+#include "RISCVInstrInfo.h"
+
+// include computeAvailableFeatures and computeRequiredFeatures.
+#define GET_AVAILABLE_OPCODE_CHECKER
+#include "RISCVGenInstrInfo.inc"
+
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+
+#include <vector>
+
+namespace llvm {
+namespace exegesis {
+
+namespace {
+
+// Stores constant value to a general-purpose (integer) register.
+static std::vector<MCInst> loadIntReg(const MCSubtargetInfo &STI, unsigned Reg,
+ const APInt &Value) {
+ SmallVector<MCInst, 8> MCInstSeq;
+ std::vector<MCInst> MatIntInstrs;
+ MCRegister DestReg = Reg;
+
+ RISCVMatInt::generateMCInstSeq(Value.getSExtValue(), STI, DestReg, MCInstSeq);
+ MatIntInstrs.resize(MCInstSeq.size());
+ std::copy(MCInstSeq.begin(), MCInstSeq.end(), MatIntInstrs.begin());
+
+ return MatIntInstrs;
+}
+
+const unsigned ScratchIntReg = RISCV::X30; // t5
+
+// Stores constant bits to a floating-point register.
+static std::vector<MCInst> loadFPRegBits(const MCSubtargetInfo &STI,
+ unsigned Reg, const APInt &Bits,
+ unsigned FmvOpcode) {
+ std::vector<MCInst> Instrs = loadIntReg(STI, ScratchIntReg, Bits);
+ Instrs.push_back(MCInstBuilder(FmvOpcode).addReg(Reg).addReg(ScratchIntReg));
+ return Instrs;
+}
+
+// main idea is:
+// we support APInt only if (represented as double) it has zero fractional
+// part: 1.0, 2.0, 3.0, etc... then we can do the trick: write int to tmp reg t5
+// and then do FCVT this is only reliable thing in 32-bit mode, otherwise we
+// need to use __floatsidf
+static std::vector<MCInst> loadFP64RegBits32(const MCSubtargetInfo &STI,
+ unsigned Reg, const APInt &Bits) {
+ double D = Bits.bitsToDouble();
+ double IPart;
+ double FPart = std::modf(D, &IPart);
+
+ if (std::abs(FPart) > std::numeric_limits<double>::epsilon()) {
+ errs() << "loadFP64RegBits32 is not implemented for doubles like " << D
+ << ", please remove fractional part\n";
+ return {};
+ }
+
+ std::vector<MCInst> Instrs = loadIntReg(STI, ScratchIntReg, Bits);
+ Instrs.push_back(
+ MCInstBuilder(RISCV::FCVT_D_W).addReg(Reg).addReg(ScratchIntReg));
+ return Instrs;
+}
+
+static MCInst nop() {
+ // ADDI X0, X0, 0
+ return MCInstBuilder(RISCV::ADDI)
+ .addReg(RISCV::X0)
+ .addReg(RISCV::X0)
+ .addImm(0);
+}
+
+static bool isVectorRegList(unsigned Reg) {
+ return RISCV::VRM2RegClass.contains(Reg) ||
+ RISCV::VRM4RegClass.contains(Reg) ||
+ RISCV::VRM8RegClass.contains(Reg) ||
+ RISCV::VRN2M1RegClass.contains(Reg) ||
+ RISCV::VRN2M2RegClass.contains(Reg) ||
+ RISCV::VRN2M4RegClass.contains(Reg) ||
+ RISCV::VRN3M1RegClass.contains(Reg) ||
+ RISCV::VRN3M2RegClass.contains(Reg) ||
+ RISCV::VRN4M1RegClass.contains(Reg) ||
+ RISCV::VRN4M2RegClass.contains(Reg) ||
+ RISCV::VRN5M1RegClass.contains(Reg) ||
+ RISCV::VRN6M1RegClass.contains(Reg) ||
+ RISCV::VRN7M1RegClass.contains(Reg) ||
+ RISCV::VRN8M1RegClass.contains(Reg);
+}
+
+class ExegesisRISCVTarget : public ExegesisTarget {
+public:
+ ExegesisRISCVTarget();
+
+ bool matchesArch(Triple::ArchType Arch) const override;
+
+ std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
+ const APInt &Value) const override;
+
+ unsigned getDefaultLoopCounterRegister(const Triple &) const override;
+
+ void decrementLoopCounterAndJump(MachineBasicBlock &MBB,
+ MachineBasicBlock &TargetMBB,
+ const MCInstrInfo &MII,
+ unsigned LoopRegister) const override;
+
+ unsigned getScratchMemoryRegister(const Triple &TT) const override;
+
+ void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
+ unsigned Offset) const override;
+
+ ArrayRef<unsigned> getUnavailableRegisters() const override;
+
+ Error randomizeTargetMCOperand(const Instruction &Instr, const Variable &Var,
+ MCOperand &AssignedValue,
+ const BitVector &ForbiddenRegs) const override;
+
+ std::vector<InstructionTemplate>
+ generateInstructionVariants(const Instruction &Instr,
+ unsigned MaxConfigsPerOpcode) const override;
+};
+
+ExegesisRISCVTarget::ExegesisRISCVTarget()
+ : ExegesisTarget(ArrayRef<CpuAndPfmCounters>{},
+ RISCV_MC::isOpcodeAvailable) {}
+
+bool ExegesisRISCVTarget::matchesArch(Triple::ArchType Arch) const {
+ return Arch == Triple::riscv32 || Arch == Triple::riscv64;
+}
+
+std::vector<MCInst> ExegesisRISCVTarget::setRegTo(const MCSubtargetInfo &STI,
+ unsigned Reg,
+ const APInt &Value) const {
+ if (RISCV::GPRRegClass.contains(Reg))
+ return loadIntReg(STI, Reg, Value);
+ if (RISCV::FPR16RegClass.contains(Reg))
+ return loadFPRegBits(STI, Reg, Value, RISCV::FMV_H_X);
+ if (RISCV::FPR32RegClass.contains(Reg))
+ return loadFPRegBits(STI, Reg, Value, RISCV::FMV_W_X);
+ if (RISCV::FPR64RegClass.contains(Reg)) {
+ if (STI.hasFeature(RISCV::Feature64Bit))
+ return loadFPRegBits(STI, Reg, Value, RISCV::FMV_D_X);
+ return loadFP64RegBits32(STI, Reg, Value);
+ }
+ if (Reg == RISCV::FRM || Reg == RISCV::VL || Reg == RISCV::VLENB ||
+ Reg == RISCV::VTYPE || RISCV::GPRPairRegClass.contains(Reg) ||
+ RISCV::VRRegClass.contains(Reg) || isVectorRegList(Reg)) {
+ // Don't initialize:
+ // - FRM
+ // - VL, VLENB, VTYPE
+ // - vector registers (and vector register lists)
+ // - Zfinx registers
+ // Generate 'NOP' so that exegesis treats such registers as initialized
+ // (it tries to initialize them with '0' anyway).
+ return {nop()};
+ }
+ errs() << "setRegTo is not implemented for Reg " << Reg
+ << ", results will be unreliable\n";
+ return {};
+}
+
+const unsigned DefaultLoopCounterReg = RISCV::X31; // t6
+const unsigned ScratchMemoryReg = RISCV::X10; // a0
+
+unsigned
+ExegesisRISCVTarget::getDefaultLoopCounterRegister(const Triple &) const {
+ return DefaultLoopCounterReg;
+}
+
+void ExegesisRISCVTarget::decrementLoopCounterAndJump(
+ MachineBasicBlock &MBB, MachineBasicBlock &TargetMBB,
+ const MCInstrInfo &MII, unsigned LoopRegister) const {
+ BuildMI(&MBB, DebugLoc(), MII.get(RISCV::ADDI))
+ .addDef(LoopRegister)
+ .addUse(LoopRegister)
+ .addImm(-1);
+ BuildMI(&MBB, DebugLoc(), MII.get(RISCV::BNE))
+ .addUse(LoopRegister)
+ .addUse(RISCV::X0)
+ .addMBB(&TargetMBB);
+}
+
+unsigned ExegesisRISCVTarget::getScratchMemoryRegister(const Triple &TT) const {
+ return ScratchMemoryReg; // a0
+}
+
+void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT,
+ unsigned Reg,
+ unsigned Offset) const {
+ // TODO: for now we ignore Offset because have no way
+ // to detect it in instruction.
+ auto &I = IT.getInstr();
+
+ auto MemOpIt =
+ find_if(I.Operands, [](const Operand &Op) { return Op.isMemory(); });
+ assert(MemOpIt != I.Operands.end() &&
+ "Instruction must have memory operands");
+
+ const Operand &MemOp = *MemOpIt;
+
+ assert(MemOp.isReg() && "Memory operand expected to be register");
+
+ IT.getValueFor(MemOp) = MCOperand::createReg(Reg);
+}
+
+const unsigned UnavailableRegisters[4] = {RISCV::X0, DefaultLoopCounterReg,
+ ScratchIntReg, ScratchMemoryReg};
+
+ArrayRef<unsigned> ExegesisRISCVTarget::getUnavailableRegisters() const {
+ return UnavailableRegisters;
+}
+
+Error ExegesisRISCVTarget::randomizeTargetMCOperand(
+ const Instruction &Instr, const Variable &Var, MCOperand &AssignedValue,
+ const BitVector &ForbiddenRegs) const {
+ uint8_t OperandType =
+ Instr.getPrimaryOperand(Var).getExplicitOperandInfo().OperandType;
+
+ switch (OperandType) {
+ case RISCVOp::OPERAND_FRMARG:
+ AssignedValue = MCOperand::createImm(RISCVFPRndMode::DYN);
+ break;
+ case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
+ AssignedValue = MCOperand::createImm(0b1 << 4);
+ break;
+ case RISCVOp::OPERAND_SIMM6_NONZERO:
+ case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO:
+ AssignedValue = MCOperand::createImm(1);
+ break;
+ default:
+ if (OperandType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
+ OperandType <= RISCVOp::OPERAND_LAST_RISCV_IMM)
+ AssignedValue = MCOperand::createImm(0);
+ }
+ return Error::success();
+}
+
+std::vector<InstructionTemplate>
+ExegesisRISCVTarget::generateInstructionVariants(
+ const Instruction &Instr, unsigned int MaxConfigsPerOpcode) const {
+ InstructionTemplate IT{&Instr};
+ for (const Operand &Op : Instr.Operands)
+ if (Op.isMemory()) {
+ IT.getValueFor(Op) = MCOperand::createReg(ScratchMemoryReg);
+ }
+ return {IT};
+}
+
+} // anonymous namespace
+
+static ExegesisTarget *getTheRISCVExegesisTarget() {
+ static ExegesisRISCVTarget Target;
+ return &Target;
+}
+
+void InitializeRISCVExegesisTarget() {
+ ExegesisTarget::registerTarget(getTheRISCVExegesisTarget());
+}
+
+} // namespace exegesis
+} // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
index 7100b51bbb72..25cdf1ce66d4 100644
--- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
@@ -53,13 +53,6 @@ computeAliasingInstructions(const LLVMState &State, const Instruction *Instr,
if (OtherOpcode == Instr->Description.getOpcode())
continue;
const Instruction &OtherInstr = State.getIC().getInstr(OtherOpcode);
- const MCInstrDesc &OtherInstrDesc = OtherInstr.Description;
- // Ignore instructions that we cannot run.
- if (OtherInstrDesc.isPseudo() || OtherInstrDesc.usesCustomInsertionHook() ||
- OtherInstrDesc.isBranch() || OtherInstrDesc.isIndirectBranch() ||
- OtherInstrDesc.isCall() || OtherInstrDesc.isReturn()) {
- continue;
- }
if (OtherInstr.hasMemoryOperands())
continue;
if (!ET.allowAsBackToBack(OtherInstr))
@@ -81,12 +74,10 @@ static ExecutionMode getExecutionModes(const Instruction &Instr,
EM |= ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS;
if (Instr.hasMemoryOperands())
EM |= ExecutionMode::SERIAL_VIA_MEMORY_INSTR;
- else {
- if (Instr.hasAliasingRegisters(ForbiddenRegisters))
- EM |= ExecutionMode::SERIAL_VIA_EXPLICIT_REGS;
- if (Instr.hasOneUseOrOneDef())
- EM |= ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR;
- }
+ if (Instr.hasAliasingNotMemoryRegisters(ForbiddenRegisters))
+ EM |= ExecutionMode::SERIAL_VIA_EXPLICIT_REGS;
+ if (Instr.hasOneUseOrOneDef())
+ EM |= ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR;
return EM;
}
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 7dcff60a8fd1..48357d443f71 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -73,6 +73,9 @@ Error SnippetGenerator::generateConfigurations(
for (CodeTemplate &CT : Templates) {
// TODO: Generate as many BenchmarkCode as needed.
{
+ CT.ScratchSpacePointerInReg =
+ State.getExegesisTarget().getScratchMemoryRegister(
+ State.getTargetMachine().getTargetTriple());
BenchmarkCode BC;
BC.Info = CT.Info;
BC.Key.Instructions.reserve(CT.Instructions.size());
@@ -108,6 +111,12 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
// Loop invariant: DefinedRegs[i] is true iif it has been set at least once
// before the current instruction.
BitVector DefinedRegs = State.getRATC().emptyRegisters();
+ // If target always expects a scratch memory register as live input,
+ // mark it as defined.
+ const ExegesisTarget &Target = State.getExegesisTarget();
+ unsigned ScratchMemoryReg = Target.getScratchMemoryRegister(
+ State.getTargetMachine().getTargetTriple());
+ DefinedRegs.set(ScratchMemoryReg);
std::vector<RegisterValue> RIV;
for (const InstructionTemplate &IT : Instructions) {
// Returns the register that this Operand sets or uses, or 0 if this is not
@@ -200,7 +209,8 @@ static void setRegisterOperandValue(const RegisterOperandAssignment &ROV,
if (ROV.Op->isExplicit()) {
auto &AssignedValue = IB.getValueFor(*ROV.Op);
if (AssignedValue.isValid()) {
- assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg);
+ // TODO don't re-assign register operands which are already "locked"
+ // by Target in corresponding InstructionTemplate
return;
}
AssignedValue = MCOperand::createReg(ROV.Reg);
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 546ec770a8d2..fa37e05956be 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -274,6 +274,10 @@ static cl::opt<int> BenchmarkProcessCPU(
cl::desc("The CPU number that the benchmarking process should executon on"),
cl::cat(BenchmarkOptions), cl::init(-1));
+static cl::opt<std::string> MAttr(
+ "mattr", cl::desc("comma-separated list of target architecture features"),
+ cl::value_desc("+feature1,-feature2,..."), cl::cat(Options), cl::init(""));
+
static ExitOnError ExitOnErr("llvm-exegesis error: ");
// Helper function that logs the error(s) and exits.
@@ -296,6 +300,18 @@ T ExitOnFileError(const Twine &FileName, Expected<T> &&E) {
return std::move(*E);
}
+static const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State,
+ unsigned Opcode) {
+ const MCInstrDesc &InstrDesc = State.getIC().getInstr(Opcode).Description;
+ if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook())
+ return "Unsupported opcode: isPseudo/usesCustomInserter";
+ if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
+ return "Unsupported opcode: isBranch/isIndirectBranch";
+ if (InstrDesc.isCall() || InstrDesc.isReturn())
+ return "Unsupported opcode: isCall/isReturn";
+ return nullptr;
+}
+
// Checks that only one of OpcodeNames, OpcodeIndex or SnippetsFile is provided,
// and returns the opcode indices or {} if snippets should be read from
// `SnippetsFile`.
@@ -334,6 +350,7 @@ static std::vector<unsigned> getOpcodesOrDie(const LLVMState &State) {
return I->getSecond();
return 0u;
};
+
SmallVector<StringRef, 2> Pieces;
StringRef(OpcodeNames.getValue())
.split(Pieces, ",", /* MaxSplit */ -1, /* KeepEmpty */ false);
@@ -352,17 +369,11 @@ static std::vector<unsigned> getOpcodesOrDie(const LLVMState &State) {
static Expected<std::vector<BenchmarkCode>>
generateSnippets(const LLVMState &State, unsigned Opcode,
const BitVector &ForbiddenRegs) {
- const Instruction &Instr = State.getIC().getInstr(Opcode);
- const MCInstrDesc &InstrDesc = Instr.Description;
// Ignore instructions that we cannot run.
- if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook())
- return make_error<Failure>(
- "Unsupported opcode: isPseudo/usesCustomInserter");
- if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
- return make_error<Failure>("Unsupported opcode: isBranch/isIndirectBranch");
- if (InstrDesc.isCall() || InstrDesc.isReturn())
- return make_error<Failure>("Unsupported opcode: isCall/isReturn");
+ if (const char *Reason = getIgnoredOpcodeReasonOrNull(State, Opcode))
+ return make_error<Failure>(Reason);
+ const Instruction &Instr = State.getIC().getInstr(Opcode);
const std::vector<InstructionTemplate> InstructionVariants =
State.getExegesisTarget().generateInstructionVariants(
Instr, MaxConfigsPerOpcode);
@@ -485,8 +496,8 @@ void benchmarkMain() {
LLVMInitialize##TargetName##AsmParser();
#include "llvm/Config/TargetExegesis.def"
- const LLVMState State =
- ExitOnErr(LLVMState::Create(TripleName, MCPU, "", UseDummyPerfCounters));
+ const LLVMState State = ExitOnErr(
+ LLVMState::Create(TripleName, MCPU, MAttr, UseDummyPerfCounters));
// Preliminary check to ensure features needed for requested
// benchmark mode are present on target CPU and/or OS.
diff --git a/llvm/tools/llvm-gsymutil/Opts.td b/llvm/tools/llvm-gsymutil/Opts.td
index 00f903c5211f..d61b418d2d84 100644
--- a/llvm/tools/llvm-gsymutil/Opts.td
+++ b/llvm/tools/llvm-gsymutil/Opts.td
@@ -18,6 +18,7 @@ defm 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.">;
+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]>;
defm arch :
diff --git a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
index 4d441465c47f..aed4ae7c615f 100644
--- a/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
+++ b/llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
@@ -64,12 +64,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- constexpr llvm::StringLiteral NAME##_init[] = VALUE; \
- constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \
- NAME##_init, std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
const opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -79,7 +80,8 @@ const opt::OptTable::Info InfoTable[] = {
class GSYMUtilOptTable : public llvm::opt::GenericOptTable {
public:
- GSYMUtilOptTable() : GenericOptTable(InfoTable) {
+ GSYMUtilOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
@@ -97,6 +99,7 @@ static bool Quiet;
static std::vector<uint64_t> LookupAddresses;
static bool LookupAddressesFromStdin;
static bool StoreMergedFunctionInfo = false;
+static bool LoadDwarfCallSites = false;
static std::string CallSiteYamlPath;
static void parseArgs(int argc, char **argv) {
@@ -189,6 +192,8 @@ static void parseArgs(int argc, char **argv) {
std::exit(1);
}
}
+
+ LoadDwarfCallSites = Args.hasArg(OPT_dwarf_callsites);
}
/// @}
@@ -363,7 +368,7 @@ static llvm::Error handleObjectFile(ObjectFile &Obj, const std::string &OutFile,
// Make a DWARF transformer object and populate the ranges of the code
// so we don't end up adding invalid functions to GSYM data.
- DwarfTransformer DT(*DICtx, Gsym);
+ DwarfTransformer DT(*DICtx, Gsym, LoadDwarfCallSites);
if (!TextRanges.empty())
Gsym.SetValidTextRanges(TextRanges);
diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp
index b76ea8dec0c9..e12016c51e90 100644
--- a/llvm/tools/llvm-ifs/llvm-ifs.cpp
+++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp
@@ -59,12 +59,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -74,7 +75,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class IFSOptTable : public opt::GenericOptTable {
public:
- IFSOptTable() : opt::GenericOptTable(InfoTable) {
+ IFSOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
index 5271fdb55659..6db78926101f 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 a8c804a459e3..6aa89413b723 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 2c60c802293a..2fc56c9fcc72 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 ccc152dc753b..646d4cef01a5 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -30,6 +30,7 @@
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
+#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
#include "llvm/ExecutionEngine/Orc/MachO.h"
@@ -90,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"),
@@ -365,7 +370,7 @@ static raw_ostream &
operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
OS << "Symbols:\n";
for (auto &SKV : SIM)
- OS << " \"" << SKV.first() << "\" " << SKV.second << "\n";
+ OS << " \"" << SKV.first << "\" " << SKV.second << "\n";
return OS;
}
@@ -399,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()))
@@ -416,8 +422,8 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
continue;
if (Sym->getLinkage() == Linkage::Weak) {
- if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
- S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
+ if (!S.CanonicalWeakDefs.count(*Sym->getName()) ||
+ S.CanonicalWeakDefs[*Sym->getName()] != G.getName()) {
LLVM_DEBUG({
dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
});
@@ -426,18 +432,18 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
LLVM_DEBUG({
dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
});
- if (S.HarnessExternals.count(Sym->getName()))
+ if (S.HarnessExternals.count(*Sym->getName()))
Sym->setScope(Scope::Default);
else
Sym->setScope(Scope::Hidden);
Sym->setLinkage(Linkage::Strong);
}
- } else if (S.HarnessExternals.count(Sym->getName())) {
+ } else if (S.HarnessExternals.count(*Sym->getName())) {
LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
Sym->setScope(Scope::Default);
Sym->setLive(true);
continue;
- } else if (S.HarnessDefinitions.count(Sym->getName())) {
+ } else if (S.HarnessDefinitions.count(*Sym->getName())) {
LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
DefinitionsToRemove.push_back(Sym);
}
@@ -449,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");
@@ -739,8 +749,7 @@ getTestObjectFileInterface(Session &S, MemoryBufferRef O) {
!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
continue;
- auto InternedName = S.ES.intern(*Name);
- I->SymbolFlags[InternedName] = std::move(*SymFlags);
+ I->SymbolFlags[S.ES.intern(*Name)] = std::move(*SymFlags);
}
return I;
@@ -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
}
@@ -949,41 +958,18 @@ public:
}
};
-static void handleLazyCallFailure() {
- dbgs() << "ERROR: failure to materialize lazy call-through target.\n";
- exit(1);
-}
-
-static void *reenter(void *Ctx, void *TrampolineAddr) {
- std::promise<void *> LandingAddressP;
- auto LandingAddressF = LandingAddressP.get_future();
-
- auto *EPCIU = static_cast<EPCIndirectionUtils *>(Ctx);
- EPCIU->getLazyCallThroughManager().resolveTrampolineLandingAddress(
- ExecutorAddr::fromPtr(TrampolineAddr), [&](ExecutorAddr LandingAddress) {
- LandingAddressP.set_value(LandingAddress.toPtr<void *>());
- });
- return LandingAddressF.get();
-}
-
Expected<std::unique_ptr<Session::LazyLinkingSupport>>
-createLazyLinkingSupport(ObjectLinkingLayer &OLL) {
- auto EPCIU = EPCIndirectionUtils::Create(OLL.getExecutionSession());
- if (!EPCIU)
- return EPCIU.takeError();
- if (auto Err = (*EPCIU)
- ->writeResolverBlock(ExecutorAddr::fromPtr(&reenter),
- ExecutorAddr::fromPtr(EPCIU->get()))
- .takeError())
- return Err;
- (*EPCIU)->createLazyCallThroughManager(
- OLL.getExecutionSession(), ExecutorAddr::fromPtr(handleLazyCallFailure));
+createLazyLinkingSupport(ObjectLinkingLayer &OLL, JITDylib &PlatformJD) {
auto RSMgr = JITLinkRedirectableSymbolManager::Create(OLL);
if (!RSMgr)
return RSMgr.takeError();
- return std::make_unique<Session::LazyLinkingSupport>(std::move(*EPCIU),
- std::move(*RSMgr), OLL);
+ auto LRMgr = createJITLinkLazyReexportsManager(OLL, **RSMgr, PlatformJD);
+ if (!LRMgr)
+ return LRMgr.takeError();
+
+ return std::make_unique<Session::LazyLinkingSupport>(std::move(*RSMgr),
+ std::move(*LRMgr), OLL);
}
Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
@@ -1007,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();
@@ -1020,7 +1017,8 @@ Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
S->Features = std::move(Features);
if (lazyLinkingRequested()) {
- if (auto LazyLinking = createLazyLinkingSupport(S->ObjLayer))
+ if (auto LazyLinking =
+ createLazyLinkingSupport(S->ObjLayer, *S->PlatformJD))
S->LazyLinking = std::move(*LazyLinking);
else
return LazyLinking.takeError();
@@ -1243,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())) {
@@ -1252,18 +1251,29 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
return Error::success();
});
+ PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) {
+ std::lock_guard<std::mutex> Lock(M);
+ ++ActiveLinks;
+ return Error::success();
+ });
PassConfig.PrePrunePasses.push_back(
[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();
});
if (AddSelfRelocations)
PassConfig.PostPrunePasses.push_back(addSelfRelocations);
+
+ PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
+ std::lock_guard<std::mutex> Lock(M);
+ if (--ActiveLinks == 0)
+ ActiveLinksCV.notify_all();
+ return Error::success();
+ });
}
Expected<JITDylib *> Session::getOrLoadDynamicLibrary(StringRef LibPath) {
@@ -1306,9 +1316,9 @@ Error Session::FileInfo::registerGOTEntry(
auto TS = GetSymbolTarget(G, Sym.getBlock());
if (!TS)
return TS.takeError();
- GOTEntryInfos[TS->getName()] = {Sym.getSymbolContent(),
- Sym.getAddress().getValue(),
- Sym.getTargetFlags()};
+ GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),
+ Sym.getAddress().getValue(),
+ Sym.getTargetFlags()};
return Error::success();
}
@@ -1322,7 +1332,7 @@ Error Session::FileInfo::registerStubEntry(
if (!TS)
return TS.takeError();
- SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[TS->getName()];
+ SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];
Entry.insert(Entry.begin(),
{Sym.getSymbolContent(), Sym.getAddress().getValue(),
Sym.getTargetFlags()});
@@ -1340,7 +1350,7 @@ Error Session::FileInfo::registerMultiStubEntry(
if (!Target)
return Target.takeError();
- SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[Target->getName()];
+ SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];
Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),
Sym.getTargetFlags());
@@ -1485,15 +1495,16 @@ Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
return GOTInfoItr->second;
}
-bool Session::isSymbolRegistered(StringRef SymbolName) {
+bool Session::isSymbolRegistered(const orc::SymbolStringPtr &SymbolName) {
return SymbolInfos.count(SymbolName);
}
Expected<Session::MemoryRegionInfo &>
-Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) {
+Session::findSymbolInfo(const orc::SymbolStringPtr &SymbolName,
+ Twine ErrorMsgStem) {
auto SymInfoItr = SymbolInfos.find(SymbolName);
if (SymInfoItr == SymbolInfos.end())
- return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName +
+ return make_error<StringError>(ErrorMsgStem + ": symbol " + *SymbolName +
" not found",
inconvertibleErrorCode());
return SymInfoItr->second;
@@ -1622,6 +1633,40 @@ 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());
+ }
+
// Only one of -oop-executor and -oop-executor-connect can be used.
if (!!OutOfProcessExecutor.getNumOccurrences() &&
!!OutOfProcessExecutorConnect.getNumOccurrences())
@@ -1641,10 +1686,17 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
OutOfProcessExecutor = OOPExecutorPath.str().str();
}
- if (lazyLinkingRequested() && !TestHarnesses.empty())
- return make_error<StringError>(
- "Lazy linking cannot be used with -harness mode",
- inconvertibleErrorCode());
+ // If lazy linking is requested then check compatibility with other options.
+ if (lazyLinkingRequested()) {
+ if (OrcRuntime.empty())
+ return make_error<StringError>("Lazy linking requries the ORC runtime",
+ inconvertibleErrorCode());
+
+ if (!TestHarnesses.empty())
+ return make_error<StringError>(
+ "Lazy linking cannot be used with -harness mode",
+ inconvertibleErrorCode());
+ }
return Error::success();
}
@@ -1719,12 +1771,13 @@ static Error addAbsoluteSymbols(Session &S,
AbsDefStmt + "\"",
inconvertibleErrorCode());
ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);
- if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}})))
+ auto InternedName = S.ES.intern(Name);
+ if (auto Err = JD.define(absoluteSymbols({{InternedName, AbsDef}})))
return Err;
// Register the absolute symbol with the session symbol infos.
- S.SymbolInfos[Name] = {ArrayRef<char>(), Addr,
- AbsDef.getFlags().getTargetFlags()};
+ S.SymbolInfos[std::move(InternedName)] =
+ {ArrayRef<char>(), Addr, AbsDef.getFlags().getTargetFlags()};
}
return Error::success();
@@ -2327,14 +2380,18 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
if (CheckFiles.empty())
return Error::success();
+ S.waitForFilesLinkedFromEntryPointFile();
+
LLVM_DEBUG(dbgs() << "Running checks...\n");
auto IsSymbolValid = [&S](StringRef Symbol) {
- return S.isSymbolRegistered(Symbol);
+ auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
+ return S.isSymbolRegistered(InternedSymbol);
};
auto GetSymbolInfo = [&S](StringRef Symbol) {
- return S.findSymbolInfo(Symbol, "Can not get symbol info");
+ auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
+ return S.findSymbolInfo(InternedSymbol, "Can not get symbol info");
};
auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h
index 40fac2fe6888..be3710971729 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h
@@ -15,9 +15,9 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
-#include "llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/RedirectionManager.h"
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
@@ -33,20 +33,14 @@ namespace llvm {
struct Session {
struct LazyLinkingSupport {
- LazyLinkingSupport(std::unique_ptr<orc::EPCIndirectionUtils> EPCIU,
- std::unique_ptr<orc::RedirectableSymbolManager> RSMgr,
+ LazyLinkingSupport(std::unique_ptr<orc::RedirectableSymbolManager> RSMgr,
+ std::unique_ptr<orc::LazyReexportsManager> LRMgr,
orc::ObjectLinkingLayer &ObjLinkingLayer)
- : EPCIU(std::move(EPCIU)), RSMgr(std::move(RSMgr)),
- LazyObjLinkingLayer(ObjLinkingLayer,
- this->EPCIU->getLazyCallThroughManager(),
- *this->RSMgr) {}
- ~LazyLinkingSupport() {
- if (auto Err = EPCIU->cleanup())
- LazyObjLinkingLayer.getExecutionSession().reportError(std::move(Err));
- }
-
- std::unique_ptr<orc::EPCIndirectionUtils> EPCIU;
+ : RSMgr(std::move(RSMgr)), LRMgr(std::move(LRMgr)),
+ LazyObjLinkingLayer(ObjLinkingLayer, *this->LRMgr) {}
+
std::unique_ptr<orc::RedirectableSymbolManager> RSMgr;
+ std::unique_ptr<orc::LazyReexportsManager> LRMgr;
orc::LazyObjectLinkingLayer LazyObjLinkingLayer;
};
@@ -67,6 +61,16 @@ struct Session {
void modifyPassConfig(jitlink::LinkGraph &G,
jitlink::PassConfiguration &PassConfig);
+ /// For -check: wait for all files that are referenced (transitively) from
+ /// the entry point *file* to be linked. (ORC's usual dependence tracking is
+ /// to fine-grained here: a lookup of the main symbol will return as soon as
+ /// all reachable symbols have been linked, but testcases may want to
+ /// inspect side-effects in unreachable symbols)..
+ void waitForFilesLinkedFromEntryPointFile() {
+ std::unique_lock<std::mutex> Lock(M);
+ return ActiveLinksCV.wait(Lock, [this]() { return ActiveLinks == 0; });
+ }
+
using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo;
struct FileInfo {
@@ -78,7 +82,6 @@ struct Session {
using LinkGraph = jitlink::LinkGraph;
using GetSymbolTargetFunction =
unique_function<Expected<Symbol &>(LinkGraph &G, jitlink::Block &)>;
-
Error registerGOTEntry(LinkGraph &G, Symbol &Sym,
GetSymbolTargetFunction GetSymbolTarget);
Error registerStubEntry(LinkGraph &G, Symbol &Sym,
@@ -88,7 +91,7 @@ struct Session {
};
using DynLibJDMap = std::map<std::string, orc::JITDylib *, std::less<>>;
- using SymbolInfoMap = StringMap<MemoryRegionInfo>;
+ using SymbolInfoMap = DenseMap<orc::SymbolStringPtr, MemoryRegionInfo>;
using FileInfoMap = StringMap<FileInfo>;
Expected<orc::JITDylib *> getOrLoadDynamicLibrary(StringRef LibPath);
@@ -111,12 +114,15 @@ struct Session {
Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
StringRef TargetName);
- bool isSymbolRegistered(StringRef Name);
- Expected<MemoryRegionInfo &> findSymbolInfo(StringRef SymbolName,
+ bool isSymbolRegistered(const orc::SymbolStringPtr &Name);
+ Expected<MemoryRegionInfo &> findSymbolInfo(const orc::SymbolStringPtr &Name,
Twine ErrorMsgStem);
DynLibJDMap DynLibJDs;
+ std::mutex M;
+ std::condition_variable ActiveLinksCV;
+ size_t ActiveLinks = 0;
SymbolInfoMap SymbolInfos;
FileInfoMap FileInfos;
diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index 3d3f3f0af4b7..94247118dc4e 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -48,12 +48,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -63,7 +64,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class LibtoolDarwinOptTable : public opt::GenericOptTable {
public:
- LibtoolDarwinOptTable() : GenericOptTable(InfoTable) {}
+ LibtoolDarwinOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp
index 711a9185e155..3c0197e8b7ba 100644
--- a/llvm/tools/llvm-lipo/llvm-lipo.cpp
+++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp
@@ -72,12 +72,13 @@ enum LipoID {
};
namespace lipo {
-#define PREFIX(NAME, VALUE) \
- static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \
- static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \
- NAME##_init, std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "LipoOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "LipoOpts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info LipoInfoTable[] = {
@@ -89,7 +90,9 @@ static constexpr opt::OptTable::Info LipoInfoTable[] = {
class LipoOptTable : public opt::GenericOptTable {
public:
- LipoOptTable() : opt::GenericOptTable(lipo::LipoInfoTable) {}
+ LipoOptTable()
+ : opt::GenericOptTable(lipo::OptionStrTable, lipo::OptionPrefixesTable,
+ lipo::LipoInfoTable) {}
};
enum class LipoAction {
diff --git a/llvm/tools/llvm-mc/Disassembler.cpp b/llvm/tools/llvm-mc/Disassembler.cpp
index a588058437ec..16897054fbea 100644
--- a/llvm/tools/llvm-mc/Disassembler.cpp
+++ b/llvm/tools/llvm-mc/Disassembler.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Disassembler.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -94,10 +95,8 @@ static bool SkipToToken(StringRef &Str) {
}
}
-
-static bool ByteArrayFromString(ByteArrayTy &ByteArray,
- StringRef &Str,
- SourceMgr &SM) {
+static bool byteArrayFromString(ByteArrayTy &ByteArray, StringRef &Str,
+ SourceMgr &SM, bool HexBytes) {
while (SkipToToken(Str)) {
// Handled by higher level
if (Str[0] == '[' || Str[0] == ']')
@@ -109,7 +108,24 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
// Convert to a byte and add to the byte vector.
unsigned ByteVal;
- if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
+ if (HexBytes) {
+ if (Next < 2) {
+ SM.PrintMessage(SMLoc::getFromPointer(Value.data()),
+ SourceMgr::DK_Error, "expected two hex digits");
+ Str = Str.substr(Next);
+ return true;
+ }
+ Next = 2;
+ unsigned C0 = hexDigitValue(Value[0]);
+ unsigned C1 = hexDigitValue(Value[1]);
+ if (C0 == -1u || C1 == -1u) {
+ SM.PrintMessage(SMLoc::getFromPointer(Value.data()),
+ SourceMgr::DK_Error, "invalid input token");
+ Str = Str.substr(Next);
+ return true;
+ }
+ ByteVal = C0 * 16 + C1;
+ } else if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
// If we have an error, print it and skip to the end of line.
SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error,
"invalid input token");
@@ -130,9 +146,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
int Disassembler::disassemble(const Target &T, const std::string &Triple,
MCSubtargetInfo &STI, MCStreamer &Streamer,
MemoryBuffer &Buffer, SourceMgr &SM,
- MCContext &Ctx,
- const MCTargetOptions &MCOptions) {
-
+ MCContext &Ctx, const MCTargetOptions &MCOptions,
+ bool HexBytes) {
std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
if (!MRI) {
errs() << "error: no register info for target " << Triple << "\n";
@@ -153,9 +168,6 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
return -1;
}
- // Set up initial section manually here
- Streamer.initSections(false, STI);
-
bool ErrorOccurred = false;
// Convert the input to a vector for disassembly.
@@ -188,7 +200,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
}
// It's a real token, get the bytes and emit them
- ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);
+ ErrorOccurred |= byteArrayFromString(ByteArray, Str, SM, HexBytes);
if (!ByteArray.first.empty())
ErrorOccurred |=
diff --git a/llvm/tools/llvm-mc/Disassembler.h b/llvm/tools/llvm-mc/Disassembler.h
index d0226abadc63..5efffca1e992 100644
--- a/llvm/tools/llvm-mc/Disassembler.h
+++ b/llvm/tools/llvm-mc/Disassembler.h
@@ -32,7 +32,7 @@ public:
static int disassemble(const Target &T, const std::string &Triple,
MCSubtargetInfo &STI, MCStreamer &Streamer,
MemoryBuffer &Buffer, SourceMgr &SM, MCContext &Ctx,
- const MCTargetOptions &MCOptions);
+ const MCTargetOptions &MCOptions, bool HexBytes);
};
} // namespace llvm
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index 898d79b9233b..70f92d09aded 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -94,6 +94,12 @@ static cl::opt<bool>
cl::desc("Prefer hex format for immediate values"),
cl::cat(MCCategory));
+static cl::opt<bool>
+ HexBytes("hex",
+ cl::desc("Take raw hexadecimal bytes as input for disassembly. "
+ "Whitespace is ignored"),
+ cl::cat(MCCategory));
+
static cl::list<std::string>
DefineSymbol("defsym",
cl::desc("Defines a symbol to be an integer constant"),
@@ -563,7 +569,7 @@ int main(int argc, char **argv) {
: MAB->createObjectWriter(*OS),
std::unique_ptr<MCCodeEmitter>(CE), *STI));
if (NoExecStack)
- Str->initSections(true, *STI);
+ Str->switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr,
VersionTuple());
}
@@ -592,7 +598,7 @@ int main(int argc, char **argv) {
}
if (disassemble)
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer,
- SrcMgr, Ctx, MCOptions);
+ SrcMgr, Ctx, MCOptions, HexBytes);
// Keep output if no errors.
if (Res == 0) {
diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp
index db69109e2d1f..1aa41096002e 100644
--- a/llvm/tools/llvm-ml/llvm-ml.cpp
+++ b/llvm/tools/llvm-ml/llvm-ml.cpp
@@ -58,12 +58,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -73,7 +74,9 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class MLOptTable : public opt::GenericOptTable {
public:
- MLOptTable() : opt::GenericOptTable(InfoTable, /*IgnoreCase=*/false) {}
+ MLOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
+ /*IgnoreCase=*/false) {}
};
} // namespace
diff --git a/llvm/tools/llvm-mt/llvm-mt.cpp b/llvm/tools/llvm-mt/llvm-mt.cpp
index 8b793b877642..3bd1bc786f86 100644
--- a/llvm/tools/llvm-mt/llvm-mt.cpp
+++ b/llvm/tools/llvm-mt/llvm-mt.cpp
@@ -40,12 +40,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -56,7 +57,9 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class CvtResOptTable : public opt::GenericOptTable {
public:
- CvtResOptTable() : opt::GenericOptTable(InfoTable, true) {}
+ CvtResOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
+ true) {}
};
} // namespace
diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index d3e8d4c5ed98..e7c3e36dd38d 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -65,12 +65,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -80,7 +81,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class NmOptTable : public opt::GenericOptTable {
public:
- NmOptTable() : opt::GenericOptTable(InfoTable) {
+ NmOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 104d802b1e1e..0925fc55317f 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -39,12 +39,13 @@ enum ObjcopyID {
};
namespace objcopy_opt {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "ObjcopyOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "ObjcopyOpts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info ObjcopyInfoTable[] = {
#define OPTION(...) \
@@ -56,7 +57,10 @@ static constexpr opt::OptTable::Info ObjcopyInfoTable[] = {
class ObjcopyOptTable : public opt::GenericOptTable {
public:
- ObjcopyOptTable() : opt::GenericOptTable(objcopy_opt::ObjcopyInfoTable) {
+ ObjcopyOptTable()
+ : opt::GenericOptTable(objcopy_opt::OptionStrTable,
+ objcopy_opt::OptionPrefixesTable,
+ objcopy_opt::ObjcopyInfoTable) {
setGroupedShortOptions(true);
setDashDashParsing(true);
}
@@ -71,13 +75,13 @@ enum InstallNameToolID {
};
namespace install_name_tool {
+#define OPTTABLE_STR_TABLE_CODE
+#include "InstallNameToolOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_PREFIXES_TABLE_CODE
#include "InstallNameToolOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = {
#define OPTION(...) \
@@ -90,7 +94,9 @@ static constexpr opt::OptTable::Info InstallNameToolInfoTable[] = {
class InstallNameToolOptTable : public opt::GenericOptTable {
public:
InstallNameToolOptTable()
- : GenericOptTable(install_name_tool::InstallNameToolInfoTable) {}
+ : GenericOptTable(install_name_tool::OptionStrTable,
+ install_name_tool::OptionPrefixesTable,
+ install_name_tool::InstallNameToolInfoTable) {}
};
enum BitcodeStripID {
@@ -102,13 +108,13 @@ enum BitcodeStripID {
};
namespace bitcode_strip {
+#define OPTTABLE_STR_TABLE_CODE
+#include "BitcodeStripOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_PREFIXES_TABLE_CODE
#include "BitcodeStripOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = {
#define OPTION(...) \
@@ -121,7 +127,9 @@ static constexpr opt::OptTable::Info BitcodeStripInfoTable[] = {
class BitcodeStripOptTable : public opt::GenericOptTable {
public:
BitcodeStripOptTable()
- : opt::GenericOptTable(bitcode_strip::BitcodeStripInfoTable) {}
+ : opt::GenericOptTable(bitcode_strip::OptionStrTable,
+ bitcode_strip::OptionPrefixesTable,
+ bitcode_strip::BitcodeStripInfoTable) {}
};
enum StripID {
@@ -132,12 +140,13 @@ enum StripID {
};
namespace strip {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
+#include "StripOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
#include "StripOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info StripInfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(STRIP_, __VA_ARGS__),
@@ -148,7 +157,9 @@ static constexpr opt::OptTable::Info StripInfoTable[] = {
class StripOptTable : public opt::GenericOptTable {
public:
- StripOptTable() : GenericOptTable(strip::StripInfoTable) {
+ StripOptTable()
+ : GenericOptTable(strip::OptionStrTable, strip::OptionPrefixesTable,
+ strip::StripInfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 5ac13495662f..d78cf485587e 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -17,7 +17,6 @@
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/llvm/tools/llvm-objdump/SourcePrinter.cpp b/llvm/tools/llvm-objdump/SourcePrinter.cpp
index 600bd6aa4d51..061e4c0bd87c 100644
--- a/llvm/tools/llvm-objdump/SourcePrinter.cpp
+++ b/llvm/tools/llvm-objdump/SourcePrinter.cpp
@@ -15,10 +15,7 @@
#include "SourcePrinter.h"
#include "llvm-objdump.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
-#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/FormatVariadic.h"
#define DEBUG_TYPE "objdump"
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 2e8a8c82b890..92f9ee4fb9f9 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -18,7 +18,6 @@
#include "llvm/Demangle/Demangle.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 246d5cfa0581..93fed8ee8e6f 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -27,12 +27,10 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/DebugInfo/BTF/BTFParser.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/Debuginfod/BuildIDFetcher.h"
#include "llvm/Debuginfod/Debuginfod.h"
@@ -40,7 +38,6 @@
#include "llvm/Demangle/Demangle.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -50,7 +47,6 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
-#include "llvm/Object/Archive.h"
#include "llvm/Object/BuildID.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
@@ -59,7 +55,6 @@
#include "llvm/Object/FaultMapParser.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Option/Arg.h"
@@ -99,10 +94,11 @@ namespace {
class CommonOptTable : public opt::GenericOptTable {
public:
- CommonOptTable(ArrayRef<Info> OptionInfos, const char *Usage,
+ CommonOptTable(const char *StrTable, ArrayRef<unsigned> PrefixesTable,
+ ArrayRef<Info> OptionInfos, const char *Usage,
const char *Description)
- : opt::GenericOptTable(OptionInfos), Usage(Usage),
- Description(Description) {
+ : opt::GenericOptTable(StrTable, PrefixesTable, OptionInfos),
+ Usage(Usage), Description(Description) {
setGroupedShortOptions(true);
}
@@ -121,12 +117,13 @@ private:
// ObjdumpOptID is in ObjdumpOptID.h
namespace objdump_opt {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "ObjdumpOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "ObjdumpOpts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info ObjdumpInfoTable[] = {
#define OPTION(...) \
@@ -139,9 +136,10 @@ static constexpr opt::OptTable::Info ObjdumpInfoTable[] = {
class ObjdumpOptTable : public CommonOptTable {
public:
ObjdumpOptTable()
- : CommonOptTable(objdump_opt::ObjdumpInfoTable,
- " [options] <input object files>",
- "llvm object file dumper") {}
+ : CommonOptTable(
+ objdump_opt::OptionStrTable, objdump_opt::OptionPrefixesTable,
+ objdump_opt::ObjdumpInfoTable, " [options] <input object files>",
+ "llvm object file dumper") {}
};
enum OtoolOptID {
@@ -152,12 +150,13 @@ enum OtoolOptID {
};
namespace otool {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
+#include "OtoolOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
#include "OtoolOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info OtoolInfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OTOOL_, __VA_ARGS__),
@@ -169,7 +168,8 @@ static constexpr opt::OptTable::Info OtoolInfoTable[] = {
class OtoolOptTable : public CommonOptTable {
public:
OtoolOptTable()
- : CommonOptTable(otool::OtoolInfoTable, " [option...] [file...]",
+ : CommonOptTable(otool::OptionStrTable, otool::OptionPrefixesTable,
+ otool::OtoolInfoTable, " [option...] [file...]",
"Mach-O object file displaying tool") {}
};
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index debaedd33429..7253cc3f4d91 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -15,8 +15,6 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/FormattedStream.h"
#include <functional>
#include <memory>
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 1d9d7bcf7654..ffc481f07185 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -21,6 +21,7 @@
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/ProfileData/MemProf.h"
#include "llvm/ProfileData/MemProfReader.h"
+#include "llvm/ProfileData/MemProfYAML.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/ProfileData/SampleProfWriter.h"
@@ -723,6 +724,43 @@ loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
return;
}
+ using ::llvm::memprof::YAMLMemProfReader;
+ if (YAMLMemProfReader::hasFormat(Input.Filename)) {
+ auto ReaderOrErr = YAMLMemProfReader::create(Input.Filename);
+ if (!ReaderOrErr)
+ exitWithError(ReaderOrErr.takeError(), Input.Filename);
+ std::unique_ptr<YAMLMemProfReader> Reader = std::move(ReaderOrErr.get());
+ // Check if the profile types can be merged, e.g. clang frontend profiles
+ // should not be merged with memprof profiles.
+ if (Error E = WC->Writer.mergeProfileKind(Reader->getProfileKind())) {
+ consumeError(std::move(E));
+ WC->Errors.emplace_back(
+ make_error<StringError>(
+ "Cannot merge MemProf profile with incompatible profile.",
+ std::error_code()),
+ Filename);
+ return;
+ }
+
+ auto MemProfError = [&](Error E) {
+ auto [ErrorCode, Msg] = InstrProfError::take(std::move(E));
+ WC->Errors.emplace_back(make_error<InstrProfError>(ErrorCode, Msg),
+ Filename);
+ };
+
+ auto MemProfData = Reader->takeMemProfData();
+
+ // Check for the empty input in case the YAML file is invalid.
+ if (MemProfData.Records.empty()) {
+ WC->Errors.emplace_back(
+ make_error<StringError>("The profile is empty.", std::error_code()),
+ Filename);
+ }
+
+ WC->Writer.addMemProfData(std::move(MemProfData), MemProfError);
+ return;
+ }
+
auto FS = vfs::getRealFileSystem();
// TODO: This only saves the first non-fatal error from InstrProfReader, and
// then added to WriterContext::Errors. However, this is not extensible, if
@@ -3242,18 +3280,38 @@ static int showSampleProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
static int showMemProfProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
if (SFormat == ShowFormat::Json)
exitWithError("JSON output is not supported for MemProf");
- auto ReaderOr = llvm::memprof::RawMemProfReader::create(
- Filename, ProfiledBinary, /*KeepNames=*/true);
- if (Error E = ReaderOr.takeError())
- // Since the error can be related to the profile or the binary we do not
- // pass whence. Instead additional context is provided where necessary in
- // the error message.
- exitWithError(std::move(E), /*Whence*/ "");
-
- std::unique_ptr<llvm::memprof::RawMemProfReader> Reader(
- ReaderOr.get().release());
-
- Reader->printYAML(OS);
+
+ // Show the raw profile in YAML.
+ if (memprof::RawMemProfReader::hasFormat(Filename)) {
+ auto ReaderOr = llvm::memprof::RawMemProfReader::create(
+ Filename, ProfiledBinary, /*KeepNames=*/true);
+ if (Error E = ReaderOr.takeError()) {
+ // Since the error can be related to the profile or the binary we do not
+ // pass whence. Instead additional context is provided where necessary in
+ // the error message.
+ exitWithError(std::move(E), /*Whence*/ "");
+ }
+
+ std::unique_ptr<llvm::memprof::RawMemProfReader> Reader(
+ ReaderOr.get().release());
+
+ Reader->printYAML(OS);
+ return 0;
+ }
+
+ // Show the indexed MemProf profile in YAML.
+ auto FS = vfs::getRealFileSystem();
+ auto ReaderOrErr = IndexedInstrProfReader::create(Filename, *FS);
+ if (Error E = ReaderOrErr.takeError())
+ exitWithError(std::move(E), Filename);
+
+ auto Reader = std::move(ReaderOrErr.get());
+ memprof::AllMemProfData Data = Reader->getAllMemProfData();
+ // Construct yaml::Output with the maximum column width of 80 so that each
+ // Frame fits in one line.
+ yaml::Output Yout(OS, nullptr, 80);
+ Yout << Data;
+
return 0;
}
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index 4bc9d9009557..a77188c462af 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -57,12 +57,13 @@ enum ID {
};
namespace rc_opt {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -73,7 +74,10 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class RcOptTable : public opt::GenericOptTable {
public:
- RcOptTable() : GenericOptTable(rc_opt::InfoTable, /* IgnoreCase = */ true) {}
+ RcOptTable()
+ : GenericOptTable(rc_opt::OptionStrTable, rc_opt::OptionPrefixesTable,
+ rc_opt::InfoTable,
+ /* IgnoreCase = */ true) {}
};
enum Windres_ID {
@@ -84,12 +88,13 @@ enum Windres_ID {
};
namespace windres_opt {
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
+#include "WindresOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
#include "WindresOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) \
@@ -102,7 +107,10 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class WindresOptTable : public opt::GenericOptTable {
public:
WindresOptTable()
- : GenericOptTable(windres_opt::InfoTable, /* IgnoreCase = */ false) {}
+ : GenericOptTable(windres_opt::OptionStrTable,
+ windres_opt::OptionPrefixesTable,
+ windres_opt::InfoTable,
+ /* IgnoreCase = */ false) {}
};
static ExitOnError ExitOnErr;
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index bb8ec41d8745..bfca65aad52b 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -6057,6 +6057,7 @@ const NoteType CoreNoteTypes[] = {
{ELF::NT_ARM_ZA, "NT_ARM_ZA (AArch64 SME ZA registers)"},
{ELF::NT_ARM_ZT, "NT_ARM_ZT (AArch64 SME ZT registers)"},
{ELF::NT_ARM_FPMR, "NT_ARM_FPMR (AArch64 Floating Point Mode Register)"},
+ {ELF::NT_ARM_GCS, "NT_ARM_GCS (AArch64 Guarded Control Stack state)"},
{ELF::NT_FILE, "NT_FILE (mapped files)"},
{ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"},
diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index 46b510cfb06a..6a099c08e1ac 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -723,7 +723,12 @@ const EnumEntry<XCOFF::CFileLangId> CFileLangIdClass[] = {
const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
#define ECase(X) \
{ #X, XCOFF::X }
- ECase(TCPU_PPC64), ECase(TCPU_COM), ECase(TCPU_970)
+ ECase(TCPU_INVALID), ECase(TCPU_PPC), ECase(TCPU_PPC64), ECase(TCPU_COM),
+ ECase(TCPU_PWR), ECase(TCPU_ANY), ECase(TCPU_601), ECase(TCPU_603),
+ ECase(TCPU_604), ECase(TCPU_620), ECase(TCPU_A35), ECase(TCPU_970),
+ ECase(TCPU_PWR5), ECase(TCPU_PWR6), ECase(TCPU_PWR5X), ECase(TCPU_PWR6E),
+ ECase(TCPU_PWR7), ECase(TCPU_PWR8), ECase(TCPU_PWR9), ECase(TCPU_PWR10),
+ ECase(TCPU_PWRX)
#undef ECase
};
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 3e76cda2dd43..2f77e5d35055 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -59,12 +59,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -74,7 +75,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class ReadobjOptTable : public opt::GenericOptTable {
public:
- ReadobjOptTable() : opt::GenericOptTable(InfoTable) {
+ ReadobjOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
index 04282d3e4877..b5574ea41e33 100644
--- a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
+++ b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
@@ -45,12 +45,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "TapiOpts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "TapiOpts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -60,7 +61,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class TAPIOptTable : public opt::GenericOptTable {
public:
- TAPIOptTable() : opt::GenericOptTable(InfoTable) {
+ TAPIOptTable()
+ : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
index 5f0697f5aaad..40bc6b180fb8 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
@@ -65,7 +65,7 @@ static bool shouldNotRemoveInstruction(const TargetInstrInfo &TII,
static void extractInstrFromFunction(Oracle &O, MachineFunction &MF) {
MachineDominatorTree MDT;
- MDT.calculate(MF);
+ MDT.recalculate(MF);
auto MRI = &MF.getRegInfo();
SetVector<MachineInstr *> ToDelete;
diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp
index 4a1b0e879036..0d7bf2483267 100644
--- a/llvm/tools/llvm-size/llvm-size.cpp
+++ b/llvm/tools/llvm-size/llvm-size.cpp
@@ -45,12 +45,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -60,7 +61,10 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class SizeOptTable : public opt::GenericOptTable {
public:
- SizeOptTable() : GenericOptTable(InfoTable) { setGroupedShortOptions(true); }
+ SizeOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
+ setGroupedShortOptions(true);
+ }
};
enum OutputFormatTy { berkeley, sysv, darwin };
diff --git a/llvm/tools/llvm-split/llvm-split.cpp b/llvm/tools/llvm-split/llvm-split.cpp
index c456403e6bc6..1b1f97f44e27 100644
--- a/llvm/tools/llvm-split/llvm-split.cpp
+++ b/llvm/tools/llvm-split/llvm-split.cpp
@@ -67,7 +67,7 @@ static cl::opt<std::string>
cl::value_desc("triple"), cl::cat(SplitCategory));
static cl::opt<std::string>
- MCPU("mcpu", cl::desc("Target CPU, ignored if -mtriple is not used"),
+ MCPU("mcpu", cl::desc("Target CPU, ignored if --mtriple is not used"),
cl::value_desc("cpu"), cl::cat(SplitCategory));
int main(int argc, char **argv) {
@@ -125,11 +125,11 @@ int main(int argc, char **argv) {
if (TM) {
if (PreserveLocals) {
- errs() << "warning: -preserve-locals has no effect when using "
+ errs() << "warning: --preserve-locals has no effect when using "
"TargetMachine::splitModule\n";
}
if (RoundRobin)
- errs() << "warning: -round-robin has no effect when using "
+ errs() << "warning: --round-robin has no effect when using "
"TargetMachine::splitModule\n";
if (TM->splitModule(*M, NumOutputs, HandleModulePart))
diff --git a/llvm/tools/llvm-strings/llvm-strings.cpp b/llvm/tools/llvm-strings/llvm-strings.cpp
index d4305096b60a..9979b93de842 100644
--- a/llvm/tools/llvm-strings/llvm-strings.cpp
+++ b/llvm/tools/llvm-strings/llvm-strings.cpp
@@ -38,12 +38,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -54,7 +55,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class StringsOptTable : public opt::GenericOptTable {
public:
- StringsOptTable() : GenericOptTable(InfoTable) {
+ StringsOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
setDashDashParsing(true);
}
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 3e41a85d6469..3ba7f59d5b84 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -56,12 +56,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -72,7 +73,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class SymbolizerOptTable : public opt::GenericOptTable {
public:
- SymbolizerOptTable() : GenericOptTable(InfoTable) {
+ SymbolizerOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
setGroupedShortOptions(true);
}
};
diff --git a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
index a091e37ff402..ca0b42472219 100644
--- a/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
+++ b/llvm/tools/llvm-tli-checker/llvm-tli-checker.cpp
@@ -33,12 +33,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
using namespace llvm::opt;
static constexpr opt::OptTable::Info InfoTable[] = {
@@ -49,7 +50,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class TLICheckerOptTable : public opt::GenericOptTable {
public:
- TLICheckerOptTable() : GenericOptTable(InfoTable) {}
+ TLICheckerOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // end anonymous namespace
diff --git a/llvm/tools/sancov/sancov.cpp b/llvm/tools/sancov/sancov.cpp
index 39feff62391f..727b94b8477c 100644
--- a/llvm/tools/sancov/sancov.cpp
+++ b/llvm/tools/sancov/sancov.cpp
@@ -67,12 +67,13 @@ enum ID {
#undef OPTION
};
-#define PREFIX(NAME, VALUE) \
- static constexpr StringLiteral NAME##_init[] = VALUE; \
- static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
- std::size(NAME##_init) - 1);
+#define OPTTABLE_STR_TABLE_CODE
#include "Opts.inc"
-#undef PREFIX
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
@@ -82,7 +83,8 @@ static constexpr opt::OptTable::Info InfoTable[] = {
class SancovOptTable : public opt::GenericOptTable {
public:
- SancovOptTable() : GenericOptTable(InfoTable) {}
+ SancovOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
};
} // namespace