LLVM: lib/Transforms/Utils/MemoryTaggingSupport.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
14
26
27namespace llvm {
29namespace {
30bool maybeReachableFromEachOther(const SmallVectorImpl<IntrinsicInst *> &Insts,
31 const DominatorTree *DT, const LoopInfo *LI,
32 size_t MaxLifetimes) {
33
34 if (Insts.size() > MaxLifetimes)
35 return true;
36 for (size_t I = 0; I < Insts.size(); ++I) {
37 for (size_t J = 0; J < Insts.size(); ++J) {
38 if (I == J)
39 continue;
41 return true;
42 }
43 }
44 return false;
45}
46}
47
53 if (Ends.size() == 1 && PDT.dominates(Ends[0], Start)) {
54 Callback(Ends[0]);
55 return true;
56 }
58 for (auto *End : Ends) {
59 EndBlocks.insert(End->getParent());
60 }
62 unsigned NumCoveredExits = 0;
63 for (auto *RI : RetVec) {
65 continue;
67
68
69
70
71 if (EndBlocks.contains(RI->getParent()) ||
73 ++NumCoveredExits;
74 }
75 }
76 if (NumCoveredExits == ReachableRetVec.size()) {
78 } else {
79
80
81 for_each(ReachableRetVec, Callback);
82
83
84 return false;
85 }
86 return true;
87}
88
92 size_t MaxLifetimes) {
93
94
95
96 return LifetimeStart.size() == 1 &&
97 (LifetimeEnd.size() == 1 ||
98 (LifetimeEnd.size() > 0 &&
99 !maybeReachableFromEachOther(LifetimeEnd, DT, LI, MaxLifetimes)));
100}
101
104 if (CallInst *CI = Inst.getParent()->getTerminatingMustTailCall())
105 return CI;
106 return &Inst;
107 }
109 return &Inst;
110 }
111 return nullptr;
112}
113
116
118 auto AddIfInteresting = [&](Value *V) {
122 return;
123 AllocaInfo &AInfo = Info.AllocasToInstrument[AI];
125 if (DVRVec.empty() || DVRVec.back() != &DVR)
126 DVRVec.push_back(&DVR);
127 }
128 };
129
130 for_each(DVR.location_ops(), AddIfInteresting);
131 if (DVR.isDbgAssign())
132 AddIfInteresting(DVR.getAddress());
133 }
134
136 if (CI->canReturnTwice()) {
137 Info.CallsReturnTwice = true;
138 }
139 }
143 Info.AllocasToInstrument[AI].AI = AI;
144 ORE.emit([&]() {
146 });
147 break;
150 [&]() { return OptimizationRemark(DebugType, "safeAlloca", &Inst); });
151 break;
153 break;
154 }
155 return;
156 }
159 if (!AI ||
161 return;
162 if (II->getIntrinsicID() == Intrinsic::lifetime_start)
163 Info.AllocasToInstrument[AI].LifetimeStart.push_back(II);
164 else
165 Info.AllocasToInstrument[AI].LifetimeEnd.push_back(II);
166 return;
167 }
168
170 if (ExitUntag)
171 Info.RetVec.push_back(ExitUntag);
172}
173
177
179
181
183
184
186
187
189
191 if (!(SSI && SSI->isSafe(AI))) {
193 }
194
196 }
198}
199
204
206 const Align NewAlignment = std::max(Info.AI->getAlign(), Alignment);
207 Info.AI->setAlignment(NewAlignment);
208 auto &Ctx = Info.AI->getFunction()->getContext();
209
212 if (Size == AlignedSize)
213 return;
214
215
216 Type *AllocatedType =
217 Info.AI->isArrayAllocation()
219 Info.AI->getAllocatedType(),
221 : Info.AI->getAllocatedType();
224 auto *NewAI = new AllocaInst(TypeWithPadding, Info.AI->getAddressSpace(),
225 nullptr, "", Info.AI->getIterator());
226 NewAI->takeName(Info.AI);
227 NewAI->setAlignment(Info.AI->getAlign());
228 NewAI->setUsedWithInAlloca(Info.AI->isUsedWithInAlloca());
229 NewAI->setSwiftError(Info.AI->isSwiftError());
230 NewAI->copyMetadata(*Info.AI);
231
232 Info.AI->replaceAllUsesWith(NewAI);
233 Info.AI->eraseFromParent();
234 Info.AI = NewAI;
235}
236
240 MDNode::get(M->getContext(), {MDString::get(M->getContext(), Name)});
243 IRB.getIntPtrTy(M->getDataLayout()), Args);
244}
245
253
256 Module *M = F->getParent();
259 IRB.getPtrTy(M->getDataLayout().getAllocaAddrSpace()),
260 {Constant::getNullValue(IRB.getInt32Ty())}),
262}
263
266
267
269 M, Intrinsic::thread_pointer,
270 IRB.getPtrTy(M->getDataLayout().getDefaultGlobalsAddressSpace()));
272 IRB.CreateCall(ThreadPointerFunc), 8 * Slot);
273}
274
278
281
282
283
285 for (size_t LocNo = 0; LocNo < DPtr->getNumVariableLocationOps(); ++LocNo)
286 if (DPtr->getVariableLocationOp(LocNo) == Info.AI)
287 DPtr->setExpression(
290 if (DAI->getAddress() == Info.AI)
291 DAI->setAddressExpression(
293 }
294 };
295
297}
298
300 unsigned int Inc) {
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 assert((4096 % Inc) == 0);
329 IRB.CreateAdd(ThreadLong, ConstantInt::get(ThreadLong->getType(), Inc)),
330 WrapMask);
331}
332
333}
334}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
This file contains constants used for implementing Dwarf debug support.
uint64_t IntrinsicInst * II
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
const Function * getParent() const
Return the enclosing method, or null if none.
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
static LLVM_ABI DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Module * getParent()
Get the module that this global value is contained inside of...
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
IntegerType * getIntPtrTy(const DataLayout &DL, unsigned AddrSpace=0)
Fetch the type of an integer with size at least as big as that of a pointer in the given address spac...
BasicBlock * GetInsertBlock() const
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
LLVM_ABI bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
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.
Triple - Helper class for working with autoconf configuration names.
ArchType getArch() const
Get the parsed architecture type of this triple.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
void visit(OptimizationRemarkEmitter &ORE, Instruction &Inst)
Definition MemoryTaggingSupport.cpp:114
AllocaInterestingness getAllocaInterestingness(const AllocaInst &AI)
Definition MemoryTaggingSupport.cpp:175
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Value * getFP(IRBuilder<> &IRB)
Definition MemoryTaggingSupport.cpp:254
bool isStandardLifetime(const SmallVectorImpl< IntrinsicInst * > &LifetimeStart, const SmallVectorImpl< IntrinsicInst * > &LifetimeEnd, const DominatorTree *DT, const LoopInfo *LI, size_t MaxLifetimes)
Definition MemoryTaggingSupport.cpp:89
bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, const LoopInfo &LI, const Instruction *Start, const SmallVectorImpl< IntrinsicInst * > &Ends, const SmallVectorImpl< Instruction * > &RetVec, llvm::function_ref< void(Instruction *)> Callback)
Definition MemoryTaggingSupport.cpp:48
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Definition MemoryTaggingSupport.cpp:200
Value * getAndroidSlotPtr(IRBuilder<> &IRB, int Slot)
Definition MemoryTaggingSupport.cpp:264
static DbgVariableRecord * DynCastToDbgAssign(DbgVariableRecord *DVR)
Definition MemoryTaggingSupport.cpp:275
Value * readRegister(IRBuilder<> &IRB, StringRef Name)
Definition MemoryTaggingSupport.cpp:237
Value * incrementThreadLong(IRBuilder<> &IRB, Value *ThreadLong, unsigned int Inc)
Definition MemoryTaggingSupport.cpp:299
void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag)
Definition MemoryTaggingSupport.cpp:279
Instruction * getUntagLocationIfFunctionExit(Instruction &Inst)
Definition MemoryTaggingSupport.cpp:102
void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align)
Definition MemoryTaggingSupport.cpp:205
Value * getPC(const Triple &TargetTriple, IRBuilder<> &IRB)
Definition MemoryTaggingSupport.cpp:246
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
auto dyn_cast_or_null(const Y &Val)
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
This struct is a compact representation of a valid (non-zero power of two) alignment.
SmallVector< DbgVariableRecord *, 2 > DbgVariableRecords