30bool maybeReachableFromEachOther(
const SmallVectorImpl<IntrinsicInst *> &Insts,
31 const DominatorTree *DT,
const LoopInfo *LI,
32 size_t MaxLifetimes) {
34 if (Insts.size() > MaxLifetimes)
36 for (
size_t I = 0;
I < Insts.size(); ++
I) {
37 for (
size_t J = 0; J < Insts.size(); ++J) {
58 for (
auto *
End : Ends) {
62 unsigned NumCoveredExits = 0;
63 for (
auto *RI : RetVec) {
71 if (EndBlocks.
contains(RI->getParent()) ||
76 if (NumCoveredExits == ReachableRetVec.
size()) {
92 size_t MaxLifetimes) {
96 return LifetimeStart.
size() == 1 &&
97 (LifetimeEnd.
size() == 1 ||
98 (LifetimeEnd.
size() > 0 &&
99 !maybeReachableFromEachOther(LifetimeEnd, DT, LI, MaxLifetimes)));
103 if (isa<ReturnInst>(Inst)) {
108 if (isa<ResumeInst, CleanupReturnInst>(Inst)) {
117 auto AddIfInteresting = [&](
Value *V) {
118 if (
auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
123 if (DVRVec.empty() || DVRVec.back() != &DVR)
124 DVRVec.push_back(&DVR);
128 for_each(DVR.location_ops(), AddIfInteresting);
129 if (DVR.isDbgAssign())
130 AddIfInteresting(DVR.getAddress());
133 if (
CallInst *CI = dyn_cast<CallInst>(&Inst)) {
134 if (CI->canReturnTwice()) {
138 if (
AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
144 auto *
II = dyn_cast<IntrinsicInst>(&Inst);
145 if (
II && (
II->getIntrinsicID() == Intrinsic::lifetime_start ||
146 II->getIntrinsicID() == Intrinsic::lifetime_end)) {
154 if (
II->getIntrinsicID() == Intrinsic::lifetime_start)
160 if (
auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst)) {
161 auto AddIfInteresting = [&](
Value *V) {
162 if (
auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
167 if (DVIVec.empty() || DVIVec.back() != DVI)
168 DVIVec.push_back(DVI);
171 for_each(DVI->location_ops(), AddIfInteresting);
172 if (
auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
173 AddIfInteresting(DAI->getAddress());
198 !(SSI && SSI->
isSafe(AI));
207 const Align NewAlignment = std::max(
Info.AI->getAlign(), Alignment);
208 Info.AI->setAlignment(NewAlignment);
209 auto &Ctx =
Info.AI->getFunction()->getContext();
213 if (
Size == AlignedSize)
217 Type *AllocatedType =
218 Info.AI->isArrayAllocation()
220 Info.AI->getAllocatedType(),
221 cast<ConstantInt>(
Info.AI->getArraySize())->getZExtValue())
222 :
Info.AI->getAllocatedType();
225 auto *NewAI =
new AllocaInst(TypeWithPadding,
Info.AI->getAddressSpace(),
226 nullptr,
"",
Info.AI->getIterator());
227 NewAI->takeName(
Info.AI);
228 NewAI->setAlignment(
Info.AI->getAlign());
229 NewAI->setUsedWithInAlloca(
Info.AI->isUsedWithInAlloca());
230 NewAI->setSwiftError(
Info.AI->isSwiftError());
231 NewAI->copyMetadata(*
Info.AI);
233 Value *NewPtr = NewAI;
236 if (
Info.AI->getType() != NewAI->getType())
239 Info.AI->replaceAllUsesWith(NewPtr);
240 Info.AI->eraseFromParent();
245 auto *
II = dyn_cast<IntrinsicInst>(V);
246 return II &&
II->isLifetimeStartOrEnd();
252 M, Intrinsic::read_register, IRB.
getIntPtrTy(M->getDataLayout()));
254 MDNode::get(M->getContext(), {MDString::get(M->getContext(), Name)});
271 M, Intrinsic::frameaddress,
272 IRB.
getPtrTy(M->getDataLayout().getAllocaAddrSpace()));
275 {Constant::getNullValue(IRB.getInt32Ty())}),
290 return dyn_cast<DbgAssignIntrinsic>(DVI);
301 auto AnnotateDbgRecord = [&](
auto *DPtr) {
306 for (
size_t LocNo = 0; LocNo < DPtr->getNumVariableLocationOps(); ++LocNo)
307 if (DPtr->getVariableLocationOp(LocNo) ==
Info.AI)
311 if (DAI->getAddress() ==
Info.AI)
312 DAI->setAddressExpression(
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.
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.
std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
static 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 no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static 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 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.
This represents the llvm.dbg.assign instruction.
This is the common base class for debug info intrinsics for variables.
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
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
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.
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...
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.
bool isSafe(const AllocaInst &AI) const
StringRef - Represent a constant reference to a string, i.e.
static 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.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
bool isInterestingAlloca(const AllocaInst &AI)
void visit(Instruction &Inst)
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
static DbgAssignIntrinsic * DynCastToDbgAssign(DbgVariableIntrinsic *DVI)
Value * getFP(IRBuilder<> &IRB)
bool isStandardLifetime(const SmallVectorImpl< IntrinsicInst * > &LifetimeStart, const SmallVectorImpl< IntrinsicInst * > &LifetimeEnd, const DominatorTree *DT, const LoopInfo *LI, size_t MaxLifetimes)
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)
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Value * getAndroidSlotPtr(IRBuilder<> &IRB, int Slot)
Value * readRegister(IRBuilder<> &IRB, StringRef Name)
void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag)
Instruction * getUntagLocationIfFunctionExit(Instruction &Inst)
void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align)
Value * getPC(const Triple &TargetTriple, IRBuilder<> &IRB)
bool isLifetimeIntrinsic(Value *V)
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.
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
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< DbgVariableIntrinsic *, 2 > DbgVariableIntrinsics
SmallVector< DbgVariableRecord *, 2 > DbgVariableRecords
MapVector< AllocaInst *, AllocaInfo > AllocasToInstrument
SmallVector< Instruction *, 4 > UnrecognizedLifetimes
SmallVector< Instruction *, 8 > RetVec