@@ -234,34 +234,53 @@ class TypeHashPointerSplitMode : public TypeHashMode {
234234 }
235235};
236236
237- // Apply opt overrides.
238- AllocTokenOptions transformOptionsFromCl (AllocTokenOptions Opts) {
239- if (!Opts.MaxTokens .has_value ())
237+ // Apply opt overrides and module flags.
238+ static AllocTokenOptions resolveOptions (AllocTokenOptions Opts,
239+ const Module &M) {
240+ auto IntModuleFlagOrNull = [&](StringRef Key) {
241+ return mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (Key));
242+ };
243+
244+ if (auto *S = dyn_cast_or_null<MDString>(M.getModuleFlag (" alloc-token-mode" )))
245+ if (auto Mode = getAllocTokenModeFromString (S->getString ()))
246+ Opts.Mode = *Mode;
247+ if (auto *Val = IntModuleFlagOrNull (" alloc-token-max" ))
248+ Opts.MaxTokens = Val->getZExtValue ();
249+ if (auto *Val = IntModuleFlagOrNull (" alloc-token-fast-abi" ))
250+ Opts.FastABI |= Val->isOne ();
251+ if (auto *Val = IntModuleFlagOrNull (" alloc-token-extended" ))
252+ Opts.Extended |= Val->isOne ();
253+
254+ // Allow overriding options from command line options.
255+ if (ClMaxTokens.getNumOccurrences ())
240256 Opts.MaxTokens = ClMaxTokens;
241- Opts.FastABI |= ClFastABI;
242- Opts.Extended |= ClExtended;
257+ if (ClFastABI.getNumOccurrences ())
258+ Opts.FastABI = ClFastABI;
259+ if (ClExtended.getNumOccurrences ())
260+ Opts.Extended = ClExtended;
261+
243262 return Opts;
244263}
245264
246265class AllocToken {
247266public:
248267 explicit AllocToken (AllocTokenOptions Opts, Module &M,
249268 ModuleAnalysisManager &MAM)
250- : Options(transformOptionsFromCl (std::move(Opts))), Mod(M),
269+ : Options(resolveOptions (std::move(Opts), M )), Mod(M),
251270 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
252- Mode(IncrementMode(*IntPtrTy, * Options.MaxTokens)) {
271+ Mode(IncrementMode(*IntPtrTy, Options.MaxTokens)) {
253272 switch (Options.Mode ) {
254273 case TokenMode::Increment:
255274 break ;
256275 case TokenMode::Random:
257- Mode.emplace <RandomMode>(*IntPtrTy, * Options.MaxTokens ,
276+ Mode.emplace <RandomMode>(*IntPtrTy, Options.MaxTokens ,
258277 M.createRNG (DEBUG_TYPE));
259278 break ;
260279 case TokenMode::TypeHash:
261- Mode.emplace <TypeHashMode>(*IntPtrTy, * Options.MaxTokens );
280+ Mode.emplace <TypeHashMode>(*IntPtrTy, Options.MaxTokens );
262281 break ;
263282 case TokenMode::TypeHashPointerSplit:
264- Mode.emplace <TypeHashPointerSplitMode>(*IntPtrTy, * Options.MaxTokens );
283+ Mode.emplace <TypeHashPointerSplitMode>(*IntPtrTy, Options.MaxTokens );
265284 break ;
266285 }
267286 }
@@ -318,8 +337,6 @@ bool AllocToken::instrumentFunction(Function &F) {
318337 if (F.getLinkage () == GlobalValue::AvailableExternallyLinkage)
319338 return false ;
320339
321- auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
322- auto &TLI = FAM.getResult <TargetLibraryAnalysis>(F);
323340 SmallVector<std::pair<CallBase *, LibFunc>, 4 > AllocCalls;
324341 SmallVector<IntrinsicInst *, 4 > IntrinsicInsts;
325342
@@ -328,6 +345,10 @@ bool AllocToken::instrumentFunction(Function &F) {
328345 F.hasFnAttribute (Attribute::SanitizeAllocToken) &&
329346 !F.hasFnAttribute (Attribute::DisableSanitizerInstrumentation);
330347
348+ // Get TLI only when required.
349+ const TargetLibraryInfo *TLI =
350+ InstrumentFunction ? &FAM.getResult <TargetLibraryAnalysis>(F) : nullptr ;
351+
331352 // Collect all allocation calls to avoid iterator invalidation.
332353 for (Instruction &I : instructions (F)) {
333354 // Collect all alloc_token_* intrinsics.
@@ -343,26 +364,28 @@ bool AllocToken::instrumentFunction(Function &F) {
343364 auto *CB = dyn_cast<CallBase>(&I);
344365 if (!CB)
345366 continue ;
346- if (std::optional<LibFunc> Func = shouldInstrumentCall (*CB, TLI))
367+ if (std::optional<LibFunc> Func = shouldInstrumentCall (*CB, * TLI))
347368 AllocCalls.emplace_back (CB, Func.value ());
348369 }
349370
371+ // Return early to avoid unnecessarily instantiating the ORE.
372+ if (AllocCalls.empty () && IntrinsicInsts.empty ())
373+ return false ;
374+
375+ auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
350376 bool Modified = false ;
351377
352- if (!AllocCalls.empty ()) {
353- for (auto &[CB, Func] : AllocCalls)
354- Modified |= replaceAllocationCall (CB, Func, ORE, TLI);
355- if (Modified)
356- NumFunctionsModified++;
357- }
378+ for (auto &[CB, Func] : AllocCalls)
379+ Modified |= replaceAllocationCall (CB, Func, ORE, *TLI);
358380
359- if (!IntrinsicInsts.empty ()) {
360- for (auto *II : IntrinsicInsts)
361- replaceIntrinsicInst (II, ORE);
381+ for (auto *II : IntrinsicInsts) {
382+ replaceIntrinsicInst (II, ORE);
362383 Modified = true ;
363- NumFunctionsModified++;
364384 }
365385
386+ if (Modified)
387+ NumFunctionsModified++;
388+
366389 return Modified;
367390}
368391
0 commit comments