LLVM: lib/Analysis/TypeMetadataUtils.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20

21using namespace llvm;

22

23

24static void

28 for (const Use &U : FPtr->uses()) {

30

31

32

33

34

35

37 continue;

39 continue;

40 if (isa(User)) {

42 DT);

43 } else if (auto *CI = dyn_cast(User)) {

45 } else if (auto *II = dyn_cast(User)) {

47 } else if (HasNonCallUses) {

48 *HasNonCallUses = true;

49 }

50 }

51}

52

53

57 for (const Use &U : VPtr->uses()) {

59 if (isa(User)) {

61 } else if (isa(User)) {

63 } else if (auto GEP = dyn_cast(User)) {

64

65 if (VPtr == GEP->getPointerOperand() && GEP->hasAllConstantIndices()) {

67 int64_t GEPOffset = M->getDataLayout().getIndexedOffsetInType(

68 GEP->getSourceElementType(), Indices);

70 CI, DT);

71 }

72 } else if (auto *Call = dyn_cast(User)) {

73 if (Call->getIntrinsicID() == llvm::Intrinsic::load_relative) {

74 if (auto *LoadOffset = dyn_cast(Call->getOperand(1))) {

76 Offset + LoadOffset->getSExtValue(), CI,

77 DT);

78 }

79 }

80 }

81 }

82}

83

90 Intrinsic::public_type_test);

91

92 const Module *M = CI->getParent()->getParent()->getParent();

93

94

95 for (const Use &CIU : CI->uses())

96 if (auto *Assume = dyn_cast(CIU.getUser()))

98

99

100

101 if (!Assumes.empty())

104}

105

112 Intrinsic::type_checked_load ||

114 Intrinsic::type_checked_load_relative);

115

118 HasNonCallUses = true;

119 return;

120 }

121

122 for (const Use &U : CI->uses()) {

123 auto CIU = U.getUser();

124 if (auto EVI = dyn_cast(CIU)) {

125 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 0) {

127 continue;

128 }

129 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {

131 continue;

132 }

133 }

134 HasNonCallUses = true;

135 }

136

137 for (Value *LoadedPtr : LoadedPtrs)

139 Offset->getZExtValue(), CI, DT);

140}

141

144

145

146

147 if (auto *Equiv = dyn_cast(I))

148 I = Equiv->getGlobalValue();

149

150 if (I->getType()->isPointerTy()) {

152 return I;

153 return nullptr;

154 }

155

157

158 if (auto *C = dyn_cast(I)) {

159 const StructLayout *SL = DL.getStructLayout(C->getType());

161 return nullptr;

162

166 TopLevelGlobal);

167 }

168 if (auto *C = dyn_cast(I)) {

171

172 unsigned Op = Offset / ElemSize;

173 if (Op >= C->getNumOperands())

174 return nullptr;

175

177 Offset % ElemSize, M, TopLevelGlobal);

178 }

179

180

181 if (auto *CI = dyn_cast(I)) {

182 if (Offset == 0 && CI->isZero()) {

183 return I;

184 }

185 }

186 if (auto *C = dyn_cast(I)) {

187 switch (C->getOpcode()) {

188 case Instruction::Trunc:

189 case Instruction::PtrToInt:

191 TopLevelGlobal);

192 case Instruction::Sub: {

193 auto *Operand0 = cast(C->getOperand(0));

194 auto *Operand1 = cast(C->getOperand(1));

195

196 auto StripGEP = [](Constant *C) {

197 auto *CE = dyn_cast(C);

198 if (!CE)

199 return C;

200 if (CE->getOpcode() != Instruction::GetElementPtr)

201 return C;

202 return CE->getOperand(0);

203 };

204 auto *Operand1TargetGlobal = StripGEP(getPointerAtOffset(Operand1, 0, M));

205

206

207

208 if (Operand1TargetGlobal != TopLevelGlobal)

209 return nullptr;

210

212 }

213 default:

214 return nullptr;

215 }

216 }

217 return nullptr;

218}

219

220std::pair<Function *, Constant *>

224 if (Ptr)

225 return std::pair<Function *, Constant *>(nullptr, nullptr);

226

227 auto C = Ptr->stripPointerCasts();

228

229 auto Fn = dyn_cast(C);

230 auto A = dyn_cast(C);

231 if (!Fn && A)

232 Fn = dyn_cast(A->getAliasee());

233

234 if (!Fn)

235 return std::pair<Function *, Constant *>(nullptr, nullptr);

236

237 return std::pair<Function *, Constant *>(Fn, C);

238}

239

241 auto *PtrExpr = dyn_cast(U);

242 if (!PtrExpr || PtrExpr->getOpcode() != Instruction::PtrToInt)

243 return;

244

245 for (auto *PtrToIntUser : PtrExpr->users()) {

246 auto *SubExpr = dyn_cast(PtrToIntUser);

247 if (!SubExpr || SubExpr->getOpcode() != Instruction::Sub)

248 return;

249

250 SubExpr->replaceNonMetadataUsesWith(

251 ConstantInt::get(SubExpr->getType(), 0));

252 }

253}

254

256 for (auto *U : C->users()) {

257 if (auto *Equiv = dyn_cast(U))

259 else

261 }

262}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Module.h This file contains the declarations for the Module class.

uint64_t IntrinsicInst * II

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

Class to represent array types.

Type * getElementType() const

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

Value * getArgOperand(unsigned i) const

This class represents a function call, abstracting a target machine's calling convention.

This is an important base class in LLVM.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

Intrinsic::ID getIntrinsicID() const LLVM_READONLY

getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

const Function * getFunction() const

Return the function this instruction belongs to.

A Module instance is used to store all the information related to an LLVM module.

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.

Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...

TypeSize getSizeInBytes() const

unsigned getElementContainingOffset(uint64_t FixedOffset) const

Given a valid byte offset into the structure, returns the structure index that contains it.

TypeSize getElementOffset(unsigned Idx) const

A Use represents the edge between a Value definition and its users.

LLVM Value Representation.

const Value * stripPointerCasts() const

Strip off pointer casts, all-zero GEPs and address space casts.

iterator_range< use_iterator > uses()

const ParentTy * getParent() const

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

void findDevirtualizableCallsForTypeCheckedLoad(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< Instruction * > &LoadedPtrs, SmallVectorImpl< Instruction * > &Preds, bool &HasNonCallUses, const CallInst *CI, DominatorTree &DT)

Given a call to the intrinsic @llvm.type.checked.load, find all devirtualizable call sites based on t...

void replaceRelativePointerUsersWithZero(Constant *C)

Finds the same "relative pointer" pattern as described above, where the target is C,...

void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst * > &Assumes, const CallInst *CI, DominatorTree &DT)

Given a call to the intrinsic @llvm.type.test, find all devirtualizable call sites based on the call ...

Constant * getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, Constant *TopLevelGlobal=nullptr)

Processes a Constant recursively looking into elements of arrays, structs and expressions to find a t...

std::pair< Function *, Constant * > getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M)

Given a vtable and a specified offset, returns the function and the trivial pointer at the specified ...