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());
196 !(SSI && SSI->
isSafe(AI));
205 const Align NewAlignment = std::max(
Info.AI->getAlign(), Alignment);
206 Info.AI->setAlignment(NewAlignment);
207 auto &Ctx =
Info.AI->getFunction()->getContext();
211 if (
Size == AlignedSize)
215 Type *AllocatedType =
216 Info.AI->isArrayAllocation()
218 Info.AI->getAllocatedType(),
219 cast<ConstantInt>(
Info.AI->getArraySize())->getZExtValue())
220 :
Info.AI->getAllocatedType();
223 auto *NewAI =
new AllocaInst(TypeWithPadding,
Info.AI->getAddressSpace(),
224 nullptr,
"",
Info.AI->getIterator());
225 NewAI->takeName(
Info.AI);
226 NewAI->setAlignment(
Info.AI->getAlign());
227 NewAI->setUsedWithInAlloca(
Info.AI->isUsedWithInAlloca());
228 NewAI->setSwiftError(
Info.AI->isSwiftError());
229 NewAI->copyMetadata(*
Info.AI);
231 Value *NewPtr = NewAI;
234 if (
Info.AI->getType() != NewAI->getType())
237 Info.AI->replaceAllUsesWith(NewPtr);
238 Info.AI->eraseFromParent();
243 auto *II = dyn_cast<IntrinsicInst>(V);
244 return II && II->isLifetimeStartOrEnd();
250 M, Intrinsic::read_register, IRB.
getIntPtrTy(M->getDataLayout()));
252 MDNode::get(M->getContext(), {MDString::get(M->getContext(), Name)});
269 M, Intrinsic::frameaddress,
270 IRB.
getPtrTy(M->getDataLayout().getAllocaAddrSpace()));
273 {Constant::getNullValue(IRB.getInt32Ty())}),
288 return dyn_cast<DbgAssignIntrinsic>(DVI);
299 auto AnnotateDbgRecord = [&](
auto *DPtr) {
304 for (
size_t LocNo = 0; LocNo < DPtr->getNumVariableLocationOps(); ++LocNo)
305 if (DPtr->getVariableLocationOp(LocNo) ==
Info.AI)
309 if (DAI->getAddress() ==
Info.AI)
310 DAI->setAddressExpression(
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
This file contains constants used for implementing Dwarf debug support.
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.
const CallInst * getTerminatingMustTailCall() const
Returns the call instruction marked 'musttail' prior to the terminating return instruction of this ba...
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 Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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)
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
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