@@ -69,27 +69,19 @@ enum class TokenMode : unsigned {
6969
7070 // / Token ID based on allocated type hash.
7171 TypeHash = 2 ,
72-
73- // Mode count - keep last
74- ModeCount
7572};
7673
7774// ===--- Command-line options ---------------------------------------------===//
7875
79- struct ModeParser : public cl ::parser<unsigned > {
80- ModeParser (cl::Option &O) : cl::parser<unsigned >(O) {}
81- bool parse (cl::Option &O, StringRef ArgName, StringRef Arg, unsigned &Value) {
82- if (cl::parser<unsigned >::parse (O, ArgName, Arg, Value))
83- return true ;
84- if (Value >= static_cast <unsigned >(TokenMode::ModeCount))
85- return O.error (" '" + Arg + " ' value invalid" );
86- return false ;
87- }
88- };
89-
90- cl::opt<unsigned , false , ModeParser>
91- ClMode (" alloc-token-mode" , cl::desc(" Token assignment mode" ), cl::Hidden,
92- cl::init (static_cast <unsigned >(TokenMode::TypeHash)));
76+ cl::opt<TokenMode>
77+ ClMode (" alloc-token-mode" , cl::Hidden, cl::desc(" Token assignment mode" ),
78+ cl::init (TokenMode::TypeHash),
79+ cl::values (clEnumValN(TokenMode::Increment, " increment" ,
80+ " Incrementally increasing token ID" ),
81+ clEnumValN (TokenMode::Random, " random" ,
82+ " Statically-assigned random token ID" ),
83+ clEnumValN (TokenMode::TypeHash, " typehash" ,
84+ " Token ID based on allocated type hash" )));
9385
9486cl::opt<std::string> ClFuncPrefix (" alloc-token-prefix" ,
9587 cl::desc (" The allocation function prefix" ),
@@ -106,7 +98,7 @@ cl::opt<bool>
10698
10799// Instrument libcalls only by default - compatible allocators only need to take
108100// care of providing standard allocation functions. With extended coverage, also
109- // instrument non-libcall allocation function calls with !alloc_token_hint
101+ // instrument non-libcall allocation function calls with !alloc_token
110102// metadata.
111103cl::opt<bool >
112104 ClExtended (" alloc-token-extended" ,
@@ -140,14 +132,14 @@ STATISTIC(NumAllocations, "Allocations found");
140132
141133// ===----------------------------------------------------------------------===//
142134
143- // / Returns the !alloc_token_hint metadata if available.
135+ // / Returns the !alloc_token metadata if available.
144136// /
145137// / Expected format is: !{<type-name>}
146- MDNode *getAllocTokenHintMetadata (const CallBase &CB) {
147- MDNode *Ret = CB.getMetadata (LLVMContext::MD_alloc_token_hint );
138+ MDNode *getAllocTokenMetadata (const CallBase &CB) {
139+ MDNode *Ret = CB.getMetadata (LLVMContext::MD_alloc_token );
148140 if (!Ret)
149141 return nullptr ;
150- assert (Ret->getNumOperands () == 1 && " bad !alloc_token_hint " );
142+ assert (Ret->getNumOperands () == 1 && " bad !alloc_token " );
151143 assert (isa<MDString>(Ret->getOperand (0 )));
152144 return Ret;
153145}
@@ -198,7 +190,7 @@ class TypeHashMode : public ModeBase {
198190 using ModeBase::ModeBase;
199191
200192 uint64_t operator ()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
201- if (MDNode *N = getAllocTokenHintMetadata (CB)) {
193+ if (MDNode *N = getAllocTokenMetadata (CB)) {
202194 MDString *S = cast<MDString>(N->getOperand (0 ));
203195 return boundedToken (xxHash64 (S->getString ()));
204196 }
@@ -212,7 +204,7 @@ class TypeHashMode : public ModeBase {
212204 ore::NV FuncNV (" Function" , CB.getParent ()->getParent ());
213205 const Function *Callee = CB.getCalledFunction ();
214206 ore::NV CalleeNV (" Callee" , Callee ? Callee->getName () : " <unknown>" );
215- return OptimizationRemark (DEBUG_TYPE, " NoAllocTokenHint " , &CB)
207+ return OptimizationRemark (DEBUG_TYPE, " NoAllocToken " , &CB)
216208 << " Call to '" << CalleeNV << " ' in '" << FuncNV
217209 << " ' without source-level type token" ;
218210 });
@@ -235,7 +227,7 @@ class AllocToken {
235227 : Options(transformOptionsFromCl(std::move(Opts))), Mod(M),
236228 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
237229 Mode(IncrementMode(*Options.MaxTokens)) {
238- switch (static_cast <TokenMode>( ClMode.getValue () )) {
230+ switch (ClMode.getValue ()) {
239231 case TokenMode::Increment:
240232 break ;
241233 case TokenMode::Random:
@@ -244,9 +236,6 @@ class AllocToken {
244236 case TokenMode::TypeHash:
245237 Mode.emplace <TypeHashMode>(*Options.MaxTokens );
246238 break ;
247- case TokenMode::ModeCount:
248- llvm_unreachable (" " );
249- break ;
250239 }
251240 }
252241
@@ -255,10 +244,11 @@ class AllocToken {
255244private:
256245 // / Returns true for !isAllocationFn() functions that are also eligible for
257246 // / instrumentation.
258- bool isInstrumentableLibFunc (LibFunc Func) const ;
247+ static bool isInstrumentableLibFunc (LibFunc Func, const Value *V,
248+ const TargetLibraryInfo *TLI);
259249
260250 // / Returns true for isAllocationFn() functions that we should ignore.
261- bool ignoreInstrumentableLibFunc (LibFunc Func) const ;
251+ static bool ignoreInstrumentableLibFunc (LibFunc Func);
262252
263253 // / Replace a call/invoke with a call/invoke to the allocation function
264254 // / with token ID.
@@ -277,6 +267,7 @@ class AllocToken {
277267
278268 const AllocTokenOptions Options;
279269 Module &Mod;
270+ IntegerType *IntPtrTy = Mod.getDataLayout().getIntPtrType(Mod.getContext());
280271 FunctionAnalysisManager &FAM;
281272 // Cache for replacement functions.
282273 DenseMap<std::pair<LibFunc, uint64_t >, FunctionCallee> TokenAllocFunctions;
@@ -316,28 +307,29 @@ bool AllocToken::instrumentFunction(Function &F) {
316307 if (TLI.getLibFunc (*Callee, Func)) {
317308 if (ignoreInstrumentableLibFunc (Func))
318309 continue ;
319- if (isInstrumentableLibFunc (Func) || isAllocationFn ( CB, &TLI))
310+ if (isInstrumentableLibFunc (Func, CB, &TLI))
320311 AllocCalls.emplace_back (CB, Func);
321- } else if (Options.Extended && getAllocTokenHintMetadata (*CB)) {
312+ } else if (Options.Extended && getAllocTokenMetadata (*CB)) {
322313 AllocCalls.emplace_back (CB, NotLibFunc);
323314 }
324315 }
325316
326- bool Modified = false ;
317+ if (AllocCalls.empty ())
318+ return false ;
327319
328- if (!AllocCalls.empty ()) {
329- for (auto &[CB, Func] : AllocCalls) {
330- replaceAllocationCall (CB, Func, ORE, TLI);
331- }
332- NumAllocations += AllocCalls.size ();
333- NumFunctionsInstrumented++;
334- Modified = true ;
335- }
320+ for (auto &[CB, Func] : AllocCalls)
321+ replaceAllocationCall (CB, Func, ORE, TLI);
322+ NumAllocations += AllocCalls.size ();
323+ NumFunctionsInstrumented++;
336324
337- return Modified ;
325+ return true ;
338326}
339327
340- bool AllocToken::isInstrumentableLibFunc (LibFunc Func) const {
328+ bool AllocToken::isInstrumentableLibFunc (LibFunc Func, const Value *V,
329+ const TargetLibraryInfo *TLI) {
330+ if (isAllocationFn (V, TLI))
331+ return true ;
332+
341333 switch (Func) {
342334 case LibFunc_posix_memalign:
343335 case LibFunc_size_returning_new:
@@ -375,7 +367,7 @@ bool AllocToken::isInstrumentableLibFunc(LibFunc Func) const {
375367 }
376368}
377369
378- bool AllocToken::ignoreInstrumentableLibFunc (LibFunc Func) const {
370+ bool AllocToken::ignoreInstrumentableLibFunc (LibFunc Func) {
379371 switch (Func) {
380372 case LibFunc_strdup:
381373 case LibFunc_dunder_strdup:
@@ -395,16 +387,17 @@ void AllocToken::replaceAllocationCall(CallBase *CB, LibFunc Func,
395387 FunctionCallee TokenAlloc = getTokenAllocFunction (*CB, TokenID, Func);
396388 if (!TokenAlloc)
397389 return ;
390+ if (Options.FastABI ) {
391+ assert (TokenAlloc.getFunctionType ()->getNumParams () == CB->arg_size ());
392+ CB->setCalledFunction (TokenAlloc);
393+ return ;
394+ }
398395
399396 IRBuilder<> IRB (CB);
400-
401397 // Original args.
402398 SmallVector<Value *, 4 > NewArgs{CB->args ()};
403- if (!Options.FastABI ) {
404- // Add token ID.
405- NewArgs.push_back (
406- ConstantInt::get (Type::getInt64Ty (Mod.getContext ()), TokenID));
407- }
399+ // Add token ID.
400+ NewArgs.push_back (ConstantInt::get (IntPtrTy, TokenID));
408401 assert (TokenAlloc.getFunctionType ()->getNumParams () == NewArgs.size ());
409402
410403 // Preserve invoke vs call semantics for exception handling.
@@ -443,15 +436,13 @@ FunctionCallee AllocToken::getTokenAllocFunction(const CallBase &CB,
443436 if (OldFTy->isVarArg ())
444437 return FunctionCallee ();
445438 // Copy params, and append token ID type.
446- LLVMContext &C = Mod.getContext ();
447439 Type *RetTy = OldFTy->getReturnType ();
448440 SmallVector<Type *, 4 > NewParams{OldFTy->params ()};
449441 std::string TokenAllocName = ClFuncPrefix;
450- if (Options.FastABI ) {
442+ if (Options.FastABI )
451443 TokenAllocName += utostr (TokenID) + " _" ;
452- } else {
453- NewParams.push_back (Type::getInt64Ty (C)); // token ID
454- }
444+ else
445+ NewParams.push_back (IntPtrTy); // token ID
455446 FunctionType *NewFTy = FunctionType::get (RetTy, NewParams, false );
456447 // Remove leading '_' - we add our own.
457448 StringRef No_ = Callee->getName ().drop_while ([](char C) { return C == ' _' ; });
@@ -480,5 +471,6 @@ PreservedAnalyses AllocTokenPass::run(Module &M, ModuleAnalysisManager &MAM) {
480471 Modified |= Pass.instrumentFunction (F);
481472 }
482473
483- return Modified ? PreservedAnalyses::none () : PreservedAnalyses::all ();
474+ return Modified ? PreservedAnalyses::none ().preserveSet <CFGAnalyses>()
475+ : PreservedAnalyses::all ();
484476}
0 commit comments