LLVM 23.0.0git
InstrumentorUtils.h
Go to the documentation of this file.
1//===-- Transforms/IPO/InstrumentorUtils.h --------------------------------===//
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// General utilities for the Instrumentor pass.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TRANSFORMS_IPO_INSTRUMENTOR_UTILS_H
14#define LLVM_TRANSFORMS_IPO_INSTRUMENTOR_UTILS_H
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/DataLayout.h"
20#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/Instruction.h"
22#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Module.h"
24
25#include <bitset>
26#include <tuple>
27
28namespace llvm {
29namespace instrumentor {
30
31/// An IR builder augmented with extra information for the instrumentor pass.
32/// The underlying IR builder features an insertion callback to keep track of
33/// the new instructions.
35 /// Construct an IR builder for the module \p M.
37 : M(M), Ctx(M.getContext()),
39 // Save the inserted instructions in a structure.
41 [&](Instruction *I) { NewInsts[I] = Epoch; })) {}
42
43 /// Destroy the IR builder and remove all erasable instructions cached during
44 /// the process of instrumenting.
46 for (auto *I : ErasableInstructions) {
47 if (!I->getType()->isVoidTy())
48 I->replaceAllUsesWith(PoisonValue::get(I->getType()));
49 I->eraseFromParent();
50 }
51
52 // Delete the alloca lists that may have been allocated.
53 for (auto &KV : AllocaMap) {
54 if (KV.second)
55 delete KV.second;
56 }
57 }
58
59 /// Get a temporary alloca to communicate (large) values with the runtime.
60 AllocaInst *getAlloca(Function *Fn, Type *Ty, bool MatchType = false) {
61 const DataLayout &DL = Fn->getDataLayout();
62 auto *&AllocaList = AllocaMap[{Fn, DL.getTypeAllocSize(Ty)}];
63 if (!AllocaList)
64 AllocaList = new AllocaListTy;
65 AllocaInst *AI = nullptr;
66 for (auto *&ListAI : *AllocaList) {
67 if (MatchType && ListAI->getAllocatedType() != Ty)
68 continue;
69 AI = ListAI;
70 ListAI = *AllocaList->rbegin();
71 break;
72 }
73 if (AI)
74 AllocaList->pop_back();
75 else
76 AI = new AllocaInst(Ty, DL.getAllocaAddrSpace(), "",
77 Fn->getEntryBlock().begin());
78 UsedAllocas[AI] = AllocaList;
79 return AI;
80 }
81
82 /// Return the temporary allocas.
84 for (auto [AI, List] : UsedAllocas)
85 List->push_back(AI);
86 UsedAllocas.clear();
87 }
88
89 /// Save instruction \p I to be erased later. The instructions are erased when
90 /// the IR builder is destroyed.
92
93 /// Commonly used values for IR inspection and creation.
94 ///{
96
98
99 const DataLayout &DL = M.getDataLayout();
100
106 ///}
107
109
110 /// Map that holds a list of currently available allocas for a function and
111 /// alloca size.
113
114 /// Map that holds the currently used allocas and the list where they belong.
115 /// Once an alloca has to be returned, it is returned directly to its list.
117
118 /// Instructions that should be erased later.
120
121 /// The underlying IR builder with insertion callback.
123
124 /// The current epoch number. Each instrumentation, e.g., of an instruction,
125 /// is happening in a dedicated epoch. The epoch allows to determine if
126 /// instrumentation instructions were already around, due to prior
127 /// instrumentations, or have been introduced to support the current
128 /// instrumentation, e.g., compute information about the current instruction.
129 unsigned Epoch = 0;
130
131 /// A mapping from instrumentation instructions to the epoch they have been
132 /// created.
134};
135
136/// Helper that represent the caches for instrumentation call arguments. The
137/// value of an argument may not need to be recomputed between the pre and post
138/// instrumentation calls.
140 /// A cache for direct and indirect arguments. The cache is indexed by the
141 /// epoch, the instrumentation opportunity name and the argument name. The
142 /// result is a value.
146};
147
148/// Boolean option bitset with a compile-time number of bits to store as many
149/// options as the enumeration type \p EnumTy defines. The enumeration type is
150/// expected to have an ascending and consecutive values, starting at zero, and
151/// the last value being artificial and named as NumConfig (i.e., the number of
152/// values in the enumeration).
153template <typename EnumTy> struct BaseConfigTy {
154 /// The bistset with as many bits as the enumeration's values.
155 std::bitset<static_cast<int>(EnumTy::NumConfig)> Options;
156
157 /// Construct the option bitset with all bits set to \p Enable. If not
158 /// provided, all options are enabled.
159 BaseConfigTy(bool Enable = true) {
160 if (Enable)
161 Options.set();
162 }
163
164 /// Check if the option \p Opt is enabled.
165 bool has(EnumTy Opt) const { return Options.test(static_cast<int>(Opt)); }
166
167 /// Set the boolean value of option \p Opt to \p Value.
168 void set(EnumTy Opt, bool Value = true) {
169 Options.set(static_cast<int>(Opt), Value);
170 }
171};
172
173} // namespace instrumentor
174} // end namespace llvm
175
176#endif // LLVM_TRANSFORMS_IPO_INSTRUMENTOR_UTILS_H
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
#define I(x, y, z)
Definition MD5.cpp:57
an instruction to allocate memory on the stack
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:461
ConstantFolder - Create constants with minimum, target independent, folding.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
const BasicBlock & getEntryBlock() const
Definition Function.h:809
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:362
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
Definition IRBuilder.h:75
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2854
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Class to represent pointers.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:314
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:313
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:286
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:311
LLVM Value Representation.
Definition Value.h:75
This is an optimization pass for GlobalISel generic memory operations.
@ Enable
Enable colors.
Definition WithColor.h:47
void set(EnumTy Opt, bool Value=true)
Set the boolean value of option Opt to Value.
std::bitset< static_cast< int >(ConfigKind::NumConfig)> Options
BaseConfigTy(bool Enable=true)
Construct the option bitset with all bits set to Enable.
bool has(EnumTy Opt) const
Check if the option Opt is enabled.
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
IRBuilder< ConstantFolder, IRBuilderCallbackInserter > IRB
The underlying IR builder with insertion callback.
~InstrumentorIRBuilderTy()
Destroy the IR builder and remove all erasable instructions cached during the process of instrumentin...
unsigned Epoch
The current epoch number.
InstrumentorIRBuilderTy(Module &M)
Construct an IR builder for the module M.
AllocaInst * getAlloca(Function *Fn, Type *Ty, bool MatchType=false)
Get a temporary alloca to communicate (large) values with the runtime.
DenseMap< AllocaInst *, AllocaListTy * > UsedAllocas
Map that holds the currently used allocas and the list where they belong.
void returnAllocas()
Return the temporary allocas.
SmallPtrSet< Instruction *, 32 > ErasableInstructions
Instructions that should be erased later.
DenseMap< Instruction *, unsigned > NewInsts
A mapping from instrumentation instructions to the epoch they have been created.
Module & M
Commonly used values for IR inspection and creation.
DenseMap< std::pair< Function *, unsigned >, AllocaListTy * > AllocaMap
Map that holds a list of currently available allocas for a function and alloca size.
void eraseLater(Instruction *I)
Save instruction I to be erased later.