Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-remarkutil/RemarkCount.cpp
35231 views
1
//===- RemarkCount.cpp ----------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Count remarks using `instruction-count` for asm-printer remarks and
10
// `annotation-count` for annotation-remarks
11
//
12
//===----------------------------------------------------------------------===//
13
#include "RemarkUtilHelpers.h"
14
#include "RemarkUtilRegistry.h"
15
16
using namespace llvm;
17
using namespace remarks;
18
using namespace llvm::remarkutil;
19
20
static cl::SubCommand InstructionCount(
21
"instruction-count",
22
"Function instruction count information (requires asm-printer remarks)");
23
static cl::SubCommand
24
AnnotationCount("annotation-count",
25
"Collect count information from annotation remarks (uses "
26
"AnnotationRemarksPass)");
27
28
namespace instructioncount {
29
INPUT_FORMAT_COMMAND_LINE_OPTIONS(InstructionCount)
30
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(InstructionCount)
31
DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(InstructionCount)
32
} // namespace instructioncount
33
34
namespace annotationcount {
35
INPUT_FORMAT_COMMAND_LINE_OPTIONS(AnnotationCount)
36
static cl::opt<std::string> AnnotationTypeToCollect(
37
"annotation-type", cl::desc("annotation-type remark to collect count for"),
38
cl::sub(AnnotationCount));
39
INPUT_OUTPUT_COMMAND_LINE_OPTIONS(AnnotationCount)
40
DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(AnnotationCount)
41
} // namespace annotationcount
42
43
static bool shouldSkipRemark(bool UseDebugLoc, Remark &Remark) {
44
return UseDebugLoc && !Remark.Loc.has_value();
45
}
46
47
namespace instructioncount {
48
/// Outputs all instruction count remarks in the file as a CSV.
49
/// \returns Error::success() on success, and an Error otherwise.
50
static Error tryInstructionCount() {
51
// Create the output buffer.
52
auto MaybeOF = getOutputFileWithFlags(OutputFileName,
53
/*Flags = */ sys::fs::OF_TextWithCRLF);
54
if (!MaybeOF)
55
return MaybeOF.takeError();
56
auto OF = std::move(*MaybeOF);
57
// Create a parser for the user-specified input format.
58
auto MaybeBuf = getInputMemoryBuffer(InputFileName);
59
if (!MaybeBuf)
60
return MaybeBuf.takeError();
61
auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
62
if (!MaybeParser)
63
return MaybeParser.takeError();
64
// Emit CSV header.
65
if (UseDebugLoc)
66
OF->os() << "Source,";
67
OF->os() << "Function,InstructionCount\n";
68
// Parse all remarks. Whenever we see an instruction count remark, output
69
// the file name and the number of instructions.
70
auto &Parser = **MaybeParser;
71
auto MaybeRemark = Parser.next();
72
for (; MaybeRemark; MaybeRemark = Parser.next()) {
73
auto &Remark = **MaybeRemark;
74
if (Remark.RemarkName != "InstructionCount")
75
continue;
76
if (shouldSkipRemark(UseDebugLoc, Remark))
77
continue;
78
auto *InstrCountArg = find_if(Remark.Args, [](const Argument &Arg) {
79
return Arg.Key == "NumInstructions";
80
});
81
assert(InstrCountArg != Remark.Args.end() &&
82
"Expected instruction count remarks to have a NumInstructions key?");
83
if (UseDebugLoc) {
84
std::string Loc = Remark.Loc->SourceFilePath.str() + ":" +
85
std::to_string(Remark.Loc->SourceLine) + +":" +
86
std::to_string(Remark.Loc->SourceColumn);
87
OF->os() << Loc << ",";
88
}
89
OF->os() << Remark.FunctionName << "," << InstrCountArg->Val << "\n";
90
}
91
auto E = MaybeRemark.takeError();
92
if (!E.isA<EndOfFileError>())
93
return E;
94
consumeError(std::move(E));
95
OF->keep();
96
return Error::success();
97
}
98
} // namespace instructioncount
99
100
namespace annotationcount {
101
static Error tryAnnotationCount() {
102
// Create the output buffer.
103
auto MaybeOF = getOutputFileWithFlags(OutputFileName,
104
/*Flags = */ sys::fs::OF_TextWithCRLF);
105
if (!MaybeOF)
106
return MaybeOF.takeError();
107
auto OF = std::move(*MaybeOF);
108
// Create a parser for the user-specified input format.
109
auto MaybeBuf = getInputMemoryBuffer(InputFileName);
110
if (!MaybeBuf)
111
return MaybeBuf.takeError();
112
auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());
113
if (!MaybeParser)
114
return MaybeParser.takeError();
115
// Emit CSV header.
116
if (UseDebugLoc)
117
OF->os() << "Source,";
118
OF->os() << "Function,Count\n";
119
// Parse all remarks. When we see the specified remark collect the count
120
// information.
121
auto &Parser = **MaybeParser;
122
auto MaybeRemark = Parser.next();
123
for (; MaybeRemark; MaybeRemark = Parser.next()) {
124
auto &Remark = **MaybeRemark;
125
if (Remark.RemarkName != "AnnotationSummary")
126
continue;
127
if (shouldSkipRemark(UseDebugLoc, Remark))
128
continue;
129
auto *RemarkNameArg = find_if(Remark.Args, [](const Argument &Arg) {
130
return Arg.Key == "type" && Arg.Val == AnnotationTypeToCollect;
131
});
132
if (RemarkNameArg == Remark.Args.end())
133
continue;
134
auto *CountArg = find_if(
135
Remark.Args, [](const Argument &Arg) { return Arg.Key == "count"; });
136
assert(CountArg != Remark.Args.end() &&
137
"Expected annotation-type remark to have a count key?");
138
if (UseDebugLoc) {
139
std::string Loc = Remark.Loc->SourceFilePath.str() + ":" +
140
std::to_string(Remark.Loc->SourceLine) + +":" +
141
std::to_string(Remark.Loc->SourceColumn);
142
OF->os() << Loc << ",";
143
}
144
OF->os() << Remark.FunctionName << "," << CountArg->Val << "\n";
145
}
146
auto E = MaybeRemark.takeError();
147
if (!E.isA<EndOfFileError>())
148
return E;
149
consumeError(std::move(E));
150
OF->keep();
151
return Error::success();
152
}
153
} // namespace annotationcount
154
155
static CommandRegistration
156
InstructionCountReg(&InstructionCount,
157
instructioncount::tryInstructionCount);
158
static CommandRegistration Yaml2Bitstream(&AnnotationCount,
159
annotationcount::tryAnnotationCount);
160
161