Skip to content

Commit 1b46db7

Browse files
authored
[ctxprof] ProfileWriter abstraction (#129590)
Introduce a `ProfileWriter` abstraction to replace the callback passed to `__llvm_ctx_profile_fetch`. Subsequent changes will add support for flat profile collection (as in, collection of non-contextual profile for those functions not under a contextual root), which require also a change in the profile format. The abstraction makes it easy to add "write flat" - related capabilities without constantly complicating the signature of `__llvm_ctx_profile_fetch`.
1 parent c8dd852 commit 1b46db7

File tree

6 files changed

+52
-43
lines changed

6 files changed

+52
-43
lines changed

compiler-rt/lib/ctx_profile/CtxInstrContextNode.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ class ContextNode final {
112112

113113
uint64_t entrycount() const { return counters()[0]; }
114114
};
115+
116+
/// Abstraction for the parameter passed to `__llvm_ctx_profile_fetch`.
117+
class ProfileWriter {
118+
public:
119+
virtual void writeContextual(const ctx_profile::ContextNode &RootNode) = 0;
120+
virtual ~ProfileWriter() = default;
121+
};
115122
} // namespace ctx_profile
116123
} // namespace llvm
117124
#endif

compiler-rt/lib/ctx_profile/CtxInstrProfiling.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,7 @@ void __llvm_ctx_profile_start_collection() {
294294
__sanitizer::Printf("[ctxprof] Initial NumMemUnits: %zu \n", NumMemUnits);
295295
}
296296

297-
bool __llvm_ctx_profile_fetch(void *Data,
298-
bool (*Writer)(void *W, const ContextNode &)) {
299-
assert(Writer);
297+
bool __llvm_ctx_profile_fetch(ProfileWriter &Writer) {
300298
__sanitizer::GenericScopedLock<__sanitizer::SpinMutex> Lock(
301299
&AllContextsMutex);
302300

@@ -308,8 +306,7 @@ bool __llvm_ctx_profile_fetch(void *Data,
308306
__sanitizer::Printf("[ctxprof] Contextual Profile is %s\n", "invalid");
309307
return false;
310308
}
311-
if (!Writer(Data, *Root->FirstNode))
312-
return false;
309+
Writer.writeContextual(*Root->FirstNode);
313310
}
314311
return true;
315312
}

compiler-rt/lib/ctx_profile/CtxInstrProfiling.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ void __llvm_ctx_profile_free();
169169
/// The Writer's first parameter plays the role of closure for Writer, and is
170170
/// what the caller of __llvm_ctx_profile_fetch passes as the Data parameter.
171171
/// The second parameter is the root of a context tree.
172-
bool __llvm_ctx_profile_fetch(void *Data,
173-
bool (*Writer)(void *, const ContextNode &));
172+
bool __llvm_ctx_profile_fetch(ProfileWriter &);
174173
}
175174
#endif // CTX_PROFILE_CTXINSTRPROFILING_H_

compiler-rt/lib/ctx_profile/tests/CtxInstrProfilingTest.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,15 @@ TEST_F(ContextTest, Dump) {
179179
(void)Subctx;
180180
__llvm_ctx_profile_release_context(&Root);
181181

182-
struct Writer {
182+
class TestProfileWriter : public ProfileWriter {
183+
public:
183184
ContextRoot *const Root;
184185
const size_t Entries;
185186
bool State = false;
186-
Writer(ContextRoot *Root, size_t Entries) : Root(Root), Entries(Entries) {}
187+
TestProfileWriter(ContextRoot *Root, size_t Entries)
188+
: Root(Root), Entries(Entries) {}
187189

188-
bool write(const ContextNode &Node) {
190+
void writeContextual(const ContextNode &Node) override {
189191
EXPECT_FALSE(Root->Taken.TryLock());
190192
EXPECT_EQ(Node.guid(), 1U);
191193
EXPECT_EQ(Node.counters()[0], Entries);
@@ -202,22 +204,17 @@ TEST_F(ContextTest, Dump) {
202204
EXPECT_EQ(SN.callsites_size(), 1U);
203205
EXPECT_EQ(SN.subContexts()[0], nullptr);
204206
State = true;
205-
return true;
206207
}
207208
};
208-
Writer W(&Root, 1);
209+
TestProfileWriter W(&Root, 1);
209210
EXPECT_FALSE(W.State);
210-
__llvm_ctx_profile_fetch(&W, [](void *W, const ContextNode &Node) -> bool {
211-
return reinterpret_cast<Writer *>(W)->write(Node);
212-
});
211+
__llvm_ctx_profile_fetch(W);
213212
EXPECT_TRUE(W.State);
214213

215214
// this resets all counters but not the internal structure.
216215
__llvm_ctx_profile_start_collection();
217-
Writer W2(&Root, 0);
216+
TestProfileWriter W2(&Root, 0);
218217
EXPECT_FALSE(W2.State);
219-
__llvm_ctx_profile_fetch(&W2, [](void *W, const ContextNode &Node) -> bool {
220-
return reinterpret_cast<Writer *>(W)->write(Node);
221-
});
218+
__llvm_ctx_profile_fetch(W2);
222219
EXPECT_TRUE(W2.State);
223220
}

compiler-rt/test/ctx_profile/TestCases/generate-context.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
#include <iostream>
1616

1717
using namespace llvm::ctx_profile;
18-
extern "C" bool __llvm_ctx_profile_fetch(void *Data,
19-
bool (*Writer)(void *,
20-
const ContextNode &));
18+
extern "C" bool __llvm_ctx_profile_fetch(ProfileWriter &);
2119

2220
// avoid name mangling
2321
extern "C" {
@@ -46,22 +44,29 @@ __attribute__((noinline)) void theRoot() {
4644
// CHECK-NEXT: check even
4745
// CHECK-NEXT: check odd
4846

49-
void printProfile(const ContextNode &Node, const std::string &Indent,
50-
const std::string &Increment) {
51-
std::cout << Indent << "Guid: " << Node.guid() << std::endl;
52-
std::cout << Indent << "Entries: " << Node.entrycount() << std::endl;
53-
std::cout << Indent << Node.counters_size() << " counters and "
54-
<< Node.callsites_size() << " callsites" << std::endl;
55-
std::cout << Indent << "Counter values: ";
56-
for (uint32_t I = 0U; I < Node.counters_size(); ++I)
57-
std::cout << Node.counters()[I] << " ";
58-
std::cout << std::endl;
59-
for (uint32_t I = 0U; I < Node.callsites_size(); ++I)
60-
for (const auto *N = Node.subContexts()[I]; N; N = N->next()) {
61-
std::cout << Indent << "At Index " << I << ":" << std::endl;
62-
printProfile(*N, Indent + Increment, Increment);
63-
}
64-
}
47+
class TestProfileWriter : public ProfileWriter {
48+
void printProfile(const ContextNode &Node, const std::string &Indent,
49+
const std::string &Increment) {
50+
std::cout << Indent << "Guid: " << Node.guid() << std::endl;
51+
std::cout << Indent << "Entries: " << Node.entrycount() << std::endl;
52+
std::cout << Indent << Node.counters_size() << " counters and "
53+
<< Node.callsites_size() << " callsites" << std::endl;
54+
std::cout << Indent << "Counter values: ";
55+
for (uint32_t I = 0U; I < Node.counters_size(); ++I)
56+
std::cout << Node.counters()[I] << " ";
57+
std::cout << std::endl;
58+
for (uint32_t I = 0U; I < Node.callsites_size(); ++I)
59+
for (const auto *N = Node.subContexts()[I]; N; N = N->next()) {
60+
std::cout << Indent << "At Index " << I << ":" << std::endl;
61+
printProfile(*N, Indent + Increment, Increment);
62+
}
63+
}
64+
65+
public:
66+
void writeContextual(const ContextNode &RootNode) override {
67+
printProfile(RootNode, "", "");
68+
}
69+
};
6570

6671
// 8657661246551306189 is theRoot. We expect 2 callsites and 2 counters - one
6772
// for the entry basic block and one for the loop.
@@ -88,11 +93,8 @@ void printProfile(const ContextNode &Node, const std::string &Indent,
8893
// CHECK-NEXT: Counter values: 2 1
8994

9095
bool profileWriter() {
91-
return __llvm_ctx_profile_fetch(
92-
nullptr, +[](void *, const ContextNode &Node) {
93-
printProfile(Node, "", " ");
94-
return true;
95-
});
96+
TestProfileWriter W;
97+
return __llvm_ctx_profile_fetch(W);
9698
}
9799

98100
int main(int argc, char **argv) {

llvm/include/llvm/ProfileData/CtxInstrContextNode.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ class ContextNode final {
112112

113113
uint64_t entrycount() const { return counters()[0]; }
114114
};
115+
116+
/// Abstraction for the parameter passed to `__llvm_ctx_profile_fetch`.
117+
class ProfileWriter {
118+
public:
119+
virtual void writeContextual(const ctx_profile::ContextNode &RootNode) = 0;
120+
virtual ~ProfileWriter() = default;
121+
};
115122
} // namespace ctx_profile
116123
} // namespace llvm
117124
#endif

0 commit comments

Comments
 (0)