57#include <system_error>
63#define DEBUG_TYPE "instrumentor"
69 "instrumentor-write-config-file",
71 "Write the instrumentor configuration into the specified JSON file"),
76 ConfigFiles(
"instrumentor-read-config-files",
77 cl::desc(
"Read the instrumentor configuration from the "
78 "specified JSON files (comma separated)"),
84 "instrumentor-read-config-paths-file",
85 cl::desc(
"Read the instrumentor configuration file "
86 "paths from the specified file (newline separated)"),
91template <
typename IRBuilderTy>
void ensureDbgLoc(IRBuilderTy &IRB) {
92 if (IRB.getCurrentDebugLocation())
94 auto *BB = IRB.GetInsertBlock();
95 if (
auto *SP = BB->getParent()->getSubprogram())
96 IRB.SetCurrentDebugLocation(
DILocation::get(BB->getContext(), 0, 0, SP));
100template <
typename IRBTy>
102 bool AllowTruncate =
false) {
105 Type *VTy = V->getType();
110 TypeSize RequestedSize =
DL.getTypeSizeInBits(Ty);
111 TypeSize ValueSize =
DL.getTypeSizeInBits(VTy);
112 bool ShouldTruncate = RequestedSize < ValueSize;
113 if (ShouldTruncate && !AllowTruncate)
115 if (ShouldTruncate && AllowTruncate)
116 return tryToCast(IRB,
117 IRB.CreateIntCast(V, IRB.getIntNTy(RequestedSize),
119 Ty,
DL, AllowTruncate);
121 return IRB.CreatePointerBitCastOrAddrSpaceCast(V, Ty);
123 return IRB.CreateIntCast(V, Ty,
false);
125 return tryToCast(IRB, IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize)), Ty,
128 return IRB.CreateBitOrPointerCast(V, Ty);
132template <
typename Ty>
134 return ConstantInt::get(
IT, Val, IsSigned);
139class InstrumentorImpl final {
144 : IConf(IConf), M(M), IIRB(IIRB) {}
152 InstChoicesPRE.clear();
153 InstChoicesPOST.clear();
154 ParsedFunctionRegex =
Regex();
159 bool shouldInstrumentTarget();
162 bool shouldInstrumentFunction(
Function &Fn);
170 bool instrumentFunction(
Function &Fn);
171 bool instrumentModule();
182 Regex ParsedFunctionRegex;
200 Twine(
"failed to parse ") + Name +
" regex: " + ErrMsg,
DS_Error));
208bool InstrumentorImpl::shouldInstrumentTarget() {
210 const bool IsGPU =
T.
isAMDGPU() ||
T.isNVPTX();
212 bool RegexMatches =
true;
215 RegexMatches = RX.
match(
T.str());
218 return ((IsGPU && IConf.
GPUEnabled->getBool()) ||
223bool InstrumentorImpl::shouldInstrumentFunction(Function &Fn) {
226 bool RegexMatches =
true;
227 if (ParsedFunctionRegex.
isValid())
233bool InstrumentorImpl::shouldInstrumentGlobalVariable(GlobalVariable &GV) {
238bool InstrumentorImpl::instrumentInstruction(Instruction &
I,
239 InstrumentationCaches &ICaches) {
250 if (
auto *IO = InstChoicesPRE.lookup(
I.getOpcode())) {
251 IIRB.
IRB.SetInsertPoint(&
I);
252 ensureDbgLoc(IIRB.
IRB);
253 Changed |= bool(IO->instrument(IPtr, IConf, IIRB, ICaches));
256 if (
auto *IO = InstChoicesPOST.lookup(
I.getOpcode())) {
257 IIRB.
IRB.SetInsertPoint(
I.getNextNode());
258 ensureDbgLoc(IIRB.
IRB);
259 Changed |= bool(IO->instrument(IPtr, IConf, IIRB, ICaches));
266bool InstrumentorImpl::instrumentFunction(Function &Fn) {
268 if (!shouldInstrumentFunction(Fn))
271 InstrumentationCaches ICaches;
273 ReversePostOrderTraversal<Function *> RPOT(&Fn);
274 for (
auto &It : RPOT) {
276 Changed |= instrumentInstruction(
I, ICaches);
278 auto *TI = It->getTerminator();
279 if (!TI->getNumSuccessors())
284 for (
auto &[Name, IO] :
291 IIRB.
IRB.SetInsertPoint(
293 ensureDbgLoc(IIRB.
IRB);
294 Changed |= bool(IO->instrument(FPtr, IConf, IIRB, ICaches));
298 for (
auto &[Name, IO] :
305 for (Instruction *FinalTI : FinalTIs) {
306 IIRB.
IRB.SetInsertPoint(FinalTI);
307 ensureDbgLoc(IIRB.
IRB);
308 Changed |= bool(IO->instrument(FPtr, IConf, IIRB, ICaches));
315bool InstrumentorImpl::instrumentModule() {
318 for (GlobalVariable &GV : M.
globals()) {
321 GV.
getName() ==
"llvm.global_dtors" ||
322 GV.
getName() ==
"llvm.global_ctors")
327 auto CreateYtor = [&](
bool Ctor) {
330 IConf.
getRTName(Ctor ?
"ctor" :
"dtor",
""), M);
333 IIRB.
IRB.SetInsertPoint(EntryBB, EntryBB->begin());
334 ensureDbgLoc(IIRB.
IRB);
335 IIRB.
IRB.CreateRetVoid();
344 InstrumentationCaches ICaches;
346 Function *CtorFn =
nullptr, *DtorFn =
nullptr;
351 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
352 for (
auto &ChoiceIt : IConf.
IChoices[Loc]) {
353 auto *IO = ChoiceIt.second;
357 YtorFn = CreateYtor(IsPRE);
358 IIRB.
IRB.SetInsertPointPastAllocas(YtorFn);
359 ensureDbgLoc(IIRB.
IRB);
360 Value *YtorPtr = YtorFn;
365 Changed |= bool(IO->instrument(YtorPtr, IConf, IIRB, ICaches));
373 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
374 for (
auto &ChoiceIt : IConf.
IChoices[Loc]) {
375 auto *IO = ChoiceIt.second;
379 YtorFn = CreateYtor(IsPRE);
380 for (GlobalVariable *GV : Globals) {
381 if (!shouldInstrumentGlobalVariable(*GV))
386 IIRB.
IRB.SetInsertPointPastAllocas(YtorFn);
387 ensureDbgLoc(IIRB.
IRB);
393 Changed |= bool(IO->instrument(GVPtr, IConf, IIRB, ICaches));
402bool InstrumentorImpl::instrument() {
404 if (!shouldInstrumentTarget())
407 StringRef FunctionRegexStr = IConf.
FunctionRegex->getString();
408 ParsedFunctionRegex =
createRegex(FunctionRegexStr,
"function", IIRB.
Ctx);
410 for (
auto &[Name, IO] :
413 InstChoicesPRE[IO->getOpcode()] = IO;
414 for (
auto &[Name, IO] :
417 InstChoicesPOST[IO->getOpcode()] = IO;
420 for (Function &Fn : M)
421 Changed |= instrumentFunction(Fn);
427 InstrumentationConfig *IC,
428 InstrumentorIRBuilderTy *IIRB)
429 : FS(FS), UserIConf(IC), UserIIRB(IIRB) {
438 InstrumentorImpl Impl(IConf, IIRB, M);
446 bool MultipleConfigs = ConfigFiles.size() > 1;
449 std::string ConfigFile =
450 ReadConfig && !ConfigFiles.empty() ? ConfigFiles[Idx] :
"";
461 ? OutputConfigFile +
"." + std::to_string(Idx)
468 }
while (++Idx < ConfigFiles.size());
477 std::unique_ptr<InstrumentationConfig> IConfInt(
478 !UserIConf ?
new InstrumentationConfig() :
nullptr);
479 std::unique_ptr<InstrumentorIRBuilderTy> IIRBInt(
480 !UserIIRB ?
new InstrumentorIRBuilderTy(M) :
nullptr);
482 auto *IConf = IConfInt ? IConfInt.get() : UserIConf;
483 auto *IIRB = IIRBInt ? IIRBInt.get() : UserIIRB;
485 auto PA = run(M, *IConf, *IIRB, !UserIConf);
491std::unique_ptr<BaseConfigurationOption>
497 BCO->setBool(DefaultValue);
502std::unique_ptr<BaseConfigurationOption>
509 BCO->setString(DefaultValue);
530 Twine(
"registered two instrumentation opportunities for the same "
552 if (V.getType()->isVoidTy())
554 return tryToCast(IIRB.
IRB, &V, &Ty,
555 IIRB.
IRB.GetInsertBlock()->getDataLayout());
561 if (V.getType()->isVoidTy())
564 auto *NewVCasted = &NewV;
567 IIRB.
IRB.SetInsertPoint(
I->getNextNode());
568 ensureDbgLoc(IIRB.
IRB);
569 NewVCasted = tryToCast(IIRB.
IRB, &NewV, V.
getType(), IIRB.
DL,
584 for (
auto &It :
IO.IRTArgs) {
587 NumReplaceableArgs += bool(It.Flags & IRTArg::REPLACABLE);
588 MightRequireIndirection |= It.Flags & IRTArg::POTENTIALLY_INDIRECT;
599 "Wrong indirection setting!");
602 for (
auto &It :
IO.IRTArgs) {
631 auto IP = IIRB.
IRB.GetInsertPoint();
634 for (
auto &It :
IO.IRTArgs) {
638 if (!Param || It.NoCache)
640 Param = It.GetterCB(*V, *It.Ty, IConf, IIRB);
643 if (Param->getType()->isVoidTy()) {
645 }
else if (Param->getType()->isAggregateType() ||
646 DL.getTypeSizeInBits(Param->getType()) >
647 DL.getTypeSizeInBits(It.Ty)) {
650 Twine(
"indirection needed for ") + It.Name +
Twine(
" in ") +
652 Twine(
", but not indicated. Instrumentation is skipped"),
656 ForceIndirection =
true;
658 Param = tryToCast(IIRB.
IRB, Param, It.Ty,
DL);
663 if (ForceIndirection) {
664 Function *Fn = IIRB.
IRB.GetInsertBlock()->getParent();
667 for (
auto &It :
IO.IRTArgs) {
675 auto *&CallParam = CallParams[
Offset++];
677 CallParams.
insert(&CallParam + 1, IIRB.
IRB.getInt32(
DL.getTypeStoreSize(
678 CallParam->getType())));
685 CallParam = CachedParam;
690 IIRB.
IRB.CreateStore(CallParam, AI);
691 CallParam = CachedParam = AI;
695 if (!ForceIndirection)
696 IIRB.
IRB.SetInsertPoint(IP);
697 ensureDbgLoc(IIRB.
IRB);
701 IConf.
getRTName(
IO.IP.isPRE() ?
"pre_" :
"post_",
IO.getName(),
702 ForceIndirection ?
"_ind" :
"");
703 auto FC = IIRB.
IRB.GetInsertBlock()->getModule()->getOrInsertFunction(
705 auto *CI = IIRB.
IRB.CreateCall(FC, CallParams);
708 for (
unsigned I = 0, E =
IO.IRTArgs.size();
I < E; ++
I) {
709 if (!
IO.IRTArgs[
I].Enabled)
714 Value *NewValue = FnTy->isVoidTy() || IsCustomReplaceable
719 if (ForceIndirection && !IsCustomReplaceable &&
724 NewValue = IIRB.
IRB.CreateLoad(V->getType(), Q);
726 V =
IO.IRTArgs[
I].SetterCB(*V, *NewValue, IConf, IIRB);
732 if constexpr (std::is_same<Ty, Use>::value)
733 return ValueOrUse.get();
735 return static_cast<Value *
>(&ValueOrUse);
738template <
typename Range>
741 auto *Fn = IIRB.
IRB.GetInsertBlock()->getParent();
742 auto *I32Ty = IIRB.
IRB.getInt32Ty();
748 if (!V->getType()->isSized())
751 ConstantValues.
push_back(getCI(I32Ty, VSize));
752 Types.push_back(I32Ty);
753 ConstantValues.
push_back(getCI(I32Ty, V->getType()->getTypeID()));
754 Types.push_back(I32Ty);
755 if (
uint32_t MisAlign = VSize % 8) {
759 Types.push_back(V->getType());
782 for (
auto [Param, Idx] : Values) {
783 auto *Ptr = IIRB.
IRB.CreateStructGEP(STy, AI, Idx);
784 IIRB.
IRB.CreateStore(Param, Ptr);
789template <
typename Range>
793 auto *Fn = IIRB.
IRB.GetInsertBlock()->getParent();
797 for (
const auto &[Idx, RE] :
enumerate(R)) {
799 if (!V->getType()->isSized())
802 auto VSize =
DL.getTypeAllocSize(V->getType());
803 auto Padding =
alignTo(VSize, 8) - VSize;
805 auto *Ptr = IIRB.
IRB.CreateConstInBoundsGEP1_32(IIRB.
Int8Ty, &Pack,
Offset);
806 auto *NewV = IIRB.
IRB.CreateLoad(V->getType(), Ptr);
816 using namespace std::placeholders;
830 "Number of function arguments (without varargs).",
IRTArg::NONE,
834 IRTArg(IIRB.
PtrTy,
"arguments",
"Description of the arguments.",
841 "Flag to indicate it is the main function.",
871 return getCI(&Ty, std::distance(FRange.begin(), FRange.end()));
887 auto CB = [&](
int Idx,
Value *ReplV) {
906 return getCI(&Ty, Fn.
getName() ==
"main");
932 IRTArg(IIRB.
PtrTy,
"address",
"The allocated memory address.",
938 IIRB.
Int64Ty,
"size",
"The allocation size.",
954 Value *SizeValue =
nullptr;
960 SizeValue = IIRB.
IRB.CreatePtrToInt(
961 IIRB.
IRB.CreateGEP(AI.getAllocatedType(), NullPtr,
962 {IIRB.IRB.getInt32(1)}),
965 if (AI.isArrayAllocation())
966 SizeValue = IIRB.
IRB.CreateMul(
967 SizeValue, IIRB.
IRB.CreateZExtOrBitCast(AI.getArraySize(), &Ty));
975 auto *NewAI = IIRB.
IRB.CreateAlloca(IIRB.
IRB.getInt8Ty(),
976 DL.getAllocaAddrSpace(), &NewV);
977 NewAI->setAlignment(AI.getAlign());
978 AI.replaceAllUsesWith(NewAI);
997 IRTArg(IIRB.
PtrTy,
"pointer",
"The accessed pointer.",
1004 "The address space of the accessed pointer.",
1032 "The atomicity ordering of the store.",
1053 return SI.getPointerOperand();
1059 SI.setOperand(
SI.getPointerOperandIndex(), &NewV);
1066 return getCI(&Ty,
SI.getPointerAddressSpace());
1072 return SI.getValueOperand();
1078 auto &
DL =
SI.getDataLayout();
1079 return getCI(&Ty,
DL.getTypeStoreSize(
SI.getValueOperand()->getType()));
1085 return getCI(&Ty,
SI.getAlign().value());
1091 return getCI(&Ty,
SI.getValueOperand()->getType()->getTypeID());
1098 return getCI(&Ty,
uint64_t(
SI.getOrdering()));
1104 return getCI(&Ty,
uint64_t(
SI.getSyncScopeID()));
1110 return getCI(&Ty,
SI.isVolatile());
1120 IRTArg(IIRB.
PtrTy,
"pointer",
"The accessed pointer.",
1127 "The address space of the accessed pointer.",
1157 "The atomicity ordering of the load.",
1178 return LI.getPointerOperand();
1184 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1191 return getCI(&Ty, LI.getPointerAddressSpace());
1202 auto &
DL = LI.getDataLayout();
1203 return getCI(&Ty,
DL.getTypeStoreSize(LI.getType()));
1209 return getCI(&Ty, LI.getAlign().value());
1215 return getCI(&Ty, LI.getType()->getTypeID());
1222 return getCI(&Ty,
uint64_t(LI.getOrdering()));
1228 return getCI(&Ty,
uint64_t(LI.getSyncScopeID()));
1234 return getCI(&Ty, LI.isVolatile());
1244 "The module/translation unit name.",
1275 IIRB.
PtrTy,
"address",
1276 "The address of the global (replaceable for definitions).",
1285 "The size of the declared type of the global.",
1296 IIRB.
Int64Ty,
"initial_value",
"The initial value of the global.",
1305 "Flag to indicate global definitions.",
1329 DL.getDefaultGlobalsAddressSpace());
1334 IIRB.
IRB.CreateStore(&NewV, ShadowGV);
1343 auto MakeInstForConst = [&](
Use &U) {
1349 I = CE->getAsInstruction();
1363 while (!Worklist.
empty()) {
1366 U->set(ReloadMap[
I->getFunction()]);
1369 if (
auto *CI = ConstToInstMap[*U]) {
1370 auto *CIClone = CI->clone();
1373 auto *BB =
PHI->getIncomingBlock(U->getOperandNo());
1374 CIClone->insertBefore(BB->getTerminator()->getIterator());
1376 CIClone->insertBefore(
I->getIterator());
1379 for (
auto &CICUse : CIClone->operands()) {
1387 while (!Worklist.
empty()) {
1389 if (!
Done.insert(U).second)
1391 MakeInstForConst(*U);
1402 if (
II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1405 InsertConsts(
I, *U);
1408 for (
auto &It : ConstToInstMap)
1410 It.second->deleteValue();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
This file contains the declarations for the subclasses of Constant, which represent the different fla...
post inline ee instrument
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static void readValuePack(const Range &R, Value &Pack, InstrumentorIRBuilderTy &IIRB, function_ref< void(int, Value *)> SetterCB)
static constexpr Value * getValue(Ty &ValueOrUse)
static Value * createValuePack(const Range &R, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Regex createRegex(StringRef Str, StringRef Name, LLVMContext &Ctx)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
ModuleAnalysisManager MAM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Defines the virtual file system interface vfs::FileSystem.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Diagnostic information for IR instrumentation reporting.
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const BasicBlock & getEntryBlock() const
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
iterator_range< arg_iterator > args()
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Argument * getArg(unsigned i) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
StringRef getSection() const
Get the custom section of this global if it has one.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
ThreadLocalMode getThreadLocalMode() const
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
uint64_t getAlignment() const
FIXME: Remove this function once transition to Align is over.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
InstrumentorPass(IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr, InstrumentationConfig *IC=nullptr, InstrumentorIRBuilderTy *IIRB=nullptr)
Construct an instrumentor pass that will use the instrumentation configuration IC and the IR builder ...
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
size_t global_size() const
StringRef getName() const
Get a short "name" for the module.
iterator_range< global_iterator > globals()
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, if any.
LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void reserve(size_type N)
iterator insert(iterator I, T &&Elt)
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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
const std::string & getTriple() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
constexpr ScalarTy getFixedValue() const
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
An efficient, type-erasing, non-owning reference to a callable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
void writeConfigToJSON(InstrumentationConfig &IConf, StringRef OutputFile, LLVMContext &Ctx)
Write the configuration in /p IConf to the file with path OutputFile.
bool readConfigPathsFile(StringRef InputFile, cl::list< std::string > &Configs, LLVMContext &Ctx, vfs::FileSystem &FS)
Read the configuration paths from the file with path InputFile into Configs.
bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, LLVMContext &Ctx, vfs::FileSystem &FS)
Read the configuration from the file with path InputFile into /p IConf.
void printRuntimeStub(const InstrumentationConfig &IConf, StringRef StubRuntimeName, LLVMContext &Ctx)
Print a runtime stub file with the implementation of the instrumentation runtime functions correspond...
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
MaybeAlign getAlign(const CallInst &I, unsigned Index)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
LLVM_ABI bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
}
BaseConfigTy< ConfigKind > ConfigTy
static Value * getSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setSize(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static std::unique_ptr< BaseConfigurationOption > createStringOption(InstrumentationConfig &IC, StringRef Name, StringRef Description, StringRef DefaultValue)
Create a string option with Name name, Description description and DefaultValue as string default val...
static std::unique_ptr< BaseConfigurationOption > createBoolOption(InstrumentationConfig &IC, StringRef Name, StringRef Description, bool DefaultValue)
Create a boolean option with Name name, Description description and DefaultValue as boolean default v...
llvm::instrumentor::FunctionIO::ConfigTy Config
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Value * setArguments(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getFunctionAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isMainFunction(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Value * getArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Value * getNumArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getFunctionName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
FunctionIO {.
static Value * setAddress(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
static Value * getAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getInitialValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isDefinition(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getDeclaredSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getSymbolName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static Value * isConstant(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
bool isReplacable(IRTArg &IRTA) const
Return whether the IRTA argument can be replaced.
IRTCallDescription(InstrumentationOpportunity &IO, Type *RetTy=nullptr)
Construct an instrumentation function description linked to the IO instrumentation opportunity and Re...
bool MightRequireIndirection
Whether any argument may require indirection.
CallInst * createLLVMCall(Value *&V, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, const DataLayout &DL, InstrumentationCaches &ICaches)
Create a call instruction that calls to the instrumentation function and passes the corresponding arg...
Type * RetTy
The return type of the instrumentation function.
InstrumentationOpportunity & IO
The instrumentation opportunity which it is linked to.
FunctionType * createLLVMSignature(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, const DataLayout &DL, bool ForceIndirection)
Create the type of the instrumentation function.
unsigned NumReplaceableArgs
The number of arguments that can be replaced.
bool RequiresIndirection
Whether the function requires indirection in some argument.
bool isPotentiallyIndirect(IRTArg &IRTA) const
Return whether the function may have any indirect argument.
Helper that represent the caches for instrumentation call arguments.
DenseMap< std::tuple< unsigned, StringRef, StringRef >, Value * > DirectArgCache
A cache for direct and indirect arguments.
DenseMap< std::tuple< unsigned, StringRef, StringRef >, Value * > IndirectArgCache
The class that contains the configuration for the instrumentor.
virtual void populate(InstrumentorIRBuilderTy &IIRB)
Populate the instrumentation opportunities.
void addChoice(InstrumentationOpportunity &IO, LLVMContext &Ctx)
Register instrumentation opportunity IO.
Constant * getGlobalString(StringRef S, InstrumentorIRBuilderTy &IIRB)
std::unique_ptr< BaseConfigurationOption > HostEnabled
std::unique_ptr< BaseConfigurationOption > DemangleFunctionNames
void init(InstrumentorIRBuilderTy &IIRB)
Initialize the config to a clean base state without loosing cached values that can be reused across c...
std::unique_ptr< BaseConfigurationOption > GPUEnabled
DenseMap< Constant *, GlobalVariable * > ConstantGlobalsCache
Mapping from constants to globals with the constant as initializer.
std::unique_ptr< BaseConfigurationOption > RuntimeStubsFile
StringRef getRTName() const
Get the runtime prefix for the instrumentation runtime functions.
void addBaseChoice(BaseConfigurationOption *BCO)
Add the base configuration option BCO into the list of base options.
std::unique_ptr< BaseConfigurationOption > FunctionRegex
std::unique_ptr< BaseConfigurationOption > TargetRegex
EnumeratedArray< StringMap< InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.
bool isPRE() const
Return whether the instrumentation location is before the event occurs.
Base class for instrumentation opportunities.
InstrumentationLocation::KindTy getLocationKind() const
Get the location kind of the instrumentation opportunity.
static Value * getIdPre(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Get the opportunity identifier for the pre and post positions.
static Value * forceCast(Value &V, Type &Ty, InstrumentorIRBuilderTy &IIRB)
Helpers to cast values, pass them to the runtime, and replace them.
static int32_t getIdFromEpoch(uint32_t CurrentEpoch)
}
static Value * getIdPost(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * replaceValue(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual StringRef getName() const =0
Get the name of the instrumentation opportunity.
SmallVector< IRTArg > IRTArgs
The list of possible arguments for the instrumentation runtime function.
void addCommonArgs(InstrumentationConfig &IConf, LLVMContext &Ctx, bool PassId)
}
An IR builder augmented with extra information for the instrumentor pass.
IRBuilder< ConstantFolder, IRBuilderCallbackInserter > IRB
The underlying IR builder with insertion callback.
unsigned Epoch
The current epoch number.
AllocaInst * getAlloca(Function *Fn, Type *Ty, bool MatchType=false)
Get a temporary alloca to communicate (large) values with the runtime.
void returnAllocas()
Return the temporary allocas.
DenseMap< Instruction *, unsigned > NewInsts
A mapping from instrumentation instructions to the epoch they have been created.
void eraseLater(Instruction *I)
Save instruction I to be erased later.
static Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Getters and setters for the arguments of the instrumentation function for the load opportunity.
static Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
static Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the load opportunity using the instrumentation config IConf and the user config UserConfig...
static Value * getModuleName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getTargetTriple(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
BaseConfigTy< ConfigKind > ConfigTy
static Value * getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Getters and setters for the arguments of the instrumentation function for the store opportunity.
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
static Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the store opportunity using the instrumentation config IConf and the user config UserConfi...
static Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
}
BaseConfigTy< ConfigKind > ConfigTy