summaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/dsymutil/DwarfLinkerForBinary.cpp4
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp4
-rw-r--r--llvm/tools/gold/gold-plugin.cpp5
-rw-r--r--llvm/tools/llvm-as/llvm-as.cpp8
-rw-r--r--llvm/tools/llvm-c-test/debuginfo.c77
-rw-r--r--llvm/tools/llvm-c-test/echo.cpp22
-rw-r--r--llvm/tools/llvm-c-test/llvm-c-test.h2
-rw-r--r--llvm/tools/llvm-c-test/main.c7
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp2
-rw-r--r--llvm/tools/llvm-cov/CoverageReport.cpp29
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.cpp3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp220
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.h4
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewText.cpp3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewText.h3
-rw-r--r--llvm/tools/llvm-dis/llvm-dis.cpp2
-rw-r--r--llvm/tools/llvm-dwarfdump/Statistics.cpp80
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp4
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp2
-rw-r--r--llvm/tools/llvm-exegesis/CMakeLists.txt20
-rw-r--r--llvm/tools/llvm-exegesis/llvm-exegesis.cpp20
-rw-r--r--llvm/tools/llvm-link/llvm-link.cpp14
-rw-r--r--llvm/tools/llvm-mc/llvm-mc.cpp7
-rw-r--r--llvm/tools/llvm-mca/CodeRegion.h8
-rw-r--r--llvm/tools/llvm-ml/llvm-ml.cpp4
-rw-r--r--llvm/tools/llvm-nm/llvm-nm.cpp3
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp5
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp4
-rw-r--r--llvm/tools/llvm-profdata/llvm-profdata.cpp44
-rw-r--r--llvm/tools/llvm-profgen/PerfReader.cpp139
-rw-r--r--llvm/tools/llvm-profgen/PerfReader.h34
-rw-r--r--llvm/tools/llvm-profgen/ProfiledBinary.cpp7
-rw-r--r--llvm/tools/llvm-profgen/ProfiledBinary.h11
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp78
-rw-r--r--llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp2
-rw-r--r--llvm/tools/opt/optdriver.cpp1
37 files changed, 643 insertions, 242 deletions
diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
index 83473704398d..f6a35708dc07 100644
--- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
+++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp
@@ -147,7 +147,7 @@ DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
if (!ObjectEntry) {
auto Err = ObjectEntry.takeError();
reportWarning(Twine(Obj.getObjectFilename()) + ": " +
- toString(std::move(Err)),
+ toStringWithoutConsuming(Err),
Obj.getObjectFilename());
return errorToErrorCode(std::move(Err));
}
@@ -156,7 +156,7 @@ DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj,
if (!Object) {
auto Err = Object.takeError();
reportWarning(Twine(Obj.getObjectFilename()) + ": " +
- toString(std::move(Err)),
+ toStringWithoutConsuming(Err),
Obj.getObjectFilename());
return errorToErrorCode(std::move(Err));
}
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index 8e144d640ed0..e2ec8cae2285 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -381,7 +381,6 @@ bool generateDsymCompanion(
auto &Writer = static_cast<MachObjectWriter &>(MCAsm.getWriter());
// Layout but don't emit.
- ObjectStreamer.flushPendingLabels();
MCAsmLayout Layout(MCAsm);
MCAsm.layout(Layout);
@@ -630,9 +629,6 @@ bool generateDsymCompanion(
// Emit the Dwarf sections contents.
for (const MCSection &Sec : MCAsm) {
- if (Sec.begin() == Sec.end())
- continue;
-
uint64_t Pos = OutFile.tell();
OutFile.write_zeros(alignTo(Pos, Sec.getAlign()) - Pos);
MCAsm.writeSectionData(OutFile, &Sec, Layout);
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 265ebcbff587..0b175a3852e4 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -307,7 +307,8 @@ namespace options {
} else if (opt.consume_front("opt-remarks-hotness-threshold=")) {
auto ResultOrErr = remarks::parseHotnessThresholdOption(opt);
if (!ResultOrErr)
- message(LDPL_FATAL, "Invalid remarks hotness threshold: %s", opt);
+ message(LDPL_FATAL, "Invalid remarks hotness threshold: %s",
+ opt.data());
else
RemarksHotnessThreshold = *ResultOrErr;
} else if (opt.consume_front("opt-remarks-format=")) {
@@ -319,7 +320,7 @@ namespace options {
} else if (opt.consume_front("time-trace-granularity=")) {
unsigned Granularity;
if (opt.getAsInteger(10, Granularity))
- message(LDPL_FATAL, "Invalid time trace granularity: %s", opt);
+ message(LDPL_FATAL, "Invalid time trace granularity: %s", opt.data());
else
time_trace_granularity = Granularity;
} else {
diff --git a/llvm/tools/llvm-as/llvm-as.cpp b/llvm/tools/llvm-as/llvm-as.cpp
index e48e3f4d22c1..082565a9ef3d 100644
--- a/llvm/tools/llvm-as/llvm-as.cpp
+++ b/llvm/tools/llvm-as/llvm-as.cpp
@@ -67,6 +67,7 @@ static cl::opt<std::string> ClDataLayout("data-layout",
cl::desc("data layout string to use"),
cl::value_desc("layout-string"),
cl::init(""), cl::cat(AsCat));
+extern cl::opt<bool> UseNewDbgInfoFormat;
extern bool WriteNewDbgInfoFormatToBitcode;
static void WriteOutputFile(const Module *M, const ModuleSummaryIndex *Index) {
@@ -142,11 +143,10 @@ int main(int argc, char **argv) {
}
// Convert to new debug format if requested.
- assert(!M->IsNewDbgInfoFormat && "Unexpectedly in new debug mode");
- if (UseNewDbgInfoFormat && WriteNewDbgInfoFormatToBitcode) {
- M->convertToNewDbgValues();
+ M->setIsNewDbgInfoFormat(UseNewDbgInfoFormat &&
+ WriteNewDbgInfoFormatToBitcode);
+ if (M->IsNewDbgInfoFormat)
M->removeDebugIntrinsicDeclarations();
- }
std::unique_ptr<ModuleSummaryIndex> Index = std::move(ModuleAndIndex.Index);
diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c
index 35c65f885af3..49c90f5b87b8 100644
--- a/llvm/tools/llvm-c-test/debuginfo.c
+++ b/llvm/tools/llvm-c-test/debuginfo.c
@@ -29,10 +29,13 @@ declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
return Decl;
}
-int llvm_test_dibuilder(bool NewDebugInfoFormat) {
+int llvm_test_dibuilder(void) {
const char *Filename = "debuginfo.c";
LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
- LLVMSetIsNewDbgInfoFormat(M, NewDebugInfoFormat);
+
+ LLVMSetIsNewDbgInfoFormat(M, true);
+ assert(LLVMIsNewDbgInfoFormat(M));
+
LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
@@ -137,38 +140,24 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) {
LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
42, Int64Ty, true, 0);
- if (LLVMIsNewDbgInfoFormat(M))
- LLVMDIBuilderInsertDeclareAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
- FooParamExpression, FooParamLocation, FooEntryBlock);
- else
- LLVMDIBuilderInsertDeclareIntrinsicAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
- FooParamExpression, FooParamLocation, FooEntryBlock);
+ LLVMDIBuilderInsertDeclareRecordAtEnd(
+ DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
+ FooParamExpression, FooParamLocation, FooEntryBlock);
+
LLVMMetadataRef FooParamVar2 =
LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
42, Int64Ty, true, 0);
- if (LLVMIsNewDbgInfoFormat(M))
- LLVMDIBuilderInsertDeclareAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
- FooParamExpression, FooParamLocation, FooEntryBlock);
- else
- LLVMDIBuilderInsertDeclareIntrinsicAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
- FooParamExpression, FooParamLocation, FooEntryBlock);
-
- LLVMMetadataRef FooParamVar3 =
- LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "c", 1, 3, File,
- 42, VectorTy, true, 0);
- if (LLVMIsNewDbgInfoFormat(M))
- LLVMDIBuilderInsertDeclareAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
- FooParamExpression, FooParamLocation, FooEntryBlock);
- else
- LLVMDIBuilderInsertDeclareIntrinsicAtEnd(
- DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
- FooParamExpression, FooParamLocation, FooEntryBlock);
+ LLVMDIBuilderInsertDeclareRecordAtEnd(
+ DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
+ FooParamExpression, FooParamLocation, FooEntryBlock);
+
+ LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(
+ DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0);
+
+ LLVMDIBuilderInsertDeclareRecordAtEnd(
+ DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
+ FooParamExpression, FooParamLocation, FooEntryBlock);
LLVMSetSubprogram(FooFunction, FunctionMetadata);
@@ -185,12 +174,9 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) {
LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
LLVMMetadataRef FooVarValueExpr =
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
- if (LLVMIsNewDbgInfoFormat(M))
- LLVMDIBuilderInsertDbgValueRecordAtEnd(
- DIB, FooVal1, FooVar1, FooVarValueExpr, FooVarsLocation, FooVarBlock);
- else
- LLVMDIBuilderInsertDbgValueIntrinsicAtEnd(
- DIB, FooVal1, FooVar1, FooVarValueExpr, FooVarsLocation, FooVarBlock);
+
+ LLVMDIBuilderInsertDbgValueRecordAtEnd(DIB, FooVal1, FooVar1, FooVarValueExpr,
+ FooVarsLocation, FooVarBlock);
LLVMMetadataRef MacroFile =
LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);
@@ -228,7 +214,24 @@ int llvm_test_dibuilder(bool NewDebugInfoFormat) {
LLVMPositionBuilderAtEnd(Builder, FooVarBlock);
LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);
LLVMValueRef Zero = LLVMConstInt(I64, 0, false);
- LLVMBuildRet(Builder, Zero);
+ LLVMValueRef Ret = LLVMBuildRet(Builder, Zero);
+
+ // Insert a `phi` before the `ret`. In the new debug info mode we need to
+ // be careful to insert before debug records too, else the debug records
+ // will come before the `phi` (and be absorbed onto it) which is an invalid
+ // state.
+ LLVMValueRef InsertPos = LLVMGetFirstInstruction(FooVarBlock);
+ LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, InsertPos);
+ LLVMValueRef Phi1 = LLVMBuildPhi(Builder, I64, "p1");
+ LLVMAddIncoming(Phi1, &Zero, &FooEntryBlock, 1);
+ // Do the same again using the other position-setting function.
+ LLVMPositionBuilderBeforeDbgRecords(Builder, FooVarBlock, InsertPos);
+ LLVMValueRef Phi2 = LLVMBuildPhi(Builder, I64, "p2");
+ LLVMAddIncoming(Phi2, &Zero, &FooEntryBlock, 1);
+ // Insert a non-phi before the `ret` but not before the debug records to
+ // test that works as expected.
+ LLVMPositionBuilder(Builder, FooVarBlock, Ret);
+ LLVMBuildAdd(Builder, Phi1, Phi2, "a");
char *MStr = LLVMPrintModuleToString(M);
puts(MStr);
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 518716168c42..6fa36421810f 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -157,8 +157,26 @@ struct TypeCloner {
return LLVMX86MMXTypeInContext(Ctx);
case LLVMTokenTypeKind:
return LLVMTokenTypeInContext(Ctx);
- case LLVMTargetExtTypeKind:
- assert(false && "Implement me");
+ case LLVMTargetExtTypeKind: {
+ const char *Name = LLVMGetTargetExtTypeName(Src);
+ unsigned NumTypeParams = LLVMGetTargetExtTypeNumTypeParams(Src);
+ unsigned NumIntParams = LLVMGetTargetExtTypeNumIntParams(Src);
+
+ SmallVector<LLVMTypeRef, 4> TypeParams((size_t)NumTypeParams);
+ SmallVector<unsigned, 4> IntParams((size_t)NumIntParams);
+
+ for (unsigned i = 0; i < TypeParams.size(); i++)
+ TypeParams[i] = Clone(LLVMGetTargetExtTypeTypeParam(Src, i));
+
+ for (unsigned i = 0; i < IntParams.size(); i++)
+ IntParams[i] = LLVMGetTargetExtTypeIntParam(Src, i);
+
+ LLVMTypeRef TargetExtTy = LLVMTargetExtTypeInContext(
+ Ctx, Name, TypeParams.data(), TypeParams.size(), IntParams.data(),
+ IntParams.size());
+
+ return TargetExtTy;
+ }
}
fprintf(stderr, "%d is not a supported typekind\n", Kind);
diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index c50d3cce8674..00566660257e 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -36,7 +36,7 @@ int llvm_calc(void);
int llvm_disassemble(void);
// debuginfo.c
-int llvm_test_dibuilder(bool NewDebugInfoFormat);
+int llvm_test_dibuilder(void);
int llvm_get_di_tag(void);
int llvm_di_type_get_name(void);
diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index 9db6e05d6350..8be9ea06fc68 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -110,11 +110,8 @@ int main(int argc, char **argv) {
} else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) {
return llvm_test_diagnostic_handler();
} else if (argc == 2 &&
- !strcmp(argv[1], "--test-dibuilder-old-debuginfo-format")) {
- return llvm_test_dibuilder(false);
- } else if (argc == 2 &&
- !strcmp(argv[1], "--test-dibuilder-new-debuginfo-format")) {
- return llvm_test_dibuilder(true);
+ !strcmp(argv[1], "--test-dibuilder-debuginfo-format")) {
+ return llvm_test_dibuilder();
} else {
print_usage();
}
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 1e5bfbe5c3aa..75028ac0bb50 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -515,7 +515,7 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) {
if (!PathRemappings)
return;
- // Convert remapping paths to native paths with trailing seperators.
+ // Convert remapping paths to native paths with trailing separators.
auto nativeWithTrailing = [](StringRef Path) -> std::string {
if (Path.empty())
return "";
diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp
index 49a35f2a943e..00aea4039bfd 100644
--- a/llvm/tools/llvm-cov/CoverageReport.cpp
+++ b/llvm/tools/llvm-cov/CoverageReport.cpp
@@ -102,8 +102,25 @@ void adjustColumnWidths(ArrayRef<StringRef> Files,
/// Prints a horizontal divider long enough to cover the given column
/// widths.
-void renderDivider(ArrayRef<size_t> ColumnWidths, raw_ostream &OS) {
- size_t Length = std::accumulate(ColumnWidths.begin(), ColumnWidths.end(), 0);
+void renderDivider(raw_ostream &OS, const CoverageViewOptions &Options, bool isFileReport) {
+ size_t Length;
+ if (isFileReport) {
+ Length = std::accumulate(std::begin(FileReportColumns), std::end(FileReportColumns), 0);
+ if (!Options.ShowRegionSummary)
+ Length -= (FileReportColumns[1] + FileReportColumns[2] + FileReportColumns[3]);
+ if (!Options.ShowInstantiationSummary)
+ Length -= (FileReportColumns[7] + FileReportColumns[8] + FileReportColumns[9]);
+ if (!Options.ShowBranchSummary)
+ Length -= (FileReportColumns[13] + FileReportColumns[14] + FileReportColumns[15]);
+ if (!Options.ShowMCDCSummary)
+ Length -= (FileReportColumns[16] + FileReportColumns[17] + FileReportColumns[18]);
+ } else {
+ Length = std::accumulate(std::begin(FunctionReportColumns), std::end(FunctionReportColumns), 0);
+ if (!Options.ShowBranchSummary)
+ Length -= (FunctionReportColumns[7] + FunctionReportColumns[8] + FunctionReportColumns[9]);
+ if (!Options.ShowMCDCSummary)
+ Length -= (FunctionReportColumns[10] + FunctionReportColumns[11] + FunctionReportColumns[12]);
+ }
for (size_t I = 0; I < Length; ++I)
OS << '-';
}
@@ -405,7 +422,7 @@ void CoverageReport::renderFunctionReports(ArrayRef<std::string> Files,
<< column("Miss", FunctionReportColumns[11], Column::RightAlignment)
<< column("Cover", FunctionReportColumns[12], Column::RightAlignment);
OS << "\n";
- renderDivider(FunctionReportColumns, OS);
+ renderDivider(OS, Options, false);
OS << "\n";
FunctionCoverageSummary Totals("TOTAL");
for (const auto &F : Functions) {
@@ -418,7 +435,7 @@ void CoverageReport::renderFunctionReports(ArrayRef<std::string> Files,
render(Function, DC, OS);
}
if (Totals.ExecutionCount) {
- renderDivider(FunctionReportColumns, OS);
+ renderDivider(OS, Options, false);
OS << "\n";
render(Totals, DC, OS);
}
@@ -544,7 +561,7 @@ void CoverageReport::renderFileReports(
Column::RightAlignment)
<< column("Cover", FileReportColumns[18], Column::RightAlignment);
OS << "\n";
- renderDivider(FileReportColumns, OS);
+ renderDivider(OS, Options, true);
OS << "\n";
std::vector<const FileCoverageSummary *> EmptyFiles;
@@ -563,7 +580,7 @@ void CoverageReport::renderFileReports(
render(*FCS, OS);
}
- renderDivider(FileReportColumns, OS);
+ renderDivider(OS, Options, true);
OS << "\n";
render(Totals, OS);
}
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index 45bddd728446..ce55e3abf23b 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -203,8 +203,7 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
if (ShowSourceName)
renderSourceName(OS, WholeFile);
- renderTableHeader(OS, (ViewDepth > 0) ? 0 : getFirstUncoveredLineNo(),
- ViewDepth);
+ renderTableHeader(OS, ViewDepth);
// We need the expansions, instantiations, and branches sorted so we can go
// through them while we iterate lines.
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index a874f7c6820d..d255f8c200b2 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -262,8 +262,7 @@ protected:
virtual void renderTitle(raw_ostream &OS, StringRef CellText) = 0;
/// Render the table header for a given source file.
- virtual void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo,
- unsigned IndentLevel) = 0;
+ virtual void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) = 0;
/// @}
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index d4b2ea3594fc..6f4d327679d6 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -88,6 +88,113 @@ const char *BeginHeader =
"<meta name='viewport' content='width=device-width,initial-scale=1'>"
"<meta charset='UTF-8'>";
+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"});
+ }
+
+ }
+
+ 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 {
+ 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
+ return last;
+ } else {
+ return undefined;
+ }
+ }
+ }
+
+ 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) {
+ next_uncovered("td.uncovered-line", reverse)
+}
+
+function next_region(reverse) {
+ next_uncovered("span.red.region", 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);
+ }
+ if (event.code == "KeyB") {
+ next_branch(reverse);
+ }
+ if (event.code == "KeyR") {
+ next_region(reverse);
+ }
+
+});
+)javascript";
+
const char *CSSForCoverage =
R"(.red {
background-color: #f004;
@@ -95,6 +202,9 @@ const char *CSSForCoverage =
.cyan {
background-color: cyan;
}
+html {
+ scroll-behavior: smooth;
+}
body {
font-family: -apple-system, sans-serif;
}
@@ -171,6 +281,18 @@ table {
text-align: right;
color: #d00;
}
+.uncovered-line.selected {
+ color: #f00;
+ font-weight: bold;
+}
+.region.red.selected {
+ background-color: #f008;
+ font-weight: bold;
+}
+.branch.red.selected {
+ background-color: #f008;
+ font-weight: bold;
+}
.tooltip {
position: relative;
display: inline;
@@ -231,12 +353,19 @@ tr:hover {
tr:last-child {
border-bottom: none;
}
-tr:has(> td >a:target) {
- background-color: #50f6;
+tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) {
+ background-color: #8884;
}
a {
color: inherit;
}
+.control {
+ position: fixed;
+ top: 0em;
+ right: 0em;
+ padding: 1em;
+ background: #FFF8;
+}
@media (prefers-color-scheme: dark) {
body {
background-color: #222;
@@ -254,6 +383,12 @@ a {
.tooltip {
background-color: #068;
}
+ .control {
+ background: #2228;
+ }
+ tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) {
+ background-color: #8884;
+ }
}
)";
@@ -298,8 +433,18 @@ std::string getPathToStyle(StringRef ViewPath) {
return PathToStyle + "style.css";
}
+std::string getPathToJavaScript(StringRef ViewPath) {
+ std::string PathToJavaScript;
+ std::string PathSep = std::string(sys::path::get_separator());
+ unsigned NumSeps = ViewPath.count(PathSep);
+ for (unsigned I = 0, E = NumSeps; I < E; ++I)
+ PathToJavaScript += ".." + PathSep;
+ return PathToJavaScript + "control.js";
+}
+
void emitPrelude(raw_ostream &OS, const CoverageViewOptions &Opts,
- const std::string &PathToStyle = "") {
+ const std::string &PathToStyle = "",
+ const std::string &PathToJavaScript = "") {
OS << "<!doctype html>"
"<html>"
<< BeginHeader;
@@ -311,6 +456,12 @@ void emitPrelude(raw_ostream &OS, const CoverageViewOptions &Opts,
OS << "<link rel='stylesheet' type='text/css' href='"
<< escape(PathToStyle, Opts) << "'>";
+ // Link to a JavaScript if one is available
+ if (PathToJavaScript.empty())
+ OS << "<script>" << JSForCoverage << "</script>";
+ else
+ OS << "<script src='" << escape(PathToJavaScript, Opts) << "'></script>";
+
OS << EndHeader << "<body>";
}
@@ -390,7 +541,8 @@ CoveragePrinterHTML::createViewFile(StringRef Path, bool InToplevel) {
emitPrelude(*OS.get(), Opts);
} else {
std::string ViewPath = getOutputPath(Path, "html", InToplevel);
- emitPrelude(*OS.get(), Opts, getPathToStyle(ViewPath));
+ emitPrelude(*OS.get(), Opts, getPathToStyle(ViewPath),
+ getPathToJavaScript(ViewPath));
}
return std::move(OS);
@@ -442,6 +594,17 @@ Error CoveragePrinterHTML::emitStyleSheet() {
return Error::success();
}
+Error CoveragePrinterHTML::emitJavaScript() {
+ auto JSOrErr = createOutputStream("control", "js", /*InToplevel=*/true);
+ if (Error E = JSOrErr.takeError())
+ return E;
+
+ OwnedStream JS = std::move(JSOrErr.get());
+ JS->operator<<(JSForCoverage);
+
+ return Error::success();
+}
+
void CoveragePrinterHTML::emitReportHeader(raw_ostream &OSRef,
const std::string &Title) {
// Emit some basic information about the coverage report.
@@ -487,6 +650,10 @@ Error CoveragePrinterHTML::createIndexFile(
if (Error E = emitStyleSheet())
return E;
+ // Emit the JavaScript UI implementation
+ if (Error E = emitJavaScript())
+ return E;
+
// Emit a file index along with some coverage statistics.
auto OSOrErr = createOutputStream("index", "html", /*InToplevel=*/true);
if (Error E = OSOrErr.takeError())
@@ -495,7 +662,7 @@ Error CoveragePrinterHTML::createIndexFile(
raw_ostream &OSRef = *OS.get();
assert(Opts.hasOutputDirectory() && "No output directory for index file");
- emitPrelude(OSRef, Opts, getPathToStyle(""));
+ emitPrelude(OSRef, Opts, getPathToStyle(""), getPathToJavaScript(""));
emitReportHeader(OSRef, "Coverage Report");
@@ -561,7 +728,8 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport {
auto IndexHtmlPath = Printer.getOutputPath((LCPath + "index").str(), "html",
/*InToplevel=*/false);
- emitPrelude(OSRef, Options, getPathToStyle(IndexHtmlPath));
+ emitPrelude(OSRef, Options, getPathToStyle(IndexHtmlPath),
+ getPathToJavaScript(IndexHtmlPath));
auto NavLink = buildTitleLinks(LCPath);
Printer.emitReportHeader(OSRef, "Coverage Report (" + NavLink + ")");
@@ -699,6 +867,10 @@ Error CoveragePrinterHTMLDirectory::createIndexFile(
if (Error E = emitStyleSheet())
return E;
+ // Emit the JavaScript UI implementation
+ if (Error E = emitJavaScript())
+ return E;
+
// Emit index files in every subdirectory.
Reporter Report(*this, Coverage, Filters);
auto TotalsOrErr = Report.prepareDirectoryReports(SourceFiles);
@@ -800,7 +972,10 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L,
auto Highlight = [&](const std::string &Snippet, unsigned LC, unsigned RC) {
if (getOptions().Debug)
HighlightedRanges.emplace_back(LC, RC);
- return tag("span", Snippet, std::string(*Color));
+ if (Snippet.empty())
+ return tag("span", Snippet, std::string(*Color));
+ else
+ return tag("span", Snippet, "region " + std::string(*Color));
};
auto CheckIfUncovered = [&](const CoverageSegment *S) {
@@ -883,7 +1058,9 @@ void SourceCoverageViewHTML::renderLineCoverageColumn(
if (Line.isMapped())
Count = tag("pre", formatCount(Line.getExecutionCount()));
std::string CoverageClass =
- (Line.getExecutionCount() > 0) ? "covered-line" : "uncovered-line";
+ (Line.getExecutionCount() > 0)
+ ? "covered-line"
+ : (Line.isMapped() ? "uncovered-line" : "skipped-line");
OS << tag("td", Count, CoverageClass);
}
@@ -957,7 +1134,7 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
}
// Display TrueCount or TruePercent.
- std::string TrueColor = R.ExecutionCount ? "None" : "red";
+ std::string TrueColor = R.ExecutionCount ? "None" : "red branch";
std::string TrueCovClass =
(R.ExecutionCount > 0) ? "covered-line" : "uncovered-line";
@@ -969,7 +1146,7 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
OS << format("%0.2f", TruePercent) << "%, ";
// Display FalseCount or FalsePercent.
- std::string FalseColor = R.FalseExecutionCount ? "None" : "red";
+ std::string FalseColor = R.FalseExecutionCount ? "None" : "red branch";
std::string FalseCovClass =
(R.FalseExecutionCount > 0) ? "covered-line" : "uncovered-line";
@@ -1053,24 +1230,21 @@ void SourceCoverageViewHTML::renderTitle(raw_ostream &OS, StringRef Title) {
if (getOptions().hasCreatedTime())
OS << tag(CreatedTimeTag,
escape(getOptions().CreatedTimeStr, getOptions()));
+
+ OS << tag("span",
+ a("javascript:next_line()", "next uncovered line (L)") + ", " +
+ a("javascript:next_region()", "next uncovered region (R)") +
+ ", " +
+ a("javascript:next_branch()", "next uncovered branch (B)"),
+ "control");
}
void SourceCoverageViewHTML::renderTableHeader(raw_ostream &OS,
- unsigned FirstUncoveredLineNo,
unsigned ViewDepth) {
- std::string SourceLabel;
- if (FirstUncoveredLineNo == 0) {
- SourceLabel = tag("td", tag("pre", "Source"));
- } else {
- std::string LinkTarget = "#L" + utostr(uint64_t(FirstUncoveredLineNo));
- SourceLabel =
- tag("td", tag("pre", "Source (" +
- a(LinkTarget, "jump to first uncovered line") +
- ")"));
- }
+ std::string Links;
renderLinePrefix(OS, ViewDepth);
- OS << tag("td", tag("pre", "Line")) << tag("td", tag("pre", "Count"))
- << SourceLabel;
+ OS << tag("td", tag("pre", "Line")) << tag("td", tag("pre", "Count"));
+ OS << tag("td", tag("pre", "Source" + Links));
renderLineSuffix(OS, ViewDepth);
}
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
index 32313a3963c4..9b7391d0043e 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
@@ -38,6 +38,7 @@ public:
protected:
Error emitStyleSheet();
+ Error emitJavaScript();
void emitReportHeader(raw_ostream &OSRef, const std::string &Title);
private:
@@ -105,8 +106,7 @@ class SourceCoverageViewHTML : public SourceCoverageView {
void renderTitle(raw_ostream &OS, StringRef Title) override;
- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo,
- unsigned IndentLevel) override;
+ void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) override;
public:
SourceCoverageViewHTML(StringRef SourceName, const MemoryBuffer &File,
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
index 580da45ecfc0..cab60c2d9034 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
@@ -414,5 +414,4 @@ void SourceCoverageViewText::renderTitle(raw_ostream &OS, StringRef Title) {
<< getOptions().CreatedTimeStr << "\n";
}
-void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned,
- unsigned) {}
+void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned) {}
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.h b/llvm/tools/llvm-cov/SourceCoverageViewText.h
index 7cb47fcbf42b..25a161b09620 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.h
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.h
@@ -93,8 +93,7 @@ class SourceCoverageViewText : public SourceCoverageView {
void renderTitle(raw_ostream &OS, StringRef Title) override;
- void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo,
- unsigned IndentLevel) override;
+ void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) override;
public:
SourceCoverageViewText(StringRef SourceName, const MemoryBuffer &File,
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index fbbb5506e43e..d28af85bc739 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -258,7 +258,7 @@ int main(int argc, char **argv) {
// All that llvm-dis does is write the assembly to a file.
if (!DontPrint) {
if (M) {
- ScopedDbgInfoFormatSetter FormatSetter(*M, WriteNewDbgInfoFormat);
+ M->setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (WriteNewDbgInfoFormat)
M->removeDebugIntrinsicDeclarations();
M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
diff --git a/llvm/tools/llvm-dwarfdump/Statistics.cpp b/llvm/tools/llvm-dwarfdump/Statistics.cpp
index 1846f9265c75..8d6dd17ceae9 100644
--- a/llvm/tools/llvm-dwarfdump/Statistics.cpp
+++ b/llvm/tools/llvm-dwarfdump/Statistics.cpp
@@ -8,6 +8,7 @@
#include "llvm-dwarfdump.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
@@ -188,6 +189,16 @@ struct LocationStats {
/// Total number of local variables processed.
SaturatingUINT64 NumVar = 0;
};
+
+/// Holds accumulated debug line statistics across all CUs.
+struct LineStats {
+ SaturatingUINT64 NumBytes = 0;
+ SaturatingUINT64 NumLineZeroBytes = 0;
+ SaturatingUINT64 NumEntries = 0;
+ SaturatingUINT64 NumIsStmtEntries = 0;
+ SaturatingUINT64 NumUniqueEntries = 0;
+ SaturatingUINT64 NumUniqueNonZeroEntries = 0;
+};
} // namespace
/// Collect debug location statistics for one DIE.
@@ -848,6 +859,7 @@ bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
StringRef FormatName = Obj.getFileFormatName();
GlobalStats GlobalStats;
LocationStats LocStats;
+ LineStats LnStats;
StringMap<PerFunctionStats> Statistics;
// This variable holds variable information for functions with
// abstract_origin globally, across all CUs.
@@ -856,6 +868,14 @@ bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
// abstract_origin.
FunctionDIECUTyMap AbstractOriginFnCUs;
CrossCUReferencingDIELocationTy CrossCUReferencesToBeResolved;
+ // Tuple representing a single source code position in the line table. Fields
+ // are respectively: Line, Col, File, where 'File' is an index into the Files
+ // vector below.
+ using LineTuple = std::tuple<uint32_t, uint16_t, uint16_t>;
+ SmallVector<std::string> Files;
+ DenseSet<LineTuple> UniqueLines;
+ DenseSet<LineTuple> UniqueNonZeroLines;
+
for (const auto &CU : static_cast<DWARFContext *>(&DICtx)->compile_units()) {
if (DWARFDie CUDie = CU->getNonSkeletonUnitDIE(false)) {
// This variable holds variable information for functions with
@@ -882,8 +902,58 @@ bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
CrossCUReferencesToBeResolved.push_back(
DIELocation(CUDie.getDwarfUnit(), CrossCUReferencingDIEOffset));
}
+ const auto *LineTable = DICtx.getLineTableForUnit(CU.get());
+ std::optional<uint64_t> LastFileIdxOpt;
+ if (LineTable)
+ LastFileIdxOpt = LineTable->getLastValidFileIndex();
+ if (LastFileIdxOpt) {
+ // Each CU has its own file index; in order to track unique line entries
+ // across CUs, we therefore need to map each CU file index to a global
+ // file index, which we store here.
+ DenseMap<uint64_t, uint16_t> CUFileMapping;
+ for (uint64_t FileIdx = 0; FileIdx <= *LastFileIdxOpt; ++FileIdx) {
+ std::string File;
+ if (LineTable->getFileNameByIndex(
+ FileIdx, CU->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ File)) {
+ auto ExistingFile = llvm::find(Files, File);
+ if (ExistingFile != Files.end()) {
+ CUFileMapping[FileIdx] = std::distance(Files.begin(), ExistingFile);
+ } else {
+ CUFileMapping[FileIdx] = Files.size();
+ Files.push_back(File);
+ }
+ }
+ }
+ for (const auto &Seq : LineTable->Sequences) {
+ LnStats.NumBytes += Seq.HighPC - Seq.LowPC;
+ // Ignore the `end_sequence` entry, since it's not interesting for us.
+ LnStats.NumEntries += Seq.LastRowIndex - Seq.FirstRowIndex - 1;
+ for (size_t RowIdx = Seq.FirstRowIndex; RowIdx < Seq.LastRowIndex - 1;
+ ++RowIdx) {
+ auto Entry = LineTable->Rows[RowIdx];
+ if (Entry.IsStmt)
+ LnStats.NumIsStmtEntries += 1;
+ assert(CUFileMapping.contains(Entry.File) &&
+ "Should have been collected earlier!");
+ uint16_t MappedFile = CUFileMapping[Entry.File];
+ UniqueLines.insert({Entry.Line, Entry.Column, MappedFile});
+ if (Entry.Line != 0) {
+ UniqueNonZeroLines.insert({Entry.Line, Entry.Column, MappedFile});
+ } else {
+ auto EntryStartAddress = Entry.Address.Address;
+ auto EntryEndAddress = LineTable->Rows[RowIdx + 1].Address.Address;
+ LnStats.NumLineZeroBytes += EntryEndAddress - EntryStartAddress;
+ }
+ }
+ }
+ }
}
+ LnStats.NumUniqueEntries = UniqueLines.size();
+ LnStats.NumUniqueNonZeroEntries = UniqueNonZeroLines.size();
+
/// Resolve CrossCU references.
collectZeroLocCovForVarsWithCrossCUReferencingAbstractOrigin(
LocStats, AbstractOriginFnCUs, GlobalAbstractOriginFnInfo,
@@ -1043,6 +1113,16 @@ bool dwarfdump::collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
printLocationStats(J, "#local vars", LocStats.LocalVarLocStats);
printLocationStats(J, "#local vars - entry values",
LocStats.LocalVarNonEntryValLocStats);
+
+ // Print line statistics for the object file.
+ printDatum(J, "#bytes with line information", LnStats.NumBytes.Value);
+ printDatum(J, "#bytes with line-0 locations", LnStats.NumLineZeroBytes.Value);
+ printDatum(J, "#line entries", LnStats.NumEntries.Value);
+ printDatum(J, "#line entries (is_stmt)", LnStats.NumIsStmtEntries.Value);
+ printDatum(J, "#line entries (unique)", LnStats.NumUniqueEntries.Value);
+ printDatum(J, "#line entries (unique non-0)",
+ LnStats.NumUniqueNonZeroEntries.Value);
+
J.objectEnd();
OS << '\n';
LLVM_DEBUG(
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 2bfc9705368e..d00cf5207571 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -502,7 +502,7 @@ static void filterByAccelName(
getDies(DICtx, DICtx.getDebugNames(), Name, Dies);
}
llvm::sort(Dies);
- Dies.erase(std::unique(Dies.begin(), Dies.end()), Dies.end());
+ Dies.erase(llvm::unique(Dies), Dies.end());
DIDumpOptions DumpOpts = getDumpOpts(DICtx);
DumpOpts.GetNameForDWARFReg = GetNameForDWARFReg;
@@ -646,7 +646,7 @@ static bool collectObjectSources(ObjectFile &Obj, DWARFContext &DICtx,
// Dedup and order the sources.
llvm::sort(Sources);
- Sources.erase(std::unique(Sources.begin(), Sources.end()), Sources.end());
+ Sources.erase(llvm::unique(Sources), Sources.end());
for (StringRef Name : Sources)
OS << Name << "\n";
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 81556b3ad4bc..4c4f2a9fdf78 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -91,7 +91,7 @@ getDWOFilenames(StringRef ExecFilename) {
std::string DWOCompDir =
dwarf::toString(Die.find(dwarf::DW_AT_comp_dir), "");
if (!DWOCompDir.empty()) {
- SmallString<16> DWOPath(std::move(DWOName));
+ SmallString<16> DWOPath(DWOName);
sys::fs::make_absolute(DWOCompDir, DWOPath);
if (!sys::fs::exists(DWOPath) && sys::fs::exists(DWOName))
DWOPaths.push_back(std::move(DWOName));
diff --git a/llvm/tools/llvm-exegesis/CMakeLists.txt b/llvm/tools/llvm-exegesis/CMakeLists.txt
index ec418a7d51ec..49cb7e176c6d 100644
--- a/llvm/tools/llvm-exegesis/CMakeLists.txt
+++ b/llvm/tools/llvm-exegesis/CMakeLists.txt
@@ -1,9 +1,7 @@
+# Has side effect of defining LLVM_EXEGESIS_TARGETS
+add_subdirectory(lib)
+
set(LLVM_LINK_COMPONENTS
- AllTargetsAsmParsers
- AllTargetsCodeGens
- AllTargetsDescs
- AllTargetsDisassemblers
- AllTargetsInfos
CodeGenTypes
MC
MCParser
@@ -11,6 +9,15 @@ set(LLVM_LINK_COMPONENTS
TargetParser
)
+foreach(t ${LLVM_EXEGESIS_TARGETS})
+ string(STRIP ${t} t)
+ list(APPEND LLVM_LINK_COMPONENTS "${t}AsmParser")
+ list(APPEND LLVM_LINK_COMPONENTS "${t}CodeGen")
+ list(APPEND LLVM_LINK_COMPONENTS "${t}Desc")
+ list(APPEND LLVM_LINK_COMPONENTS "${t}Disassembler")
+ list(APPEND LLVM_LINK_COMPONENTS "${t}Info")
+endforeach()
+
add_llvm_tool(llvm-exegesis
DISABLE_LLVM_LINK_LLVM_DYLIB
llvm-exegesis.cpp
@@ -19,9 +26,6 @@ add_llvm_tool(llvm-exegesis
intrinsics_gen
)
-# Has side effect of defining LLVM_EXEGESIS_TARGETS
-add_subdirectory(lib)
-
# Link all enabled exegesis targets
set(libs)
foreach(t ${LLVM_EXEGESIS_TARGETS})
diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 06e1c7f3c1bb..e6a43cfc6db5 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -470,9 +470,11 @@ void benchmarkMain() {
#endif
}
- InitializeAllAsmPrinters();
- InitializeAllAsmParsers();
InitializeAllExegesisTargets();
+#define LLVM_EXEGESIS(TargetName) \
+ LLVMInitialize##TargetName##AsmPrinter(); \
+ LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/TargetExegesis.def"
const LLVMState State =
ExitOnErr(LLVMState::Create(TripleName, MCPU, "", UseDummyPerfCounters));
@@ -621,9 +623,11 @@ static void analysisMain() {
"and --analysis-inconsistencies-output-file must be specified");
}
- InitializeAllAsmPrinters();
- InitializeAllDisassemblers();
InitializeAllExegesisTargets();
+#define LLVM_EXEGESIS(TargetName) \
+ LLVMInitialize##TargetName##AsmPrinter(); \
+ LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/TargetExegesis.def"
auto MemoryBuffer = ExitOnFileError(
BenchmarkFile,
@@ -690,9 +694,11 @@ int main(int Argc, char **Argv) {
InitLLVM X(Argc, Argv);
// Initialize targets so we can print them when flag --version is specified.
- InitializeAllTargetInfos();
- InitializeAllTargets();
- InitializeAllTargetMCs();
+#define LLVM_EXEGESIS(TargetName) \
+ LLVMInitialize##TargetName##Target(); \
+ LLVMInitialize##TargetName##TargetInfo(); \
+ LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/TargetExegesis.def"
// Register the Target and CPU printer for --version.
cl::AddExtraVersionPrinter(sys::printDefaultTargetAndDetectedCPU);
diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp
index 7794f2d81ed0..24ee02be7e9e 100644
--- a/llvm/tools/llvm-link/llvm-link.cpp
+++ b/llvm/tools/llvm-link/llvm-link.cpp
@@ -377,9 +377,13 @@ static bool importFunctions(const char *argv0, Module &DestModule) {
if (Verbose)
errs() << "Importing " << FunctionName << " from " << FileName << "\n";
+ // `-import` specifies the `<filename,function-name>` pairs to import as
+ // definition, so make the import type definition directly.
+ // FIXME: A follow-up patch should add test coverage for import declaration
+ // in `llvm-link` CLI (e.g., by introducing a new command line option).
auto &Entry =
ImportList[FileNameStringCache.insert(FileName).first->getKey()];
- Entry.insert(F->getGUID());
+ Entry[F->getGUID()] = GlobalValueSummary::Definition;
}
auto CachedModuleLoader = [&](StringRef Identifier) {
return ModuleLoaderCache.takeModule(std::string(Identifier));
@@ -489,12 +493,6 @@ int main(int argc, char **argv) {
if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET)
LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE;
- // RemoveDIs debug-info transition: tests may request that we /try/ to use the
- // new debug-info format.
- if (TryUseNewDbgInfoFormat) {
- // Turn the new debug-info format on.
- UseNewDbgInfoFormat = true;
- }
// Since llvm-link collects multiple IR modules together, for simplicity's
// sake we disable the "PreserveInputDbgFormat" flag to enforce a single
// debug info format.
@@ -556,7 +554,7 @@ int main(int argc, char **argv) {
SetFormat(WriteNewDbgInfoFormat);
Composite->print(Out.os(), nullptr, PreserveAssemblyUseListOrder);
} else if (Force || !CheckBitcodeOutputToConsole(Out.os())) {
- SetFormat(WriteNewDbgInfoFormatToBitcode);
+ SetFormat(UseNewDbgInfoFormat && WriteNewDbgInfoFormatToBitcode);
WriteBitcodeToFile(*Composite, Out.os(), PreserveBitcodeUseListOrder);
}
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index 506e4f22ef8f..de999a48d575 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -183,10 +183,6 @@ static cl::opt<std::string> MainFileName(
cl::desc("Specifies the name we should consider the input file"),
cl::cat(MCCategory));
-static cl::opt<bool> SaveTempLabels("save-temp-labels",
- cl::desc("Don't discard temporary labels"),
- cl::cat(MCCategory));
-
static cl::opt<bool> LexMasmIntegers(
"masm-integers",
cl::desc("Enable binary and hex masm integers (0b110 and 0ABCh)"),
@@ -428,9 +424,6 @@ int main(int argc, char **argv) {
TheTarget->createMCObjectFileInfo(Ctx, PIC, LargeCodeModel));
Ctx.setObjectFileInfo(MOFI.get());
- if (SaveTempLabels)
- Ctx.setAllowTemporaryLabels(false);
-
Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
// Default to 4 for dwarf version.
unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4;
diff --git a/llvm/tools/llvm-mca/CodeRegion.h b/llvm/tools/llvm-mca/CodeRegion.h
index 5a2e8baa1f3e..ef8804f1b494 100644
--- a/llvm/tools/llvm-mca/CodeRegion.h
+++ b/llvm/tools/llvm-mca/CodeRegion.h
@@ -104,11 +104,9 @@ public:
dropInstructions(const llvm::SmallPtrSetImpl<const llvm::MCInst *> &Insts) {
if (Insts.empty())
return Instructions;
- Instructions.erase(std::remove_if(Instructions.begin(), Instructions.end(),
- [&Insts](const llvm::MCInst &Inst) {
- return Insts.contains(&Inst);
- }),
- Instructions.end());
+ llvm::erase_if(Instructions, [&Insts](const llvm::MCInst &Inst) {
+ return Insts.contains(&Inst);
+ });
return Instructions;
}
diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp
index f1f39af059aa..24643bd4296b 100644
--- a/llvm/tools/llvm-ml/llvm-ml.cpp
+++ b/llvm/tools/llvm-ml/llvm-ml.cpp
@@ -263,6 +263,7 @@ int llvm_ml_main(int Argc, char **Argv, const llvm::ToolContext &) {
MCTargetOptions MCOptions;
MCOptions.AssemblyLanguage = "masm";
MCOptions.MCFatalWarnings = InputArgs.hasArg(OPT_fatal_warnings);
+ MCOptions.MCSaveTempLabels = InputArgs.hasArg(OPT_save_temp_labels);
Triple TheTriple = GetTriple(ProgName, InputArgs);
std::string Error;
@@ -330,9 +331,6 @@ int llvm_ml_main(int Argc, char **Argv, const llvm::ToolContext &) {
Ctx, /*PIC=*/false, /*LargeCodeModel=*/true));
Ctx.setObjectFileInfo(MOFI.get());
- if (InputArgs.hasArg(OPT_save_temp_labels))
- Ctx.setAllowTemporaryLabels(false);
-
// Set compilation information.
SmallString<128> CWD;
if (!sys::fs::current_path(CWD))
diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index e3b81451fcac..d3e8d4c5ed98 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -2395,8 +2395,7 @@ exportSymbolNamesFromFiles(const std::vector<std::string> &InputFilenames) {
llvm::erase_if(SymbolList,
[](const NMSymbol &s) { return !s.shouldPrint(); });
sortSymbolList(SymbolList);
- SymbolList.erase(std::unique(SymbolList.begin(), SymbolList.end()),
- SymbolList.end());
+ SymbolList.erase(llvm::unique(SymbolList), SymbolList.end());
printExportSymbolList(SymbolList);
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 675364a1c1bc..6249be4f332b 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1570,8 +1570,7 @@ static void addSymbolizer(
LabelAddrs.insert(LabelAddrs.end(), LabelAddrsRef.begin(),
LabelAddrsRef.end());
llvm::sort(LabelAddrs);
- LabelAddrs.resize(std::unique(LabelAddrs.begin(), LabelAddrs.end()) -
- LabelAddrs.begin());
+ LabelAddrs.resize(llvm::unique(LabelAddrs) - LabelAddrs.begin());
// Add the labels.
for (unsigned LabelNum = 0; LabelNum != LabelAddrs.size(); ++LabelNum) {
auto Name = std::make_unique<std::string>();
@@ -3152,7 +3151,7 @@ void Dumper::printPrivateHeaders() {
}
static void printFileHeaders(const ObjectFile *O) {
- if (!O->isELF() && !O->isCOFF())
+ if (!O->isELF() && !O->isCOFF() && !O->isXCOFF())
reportError(O->getFileName(), "Invalid/Unsupported object file format");
Triple::ArchType AT = O->getArch();
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
index 1cecbfc463fe..b2362ecb7570 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -1494,13 +1494,13 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() {
if (auto EC = Visitor.visitSymbolStreamFiltered(ModS.getSymbolArray(),
Filter)) {
P.formatLine("Error while processing symbol records. {0}",
- toString(std::move(EC)));
+ toStringWithoutConsuming(EC));
return EC;
}
} else if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray(),
SS.Offset)) {
P.formatLine("Error while processing symbol records. {0}",
- toString(std::move(EC)));
+ toStringWithoutConsuming(EC));
return EC;
}
return Error::success();
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index fae6d1e989ab..2ce0668601bc 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -291,6 +291,11 @@ cl::opt<bool> DropProfileSymbolList(
cl::desc("Drop the profile symbol list when merging AutoFDO profiles "
"(only meaningful for -sample)"));
+cl::opt<bool> KeepVTableSymbols(
+ "keep-vtable-symbols", cl::init(false), cl::Hidden,
+ cl::sub(MergeSubcommand),
+ cl::desc("If true, keep the vtable symbols in indexed profiles"));
+
// Temporary support for writing the previous version of the format, to enable
// some forward compatibility.
// TODO: Consider enabling this with future version changes as well, to ease
@@ -767,11 +772,12 @@ static void loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
});
}
- const InstrProfSymtab &symtab = Reader->getSymtab();
- const auto &VTableNames = symtab.getVTableNames();
+ if (KeepVTableSymbols) {
+ const InstrProfSymtab &symtab = Reader->getSymtab();
+ const auto &VTableNames = symtab.getVTableNames();
- for (const auto &kv : VTableNames) {
- WC->Writer.addVTableName(kv.getKey());
+ for (const auto &kv : VTableNames)
+ WC->Writer.addVTableName(kv.getKey());
}
if (Reader->hasTemporalProfile()) {
@@ -2695,30 +2701,30 @@ static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
uint32_t NS = Func.getNumValueSites(VK);
Stats.TotalNumValueSites += NS;
for (size_t I = 0; I < NS; ++I) {
- uint32_t NV = Func.getNumValueDataForSite(VK, I);
- std::unique_ptr<InstrProfValueData[]> VD = Func.getValueForSite(VK, I);
+ auto VD = Func.getValueArrayForSite(VK, I);
+ uint32_t NV = VD.size();
+ if (NV == 0)
+ continue;
Stats.TotalNumValues += NV;
- if (NV) {
- Stats.TotalNumValueSitesWithValueProfile++;
- if (NV > Stats.ValueSitesHistogram.size())
- Stats.ValueSitesHistogram.resize(NV, 0);
- Stats.ValueSitesHistogram[NV - 1]++;
- }
+ Stats.TotalNumValueSitesWithValueProfile++;
+ if (NV > Stats.ValueSitesHistogram.size())
+ Stats.ValueSitesHistogram.resize(NV, 0);
+ Stats.ValueSitesHistogram[NV - 1]++;
uint64_t SiteSum = 0;
- for (uint32_t V = 0; V < NV; V++)
- SiteSum += VD[V].Count;
+ for (const auto &V : VD)
+ SiteSum += V.Count;
if (SiteSum == 0)
SiteSum = 1;
- for (uint32_t V = 0; V < NV; V++) {
+ for (const auto &V : VD) {
OS << "\t[ " << format("%2u", I) << ", ";
if (Symtab == nullptr)
- OS << format("%4" PRIu64, VD[V].Value);
+ OS << format("%4" PRIu64, V.Value);
else
- OS << Symtab->getFuncOrVarName(VD[V].Value);
- OS << ", " << format("%10" PRId64, VD[V].Count) << " ] ("
- << format("%.2f%%", (VD[V].Count * 100.0 / SiteSum)) << ")\n";
+ OS << Symtab->getFuncOrVarName(V.Value);
+ OS << ", " << format("%10" PRId64, V.Count) << " ] ("
+ << format("%.2f%%", (V.Count * 100.0 / SiteSum)) << ")\n";
}
}
}
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index e63c6d61b3bf..111c546f5329 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -321,7 +321,7 @@ bool VirtualUnwinder::unwind(const PerfSample *Sample, uint64_t Repeat) {
std::unique_ptr<PerfReaderBase>
PerfReaderBase::create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
- std::optional<uint32_t> PIDFilter) {
+ std::optional<int32_t> PIDFilter) {
std::unique_ptr<PerfReaderBase> PerfReader;
if (PerfInput.Format == PerfFormat::UnsymbolizedProfile) {
@@ -331,9 +331,10 @@ PerfReaderBase::create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
}
// For perf data input, we need to convert them into perf script first.
+ // If this is a kernel perf file, there is no need for retrieving PIDs.
if (PerfInput.Format == PerfFormat::PerfData)
- PerfInput =
- PerfScriptReader::convertPerfDataToTrace(Binary, PerfInput, PIDFilter);
+ PerfInput = PerfScriptReader::convertPerfDataToTrace(
+ Binary, Binary->isKernel(), PerfInput, PIDFilter);
assert((PerfInput.Format == PerfFormat::PerfScript) &&
"Should be a perfscript!");
@@ -353,9 +354,9 @@ PerfReaderBase::create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
}
PerfInputFile
-PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary,
+PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
PerfInputFile &File,
- std::optional<uint32_t> PIDFilter) {
+ std::optional<int32_t> PIDFilter) {
StringRef PerfData = File.InputFile;
// Run perf script to retrieve PIDs matching binary we're interested in.
auto PerfExecutable = sys::Process::FindInEnvPath("PATH", "perf");
@@ -363,49 +364,59 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary,
exitWithError("Perf not found.");
}
std::string PerfPath = *PerfExecutable;
-
SmallString<128> PerfTraceFile;
sys::fs::createUniquePath("perf-script-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.tmp",
PerfTraceFile, /*MakeAbsolute=*/true);
std::string ErrorFile = std::string(PerfTraceFile) + ".err";
- StringRef ScriptMMapArgs[] = {PerfPath, "script", "--show-mmap-events",
- "-F", "comm,pid", "-i",
- PerfData};
std::optional<StringRef> Redirects[] = {std::nullopt, // Stdin
StringRef(PerfTraceFile), // Stdout
StringRef(ErrorFile)}; // Stderr
- sys::ExecuteAndWait(PerfPath, ScriptMMapArgs, std::nullopt, Redirects);
-
PerfScriptReader::TempFileCleanups.emplace_back(PerfTraceFile);
PerfScriptReader::TempFileCleanups.emplace_back(ErrorFile);
- // Collect the PIDs
- TraceStream TraceIt(PerfTraceFile);
std::string PIDs;
- std::unordered_set<uint32_t> PIDSet;
- while (!TraceIt.isAtEoF()) {
- MMapEvent MMap;
- if (isMMap2Event(TraceIt.getCurrentLine()) &&
- extractMMap2EventForBinary(Binary, TraceIt.getCurrentLine(), MMap)) {
- auto It = PIDSet.emplace(MMap.PID);
- if (It.second && (!PIDFilter || MMap.PID == *PIDFilter)) {
- if (!PIDs.empty()) {
- PIDs.append(",");
+ if (!SkipPID) {
+ StringRef ScriptMMapArgs[] = {PerfPath, "script", "--show-mmap-events",
+ "-F", "comm,pid", "-i",
+ PerfData};
+ sys::ExecuteAndWait(PerfPath, ScriptMMapArgs, std::nullopt, Redirects);
+
+ // Collect the PIDs
+ TraceStream TraceIt(PerfTraceFile);
+ std::unordered_set<int32_t> PIDSet;
+ while (!TraceIt.isAtEoF()) {
+ MMapEvent MMap;
+ if (isMMapEvent(TraceIt.getCurrentLine()) &&
+ extractMMapEventForBinary(Binary, TraceIt.getCurrentLine(), MMap)) {
+ auto It = PIDSet.emplace(MMap.PID);
+ if (It.second && (!PIDFilter || MMap.PID == *PIDFilter)) {
+ if (!PIDs.empty()) {
+ PIDs.append(",");
+ }
+ PIDs.append(utostr(MMap.PID));
}
- PIDs.append(utostr(MMap.PID));
}
+ TraceIt.advance();
}
- TraceIt.advance();
- }
- if (PIDs.empty()) {
- exitWithError("No relevant mmap event is found in perf data.");
+ if (PIDs.empty()) {
+ exitWithError("No relevant mmap event is found in perf data.");
+ }
}
// Run perf script again to retrieve events for PIDs collected above
- StringRef ScriptSampleArgs[] = {PerfPath, "script", "--show-mmap-events",
- "-F", "ip,brstack", "--pid",
- PIDs, "-i", PerfData};
+ SmallVector<StringRef, 8> ScriptSampleArgs;
+ ScriptSampleArgs.push_back(PerfPath);
+ ScriptSampleArgs.push_back("script");
+ ScriptSampleArgs.push_back("--show-mmap-events");
+ ScriptSampleArgs.push_back("-F");
+ ScriptSampleArgs.push_back("ip,brstack");
+ ScriptSampleArgs.push_back("-i");
+ ScriptSampleArgs.push_back(PerfData);
+ if (!PIDs.empty()) {
+ ScriptSampleArgs.push_back("--pid");
+ ScriptSampleArgs.push_back(PIDs);
+ }
sys::ExecuteAndWait(PerfPath, ScriptSampleArgs, std::nullopt, Redirects);
return {std::string(PerfTraceFile), PerfFormat::PerfScript,
@@ -428,7 +439,10 @@ static StringRef filename(StringRef Path, bool UseBackSlash) {
void PerfScriptReader::updateBinaryAddress(const MMapEvent &Event) {
// Drop the event which doesn't belong to user-provided binary
StringRef BinaryName = filename(Event.BinaryPath, Binary->isCOFF());
- if (Binary->getName() != BinaryName)
+ bool IsKernel = Binary->isKernel();
+ if (!IsKernel && Binary->getName() != BinaryName)
+ return;
+ if (IsKernel && !Binary->isKernelImageName(BinaryName))
return;
// Drop the event if process does not match pid filter
@@ -441,7 +455,7 @@ void PerfScriptReader::updateBinaryAddress(const MMapEvent &Event) {
return;
}
- if (Event.Offset == Binary->getTextSegmentOffset()) {
+ if (IsKernel || Event.Offset == Binary->getTextSegmentOffset()) {
// A binary image could be unloaded and then reloaded at different
// place, so update binary load address.
// Only update for the first executable segment and assume all other
@@ -550,7 +564,7 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
// The raw format of LBR stack is like:
// 0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 ...
// ... 0x4005c8/0x4005dc/P/-/-/0
- // It's in FIFO order and seperated by whitespace.
+ // It's in FIFO order and separated by whitespace.
SmallVector<StringRef, 32> Records;
TraceIt.getCurrentLine().rtrim().split(Records, " ", -1, false);
auto WarnInvalidLBR = [](TraceStream &TraceIt) {
@@ -950,16 +964,23 @@ void PerfScriptReader::parseSample(TraceStream &TraceIt) {
parseSample(TraceIt, Count);
}
-bool PerfScriptReader::extractMMap2EventForBinary(ProfiledBinary *Binary,
- StringRef Line,
- MMapEvent &MMap) {
- // Parse a line like:
+bool PerfScriptReader::extractMMapEventForBinary(ProfiledBinary *Binary,
+ StringRef Line,
+ MMapEvent &MMap) {
+ // Parse a MMap2 line like:
// PERF_RECORD_MMAP2 2113428/2113428: [0x7fd4efb57000(0x204000) @ 0
// 08:04 19532229 3585508847]: r-xp /usr/lib64/libdl-2.17.so
- constexpr static const char *const Pattern =
- "PERF_RECORD_MMAP2 ([0-9]+)/[0-9]+: "
+ constexpr static const char *const MMap2Pattern =
+ "PERF_RECORD_MMAP2 (-?[0-9]+)/[0-9]+: "
"\\[(0x[a-f0-9]+)\\((0x[a-f0-9]+)\\) @ "
"(0x[a-f0-9]+|0) .*\\]: [-a-z]+ (.*)";
+ // Parse a MMap line like
+ // PERF_RECORD_MMAP -1/0: [0xffffffff81e00000(0x3e8fa000) @ \
+ // 0xffffffff81e00000]: x [kernel.kallsyms]_text
+ constexpr static const char *const MMapPattern =
+ "PERF_RECORD_MMAP (-?[0-9]+)/[0-9]+: "
+ "\\[(0x[a-f0-9]+)\\((0x[a-f0-9]+)\\) @ "
+ "(0x[a-f0-9]+|0)\\]: [-a-z]+ (.*)";
// Field 0 - whole line
// Field 1 - PID
// Field 2 - base address
@@ -975,14 +996,25 @@ bool PerfScriptReader::extractMMap2EventForBinary(ProfiledBinary *Binary,
BINARY_PATH = 5
};
- Regex RegMmap2(Pattern);
+ bool R = false;
SmallVector<StringRef, 6> Fields;
- bool R = RegMmap2.match(Line, &Fields);
+ if (Line.contains("PERF_RECORD_MMAP2 ")) {
+ Regex RegMmap2(MMap2Pattern);
+ R = RegMmap2.match(Line, &Fields);
+ } else if (Line.contains("PERF_RECORD_MMAP ")) {
+ Regex RegMmap(MMapPattern);
+ R = RegMmap.match(Line, &Fields);
+ } else
+ llvm_unreachable("unexpected MMAP event entry");
+
if (!R) {
std::string WarningMsg = "Cannot parse mmap event: " + Line.str() + " \n";
WithColor::warning() << WarningMsg;
+ return false;
}
- Fields[PID].getAsInteger(10, MMap.PID);
+ long long MMapPID = 0;
+ getAsSignedInteger(Fields[PID], 10, MMapPID);
+ MMap.PID = MMapPID;
Fields[MMAPPED_ADDRESS].getAsInteger(0, MMap.Address);
Fields[MMAPPED_SIZE].getAsInteger(0, MMap.Size);
Fields[PAGE_OFFSET].getAsInteger(0, MMap.Offset);
@@ -993,19 +1025,22 @@ bool PerfScriptReader::extractMMap2EventForBinary(ProfiledBinary *Binary,
}
StringRef BinaryName = filename(MMap.BinaryPath, Binary->isCOFF());
+ if (Binary->isKernel()) {
+ return Binary->isKernelImageName(BinaryName);
+ }
return Binary->getName() == BinaryName;
}
-void PerfScriptReader::parseMMap2Event(TraceStream &TraceIt) {
+void PerfScriptReader::parseMMapEvent(TraceStream &TraceIt) {
MMapEvent MMap;
- if (extractMMap2EventForBinary(Binary, TraceIt.getCurrentLine(), MMap))
+ if (extractMMapEventForBinary(Binary, TraceIt.getCurrentLine(), MMap))
updateBinaryAddress(MMap);
TraceIt.advance();
}
void PerfScriptReader::parseEventOrSample(TraceStream &TraceIt) {
- if (isMMap2Event(TraceIt.getCurrentLine()))
- parseMMap2Event(TraceIt);
+ if (isMMapEvent(TraceIt.getCurrentLine()))
+ parseMMapEvent(TraceIt);
else
parseSample(TraceIt);
}
@@ -1032,7 +1067,7 @@ bool PerfScriptReader::isLBRSample(StringRef Line) {
return false;
}
-bool PerfScriptReader::isMMap2Event(StringRef Line) {
+bool PerfScriptReader::isMMapEvent(StringRef Line) {
// Short cut to avoid string find is possible.
if (Line.empty() || Line.size() < 50)
return false;
@@ -1040,9 +1075,9 @@ bool PerfScriptReader::isMMap2Event(StringRef Line) {
if (std::isdigit(Line[0]))
return false;
- // PERF_RECORD_MMAP2 does not appear at the beginning of the line
- // for ` perf script --show-mmap-events -i ...`
- return Line.contains("PERF_RECORD_MMAP2");
+ // PERF_RECORD_MMAP2 or PERF_RECORD_MMAP does not appear at the beginning of
+ // the line for ` perf script --show-mmap-events -i ...`
+ return Line.contains("PERF_RECORD_MMAP");
}
// The raw hybird sample is like
@@ -1208,6 +1243,10 @@ void PerfScriptReader::warnInvalidRange() {
void PerfScriptReader::parsePerfTraces() {
// Parse perf traces and do aggregation.
parseAndAggregateTrace();
+ if (Binary->isKernel() && !Binary->getIsLoadedByMMap()) {
+ exitWithError(
+ "Kernel is requested, but no kernel is found in mmap events.");
+ }
emitWarningSummary(NumLeafExternalFrame, NumTotalSample,
"of samples have leaf external frame in call stack.");
diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h
index b821cbe13efa..a3bd7a0a6493 100644
--- a/llvm/tools/llvm-profgen/PerfReader.h
+++ b/llvm/tools/llvm-profgen/PerfReader.h
@@ -570,7 +570,7 @@ public:
virtual ~PerfReaderBase() = default;
static std::unique_ptr<PerfReaderBase>
create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
- std::optional<uint32_t> PIDFilter);
+ std::optional<int32_t> PIDFilter);
// Entry of the reader to parse multiple perf traces
virtual void parsePerfTraces() = 0;
@@ -595,15 +595,15 @@ protected:
class PerfScriptReader : public PerfReaderBase {
public:
PerfScriptReader(ProfiledBinary *B, StringRef PerfTrace,
- std::optional<uint32_t> PID)
- : PerfReaderBase(B, PerfTrace), PIDFilter(PID){};
+ std::optional<int32_t> PID)
+ : PerfReaderBase(B, PerfTrace), PIDFilter(PID) {};
// Entry of the reader to parse multiple perf traces
void parsePerfTraces() override;
// Generate perf script from perf data
- static PerfInputFile
- convertPerfDataToTrace(ProfiledBinary *Binary, PerfInputFile &File,
- std::optional<uint32_t> PIDFilter);
+ static PerfInputFile convertPerfDataToTrace(ProfiledBinary *Binary,
+ bool SkipPID, PerfInputFile &File,
+ std::optional<int32_t> PIDFilter);
// Extract perf script type by peaking at the input
static PerfContent checkPerfScriptType(StringRef FileName);
@@ -615,7 +615,7 @@ public:
protected:
// The parsed MMap event
struct MMapEvent {
- uint64_t PID = 0;
+ int64_t PID = 0;
uint64_t Address = 0;
uint64_t Size = 0;
uint64_t Offset = 0;
@@ -625,15 +625,15 @@ protected:
// Check whether a given line is LBR sample
static bool isLBRSample(StringRef Line);
// Check whether a given line is MMAP event
- static bool isMMap2Event(StringRef Line);
- // Parse a single line of a PERF_RECORD_MMAP2 event looking for a
+ static bool isMMapEvent(StringRef Line);
+ // Parse a single line of a PERF_RECORD_MMAP event looking for a
// mapping between the binary name and its memory layout.
- static bool extractMMap2EventForBinary(ProfiledBinary *Binary, StringRef Line,
- MMapEvent &MMap);
+ static bool extractMMapEventForBinary(ProfiledBinary *Binary, StringRef Line,
+ MMapEvent &MMap);
// Update base address based on mmap events
void updateBinaryAddress(const MMapEvent &Event);
// Parse mmap event and update binary address
- void parseMMap2Event(TraceStream &TraceIt);
+ void parseMMapEvent(TraceStream &TraceIt);
// Parse perf events/samples and do aggregation
void parseAndAggregateTrace();
// Parse either an MMAP event or a perf sample
@@ -669,7 +669,7 @@ protected:
// Keep track of all invalid return addresses
std::set<uint64_t> InvalidReturnAddresses;
// PID for the process of interest
- std::optional<uint32_t> PIDFilter;
+ std::optional<int32_t> PIDFilter;
};
/*
@@ -681,8 +681,8 @@ protected:
class LBRPerfReader : public PerfScriptReader {
public:
LBRPerfReader(ProfiledBinary *Binary, StringRef PerfTrace,
- std::optional<uint32_t> PID)
- : PerfScriptReader(Binary, PerfTrace, PID){};
+ std::optional<int32_t> PID)
+ : PerfScriptReader(Binary, PerfTrace, PID) {};
// Parse the LBR only sample.
void parseSample(TraceStream &TraceIt, uint64_t Count) override;
};
@@ -699,8 +699,8 @@ public:
class HybridPerfReader : public PerfScriptReader {
public:
HybridPerfReader(ProfiledBinary *Binary, StringRef PerfTrace,
- std::optional<uint32_t> PID)
- : PerfScriptReader(Binary, PerfTrace, PID){};
+ std::optional<int32_t> PID)
+ : PerfScriptReader(Binary, PerfTrace, PID) {};
// Parse the hybrid sample including the call and LBR line
void parseSample(TraceStream &TraceIt, uint64_t Count) override;
void generateUnsymbolizedProfile() override;
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
index 1baf35820f97..a7e506d32ac2 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
@@ -56,6 +56,10 @@ static cl::list<std::string> DisassembleFunctions(
cl::desc("List of functions to print disassembly for. Accept demangled "
"names only. Only work with show-disassembly-only"));
+static cl::opt<bool>
+ KernelBinary("kernel",
+ cl::desc("Generate the profile for Linux kernel binary."));
+
extern cl::opt<bool> ShowDetailedWarning;
extern cl::opt<bool> InferMissingFrames;
@@ -221,6 +225,9 @@ void ProfiledBinary::load() {
LLVM_DEBUG(dbgs() << "Loading " << Path << "\n");
+ // Mark the binary as a kernel image;
+ IsKernel = KernelBinary;
+
// Find the preferred load address for text sections.
setPreferredTextSegmentAddresses(Obj);
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h
index 5d2088ad7691..8d96d1598959 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.h
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.h
@@ -291,6 +291,9 @@ class ProfiledBinary {
// Whether we need to symbolize all instructions to get function context size.
bool TrackFuncContextSize = false;
+ // Whether this is a kernel image;
+ bool IsKernel = false;
+
// Indicate if the base loading address is parsed from the mmap event or uses
// the preferred address
bool IsLoadedByMMap = false;
@@ -428,6 +431,14 @@ public:
bool usePseudoProbes() const { return UsePseudoProbes; }
bool useFSDiscriminator() const { return UseFSDiscriminator; }
+ bool isKernel() const { return IsKernel; }
+
+ static bool isKernelImageName(StringRef BinaryName) {
+ return BinaryName == "[kernel.kallsyms]" ||
+ BinaryName == "[kernel.kallsyms]_stext" ||
+ BinaryName == "[kernel.kallsyms]_text";
+ }
+
// Get the index in CodeAddressVec for the address
// As we might get an address which is not the code
// here it would round to the next valid code address by
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index c696934a959b..a986ba88fdcf 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -793,7 +793,11 @@ public:
void printEmptyGroupMessage() const override;
+ void printDynamicTable() override;
+
private:
+ void printAuxillaryDynamicTableEntryInfo(const Elf_Dyn &Entry);
+
std::unique_ptr<DictScope> FileScope;
};
@@ -2313,6 +2317,12 @@ std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
return OS.str();
};
+ const std::map<uint64_t, const char *> TagNames = {
+ {DT_NEEDED, "Shared library"}, {DT_SONAME, "Library soname"},
+ {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
+ {DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"},
+ {DT_RUNPATH, "Library runpath"},
+ };
// Handle custom printing of architecture specific tags
switch (Obj.getHeader().e_machine) {
case EM_AARCH64:
@@ -2470,18 +2480,11 @@ std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
case DT_AUXILIARY:
case DT_USED:
case DT_FILTER:
+ return (Twine(TagNames.at(Type)) + ": " + getDynamicString(Value)).str();
case DT_RPATH:
- case DT_RUNPATH: {
- const std::map<uint64_t, const char *> TagNames = {
- {DT_NEEDED, "Shared library"}, {DT_SONAME, "Library soname"},
- {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
- {DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"},
- {DT_RUNPATH, "Library runpath"},
- };
-
+ case DT_RUNPATH:
return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")
.str();
- }
case DT_FLAGS:
return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags));
case DT_FLAGS_1:
@@ -7365,6 +7368,63 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
W.startLine() << "]\n";
}
+template <class ELFT>
+void JSONELFDumper<ELFT>::printAuxillaryDynamicTableEntryInfo(
+ const Elf_Dyn &Entry) {
+ auto FormatFlags = [this, Value = Entry.getVal()](auto Flags) {
+ ListScope L(this->W, "Flags");
+ for (const auto &Flag : Flags) {
+ if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
+ this->W.printString(Flag.Name);
+ }
+ };
+ switch (Entry.getTag()) {
+ case DT_SONAME:
+ this->W.printString("Name", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_AUXILIARY:
+ case DT_FILTER:
+ case DT_NEEDED:
+ this->W.printString("Library", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_USED:
+ this->W.printString("Object", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_RPATH:
+ case DT_RUNPATH: {
+ StringRef Value = this->getDynamicString(Entry.getVal());
+ ListScope L(this->W, "Path");
+ while (!Value.empty()) {
+ auto [Front, Back] = Value.split(':');
+ this->W.printString(Front);
+ Value = Back;
+ }
+ break;
+ }
+ case DT_FLAGS:
+ FormatFlags(ArrayRef(ElfDynamicDTFlags));
+ break;
+ case DT_FLAGS_1:
+ FormatFlags(ArrayRef(ElfDynamicDTFlags1));
+ break;
+ default:
+ return;
+ }
+}
+
+template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() {
+ Elf_Dyn_Range Table = this->dynamic_table();
+ ListScope L(this->W, "DynamicSection");
+ for (const auto &Entry : Table) {
+ DictScope D(this->W);
+ uintX_t Tag = Entry.getTag();
+ this->W.printHex("Tag", Tag);
+ this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag));
+ this->W.printHex("Value", Entry.getVal());
+ this->printAuxillaryDynamicTableEntryInfo(Entry);
+ }
+}
+
template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
W.startLine() << "Dynamic Relocations {\n";
W.indent();
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
index b97d75a822f7..5f0697f5aaad 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.runOnMachineFunction(MF);
+ MDT.calculate(MF);
auto MRI = &MF.getRegInfo();
SetVector<MachineInstr *> ToDelete;
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index d322666b207d..a088e7512f5f 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -47,6 +47,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Target/TargetMachine.h"