@@ -53,10 +53,9 @@ class CtxInstrumentationLowerer final {
5353 Module &M;
5454 ModuleAnalysisManager &MAM;
5555 Type *ContextNodeTy = nullptr ;
56- Type *ContextRootTy = nullptr ;
5756 Type *FunctionDataTy = nullptr ;
5857
59- DenseMap <const Function *, Constant *> ContextRootMap ;
58+ DenseSet <const Function *> ContextRootSet ;
6059 Function *StartCtx = nullptr ;
6160 Function *GetCtx = nullptr ;
6261 Function *ReleaseCtx = nullptr ;
@@ -114,15 +113,6 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
114113 auto *I32Ty = Type::getInt32Ty (M.getContext ());
115114 auto *I64Ty = Type::getInt64Ty (M.getContext ());
116115
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- });
126116 FunctionDataTy =
127117 StructType::get (M.getContext (), {
128118 PointerTy, /* Next*/
@@ -144,10 +134,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
144134 if (const auto *F = M.getFunction (Fname)) {
145135 if (F->isDeclaration ())
146136 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));
137+ ContextRootSet.insert (F);
151138 for (const auto &BB : *F)
152139 for (const auto &I : BB)
153140 if (const auto *CB = dyn_cast<CallBase>(&I))
@@ -165,7 +152,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
165152 M.getOrInsertFunction (
166153 CompilerRtAPINames::StartCtx,
167154 FunctionType::get (PointerTy,
168- {PointerTy, /* ContextRoot */
155+ {PointerTy, /* FunctionData */
169156 I64Ty, /* Guid*/ I32Ty,
170157 /* NumCounters*/ I32Ty /* NumCallsites*/ },
171158 false ))
@@ -184,7 +171,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
184171 M.getOrInsertFunction (CompilerRtAPINames::ReleaseCtx,
185172 FunctionType::get (Type::getVoidTy (M.getContext ()),
186173 {
187- PointerTy, /* ContextRoot */
174+ PointerTy, /* FunctionData */
188175 },
189176 false ))
190177 .getCallee ());
@@ -224,7 +211,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
224211 Value *RealContext = nullptr ;
225212
226213 StructType *ThisContextType = nullptr ;
227- Value *TheRootContext = nullptr ;
214+ Value *TheRootFuctionData = nullptr ;
228215 Value *ExpectedCalleeTLSAddr = nullptr ;
229216 Value *CallsiteInfoTLSAddr = nullptr ;
230217
@@ -246,23 +233,23 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
246233 ArrayType::get (Builder.getPtrTy (), NumCallsites)});
247234 // Figure out which way we obtain the context object for this function -
248235 // 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
236+ // former case, we also set TheRootFuctionData since we need to release it
250237 // at the end (plus it can be used to know if we have an entrypoint or a
251238 // regular function)
252- auto Iter = ContextRootMap.find (&F);
253- if (Iter != ContextRootMap.end ()) {
254- TheRootContext = Iter->second ;
239+ // Make up a compact name, these names end up taking up a lot of space
240+ // in the binary.
241+ auto *FData = new GlobalVariable (M, FunctionDataTy, false ,
242+ GlobalVariable::InternalLinkage,
243+ Constant::getNullValue (FunctionDataTy));
244+
245+ if (ContextRootSet.contains (&F)) {
255246 Context = Builder.CreateCall (
256- StartCtx, {TheRootContext , Guid, Builder.getInt32 (NumCounters),
247+ StartCtx, {FData , Guid, Builder.getInt32 (NumCounters),
257248 Builder.getInt32 (NumCallsites)});
249+ TheRootFuctionData = FData;
258250 ORE.emit (
259251 [&] { return OptimizationRemark (DEBUG_TYPE, " Entrypoint" , &F); });
260252 } 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));
266253 Context = Builder.CreateCall (GetCtx, {FData, &F, Guid,
267254 Builder.getInt32 (NumCounters),
268255 Builder.getInt32 (NumCallsites)});
@@ -347,10 +334,10 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
347334 break ;
348335 }
349336 I.eraseFromParent ();
350- } else if (TheRootContext && isa<ReturnInst>(I)) {
337+ } else if (TheRootFuctionData && isa<ReturnInst>(I)) {
351338 // Remember to release the context if we are an entrypoint.
352339 IRBuilder<> Builder (&I);
353- Builder.CreateCall (ReleaseCtx, {TheRootContext });
340+ Builder.CreateCall (ReleaseCtx, {TheRootFuctionData });
354341 ContextWasReleased = true ;
355342 }
356343 }
@@ -359,7 +346,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
359346 // to disallow this, (so this then stays as an error), another is to detect
360347 // that and then do a wrapper or disallow the tail call. This only affects
361348 // instrumentation, when we want to detect the call graph.
362- if (TheRootContext && !ContextWasReleased)
349+ if (TheRootFuctionData && !ContextWasReleased)
363350 F.getContext ().emitError (
364351 " [ctx_prof] An entrypoint was instrumented but it has no `ret` "
365352 " instructions above which to release the context: " +
0 commit comments