LLVM 22.0.0git
AllocToken.cpp
Go to the documentation of this file.
1//===- AllocToken.cpp - Allocation token instrumentation ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements AllocToken, an instrumentation pass that
10// replaces allocation calls with token-enabled versions.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/Statistic.h"
20#include "llvm/ADT/StringRef.h"
24#include "llvm/IR/Analysis.h"
25#include "llvm/IR/Attributes.h"
26#include "llvm/IR/Constants.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/GlobalValue.h"
30#include "llvm/IR/IRBuilder.h"
32#include "llvm/IR/InstrTypes.h"
34#include "llvm/IR/Metadata.h"
35#include "llvm/IR/Module.h"
36#include "llvm/IR/PassManager.h"
37#include "llvm/IR/Type.h"
45#include <cassert>
46#include <cstddef>
47#include <cstdint>
48#include <limits>
49#include <memory>
50#include <optional>
51#include <string>
52#include <utility>
53#include <variant>
54
55using namespace llvm;
56
57#define DEBUG_TYPE "alloc-token"
58
59namespace {
60
61//===--- Constants --------------------------------------------------------===//
62
63enum class TokenMode : unsigned {
64 /// Incrementally increasing token ID.
65 Increment = 0,
66
67 /// Simple mode that returns a statically-assigned random token ID.
68 Random = 1,
69
70 /// Token ID based on allocated type hash.
71 TypeHash = 2,
72};
73
74//===--- Command-line options ---------------------------------------------===//
75
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")));
85
86cl::opt<std::string> ClFuncPrefix("alloc-token-prefix",
87 cl::desc("The allocation function prefix"),
88 cl::Hidden, cl::init("__alloc_token_"));
89
90cl::opt<uint64_t> ClMaxTokens("alloc-token-max",
91 cl::desc("Maximum number of tokens (0 = no max)"),
93
95 ClFastABI("alloc-token-fast-abi",
96 cl::desc("The token ID is encoded in the function name"),
97 cl::Hidden, cl::init(false));
98
99// Instrument libcalls only by default - compatible allocators only need to take
100// care of providing standard allocation functions. With extended coverage, also
101// instrument non-libcall allocation function calls with !alloc_token
102// metadata.
104 ClExtended("alloc-token-extended",
105 cl::desc("Extend coverage to custom allocation functions"),
106 cl::Hidden, cl::init(false));
107
108// C++ defines ::operator new (and variants) as replaceable (vs. standard
109// library versions), which are nobuiltin, and are therefore not covered by
110// isAllocationFn(). Cover by default, as users of AllocToken are already
111// required to provide token-aware allocation functions (no defaults).
112cl::opt<bool> ClCoverReplaceableNew("alloc-token-cover-replaceable-new",
113 cl::desc("Cover replaceable operator new"),
114 cl::Hidden, cl::init(true));
115
116cl::opt<uint64_t> ClFallbackToken(
117 "alloc-token-fallback",
118 cl::desc("The default fallback token where none could be determined"),
119 cl::Hidden, cl::init(0));
120
121//===--- Statistics -------------------------------------------------------===//
122
123STATISTIC(NumFunctionsInstrumented, "Functions instrumented");
124STATISTIC(NumAllocationsInstrumented, "Allocations instrumented");
125
126//===----------------------------------------------------------------------===//
127
128/// Returns the !alloc_token metadata if available.
129///
130/// Expected format is: !{<type-name>}
131MDNode *getAllocTokenMetadata(const CallBase &CB) {
132 MDNode *Ret = CB.getMetadata(LLVMContext::MD_alloc_token);
133 if (!Ret)
134 return nullptr;
135 assert(Ret->getNumOperands() == 1 && "bad !alloc_token");
136 assert(isa<MDString>(Ret->getOperand(0)));
137 return Ret;
138}
139
140class ModeBase {
141public:
142 explicit ModeBase(const IntegerType &TokenTy, uint64_t MaxTokens)
143 : MaxTokens(MaxTokens ? MaxTokens : TokenTy.getBitMask()) {
144 assert(MaxTokens <= TokenTy.getBitMask());
145 }
146
147protected:
148 uint64_t boundedToken(uint64_t Val) const {
149 assert(MaxTokens != 0);
150 return Val % MaxTokens;
151 }
152
153 const uint64_t MaxTokens;
154};
155
156/// Implementation for TokenMode::Increment.
157class IncrementMode : public ModeBase {
158public:
159 using ModeBase::ModeBase;
160
161 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
162 return boundedToken(Counter++);
163 }
164
165private:
166 uint64_t Counter = 0;
167};
168
169/// Implementation for TokenMode::Random.
170class RandomMode : public ModeBase {
171public:
172 RandomMode(const IntegerType &TokenTy, uint64_t MaxTokens,
173 std::unique_ptr<RandomNumberGenerator> RNG)
174 : ModeBase(TokenTy, MaxTokens), RNG(std::move(RNG)) {}
175 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
176 return boundedToken((*RNG)());
177 }
178
179private:
180 std::unique_ptr<RandomNumberGenerator> RNG;
181};
182
183/// Implementation for TokenMode::TypeHash. The implementation ensures
184/// hashes are stable across different compiler invocations. Uses SipHash as the
185/// hash function.
186class TypeHashMode : public ModeBase {
187public:
188 using ModeBase::ModeBase;
189
190 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
191 if (MDNode *N = getAllocTokenMetadata(CB)) {
192 MDString *S = cast<MDString>(N->getOperand(0));
193 return boundedToken(getStableSipHash(S->getString()));
194 }
195 remarkNoMetadata(CB, ORE);
196 return ClFallbackToken;
197 }
198
199 /// Remark that there was no precise type information.
200 static void remarkNoMetadata(const CallBase &CB,
202 ORE.emit([&] {
203 ore::NV FuncNV("Function", CB.getParent()->getParent());
204 const Function *Callee = CB.getCalledFunction();
205 ore::NV CalleeNV("Callee", Callee ? Callee->getName() : "<unknown>");
206 return OptimizationRemark(DEBUG_TYPE, "NoAllocToken", &CB)
207 << "Call to '" << CalleeNV << "' in '" << FuncNV
208 << "' without source-level type token";
209 });
210 }
211};
212
213// Apply opt overrides.
214AllocTokenOptions transformOptionsFromCl(AllocTokenOptions Opts) {
215 if (!Opts.MaxTokens.has_value())
216 Opts.MaxTokens = ClMaxTokens;
217 Opts.FastABI |= ClFastABI;
218 Opts.Extended |= ClExtended;
219 return Opts;
220}
221
222class AllocToken {
223public:
224 explicit AllocToken(AllocTokenOptions Opts, Module &M,
226 : Options(transformOptionsFromCl(std::move(Opts))), Mod(M),
227 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
228 Mode(IncrementMode(*IntPtrTy, *Options.MaxTokens)) {
229 switch (ClMode.getValue()) {
230 case TokenMode::Increment:
231 break;
232 case TokenMode::Random:
233 Mode.emplace<RandomMode>(*IntPtrTy, *Options.MaxTokens,
234 M.createRNG(DEBUG_TYPE));
235 break;
236 case TokenMode::TypeHash:
237 Mode.emplace<TypeHashMode>(*IntPtrTy, *Options.MaxTokens);
238 break;
239 }
240 }
241
242 bool instrumentFunction(Function &F);
243
244private:
245 /// Returns the LibFunc (or NotLibFunc) if this call should be instrumented.
246 std::optional<LibFunc>
247 shouldInstrumentCall(const CallBase &CB, const TargetLibraryInfo &TLI) const;
248
249 /// Returns true for functions that are eligible for instrumentation.
250 static bool isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
251 const TargetLibraryInfo &TLI);
252
253 /// Returns true for isAllocationFn() functions that we should ignore.
254 static bool ignoreInstrumentableLibFunc(LibFunc Func);
255
256 /// Replace a call/invoke with a call/invoke to the allocation function
257 /// with token ID.
258 bool replaceAllocationCall(CallBase *CB, LibFunc Func,
260 const TargetLibraryInfo &TLI);
261
262 /// Return replacement function for a LibFunc that takes a token ID.
263 FunctionCallee getTokenAllocFunction(const CallBase &CB, uint64_t TokenID,
264 LibFunc OriginalFunc);
265
266 /// Return the token ID from metadata in the call.
268 return std::visit([&](auto &&Mode) { return Mode(CB, ORE); }, Mode);
269 }
270
272 Module &Mod;
273 IntegerType *IntPtrTy = Mod.getDataLayout().getIntPtrType(Mod.getContext());
275 // Cache for replacement functions.
277 // Selected mode.
278 std::variant<IncrementMode, RandomMode, TypeHashMode> Mode;
279};
280
281bool AllocToken::instrumentFunction(Function &F) {
282 // Do not apply any instrumentation for naked functions.
283 if (F.hasFnAttribute(Attribute::Naked))
284 return false;
285 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
286 return false;
287 // Don't touch available_externally functions, their actual body is elsewhere.
288 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
289 return false;
290 // Only instrument functions that have the sanitize_alloc_token attribute.
291 if (!F.hasFnAttribute(Attribute::SanitizeAllocToken))
292 return false;
293
294 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
295 auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
297
298 // Collect all allocation calls to avoid iterator invalidation.
299 for (Instruction &I : instructions(F)) {
300 auto *CB = dyn_cast<CallBase>(&I);
301 if (!CB)
302 continue;
303 if (std::optional<LibFunc> Func = shouldInstrumentCall(*CB, TLI))
304 AllocCalls.emplace_back(CB, Func.value());
305 }
306
307 bool Modified = false;
308 for (auto &[CB, Func] : AllocCalls)
309 Modified |= replaceAllocationCall(CB, Func, ORE, TLI);
310
311 if (Modified)
312 NumFunctionsInstrumented++;
313 return Modified;
314}
315
316std::optional<LibFunc>
317AllocToken::shouldInstrumentCall(const CallBase &CB,
318 const TargetLibraryInfo &TLI) const {
319 const Function *Callee = CB.getCalledFunction();
320 if (!Callee)
321 return std::nullopt;
322
323 // Ignore nobuiltin of the CallBase, so that we can cover nobuiltin libcalls
324 // if requested via isInstrumentableLibFunc(). Note that isAllocationFn() is
325 // returning false for nobuiltin calls.
326 LibFunc Func;
327 if (TLI.getLibFunc(*Callee, Func)) {
328 if (isInstrumentableLibFunc(Func, CB, TLI))
329 return Func;
330 } else if (Options.Extended && getAllocTokenMetadata(CB)) {
331 return NotLibFunc;
332 }
333
334 return std::nullopt;
335}
336
337bool AllocToken::isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
338 const TargetLibraryInfo &TLI) {
339 if (ignoreInstrumentableLibFunc(Func))
340 return false;
341
342 if (isAllocationFn(&CB, &TLI))
343 return true;
344
345 switch (Func) {
346 // These libfuncs don't return normal pointers, and are therefore not handled
347 // by isAllocationFn().
348 case LibFunc_posix_memalign:
349 case LibFunc_size_returning_new:
350 case LibFunc_size_returning_new_hot_cold:
351 case LibFunc_size_returning_new_aligned:
352 case LibFunc_size_returning_new_aligned_hot_cold:
353 return true;
354
355 // See comment above ClCoverReplaceableNew.
356 case LibFunc_Znwj:
357 case LibFunc_ZnwjRKSt9nothrow_t:
358 case LibFunc_ZnwjSt11align_val_t:
359 case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
360 case LibFunc_Znwm:
361 case LibFunc_Znwm12__hot_cold_t:
362 case LibFunc_ZnwmRKSt9nothrow_t:
363 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
364 case LibFunc_ZnwmSt11align_val_t:
365 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
366 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
367 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
368 case LibFunc_Znaj:
369 case LibFunc_ZnajRKSt9nothrow_t:
370 case LibFunc_ZnajSt11align_val_t:
371 case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
372 case LibFunc_Znam:
373 case LibFunc_Znam12__hot_cold_t:
374 case LibFunc_ZnamRKSt9nothrow_t:
375 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
376 case LibFunc_ZnamSt11align_val_t:
377 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
378 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
379 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
380 return ClCoverReplaceableNew;
381
382 default:
383 return false;
384 }
385}
386
387bool AllocToken::ignoreInstrumentableLibFunc(LibFunc Func) {
388 switch (Func) {
389 case LibFunc_strdup:
390 case LibFunc_dunder_strdup:
391 case LibFunc_strndup:
392 case LibFunc_dunder_strndup:
393 return true;
394 default:
395 return false;
396 }
397}
398
399bool AllocToken::replaceAllocationCall(CallBase *CB, LibFunc Func,
401 const TargetLibraryInfo &TLI) {
402 uint64_t TokenID = getToken(*CB, ORE);
403
404 FunctionCallee TokenAlloc = getTokenAllocFunction(*CB, TokenID, Func);
405 if (!TokenAlloc)
406 return false;
407 NumAllocationsInstrumented++;
408
409 if (Options.FastABI) {
410 assert(TokenAlloc.getFunctionType()->getNumParams() == CB->arg_size());
411 CB->setCalledFunction(TokenAlloc);
412 return true;
413 }
414
415 IRBuilder<> IRB(CB);
416 // Original args.
417 SmallVector<Value *, 4> NewArgs{CB->args()};
418 // Add token ID, truncated to IntPtrTy width.
419 NewArgs.push_back(ConstantInt::get(IntPtrTy, TokenID));
420 assert(TokenAlloc.getFunctionType()->getNumParams() == NewArgs.size());
421
422 // Preserve invoke vs call semantics for exception handling.
423 CallBase *NewCall;
424 if (auto *II = dyn_cast<InvokeInst>(CB)) {
425 NewCall = IRB.CreateInvoke(TokenAlloc, II->getNormalDest(),
426 II->getUnwindDest(), NewArgs);
427 } else {
428 NewCall = IRB.CreateCall(TokenAlloc, NewArgs);
429 cast<CallInst>(NewCall)->setTailCall(CB->isTailCall());
430 }
431 NewCall->setCallingConv(CB->getCallingConv());
432 NewCall->copyMetadata(*CB);
433 NewCall->setAttributes(CB->getAttributes());
434
435 // Replace all uses and delete the old call.
436 CB->replaceAllUsesWith(NewCall);
437 CB->eraseFromParent();
438 return true;
439}
440
441FunctionCallee AllocToken::getTokenAllocFunction(const CallBase &CB,
442 uint64_t TokenID,
443 LibFunc OriginalFunc) {
444 std::optional<std::pair<LibFunc, uint64_t>> Key;
445 if (OriginalFunc != NotLibFunc) {
446 Key = std::make_pair(OriginalFunc, Options.FastABI ? TokenID : 0);
447 auto It = TokenAllocFunctions.find(*Key);
448 if (It != TokenAllocFunctions.end())
449 return It->second;
450 }
451
452 const Function *Callee = CB.getCalledFunction();
453 if (!Callee)
454 return FunctionCallee();
455 const FunctionType *OldFTy = Callee->getFunctionType();
456 if (OldFTy->isVarArg())
457 return FunctionCallee();
458 // Copy params, and append token ID type.
459 Type *RetTy = OldFTy->getReturnType();
460 SmallVector<Type *, 4> NewParams{OldFTy->params()};
461 std::string TokenAllocName = ClFuncPrefix;
462 if (Options.FastABI)
463 TokenAllocName += utostr(TokenID) + "_";
464 else
465 NewParams.push_back(IntPtrTy); // token ID
466 TokenAllocName += Callee->getName();
467 FunctionType *NewFTy = FunctionType::get(RetTy, NewParams, false);
468 FunctionCallee TokenAlloc = Mod.getOrInsertFunction(TokenAllocName, NewFTy);
469 if (Function *F = dyn_cast<Function>(TokenAlloc.getCallee()))
470 F->copyAttributesFrom(Callee); // preserve attrs
471
472 if (Key.has_value())
473 TokenAllocFunctions[*Key] = TokenAlloc;
474 return TokenAlloc;
475}
476
477} // namespace
478
481
483 AllocToken Pass(Options, M, MAM);
484 bool Modified = false;
485
486 for (Function &F : M) {
487 if (F.empty())
488 continue; // declaration
489 Modified |= Pass.instrumentFunction(F);
490 }
491
494}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
#define DEBUG_TYPE
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:273
This file contains the declarations for metadata subclasses.
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
LLVM_ABI AllocTokenPass(AllocTokenOptions Opts={})
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
void setAttributes(AttributeList A)
Set the attributes for this call.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
LLVM_ABI bool isTailCall() const
Tests if this call site is marked as a tail call.
void setTailCall(bool IsTc=true)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionType * getFunctionType()
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
InvokeInst * CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > OpBundles, const Twine &Name="")
Create an invoke instruction.
Definition IRBuilder.h:1235
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2511
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2783
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
Class to represent integer types.
uint64_t getBitMask() const
Return a bitmask with ones set for all of the bits that can be set by an unsigned version of this typ...
Metadata node.
Definition Metadata.h:1078
A single uniqued string.
Definition Metadata.h:721
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:618
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for applied optimization remarks.
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:546
const ParentTy * getParent() const
Definition ilist_node.h:34
Pass manager infrastructure for declaring and invalidating analyses.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:644
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI uint64_t getStableSipHash(StringRef Str)
Compute a stable 64-bit hash of the given string.
Definition SipHash.cpp:39
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1869
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:560
LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:867
#define N
std::optional< uint64_t > MaxTokens
Definition AllocToken.h:26