LLVM 24.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"
17#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/Analysis.h"
24#include "llvm/IR/Attributes.h"
25#include "llvm/IR/Constants.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/IRBuilder.h"
31#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 <cstdint>
47#include <memory>
48#include <optional>
49#include <string>
50#include <utility>
51#include <variant>
52
53using namespace llvm;
55
56#define DEBUG_TYPE "alloc-token"
57
58namespace {
59
60//===--- Command-line options ---------------------------------------------===//
61
62cl::opt<std::string> ClFuncPrefix("alloc-token-prefix",
63 cl::desc("The allocation function prefix"),
64 cl::Hidden, cl::init("__alloc_token_"));
65
67 ClMaxTokens("alloc-token-max",
68 cl::desc("Maximum number of tokens (0 = target SIZE_MAX)"),
70
72 ClFastABI("alloc-token-fast-abi",
73 cl::desc("The token ID is encoded in the function name"),
74 cl::Hidden, cl::init(false));
75
76// Instrument libcalls only by default - compatible allocators only need to take
77// care of providing standard allocation functions. With extended coverage, also
78// instrument non-libcall allocation function calls with !alloc_token
79// metadata.
81 ClExtended("alloc-token-extended",
82 cl::desc("Extend coverage to custom allocation functions"),
83 cl::Hidden, cl::init(false));
84
85// C++ defines ::operator new (and variants) as replaceable (vs. standard
86// library versions), which are nobuiltin, and are therefore not covered by
87// isAllocationFn(). Cover by default, as users of AllocToken are already
88// required to provide token-aware allocation functions (no defaults).
89cl::opt<bool> ClCoverReplaceableNew("alloc-token-cover-replaceable-new",
90 cl::desc("Cover replaceable operator new"),
91 cl::Hidden, cl::init(true));
92
93cl::opt<uint64_t> ClFallbackToken(
94 "alloc-token-fallback",
95 cl::desc("The default fallback token where none could be determined"),
97
98//===--- Statistics -------------------------------------------------------===//
99
100STATISTIC(NumFunctionsModified, "Functions modified");
101STATISTIC(NumAllocationsInstrumented, "Allocations instrumented");
102
103//===----------------------------------------------------------------------===//
104
105/// Returns the !alloc_token metadata if available.
106///
107/// Expected format is: !{<type-name>, <contains-pointer>}
108MDNode *getAllocTokenMetadata(const CallBase &CB) {
109 MDNode *Ret = nullptr;
110 if (auto *II = dyn_cast<IntrinsicInst>(&CB);
111 II && II->getIntrinsicID() == Intrinsic::alloc_token_id) {
112 auto *MDV = cast<MetadataAsValue>(II->getArgOperand(0));
113 Ret = cast<MDNode>(MDV->getMetadata());
114 // If the intrinsic has an empty MDNode, type inference failed.
115 if (Ret->getNumOperands() == 0)
116 return nullptr;
117 } else {
118 Ret = CB.getMetadata(LLVMContext::MD_alloc_token);
119 if (!Ret)
120 return nullptr;
121 }
122 assert(Ret->getNumOperands() == 2 && "bad !alloc_token");
125 return Ret;
126}
127
128bool containsPointer(const MDNode *MD) {
130 auto *CI = cast<ConstantInt>(C->getValue());
131 return CI->getValue().getBoolValue();
132}
133
134class ModeBase {
135public:
136 explicit ModeBase(const IntegerType &TokenTy, uint64_t MaxTokens)
137 : MaxTokens(MaxTokens ? MaxTokens : TokenTy.getBitMask()) {
138 assert(MaxTokens <= TokenTy.getBitMask());
139 }
140
141protected:
142 uint64_t boundedToken(uint64_t Val) const {
143 assert(MaxTokens != 0);
144 return Val % MaxTokens;
145 }
146
147 const uint64_t MaxTokens;
148};
149
150/// Implementation for TokenMode::Increment.
151class IncrementMode : public ModeBase {
152public:
153 using ModeBase::ModeBase;
154
155 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
156 return boundedToken(Counter++);
157 }
158
159private:
160 uint64_t Counter = 0;
161};
162
163/// Implementation for TokenMode::Random.
164class RandomMode : public ModeBase {
165public:
166 RandomMode(const IntegerType &TokenTy, uint64_t MaxTokens,
167 std::unique_ptr<RandomNumberGenerator> RNG)
168 : ModeBase(TokenTy, MaxTokens), RNG(std::move(RNG)) {}
169 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &) {
170 return boundedToken((*RNG)());
171 }
172
173private:
174 std::unique_ptr<RandomNumberGenerator> RNG;
175};
176
177/// Implementation for TokenMode::TypeHash. The implementation ensures
178/// hashes are stable across different compiler invocations. Uses SipHash as the
179/// hash function.
180class TypeHashMode : public ModeBase {
181public:
182 using ModeBase::ModeBase;
183
184 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
185
186 if (MDNode *N = getAllocTokenMetadata(CB)) {
187 MDString *S = cast<MDString>(N->getOperand(0));
188 AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
189 if (auto Token = getAllocToken(TokenMode::TypeHash, Metadata, MaxTokens))
190 return *Token;
191 }
192 // Fallback.
193 remarkNoMetadata(CB, ORE);
194 return ClFallbackToken;
195 }
196
197protected:
198 /// Remark that there was no precise type information.
199 static void remarkNoMetadata(const CallBase &CB,
201 ORE.emit([&] {
202 ore::NV FuncNV("Function", CB.getParent()->getParent());
203 const Function *Callee = CB.getCalledFunction();
204 ore::NV CalleeNV("Callee", Callee ? Callee->getName() : "<unknown>");
205 return OptimizationRemark(DEBUG_TYPE, "NoAllocToken", &CB)
206 << "Call to '" << CalleeNV << "' in '" << FuncNV
207 << "' without source-level type token";
208 });
209 }
210};
211
212/// Implementation for TokenMode::TypeHashPointerSplit.
213class TypeHashPointerSplitMode : public TypeHashMode {
214public:
215 using TypeHashMode::TypeHashMode;
216
217 uint64_t operator()(const CallBase &CB, OptimizationRemarkEmitter &ORE) {
218 if (MDNode *N = getAllocTokenMetadata(CB)) {
219 MDString *S = cast<MDString>(N->getOperand(0));
220 AllocTokenMetadata Metadata{S->getString(), containsPointer(N)};
222 MaxTokens))
223 return *Token;
224 }
225 // Pick the fallback token (ClFallbackToken), which by default is 0, meaning
226 // it'll fall into the pointer-less bucket. Override by setting
227 // -alloc-token-fallback if that is the wrong choice.
228 remarkNoMetadata(CB, ORE);
229 return ClFallbackToken;
230 }
231};
232
233// Apply opt overrides and module flags.
234static AllocTokenOptions resolveOptions(AllocTokenOptions Opts,
235 const Module &M) {
236 auto IntModuleFlagOrNull = [&](StringRef Key) {
237 return mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(Key));
238 };
239
240 if (auto *S = dyn_cast_or_null<MDString>(M.getModuleFlag("alloc-token-mode")))
241 if (auto Mode = getAllocTokenModeFromString(S->getString()))
242 Opts.Mode = *Mode;
243 if (auto *Val = IntModuleFlagOrNull("alloc-token-max"))
244 Opts.MaxTokens = Val->getZExtValue();
245 if (auto *Val = IntModuleFlagOrNull("alloc-token-fast-abi"))
246 Opts.FastABI |= Val->isOne();
247 if (auto *Val = IntModuleFlagOrNull("alloc-token-extended"))
248 Opts.Extended |= Val->isOne();
249
250 // Allow overriding options from command line options.
251 if (ClMaxTokens.getNumOccurrences())
252 Opts.MaxTokens = ClMaxTokens;
253 if (ClFastABI.getNumOccurrences())
254 Opts.FastABI = ClFastABI;
255 if (ClExtended.getNumOccurrences())
256 Opts.Extended = ClExtended;
257
258 return Opts;
259}
260
261class AllocToken {
262public:
263 explicit AllocToken(AllocTokenOptions Opts, Module &M,
265 : Options(resolveOptions(std::move(Opts), M)), Mod(M),
266 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
267 Mode(IncrementMode(*IntPtrTy, Options.MaxTokens)) {
268 switch (Options.Mode) {
270 break;
272 Mode.emplace<RandomMode>(*IntPtrTy, Options.MaxTokens,
273 M.createRNG(DEBUG_TYPE));
274 break;
276 Mode.emplace<TypeHashMode>(*IntPtrTy, Options.MaxTokens);
277 break;
279 Mode.emplace<TypeHashPointerSplitMode>(*IntPtrTy, Options.MaxTokens);
280 break;
281 }
282 }
283
284 bool instrumentFunction(Function &F);
285
286private:
287 /// Returns the LibFunc (or NotLibFunc) if this call should be instrumented.
288 std::optional<LibFunc>
289 shouldInstrumentCall(const CallBase &CB, const TargetLibraryInfo &TLI) const;
290
291 /// Returns true for functions that are eligible for instrumentation.
292 static bool isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
293 const TargetLibraryInfo &TLI);
294
295 /// Returns true for isAllocationFn() functions that we should ignore.
296 static bool ignoreInstrumentableLibFunc(LibFunc Func);
297
298 /// Replace a call/invoke with a call/invoke to the allocation function
299 /// with token ID.
300 bool replaceAllocationCall(CallBase *CB, LibFunc Func,
302 const TargetLibraryInfo &TLI);
303
304 /// Return replacement function for a LibFunc that takes a token ID.
305 FunctionCallee getTokenAllocFunction(const CallBase &CB, uint64_t TokenID,
306 LibFunc OriginalFunc);
307
308 /// Lower alloc_token_* intrinsics.
309 void replaceIntrinsicInst(IntrinsicInst *II, OptimizationRemarkEmitter &ORE);
310
311 /// Return the token ID from metadata in the call.
313 return std::visit([&](auto &&Mode) { return Mode(CB, ORE); }, Mode);
314 }
315
317 Module &Mod;
318 IntegerType *IntPtrTy = Mod.getDataLayout().getIntPtrType(Mod.getContext());
320 // Cache for replacement functions.
322 // Selected mode.
323 std::variant<IncrementMode, RandomMode, TypeHashMode,
324 TypeHashPointerSplitMode>
325 Mode;
326};
327
328bool AllocToken::instrumentFunction(Function &F) {
329 // Do not apply any instrumentation for naked functions.
330 if (F.hasFnAttribute(Attribute::Naked))
331 return false;
332 // Don't touch available_externally functions, their actual body is elsewhere.
333 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
334 return false;
335
337 SmallVector<IntrinsicInst *, 4> IntrinsicInsts;
338
339 // Only instrument functions that have the sanitize_alloc_token attribute.
340 const bool InstrumentFunction =
341 F.hasFnAttribute(Attribute::SanitizeAllocToken) &&
342 !F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation);
343
344 // Get TLI only when required.
345 const TargetLibraryInfo *TLI =
346 InstrumentFunction ? &FAM.getResult<TargetLibraryAnalysis>(F) : nullptr;
347
348 // Collect all allocation calls to avoid iterator invalidation.
349 for (Instruction &I : instructions(F)) {
350 // Collect all alloc_token_* intrinsics.
351 if (auto *II = dyn_cast<IntrinsicInst>(&I);
352 II && II->getIntrinsicID() == Intrinsic::alloc_token_id) {
353 IntrinsicInsts.emplace_back(II);
354 continue;
355 }
356
357 if (!InstrumentFunction)
358 continue;
359
360 auto *CB = dyn_cast<CallBase>(&I);
361 if (!CB)
362 continue;
363 if (std::optional<LibFunc> Func = shouldInstrumentCall(*CB, *TLI))
364 AllocCalls.emplace_back(CB, Func.value());
365 }
366
367 // Return early to avoid unnecessarily instantiating the ORE.
368 if (AllocCalls.empty() && IntrinsicInsts.empty())
369 return false;
370
371 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
372 bool Modified = false;
373
374 for (auto &[CB, Func] : AllocCalls)
375 Modified |= replaceAllocationCall(CB, Func, ORE, *TLI);
376
377 for (auto *II : IntrinsicInsts) {
378 replaceIntrinsicInst(II, ORE);
379 Modified = true;
380 }
381
382 if (Modified)
383 NumFunctionsModified++;
384
385 return Modified;
386}
387
388std::optional<LibFunc>
389AllocToken::shouldInstrumentCall(const CallBase &CB,
390 const TargetLibraryInfo &TLI) const {
391 const Function *Callee = CB.getCalledFunction();
392 if (!Callee)
393 return std::nullopt;
394
395 // Ignore nobuiltin of the CallBase, so that we can cover nobuiltin libcalls
396 // if requested via isInstrumentableLibFunc(). Note that isAllocationFn() is
397 // returning false for nobuiltin calls.
398 LibFunc Func = TLI.getLibFunc(*Callee);
399 if (Func != NotLibFunc) {
400 if (isInstrumentableLibFunc(Func, CB, TLI))
401 return Func;
402 } else if (Options.Extended && CB.getMetadata(LLVMContext::MD_alloc_token)) {
403 return NotLibFunc;
404 }
405
406 return std::nullopt;
407}
408
409bool AllocToken::isInstrumentableLibFunc(LibFunc Func, const CallBase &CB,
410 const TargetLibraryInfo &TLI) {
411 if (ignoreInstrumentableLibFunc(Func))
412 return false;
413
414 if (isAllocationFn(&CB, &TLI))
415 return true;
416
417 switch (Func) {
418 // These libfuncs don't return normal pointers, and are therefore not handled
419 // by isAllocationFn().
420 case LibFunc_posix_memalign:
421 case LibFunc_size_returning_new:
422 case LibFunc_size_returning_new_hot_cold:
423 case LibFunc_size_returning_new_aligned:
424 case LibFunc_size_returning_new_aligned_hot_cold:
425 return true;
426
427 // See comment above ClCoverReplaceableNew.
428 case LibFunc_Znwj:
429 case LibFunc_ZnwjRKSt9nothrow_t:
430 case LibFunc_ZnwjSt11align_val_t:
431 case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
432 case LibFunc_Znwm:
433 case LibFunc_Znwm12__hot_cold_t:
434 case LibFunc_ZnwmRKSt9nothrow_t:
435 case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
436 case LibFunc_ZnwmSt11align_val_t:
437 case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
438 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
439 case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
440 case LibFunc_Znaj:
441 case LibFunc_ZnajRKSt9nothrow_t:
442 case LibFunc_ZnajSt11align_val_t:
443 case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
444 case LibFunc_Znam:
445 case LibFunc_Znam12__hot_cold_t:
446 case LibFunc_ZnamRKSt9nothrow_t:
447 case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
448 case LibFunc_ZnamSt11align_val_t:
449 case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
450 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
451 case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
452 return ClCoverReplaceableNew;
453
454 default:
455 return false;
456 }
457}
458
459bool AllocToken::ignoreInstrumentableLibFunc(LibFunc Func) {
460 switch (Func) {
461 case LibFunc_strdup:
462 case LibFunc_dunder_strdup:
463 case LibFunc_strndup:
464 case LibFunc_dunder_strndup:
465 return true;
466 default:
467 return false;
468 }
469}
470
471bool AllocToken::replaceAllocationCall(CallBase *CB, LibFunc Func,
473 const TargetLibraryInfo &TLI) {
474 uint64_t TokenID = getToken(*CB, ORE);
475
476 FunctionCallee TokenAlloc = getTokenAllocFunction(*CB, TokenID, Func);
477 if (!TokenAlloc)
478 return false;
479 NumAllocationsInstrumented++;
480
481 if (Options.FastABI) {
482 assert(TokenAlloc.getFunctionType()->getNumParams() == CB->arg_size());
483 CB->setCalledFunction(TokenAlloc);
484 return true;
485 }
486
487 IRBuilder<> IRB(CB);
488 // Original args.
489 SmallVector<Value *, 4> NewArgs{CB->args()};
490 // Add token ID, truncated to IntPtrTy width.
491 NewArgs.push_back(ConstantInt::get(IntPtrTy, TokenID));
492 assert(TokenAlloc.getFunctionType()->getNumParams() == NewArgs.size());
493
494 // Preserve invoke vs call semantics for exception handling.
495 CallBase *NewCall;
496 if (auto *II = dyn_cast<InvokeInst>(CB)) {
497 NewCall = IRB.CreateInvoke(TokenAlloc, II->getNormalDest(),
498 II->getUnwindDest(), NewArgs);
499 } else {
500 NewCall = IRB.CreateCall(TokenAlloc, NewArgs);
501 cast<CallInst>(NewCall)->setTailCall(CB->isTailCall());
502 }
503 NewCall->setCallingConv(CB->getCallingConv());
504 NewCall->copyMetadata(*CB);
505 NewCall->setAttributes(CB->getAttributes());
506
507 // Replace all uses and delete the old call.
508 CB->replaceAllUsesWith(NewCall);
509 CB->eraseFromParent();
510 return true;
511}
512
513FunctionCallee AllocToken::getTokenAllocFunction(const CallBase &CB,
514 uint64_t TokenID,
515 LibFunc OriginalFunc) {
516 std::optional<std::pair<LibFunc, uint64_t>> Key;
517 if (OriginalFunc != NotLibFunc) {
518 Key = std::make_pair(OriginalFunc, Options.FastABI ? TokenID : 0);
519 auto It = TokenAllocFunctions.find(*Key);
520 if (It != TokenAllocFunctions.end())
521 return It->second;
522 }
523
524 const Function *Callee = CB.getCalledFunction();
525 if (!Callee)
526 return FunctionCallee();
527 const FunctionType *OldFTy = Callee->getFunctionType();
528 if (OldFTy->isVarArg())
529 return FunctionCallee();
530 // Copy params, and append token ID type.
531 Type *RetTy = OldFTy->getReturnType();
532 SmallVector<Type *, 4> NewParams{OldFTy->params()};
533 std::string TokenAllocName = ClFuncPrefix;
534 if (Options.FastABI)
535 TokenAllocName += utostr(TokenID) + "_";
536 else
537 NewParams.push_back(IntPtrTy); // token ID
538 TokenAllocName += Callee->getName();
539 FunctionType *NewFTy = FunctionType::get(RetTy, NewParams, false);
540 AttributeList NewAttrs = Callee->getAttributes();
541 FunctionCallee TokenAlloc =
542 Mod.getOrInsertFunction(TokenAllocName, NewFTy, NewAttrs);
543
544 if (Key.has_value())
545 TokenAllocFunctions[*Key] = TokenAlloc;
546 return TokenAlloc;
547}
548
549void AllocToken::replaceIntrinsicInst(IntrinsicInst *II,
551 assert(II->getIntrinsicID() == Intrinsic::alloc_token_id);
552
553 uint64_t TokenID = getToken(*II, ORE);
554 Value *V = ConstantInt::get(IntPtrTy, TokenID);
555 II->replaceAllUsesWith(V);
556 II->eraseFromParent();
557}
558
559} // namespace
560
563
565 AllocToken Pass(Options, M, MAM);
566 bool Modified = false;
567
568 for (Function &F : M) {
569 if (F.empty())
570 continue; // declaration
571 Modified |= Pass.instrumentFunction(F);
572 }
573
576}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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:54
#define I(x, y, z)
Definition MD5.cpp:57
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:621
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 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:1264
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2564
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2903
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:1069
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1426
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1432
A single uniqued string.
Definition Metadata.h:722
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:633
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
LibFunc getLibFunc(StringRef funcName) 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:46
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:553
int getNumOccurrences() const
const ParentTy * getParent() const
Definition ilist_node.h:34
Pass manager infrastructure for declaring and invalidating analyses.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:683
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)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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
IntPtrTy
Definition InstrProf.h:82
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:1917
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
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
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:878
#define N
Metadata about an allocation used to generate a token ID.
Definition AllocToken.h:53
AllocTokenMode Mode
Definition AllocToken.h:27