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