@@ -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,14 +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- SanitizerMutexType, /* Taken*/
124- });
125116 FunctionDataTy =
126117 StructType::get (M.getContext (), {
127118 PointerTy, /* Next*/
@@ -143,10 +134,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
143134 if (const auto *F = M.getFunction (Fname)) {
144135 if (F->isDeclaration ())
145136 continue ;
146- auto *G = M.getOrInsertGlobal (Fname + " _ctx_root" , ContextRootTy);
147- cast<GlobalVariable>(G)->setInitializer (
148- Constant::getNullValue (ContextRootTy));
149- ContextRootMap.insert (std::make_pair (F, G));
137+ ContextRootSet.insert (F);
150138 for (const auto &BB : *F)
151139 for (const auto &I : BB)
152140 if (const auto *CB = dyn_cast<CallBase>(&I))
@@ -164,7 +152,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
164152 M.getOrInsertFunction (
165153 CompilerRtAPINames::StartCtx,
166154 FunctionType::get (PointerTy,
167- {PointerTy, /* ContextRoot */
155+ {PointerTy, /* FunctionData */
168156 I64Ty, /* Guid*/ I32Ty,
169157 /* NumCounters*/ I32Ty /* NumCallsites*/ },
170158 false ))
@@ -183,7 +171,7 @@ CtxInstrumentationLowerer::CtxInstrumentationLowerer(Module &M,
183171 M.getOrInsertFunction (CompilerRtAPINames::ReleaseCtx,
184172 FunctionType::get (Type::getVoidTy (M.getContext ()),
185173 {
186- PointerTy, /* ContextRoot */
174+ PointerTy, /* FunctionData */
187175 },
188176 false ))
189177 .getCallee ());
@@ -223,7 +211,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
223211 Value *RealContext = nullptr ;
224212
225213 StructType *ThisContextType = nullptr ;
226- Value *TheRootContext = nullptr ;
214+ Value *TheRootFuctionData = nullptr ;
227215 Value *ExpectedCalleeTLSAddr = nullptr ;
228216 Value *CallsiteInfoTLSAddr = nullptr ;
229217
@@ -245,23 +233,23 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
245233 ArrayType::get (Builder.getPtrTy (), NumCallsites)});
246234 // Figure out which way we obtain the context object for this function -
247235 // if it's an entrypoint, then we call StartCtx, otherwise GetCtx. In the
248- // 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
249237 // at the end (plus it can be used to know if we have an entrypoint or a
250238 // regular function)
251- auto Iter = ContextRootMap.find (&F);
252- if (Iter != ContextRootMap.end ()) {
253- 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)) {
254246 Context = Builder.CreateCall (
255- StartCtx, {TheRootContext , Guid, Builder.getInt32 (NumCounters),
247+ StartCtx, {FData , Guid, Builder.getInt32 (NumCounters),
256248 Builder.getInt32 (NumCallsites)});
249+ TheRootFuctionData = FData;
257250 ORE.emit (
258251 [&] { return OptimizationRemark (DEBUG_TYPE, " Entrypoint" , &F); });
259252 } else {
260- // Make up a compact name, these names end up taking up a lot of space
261- // in the binary.
262- auto *FData = new GlobalVariable (
263- M, FunctionDataTy, false , GlobalVariable::InternalLinkage,
264- Constant::getNullValue (FunctionDataTy));
265253 Context = Builder.CreateCall (GetCtx, {FData, &F, Guid,
266254 Builder.getInt32 (NumCounters),
267255 Builder.getInt32 (NumCallsites)});
@@ -346,10 +334,10 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
346334 break ;
347335 }
348336 I.eraseFromParent ();
349- } else if (TheRootContext && isa<ReturnInst>(I)) {
337+ } else if (TheRootFuctionData && isa<ReturnInst>(I)) {
350338 // Remember to release the context if we are an entrypoint.
351339 IRBuilder<> Builder (&I);
352- Builder.CreateCall (ReleaseCtx, {TheRootContext });
340+ Builder.CreateCall (ReleaseCtx, {TheRootFuctionData });
353341 ContextWasReleased = true ;
354342 }
355343 }
@@ -358,7 +346,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
358346 // to disallow this, (so this then stays as an error), another is to detect
359347 // that and then do a wrapper or disallow the tail call. This only affects
360348 // instrumentation, when we want to detect the call graph.
361- if (TheRootContext && !ContextWasReleased)
349+ if (TheRootFuctionData && !ContextWasReleased)
362350 F.getContext ().emitError (
363351 " [ctx_prof] An entrypoint was instrumented but it has no `ret` "
364352 " instructions above which to release the context: " +
0 commit comments