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"
35#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
37#include "llvm/IR/PassManager.h"
38#include "llvm/IR/Type.h"
47#include <cassert>
48#include <cstddef>
49#include <cstdint>
50#include <limits>
51#include <memory>
52#include <optional>
53#include <string>
54#include <utility>
55#include <variant>
56
57using namespace llvm;
59
60#define DEBUG_TYPE "alloc-token"
61
62namespace {
63
64//===--- Command-line options ---------------------------------------------===//
65
66cl::opt<std::string> ClFuncPrefix("alloc-token-prefix",
67 cl::desc("The allocation function prefix"),
68 cl::Hidden, cl::init("__alloc_token_"));
69
70cl::opt<uint64_t> ClMaxTokens("alloc-token-max",
71 cl::desc("Maximum number of tokens (0 = no max)"),
73
75 ClFastABI("alloc-token-fast-abi",
76 cl::desc("The token ID is encoded in the function name"),
77 cl::Hidden, cl::init(false));
78
79// Instrument libcalls only by default - compatible allocators only need to take
80// care of providing standard allocation functions. With extended coverage, also
81// instrument non-libcall allocation function calls with !alloc_token
82// metadata.
84 ClExtended("alloc-token-extended",
85 cl::desc("Extend coverage to custom allocation functions"),
86 cl::Hidden, cl::init(false));
87
88// C++ defines ::operator new (and variants) as replaceable (vs. standard
89// library versions), which are nobuiltin, and are therefore not covered by
90// isAllocationFn(). Cover by default, as users of AllocToken are already
91// required to provide token-aware allocation functions (no defaults).
92cl::opt<bool> ClCoverReplaceableNew("alloc-token-cover-replaceable-new",
93 cl::desc("Cover replaceable operator new"),
94 cl::Hidden, cl::init(true));
95
96cl::opt<uint64_t> ClFallbackToken(
97 "alloc-token-fallback",
98 cl::desc("The default fallback token where none could be determined"),
100
101//===--- Statistics -------------------------------------------------------===//
102
103STATISTIC(NumFunctionsModified, "Functions modified");
104STATISTIC(NumAllocationsInstrumented, "Allocations instrumented");
105
106//===----------------------------------------------------------------------===//
107
108/// Returns the !alloc_token metadata if available.
109///
110/// Expected format is: !{<type-name>, <contains-pointer>}
111MDNode *getAllocTokenMetadata(const CallBase &CB) {
112 MDNode *Ret = nullptr;
113 if (auto *II = dyn_cast<IntrinsicInst>(&CB);
114 II && II->getIntrinsicID() == Intrinsic::alloc_token_id) {
115 auto *MDV = cast<MetadataAsValue>(II->getArgOperand(0));
116 Ret = cast<MDNode>(MDV->getMetadata());
117 // If the intrinsic has an empty MDNode, type inference failed.
118 if (Ret->getNumOperands() == 0)
119 return nullptr;
120 } else {
121 Ret = CB.getMetadata(LLVMContext::MD_alloc_token);
122 if (!Ret)
123 return nullptr;
124 }
125 assert(Ret->getNumOperands() == 2 && "bad !alloc_token");
126 assert(isa<MDString>(Ret->getOperand(0)));
127 assert(isa<ConstantAsMetadata>(Ret->getOperand(1)));
128 return Ret;
129}
130
131bool containsPointer(const MDNode *MD) {
133 auto *CI = cast<ConstantInt>(C->getValue());
134 return CI->getValue().getBoolValue();
135}
136
137class ModeBase {
138public:
139 explicit ModeBase(const IntegerType &TokenTy, uint64_t MaxTokens)
140 : MaxTokens(MaxTokens ? MaxTokens : TokenTy.getBitMask()) {
141 assert(MaxTokens <= TokenTy.getBitMask());
142 }
143
144protected:
145 uint64_t boundedToken(uint64_t Val) const {
146 assert(MaxTokens != 0);
147 return Val % MaxTokens;
148 }
149
150 const uint64_t MaxTokens;
151};
152
153/// Implementation for TokenMode::Increment.
154class IncrementMode : public ModeBase {
155public:
156 using ModeBase::ModeBase;
157
158 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
159 return boundedToken(Counter++);
160 }
161
162private:
163 uint64_t Counter = 0;
164};
165
166/// Implementation for TokenMode::Random.
167class RandomMode : public ModeBase {
168public:
169 RandomMode(const IntegerType &TokenTy, uint64_t MaxTokens,
170 std::unique_ptr<RandomNumberGenerator> RNG)
171 : ModeBase(TokenTy, MaxTokens), RNG(std::move(RNG)) {}
172 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
173 return boundedToken((*RNG)());
174 }
175
176private:
177 std::unique_ptr<RandomNumberGenerator> RNG;
178};
179
180/// Implementation for TokenMode::TypeHash. The implementation ensures
181/// hashes are stable across different compiler invocations. Uses SipHash as the
182/// hash function.
183class TypeHashMode : public ModeBase {
184public:
185 using ModeBase::ModeBase;
186
187 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
188
189 if (MDNode *N = getAllocTokenMetadata(CB)) {
190 MDString *S = cast<MDString>(N->getOperand(0));
191 AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
192 if (auto Token = getAllocToken(TokenMode::TypeHash, Metadata, MaxTokens))
193 return *Token;
194 }
195 // Fallback.
196 remarkNoMetadata(CB, ORE);
197 return ClFallbackToken;
198 }
199
200protected:
201 /// Remark that there was no precise type information.
202 static void remarkNoMetadata(const CallBase &CB,
204 ORE.emit([&] {
205 ore::NV FuncNV("Function", CB.getParent()->getParent());
206 const Function *Callee = CB.getCalledFunction();
207 ore::NV CalleeNV("Callee", Callee ? Callee->getName() : "<unknown>");
208 return OptimizationRemark(DEBUG_TYPE, "NoAllocToken", &CB)
209 << "Call to '" << CalleeNV << "' in '" << FuncNV
210 << "' without source-level type token";
211 });
212 }
213};
214
215/// Implementation for TokenMode::TypeHashPointerSplit.
216class TypeHashPointerSplitMode : public TypeHashMode {
217public:
218 using TypeHashMode::TypeHashMode;
219
220 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
221 if (MDNode *N = getAllocTokenMetadata(CB)) {
222 MDString *S = cast<MDString>(N->getOperand(0));
223 AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
225 MaxTokens))
226 return *Token;
227 }
228 // Pick the fallback token (ClFallbackToken), which by default is 0, meaning
229 // it'll fall into the pointer-less bucket. Override by setting
230 // -alloc-token-fallback if that is the wrong choice.
231 remarkNoMetadata(CB, ORE);
232 return ClFallbackToken;
233 }
234};
235
236// Apply opt overrides.
237AllocTokenOptions transformOptionsFromCl(AllocTokenOptions Opts) {
238 if (!Opts.MaxTokens.has_value())
239 Opts.MaxTokens = ClMaxTokens;
240 Opts.FastABI |= ClFastABI;
241 Opts.Extended |= ClExtended;
242 return Opts;
243}
244
245class AllocToken {
246public:
247 explicit AllocToken(AllocTokenOptions Opts, Module &M,
249 : Options(transformOptionsFromCl(std::move(Opts))), Mod(M),
250 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
251 Mode(IncrementMode(*IntPtrTy, *Options.MaxTokens)) {
252 switch (Options.Mode) {
254 break;
256 Mode.emplace<RandomMode>(*IntPtrTy, *Options.MaxTokens,
257 M.createRNG(DEBUG_TYPE));
258 break;
260 Mode.emplace<TypeHashMode>(*IntPtrTy, *Options.MaxTokens);
261 break;
263 Mode.emplace<TypeHashPointerSplitMode>(*IntPtrTy, *Options.MaxTokens);
264 break;
265 }
266 }
267
268 bool instrumentFunction(Function &F);
269
270private:
271 /// Returns the LibFunc (or NotLibFunc) if this call should be instrumented.
272 std::optional<LibFunc>
273 shouldInstrumentCall(const CallBase &CB, const TargetLibraryInfo &TLI) const;
274
275 /// Returns true for functions that are eligible for instrumentation.
276 static bool isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
277 const TargetLibraryInfo &TLI);
278
279 /// Returns true for isAllocationFn() functions that we should ignore.
280 static bool ignoreInstrumentableLibFunc(LibFunc Func);
281
282 /// Replace a call/invoke with a call/invoke to the allocation function
283 /// with token ID.
284 bool replaceAllocationCall(CallBase *CB, LibFunc Func,
286 const TargetLibraryInfo &TLI);
287
288 /// Return replacement function for a LibFunc that takes a token ID.
289 FunctionCallee getTokenAllocFunction(const CallBase &CB, uint64_t TokenID,
290 LibFunc OriginalFunc);
291
292 /// Lower alloc_token_* intrinsics.
293 void replaceIntrinsicInst(IntrinsicInst *II, OptimizationRemarkEmitter &ORE);
294
295 /// Return the token ID from metadata in the call.
297 return std::visit([&](auto &&Mode) { return Mode(CB, ORE); }, Mode);
298 }
299
301 Module &Mod;
302 IntegerType *IntPtrTy = Mod.getDataLayout().getIntPtrType(Mod.getContext());
304 // Cache for replacement functions.
306 // Selected mode.
307 std::variant<IncrementMode, RandomMode, TypeHashMode,
308 TypeHashPointerSplitMode>
309 Mode;
310};
311
312bool AllocToken::instrumentFunction(Function &F) {
313 // Do not apply any instrumentation for naked functions.
314 if (F.hasFnAttribute(Attribute::Naked))
315 return false;
316 // Don't touch available_externally functions, their actual body is elsewhere.
317 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
318 return false;
319
320 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
321 auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
323 SmallVector<IntrinsicInst *, 4> IntrinsicInsts;
324
325 // Only instrument functions that have the sanitize_alloc_token attribute.
326 const bool InstrumentFunction =
327 F.hasFnAttribute(Attribute::SanitizeAllocToken) &&
328 !F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation);
329
330 // Collect all allocation calls to avoid iterator invalidation.
331 for (Instruction &I : instructions(F)) {
332 // Collect all alloc_token_* intrinsics.
333 if (auto *II = dyn_cast<IntrinsicInst>(&I);
334 II && II->getIntrinsicID() == Intrinsic::alloc_token_id) {
335 IntrinsicInsts.emplace_back(II);
336 continue;
337 }
338
339 if (!InstrumentFunction)
340 continue;
341
342 auto *CB = dyn_cast<CallBase>(&I);
343 if (!CB)
344 continue;
345 if (std::optional<LibFunc> Func = shouldInstrumentCall(*CB, TLI))
346 AllocCalls.emplace_back(CB, Func.value());
347 }
348
349 bool Modified = false;
350
351 if (!AllocCalls.empty()) {
352 for (auto &[CB, Func] : AllocCalls)
353 Modified |= replaceAllocationCall(CB, Func, ORE, TLI);
354 if (Modified)
355 NumFunctionsModified++;
356 }
357
358 if (!IntrinsicInsts.empty()) {
359 for (auto *II : IntrinsicInsts)
360 replaceIntrinsicInst(II, ORE);
361 Modified = true;
362 NumFunctionsModified++;
363 }
364
365 return Modified;
366}
367
368std::optional<LibFunc>
369AllocToken::shouldInstrumentCall(const CallBase &CB,
370 const TargetLibraryInfo &TLI) const {
371 const Function *Callee = CB.getCalledFunction();
372 if (!Callee)
373 return std::nullopt;
374
375 // Ignore nobuiltin of the CallBase, so that we can cover nobuiltin libcalls
376 // if requested via isInstrumentableLibFunc(). Note that isAllocationFn() is
377 // returning false for nobuiltin calls.
378 LibFunc Func;
379 if (TLI.getLibFunc(*Callee, Func)) {
380 if (isInstrumentableLibFunc(Func, CB, TLI))
381 return Func;
382 } else if (Options.Extended && CB.getMetadata(LLVMContext::MD_alloc_token)) {
383 return NotLibFunc;
384 }
385
386 return std::nullopt;
387}
388
389bool AllocToken::isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
390 const TargetLibraryInfo &TLI) {
391 if (ignoreInstrumentableLibFunc(Func))
392 return false;
393
394 if (isAllocationFn(&CB, &TLI))
395 return true;
396
397 switch (Func) {
398 // These libfuncs don't return normal pointers, and are therefore not handled
399 // by isAllocationFn().
400 case LibFunc_posix_memalign:
401 case LibFunc_size_returning_new:
402 case LibFunc_size_returning_new_hot_cold:
403 case LibFunc_size_returning_new_aligned:
404 case LibFunc_size_returning_new_aligned_hot_cold:
405 return true;
406
407 // See comment above ClCoverReplaceableNew.
408 case LibFunc_Znwj:
409 case LibFunc_ZnwjRKSt9nothrow_t:
410 case LibFunc_ZnwjSt11align_val_t:
411 case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
412 case LibFunc_Znwm:
413 case LibFunc_Znwm12__hot_cold_t:
414 case LibFunc_ZnwmRKSt9nothrow_t:
415 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
416 case LibFunc_ZnwmSt11align_val_t:
417 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
418 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
419 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
420 case LibFunc_Znaj:
421 case LibFunc_ZnajRKSt9nothrow_t:
422 case LibFunc_ZnajSt11align_val_t:
423 case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
424 case LibFunc_Znam:
425 case LibFunc_Znam12__hot_cold_t:
426 case LibFunc_ZnamRKSt9nothrow_t:
427 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
428 case LibFunc_ZnamSt11align_val_t:
429 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
430 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
431 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
432 return ClCoverReplaceableNew;
433
434 default:
435 return false;
436 }
437}
438
439bool AllocToken::ignoreInstrumentableLibFunc(LibFunc Func) {
440 switch (Func) {
441 case LibFunc_strdup:
442 case LibFunc_dunder_strdup:
443 case LibFunc_strndup:
444 case LibFunc_dunder_strndup:
445 return true;
446 default:
447 return false;
448 }
449}
450
451bool AllocToken::replaceAllocationCall(CallBase *CB, LibFunc Func,
453 const TargetLibraryInfo &TLI) {
454 uint64_t TokenID = getToken(*CB, ORE);
455
456 FunctionCallee TokenAlloc = getTokenAllocFunction(*CB, TokenID, Func);
457 if (!TokenAlloc)
458 return false;
459 NumAllocationsInstrumented++;
460
461 if (Options.FastABI) {
462 assert(TokenAlloc.getFunctionType()->getNumParams() == CB->arg_size());
463 CB->setCalledFunction(TokenAlloc);
464 return true;
465 }
466
467 IRBuilder<> IRB(CB);
468 // Original args.
469 SmallVector<Value *, 4> NewArgs{CB->args()};
470 // Add token ID, truncated to IntPtrTy width.
471 NewArgs.push_back(ConstantInt::get(IntPtrTy, TokenID));
472 assert(TokenAlloc.getFunctionType()->getNumParams() == NewArgs.size());
473
474 // Preserve invoke vs call semantics for exception handling.
475 CallBase *NewCall;
476 if (auto *II = dyn_cast<InvokeInst>(CB)) {
477 NewCall = IRB.CreateInvoke(TokenAlloc, II->getNormalDest(),
478 II->getUnwindDest(), NewArgs);
479 } else {
480 NewCall = IRB.CreateCall(TokenAlloc, NewArgs);
481 cast<CallInst>(NewCall)->setTailCall(CB->isTailCall());
482 }
483 NewCall->setCallingConv(CB->getCallingConv());
484 NewCall->copyMetadata(*CB);
485 NewCall->setAttributes(CB->getAttributes());
486
487 // Replace all uses and delete the old call.
488 CB->replaceAllUsesWith(NewCall);
489 CB->eraseFromParent();
490 return true;
491}
492
493FunctionCallee AllocToken::getTokenAllocFunction(const CallBase &CB,
494 uint64_t TokenID,
495 LibFunc OriginalFunc) {
496 std::optional<std::pair<LibFunc, uint64_t>> Key;
497 if (OriginalFunc != NotLibFunc) {
498 Key = std::make_pair(OriginalFunc, Options.FastABI ? TokenID : 0);
499 auto It = TokenAllocFunctions.find(*Key);
500 if (It != TokenAllocFunctions.end())
501 return It->second;
502 }
503
504 const Function *Callee = CB.getCalledFunction();
505 if (!Callee)
506 return FunctionCallee();
507 const FunctionType *OldFTy = Callee->getFunctionType();
508 if (OldFTy->isVarArg())
509 return FunctionCallee();
510 // Copy params, and append token ID type.
511 Type *RetTy = OldFTy->getReturnType();
512 SmallVector<Type *, 4> NewParams{OldFTy->params()};
513 std::string TokenAllocName = ClFuncPrefix;
514 if (Options.FastABI)
515 TokenAllocName += utostr(TokenID) + "_";
516 else
517 NewParams.push_back(IntPtrTy); // token ID
518 TokenAllocName += Callee->getName();
519 FunctionType *NewFTy = FunctionType::get(RetTy, NewParams, false);
520 FunctionCallee TokenAlloc = Mod.getOrInsertFunction(TokenAllocName, NewFTy);
521 if (Function *F = dyn_cast<Function>(TokenAlloc.getCallee()))
522 F->copyAttributesFrom(Callee); // preserve attrs
523
524 if (Key.has_value())
525 TokenAllocFunctions[*Key] = TokenAlloc;
526 return TokenAlloc;
527}
528
529void AllocToken::replaceIntrinsicInst(IntrinsicInst *II,
531 assert(II->getIntrinsicID() == Intrinsic::alloc_token_id);
532
533 uint64_t TokenID = getToken(*II, ORE);
534 Value *V = ConstantInt::get(IntPtrTy, TokenID);
535 II->replaceAllUsesWith(V);
536 II->eraseFromParent();
537}
538
539} // namespace
540
543
545 AllocToken Pass(Options, M, MAM);
546 bool Modified = false;
547
548 for (Function &F : M) {
549 if (F.empty())
550 continue; // declaration
551 Modified |= Pass.instrumentFunction(F);
552 }
553
556}
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...
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:593
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.
AllocTokenMode TokenMode
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:2788
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...
A wrapper class for inspecting calls to intrinsic functions.
Metadata node.
Definition Metadata.h:1078
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1442
A single uniqued string.
Definition Metadata.h:721
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:618
Root of the metadata hierarchy.
Definition Metadata.h:64
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
reference emplace_back(ArgTypes &&... Args)
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 Value Representation.
Definition Value.h:75
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.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::optional< uint64_t > getAllocToken(AllocTokenMode Mode, const AllocTokenMetadata &Metadata, uint64_t MaxTokens)
Calculates stable allocation token ID.
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:643
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
std::string utostr(uint64_t X, bool isNeg=false)
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:547
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:1867
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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.
AllocTokenMode
Modes for generating allocation token IDs.
Definition AllocToken.h:24
@ TypeHash
Token ID based on allocated type hash.
Definition AllocToken.h:32
@ Random
Simple mode that returns a statically-assigned random token ID.
Definition AllocToken.h:29
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
@ TypeHashPointerSplit
Token ID based on allocated type hash, where the top half ID-space is reserved for types that contain...
Definition AllocToken.h:37
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
Metadata about an allocation used to generate a token ID.
Definition AllocToken.h:50
std::optional< uint64_t > MaxTokens
Definition AllocToken.h:28