@@ -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,18 +113,10 @@ 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*/
119+ PointerTy, /* CtxRoot*/
129120 PointerTy, /* FlatCtx*/
130121 SanitizerMutexType, /* Mutex*/
131122 });
@@ -144,10 +135,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
144135 if (const auto *F = M.getFunction (Fname)) {
145136 if (F->isDeclaration ())
146137 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);
151139 for (const auto &BB : *F)
152140 for (const auto &I : BB)
153141 if (const auto *CB = dyn_cast<CallBase>(&I))
@@ -165,7 +153,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
165153 M.getOrInsertFunction (
166154 CompilerRtAPINames::StartCtx,
167155 FunctionType::get (PointerTy,
168- {PointerTy, /* ContextRoot */
156+ {PointerTy, /* FunctionData */
169157 I64Ty, /* Guid*/ I32Ty,
170158 /* NumCounters*/ I32Ty /* NumCallsites*/ },
171159 false ))
@@ -184,7 +172,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
184172 M.getOrInsertFunction (CompilerRtAPINames::ReleaseCtx,
185173 FunctionType::get (Type::getVoidTy (M.getContext ()),
186174 {
187- PointerTy, /* ContextRoot */
175+ PointerTy, /* FunctionData */
188176 },
189177 false ))
190178 .getCallee ());
@@ -224,7 +212,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
224212 Value *RealContext = nullptr ;
225213
226214 StructType *ThisContextType = nullptr ;
227- Value *TheRootContext = nullptr ;
215+ Value *TheRootFuctionData = nullptr ;
228216 Value *ExpectedCalleeTLSAddr = nullptr ;
229217 Value *CallsiteInfoTLSAddr = nullptr ;
230218
@@ -246,23 +234,23 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
246234 ArrayType::get (Builder.getPtrTy (), NumCallsites)});
247235 // Figure out which way we obtain the context object for this function -
248236 // 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
250238 // at the end (plus it can be used to know if we have an entrypoint or a
251239 // 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)) {
255247 Context = Builder.CreateCall (
256- StartCtx, {TheRootContext , Guid, Builder.getInt32 (NumCounters),
248+ StartCtx, {FData , Guid, Builder.getInt32 (NumCounters),
257249 Builder.getInt32 (NumCallsites)});
250+ TheRootFuctionData = FData;
258251 ORE.emit (
259252 [&] { return OptimizationRemark (DEBUG_TYPE, " Entrypoint" , &F); });
260253 } 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));
266254 Context = Builder.CreateCall (GetCtx, {FData, &F, Guid,
267255 Builder.getInt32 (NumCounters),
268256 Builder.getInt32 (NumCallsites)});
@@ -347,10 +335,10 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
347335 break ;
348336 }
349337 I.eraseFromParent ();
350- } else if (TheRootContext && isa<ReturnInst>(I)) {
338+ } else if (TheRootFuctionData && isa<ReturnInst>(I)) {
351339 // Remember to release the context if we are an entrypoint.
352340 IRBuilder<> Builder (&I);
353- Builder.CreateCall (ReleaseCtx, {TheRootContext });
341+ Builder.CreateCall (ReleaseCtx, {TheRootFuctionData });
354342 ContextWasReleased = true ;
355343 }
356344 }
@@ -359,7 +347,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
359347 // to disallow this, (so this then stays as an error), another is to detect
360348 // that and then do a wrapper or disallow the tail call. This only affects
361349 // instrumentation, when we want to detect the call graph.
362- if (TheRootContext && !ContextWasReleased)
350+ if (TheRootFuctionData && !ContextWasReleased)
363351 F.getContext ().emitError (
364352 " [ctx_prof] An entrypoint was instrumented but it has no `ret` "
365353 " instructions above which to release the context: " +
0 commit comments