@@ -53,10 +53,9 @@ class CtxInstrumentationLowerer final {
53
53
Module &M;
54
54
ModuleAnalysisManager &MAM;
55
55
Type *ContextNodeTy = nullptr ;
56
- Type *ContextRootTy = nullptr ;
57
56
Type *FunctionDataTy = nullptr ;
58
57
59
- DenseMap <const Function *, Constant *> ContextRootMap ;
58
+ DenseSet <const Function *> ContextRootSet ;
60
59
Function *StartCtx = nullptr ;
61
60
Function *GetCtx = nullptr ;
62
61
Function *ReleaseCtx = nullptr ;
@@ -114,18 +113,10 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
114
113
auto *I32Ty = Type::getInt32Ty (M.getContext ());
115
114
auto *I64Ty = Type::getInt64Ty (M.getContext ());
116
115
117
- // The ContextRoot type
118
- ContextRootTy =
119
- StructType::get (M.getContext (), {
120
- PointerTy, /* FirstNode*/
121
- PointerTy, /* FirstMemBlock*/
122
- PointerTy, /* CurrentMem*/
123
- I64Ty, /* TotalEntries*/
124
- SanitizerMutexType, /* Taken*/
125
- });
126
116
FunctionDataTy =
127
117
StructType::get (M.getContext (), {
128
118
PointerTy, /* Next*/
119
+ PointerTy, /* CtxRoot*/
129
120
PointerTy, /* FlatCtx*/
130
121
SanitizerMutexType, /* Mutex*/
131
122
});
@@ -144,10 +135,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
144
135
if (const auto *F = M.getFunction (Fname)) {
145
136
if (F->isDeclaration ())
146
137
continue ;
147
- auto *G = M.getOrInsertGlobal (Fname + " _ctx_root" , ContextRootTy);
148
- cast<GlobalVariable>(G)->setInitializer (
149
- Constant::getNullValue (ContextRootTy));
150
- ContextRootMap.insert (std::make_pair (F, G));
138
+ ContextRootSet.insert (F);
151
139
for (const auto &BB : *F)
152
140
for (const auto &I : BB)
153
141
if (const auto *CB = dyn_cast<CallBase>(&I))
@@ -165,7 +153,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
165
153
M.getOrInsertFunction (
166
154
CompilerRtAPINames::StartCtx,
167
155
FunctionType::get (PointerTy,
168
- {PointerTy, /* ContextRoot */
156
+ {PointerTy, /* FunctionData */
169
157
I64Ty, /* Guid*/ I32Ty,
170
158
/* NumCounters*/ I32Ty /* NumCallsites*/ },
171
159
false ))
@@ -184,7 +172,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
184
172
M.getOrInsertFunction (CompilerRtAPINames::ReleaseCtx,
185
173
FunctionType::get (Type::getVoidTy (M.getContext ()),
186
174
{
187
- PointerTy, /* ContextRoot */
175
+ PointerTy, /* FunctionData */
188
176
},
189
177
false ))
190
178
.getCallee ());
@@ -224,7 +212,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
224
212
Value *RealContext = nullptr ;
225
213
226
214
StructType *ThisContextType = nullptr ;
227
- Value *TheRootContext = nullptr ;
215
+ Value *TheRootFuctionData = nullptr ;
228
216
Value *ExpectedCalleeTLSAddr = nullptr ;
229
217
Value *CallsiteInfoTLSAddr = nullptr ;
230
218
@@ -246,23 +234,23 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
246
234
ArrayType::get (Builder.getPtrTy (), NumCallsites)});
247
235
// Figure out which way we obtain the context object for this function -
248
236
// if it's an entrypoint, then we call StartCtx, otherwise GetCtx. In the
249
- // former case, we also set TheRootContext since we need to release it
237
+ // former case, we also set TheRootFuctionData since we need to release it
250
238
// at the end (plus it can be used to know if we have an entrypoint or a
251
239
// regular function)
252
- auto Iter = ContextRootMap.find (&F);
253
- if (Iter != ContextRootMap.end ()) {
254
- TheRootContext = Iter->second ;
240
+ // Don't set a name, they end up taking a lot of space and we don't need
241
+ // them.
242
+ auto *FData = new GlobalVariable (M, FunctionDataTy, false ,
243
+ GlobalVariable::InternalLinkage,
244
+ Constant::getNullValue (FunctionDataTy));
245
+
246
+ if (ContextRootSet.contains (&F)) {
255
247
Context = Builder.CreateCall (
256
- StartCtx, {TheRootContext , Guid, Builder.getInt32 (NumCounters),
248
+ StartCtx, {FData , Guid, Builder.getInt32 (NumCounters),
257
249
Builder.getInt32 (NumCallsites)});
250
+ TheRootFuctionData = FData;
258
251
ORE.emit (
259
252
[&] { return OptimizationRemark (DEBUG_TYPE, " Entrypoint" , &F); });
260
253
} else {
261
- // Make up a compact name, these names end up taking up a lot of space
262
- // in the binary.
263
- auto *FData = new GlobalVariable (
264
- M, FunctionDataTy, false , GlobalVariable::InternalLinkage,
265
- Constant::getNullValue (FunctionDataTy));
266
254
Context = Builder.CreateCall (GetCtx, {FData, &F, Guid,
267
255
Builder.getInt32 (NumCounters),
268
256
Builder.getInt32 (NumCallsites)});
@@ -347,10 +335,10 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
347
335
break ;
348
336
}
349
337
I.eraseFromParent ();
350
- } else if (TheRootContext && isa<ReturnInst>(I)) {
338
+ } else if (TheRootFuctionData && isa<ReturnInst>(I)) {
351
339
// Remember to release the context if we are an entrypoint.
352
340
IRBuilder<> Builder (&I);
353
- Builder.CreateCall (ReleaseCtx, {TheRootContext });
341
+ Builder.CreateCall (ReleaseCtx, {TheRootFuctionData });
354
342
ContextWasReleased = true ;
355
343
}
356
344
}
@@ -359,7 +347,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
359
347
// to disallow this, (so this then stays as an error), another is to detect
360
348
// that and then do a wrapper or disallow the tail call. This only affects
361
349
// instrumentation, when we want to detect the call graph.
362
- if (TheRootContext && !ContextWasReleased)
350
+ if (TheRootFuctionData && !ContextWasReleased)
363
351
F.getContext ().emitError (
364
352
" [ctx_prof] An entrypoint was instrumented but it has no `ret` "
365
353
" instructions above which to release the context: " +
0 commit comments