Skip to content

Commit cd495d2

Browse files
authored
Add source file name for template instantiations in -ftime-trace (#98320)
This is helpful in identifying file and location which contain the particular template declaration.
1 parent 9fae0c6 commit cd495d2

File tree

13 files changed

+223
-64
lines changed

13 files changed

+223
-64
lines changed

a-abfdec1d.o.tmp

Whitespace-only changes.

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,9 @@ Improvements to Clang's time-trace
736736
- Clang now specifies that using ``auto`` in a lambda parameter is a C++14 extension when
737737
appropriate. (`#46059: <https://github.com/llvm/llvm-project/issues/46059>`_).
738738

739+
- Clang now adds source file infomation for template instantiations as ``event["args"]["filename"]``. This
740+
added behind an option ``-ftime-trace-verbose``. This is expected to increase the size of trace by 2-3 times.
741+
739742
Improvements to Coverage Mapping
740743
--------------------------------
741744

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,6 +3988,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou
39883988
HelpText<"Minimum time granularity (in microseconds) traced by time profiler">,
39893989
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
39903990
MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">;
3991+
def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group<f_Group>,
3992+
HelpText<"Make time trace capture verbose event details (e.g. source filenames). This can increase the size of the output by 2-3 times">,
3993+
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
3994+
MarshallingInfoFlag<FrontendOpts<"TimeTraceVerbose">>;
39913995
def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>,
39923996
HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">,
39933997
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,11 @@ class FrontendOptions {
580580
/// Minimum time granularity (in microseconds) traced by time profiler.
581581
unsigned TimeTraceGranularity;
582582

583+
/// Make time trace capture verbose event details (e.g. source filenames).
584+
/// This can increase the size of the output by 2-3 times.
585+
LLVM_PREFERRED_TYPE(bool)
586+
unsigned TimeTraceVerbose : 1;
587+
583588
/// Path which stores the output files for -ftime-trace
584589
std::string TimeTracePath;
585590

@@ -601,7 +606,8 @@ class FrontendOptions {
601606
EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false),
602607
EmitSymbolGraphSymbolLabelsForTesting(false),
603608
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
604-
UseClangIRPipeline(false), TimeTraceGranularity(500) {}
609+
UseClangIRPipeline(false), TimeTraceGranularity(500),
610+
TimeTraceVerbose(false) {}
605611

606612
/// getInputKindForExtension - Return the appropriate input kind for a file
607613
/// extension. For example, "c" would return Language::C.

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6754,6 +6754,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
67546754
if (const char *Name = C.getTimeTraceFile(&JA)) {
67556755
CmdArgs.push_back(Args.MakeArgString("-ftime-trace=" + Twine(Name)));
67566756
Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ);
6757+
Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_verbose);
67576758
}
67586759

67596760
if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,11 +3426,16 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
34263426
return true;
34273427

34283428
llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {
3429-
std::string Name;
3430-
llvm::raw_string_ostream OS(Name);
3429+
llvm::TimeTraceMetadata M;
3430+
llvm::raw_string_ostream OS(M.Detail);
34313431
Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(),
34323432
/*Qualified=*/true);
3433-
return Name;
3433+
if (llvm::isTimeTraceVerbose()) {
3434+
auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation());
3435+
M.File = SourceMgr.getFilename(Loc);
3436+
M.Line = SourceMgr.getExpansionLineNumber(Loc);
3437+
}
3438+
return M;
34343439
});
34353440

34363441
Pattern = PatternDef;

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4966,11 +4966,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
49664966
}
49674967

49684968
llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() {
4969-
std::string Name;
4970-
llvm::raw_string_ostream OS(Name);
4969+
llvm::TimeTraceMetadata M;
4970+
llvm::raw_string_ostream OS(M.Detail);
49714971
Function->getNameForDiagnostic(OS, getPrintingPolicy(),
49724972
/*Qualified=*/true);
4973-
return Name;
4973+
if (llvm::isTimeTraceVerbose()) {
4974+
auto Loc = SourceMgr.getExpansionLoc(Function->getLocation());
4975+
M.File = SourceMgr.getFilename(Loc);
4976+
M.Line = SourceMgr.getExpansionLineNumber(Loc);
4977+
}
4978+
return M;
49744979
});
49754980

49764981
// If we're performing recursive template instantiation, create our own

clang/test/Driver/ftime-trace-sections.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: rm -rf %t && mkdir %t && cd %t
2-
// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o out %s
2+
// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s
33
// RUN: %python %S/ftime-trace-sections.py < out.json
44

55
template <typename T>

clang/test/Driver/ftime-trace.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
// RUN: rm -rf %t && mkdir -p %t && cd %t
2-
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -o out %s
2+
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s
33
// RUN: cat out.json \
44
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
55
// RUN: | FileCheck %s
6-
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -o out %s
6+
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s
77
// RUN: cat new-name.json \
88
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
99
// RUN: | FileCheck %s
1010
// RUN: mkdir dir1 dir2
11-
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -o out %s
11+
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s
1212
// RUN: cat dir1/out.json \
1313
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
1414
// RUN: | FileCheck %s
15-
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -o out %s
15+
// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s
1616
// RUN: cat dir2/out.json \
1717
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
1818
// RUN: | FileCheck %s
@@ -34,32 +34,33 @@
3434
// RUN: mkdir d e f && cp %s d/a.cpp && touch d/b.c
3535

3636
/// TODO: Support -fno-integrated-as.
37-
// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1
38-
// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0"
37+
// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1
38+
// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
3939

40-
// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2
41-
// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0"
42-
// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0"
40+
// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2
41+
// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
42+
// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
4343

4444
/// -o specifies the link output. Create ${output}-${basename}.json.
45-
// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1
46-
// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0"
47-
// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0"
45+
// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1
46+
// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
47+
// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
4848

4949
/// -dumpdir is f/g, not ending with a path separator. We create f/g${basename}.json.
50-
// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2
51-
// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0"
52-
// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0"
50+
// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2
51+
// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
52+
// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
5353

54-
// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3
55-
// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0"
56-
// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0"
54+
// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3
55+
// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
56+
// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose"
5757

58-
// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -xassembler d/a.cpp 2>&1 | \
58+
// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -ftime-trace-verbose -xassembler d/a.cpp 2>&1 | \
5959
// RUN: FileCheck %s --check-prefix=UNUSED
6060
// UNUSED: warning: argument unused during compilation: '-ftime-trace'
6161
// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace=e'
6262
// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-granularity=1'
63+
// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-verbose'
6364
// UNUSED-NOT: warning:
6465

6566
template <typename T>

clang/tools/driver/cc1_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
241241

242242
if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
243243
llvm::timeTraceProfilerInitialize(
244-
Clang->getFrontendOpts().TimeTraceGranularity, Argv0);
244+
Clang->getFrontendOpts().TimeTraceGranularity, Argv0,
245+
Clang->getFrontendOpts().TimeTraceVerbose);
245246
}
246247
// --print-supported-cpus takes priority over the actual compilation.
247248
if (Clang->getFrontendOpts().PrintSupportedCPUs)

clang/unittests/Support/TimeProfilerTest.cpp

Lines changed: 94 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010
#include "clang/Frontend/FrontendActions.h"
1111
#include "clang/Lex/PreprocessorOptions.h"
1212

13+
#include "llvm/ADT/StringMap.h"
1314
#include "llvm/Support/JSON.h"
1415
#include "llvm/Support/TimeProfiler.h"
16+
#include "llvm/Support/VirtualFileSystem.h"
1517
#include <stack>
1618

1719
#include "gtest/gtest.h"
20+
#include <tuple>
1821

1922
using namespace clang;
2023
using namespace llvm;
@@ -23,7 +26,8 @@ namespace {
2326

2427
// Should be called before testing.
2528
void setupProfiler() {
26-
timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test");
29+
timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test",
30+
/*TimeTraceVerbose=*/true);
2731
}
2832

2933
// Should be called after `compileFromString()`.
@@ -38,14 +42,24 @@ std::string teardownProfiler() {
3842

3943
// Returns true if code compiles successfully.
4044
// We only parse AST here. This is enough for constexpr evaluation.
41-
bool compileFromString(StringRef Code, StringRef Standard, StringRef FileName) {
45+
bool compileFromString(StringRef Code, StringRef Standard, StringRef File,
46+
llvm::StringMap<std::string> Headers = {}) {
4247
CompilerInstance Compiler;
4348
Compiler.createDiagnostics();
4449

50+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
51+
new llvm::vfs::InMemoryFileSystem());
52+
FS->addFile(File, 0, MemoryBuffer::getMemBuffer(Code));
53+
for (const auto &Header : Headers) {
54+
FS->addFile(Header.getKey(), 0,
55+
MemoryBuffer::getMemBuffer(Header.getValue()));
56+
}
57+
llvm::IntrusiveRefCntPtr<FileManager> Files(
58+
new FileManager(FileSystemOptions(), FS));
59+
Compiler.setFileManager(Files.get());
60+
4561
auto Invocation = std::make_shared<CompilerInvocation>();
46-
Invocation->getPreprocessorOpts().addRemappedFile(
47-
FileName, MemoryBuffer::getMemBuffer(Code).release());
48-
const char *Args[] = {Standard.data(), FileName.data()};
62+
std::vector<const char *> Args = {Standard.data(), File.data()};
4963
CompilerInvocation::CreateFromArgs(*Invocation, Args,
5064
Compiler.getDiagnostics());
5165
Compiler.setInvocation(std::move(Invocation));
@@ -60,13 +74,27 @@ bool compileFromString(StringRef Code, StringRef Standard, StringRef FileName) {
6074
return Compiler.ExecuteAction(Action);
6175
}
6276

77+
std::string GetMetadata(json::Object *Event) {
78+
std::string Metadata;
79+
llvm::raw_string_ostream OS(Metadata);
80+
if (json::Object *Args = Event->getObject("args")) {
81+
if (auto Detail = Args->getString("detail"))
82+
OS << Detail->str();
83+
if (auto File = Args->getString("file"))
84+
OS << ", " << File->str();
85+
if (auto Line = Args->getInteger("line"))
86+
OS << ":" << *Line;
87+
}
88+
return Metadata;
89+
}
90+
6391
// Returns pretty-printed trace graph.
6492
std::string buildTraceGraph(StringRef Json) {
6593
struct EventRecord {
6694
int64_t TimestampBegin;
6795
int64_t TimestampEnd;
68-
StringRef Name;
69-
StringRef Detail;
96+
std::string Name;
97+
std::string Metadata;
7098
};
7199
std::vector<EventRecord> Events;
72100

@@ -81,18 +109,21 @@ std::string buildTraceGraph(StringRef Json) {
81109
int64_t TimestampBegin = TraceEventObj->getInteger("ts").value_or(0);
82110
int64_t TimestampEnd =
83111
TimestampBegin + TraceEventObj->getInteger("dur").value_or(0);
84-
StringRef Name = TraceEventObj->getString("name").value_or("");
85-
StringRef Detail = "";
86-
if (json::Object *Args = TraceEventObj->getObject("args"))
87-
Detail = Args->getString("detail").value_or("");
112+
std::string Name = TraceEventObj->getString("name").value_or("").str();
113+
std::string Metadata = GetMetadata(TraceEventObj);
114+
115+
// Source events are asynchronous events and may not perfectly nest the
116+
// synchronous events. Skip testing them.
117+
if (Name == "Source")
118+
continue;
88119

89120
// This is a "summary" event, like "Total PerformPendingInstantiations",
90121
// skip it
91122
if (TimestampBegin == 0)
92123
continue;
93124

94125
Events.emplace_back(
95-
EventRecord{TimestampBegin, TimestampEnd, Name, Detail});
126+
EventRecord{TimestampBegin, TimestampEnd, Name, Metadata});
96127
}
97128

98129
// There can be nested events that are very fast, for example:
@@ -132,9 +163,9 @@ std::string buildTraceGraph(StringRef Json) {
132163
Stream << "| ";
133164
}
134165
Stream.write(Event.Name.data(), Event.Name.size());
135-
if (!Event.Detail.empty()) {
166+
if (!Event.Metadata.empty()) {
136167
Stream << " (";
137-
Stream.write(Event.Detail.data(), Event.Detail.size());
168+
Stream.write(Event.Metadata.data(), Event.Metadata.size());
138169
Stream << ")";
139170
}
140171
Stream << "\n";
@@ -145,7 +176,7 @@ std::string buildTraceGraph(StringRef Json) {
145176
} // namespace
146177

147178
TEST(TimeProfilerTest, ConstantEvaluationCxx20) {
148-
constexpr StringRef Code = R"(
179+
std::string Code = R"(
149180
void print(double value);
150181
151182
namespace slow_namespace {
@@ -175,8 +206,7 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line
175206
setupProfiler();
176207
ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc"));
177208
std::string Json = teardownProfiler();
178-
std::string TraceGraph = buildTraceGraph(Json);
179-
ASSERT_TRUE(TraceGraph == R"(
209+
ASSERT_EQ(R"(
180210
Frontend
181211
| ParseDeclarationOrFunctionDefinition (test.cc:2:1)
182212
| ParseDeclarationOrFunctionDefinition (test.cc:6:1)
@@ -202,14 +232,54 @@ Frontend
202232
| ParseDeclarationOrFunctionDefinition (test.cc:25:1)
203233
| | EvaluateAsInitializer (slow_init_list)
204234
| PerformPendingInstantiations
205-
)");
235+
)",
236+
buildTraceGraph(Json));
237+
}
238+
239+
TEST(TimeProfilerTest, TemplateInstantiations) {
240+
std::string B_H = R"(
241+
template <typename T>
242+
T fooB(T t) {
243+
return T();
244+
}
206245
207-
// NOTE: If this test is failing, run this test with
208-
// `llvm::errs() << TraceGraph;` and change the assert above.
246+
#define MacroTemp(x) template <typename T> void foo##x(T) { T(); }
247+
)";
248+
249+
std::string A_H = R"(
250+
#include "b.h"
251+
252+
MacroTemp(MTA)
253+
254+
template <typename T>
255+
void fooA(T t) { fooB(t); fooMTA(t); }
256+
)";
257+
std::string Code = R"(
258+
#include "a.h"
259+
void user() { fooA(0); }
260+
)";
261+
262+
setupProfiler();
263+
ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc",
264+
/*Headers=*/{{"a.h", A_H}, {"b.h", B_H}}));
265+
std::string Json = teardownProfiler();
266+
ASSERT_EQ(R"(
267+
Frontend
268+
| ParseFunctionDefinition (fooB)
269+
| ParseFunctionDefinition (fooMTA)
270+
| ParseFunctionDefinition (fooA)
271+
| ParseDeclarationOrFunctionDefinition (test.cc:3:5)
272+
| | ParseFunctionDefinition (user)
273+
| PerformPendingInstantiations
274+
| | InstantiateFunction (fooA<int>, ./a.h:7)
275+
| | | InstantiateFunction (fooB<int>, ./b.h:3)
276+
| | | InstantiateFunction (fooMTA<int>, ./a.h:4)
277+
)",
278+
buildTraceGraph(Json));
209279
}
210280

211281
TEST(TimeProfilerTest, ConstantEvaluationC99) {
212-
constexpr StringRef Code = R"(
282+
std::string Code = R"(
213283
struct {
214284
short quantval[4]; // 3rd line
215285
} value;
@@ -218,15 +288,12 @@ struct {
218288
setupProfiler();
219289
ASSERT_TRUE(compileFromString(Code, "-std=c99", "test.c"));
220290
std::string Json = teardownProfiler();
221-
std::string TraceGraph = buildTraceGraph(Json);
222-
ASSERT_TRUE(TraceGraph == R"(
291+
ASSERT_EQ(R"(
223292
Frontend
224293
| ParseDeclarationOrFunctionDefinition (test.c:2:1)
225294
| | isIntegerConstantExpr (<test.c:3:18>)
226295
| | EvaluateKnownConstIntCheckOverflow (<test.c:3:18>)
227296
| PerformPendingInstantiations
228-
)");
229-
230-
// NOTE: If this test is failing, run this test with
231-
// `llvm::errs() << TraceGraph;` and change the assert above.
297+
)",
298+
buildTraceGraph(Json));
232299
}

0 commit comments

Comments
 (0)