LLVM: lib/Transforms/Utils/VNCoercion.cpp Source File (original) (raw)

6

7#define DEBUG_TYPE "vncoerce"

8

9namespace llvm {

10namespace VNCoercion {

11

15

16

20 if (StoredTy == LoadTy)

21 return true;

22

24 TypeSize MinStoreSize = DL.getTypeSizeInBits(StoredTy);

25 TypeSize LoadSize = DL.getTypeSizeInBits(LoadTy);

27 MinStoreSize == LoadSize)

28 return true;

29

30

31

32

35 return false;

36

37

38

39 const auto &Attrs = F->getAttributes().getFnAttrs();

40 unsigned MinVScale = Attrs.getVScaleRangeMin();

41 MinStoreSize =

45 return false;

46 }

47

48

49 if (llvm::alignTo(MinStoreSize, 8) != MinStoreSize)

50 return false;

51

52

54 return false;

55

56 bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType());

57 bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType());

58

59 if (StoredNI != LoadNI) {

60

61

62

64 return CI->isNullValue();

65 return false;

66 } else if (StoredNI && LoadNI &&

69 return false;

70 }

71

72

73

74

75 if (StoredNI && (StoredTy->isScalableTy() || MinStoreSize != LoadSize))

76 return false;

77

79 return false;

80

81 return true;

82}

83

84

85

86

87

88

89

93 "precondition violation - materialization can't fail");

97

98

100

101

102

105 return Helper.CreateIntrinsic(LoadedTy, Intrinsic::vector_extract,

106 {StoredVal, Helper.getInt64(0)});

107 }

108

109 TypeSize StoredValSize = DL.getTypeSizeInBits(StoredValTy);

110 TypeSize LoadedValSize = DL.getTypeSizeInBits(LoadedTy);

111

112

113 if (StoredValSize == LoadedValSize) {

114

116 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);

117 } else {

118

120 StoredValTy = DL.getIntPtrType(StoredValTy);

121 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);

122 }

123

124 Type *TypeToCastTo = LoadedTy;

126 TypeToCastTo = DL.getIntPtrType(TypeToCastTo);

127

128 if (StoredValTy != TypeToCastTo)

129 StoredVal = Helper.CreateBitCast(StoredVal, TypeToCastTo);

130

131

133 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);

134 }

135

138

139 return StoredVal;

140 }

141

142

143

146 "canCoerceMustAliasedValueToLoad fail");

147

148

150 StoredValTy = DL.getIntPtrType(StoredValTy);

151 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);

152 }

153

154

157 StoredVal = Helper.CreateBitCast(StoredVal, StoredValTy);

158 }

159

160

161

162 if (DL.isBigEndian()) {

163 uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -

164 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();

166 StoredVal, ConstantInt::get(StoredVal->getType(), ShiftAmt));

167 }

168

169

172

173 if (LoadedTy != NewIntTy) {

174

176 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);

177 else

178

179 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);

180 }

181

184

185 return StoredVal;

186}

187

188

189

190

191

192

193

194

195

200

201

203 return -1;

204

205 int64_t StoreOffset = 0, LoadOffset = 0;

206 Value *StoreBase =

209 if (StoreBase != LoadBase)

210 return -1;

211

212 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue();

213

214 if ((WriteSizeInBits & 7) | (LoadSize & 7))

215 return -1;

216 uint64_t StoreSize = WriteSizeInBits / 8;

217 LoadSize /= 8;

218

219

220

221

222

223 if (StoreOffset > LoadOffset ||

224 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))

225 return -1;

226

227

228

229 return LoadOffset - StoreOffset;

230}

231

232

233

237

238

240 return -1;

241

243 return -1;

244

250}

251

252

253

254

257

259 return -1;

260

262 return -1;

263

265 uint64_t DepSize = DL.getTypeSizeInBits(DepLI->getType()).getFixedValue();

267}

268

271

273 if (!SizeCst)

274 return -1;

276

277

278

280 if (DL.isNonIntegralPointerType(LoadTy->getScalarType())) {

282 if (!CI || !CI->isZero())

283 return -1;

284 }

286 MemSizeInBits, DL);

287 }

288

289

290

291

293

295 if (!Src)

296 return -1;

297

300 return -1;

301

302

304 MemSizeInBits, DL);

307

308

309

310 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());

313 return -1;

314}

315

320

321

322

323

327 return SrcVal;

328 }

329

330

331

333 assert(Offset == 0 && "Expected a zero offset for scalable types");

334 return SrcVal;

335 }

336

337

338

339

344 return SrcVal;

345 }

346

348 (DL.getTypeSizeInBits(SrcVal->getType()).getFixedValue() + 7) / 8;

349 uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;

350

351

353 SrcVal =

354 Builder.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getType()));

356 SrcVal =

357 Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8));

358

359

360 unsigned ShiftAmt;

361 if (DL.isLittleEndian())

362 ShiftAmt = Offset * 8;

363 else

364 ShiftAmt = (StoreSize - LoadSize - Offset) * 8;

365 if (ShiftAmt)

366 SrcVal = Builder.CreateLShr(SrcVal,

367 ConstantInt::get(SrcVal->getType(), ShiftAmt));

368

369 if (LoadSize != StoreSize)

370 SrcVal = Builder.CreateTruncOrBitCast(SrcVal,

372 return SrcVal;

373}

374

378#ifndef NDEBUG

380 TypeSize LoadSize = DL.getTypeStoreSize(LoadTy);

382 MinSrcValSize =

384 F->getAttributes().getFnAttrs().getVScaleRangeMin());

386 "Expected Offset + LoadSize <= SrcValSize");

389 "Expected offset of zero and LoadSize <= SrcValSize");

390#endif

394}

395

398#ifndef NDEBUG

399 unsigned SrcValSize = DL.getTypeStoreSize(SrcVal->getType()).getFixedValue();

400 unsigned LoadSize = DL.getTypeStoreSize(LoadTy).getFixedValue();

402#endif

404}

405

406

407

412 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;

414

415

416

418

419

420 Value *Val = MSI->getValue();

421 if (LoadSize != 1)

422 Val =

423 Builder.CreateZExtOrBitCast(Val, IntegerType::get(Ctx, LoadSize * 8));

424 Value *OneElt = Val;

425

426

427 for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {

428

429 if (NumBytesSet * 2 <= LoadSize) {

430 Value *ShVal = Builder.CreateShl(

431 Val, ConstantInt::get(Val->getType(), NumBytesSet * 8));

432 Val = Builder.CreateOr(Val, ShVal);

433 NumBytesSet <<= 1;

434 continue;

435 }

436

437

439 Builder.CreateShl(Val, ConstantInt::get(Val->getType(), 1 * 8));

440 Val = Builder.CreateOr(OneElt, ShVal);

441 ++NumBytesSet;

442 }

443

446 }

447

448

451 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());

454}

455

459 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;

460

461

462

465 if (!Val)

466 return nullptr;

467

468 Val = ConstantInt::get(Ctx, APInt::getSplat(LoadSize * 8, Val->getValue()));

470 }

471

472

475 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());

478}

479}

480}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Class for arbitrary precision integers.

static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)

Return a value containing V broadcasted over NewLen bits.

This is the shared class of boolean and integer constants.

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

This is an important base class in LLVM.

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

bool isConstant() const

If the value is a global constant, its value is immutable throughout the runtime execution of the pro...

bool hasDefinitiveInitializer() const

hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...

Common base class shared among various IRBuilders.

Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")

Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

ConstantInt * getInt64(uint64_t C)

Get a constant 64-bit value.

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 * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")

Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")

Value * CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name="")

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

This is an important class for using LLVM in a threaded context.

An instruction for reading from memory.

Value * getPointerOperand()

This is the common base class for memset/memcpy/memmove.

This class wraps the llvm.memset and llvm.memset.inline intrinsics.

Value * getSource() const

This is just like getRawSource, but it strips off any cast instructions that feed it,...

This class wraps the llvm.memcpy/memmove intrinsics.

An instruction for storing to memory.

Value * getValueOperand()

Value * getPointerOperand()

static constexpr TypeSize getFixed(ScalarTy ExactSize)

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.

bool isPointerTy() const

True if this is an instance of PointerType.

LLVM_ABI unsigned getPointerAddressSpace() const

Get the address space of this pointer or pointer vector type.

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

bool isTargetExtTy() const

Return true if this is a target extension type.

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

bool isPtrOrPtrVectorTy() const

Return true if this is a pointer type or a vector of pointer types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)

constexpr bool isScalable() const

Returns whether the quantity is scaled by a runtime quantity (vscale).

constexpr ScalarTy getKnownMinValue() const

Returns the minimum value this quantity can represent.

static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)

@ C

The default llvm calling convention, compatible with C.

static int analyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr, Value *WritePtr, uint64_t WriteSizeInBits, const DataLayout &DL)

This function is called when we have a memdep query of a load that ends up being a clobbering memory ...

Definition VNCoercion.cpp:196

static Value * getStoreValueForLoadHelper(Value *SrcVal, unsigned Offset, Type *LoadTy, IRBuilderBase &Builder, const DataLayout &DL)

Definition VNCoercion.cpp:316

int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)

This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...

Definition VNCoercion.cpp:234

Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)

If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...

Definition VNCoercion.cpp:408

Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)

Definition VNCoercion.cpp:396

Value * coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, IRBuilderBase &IRB, Function *F)

If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different ty...

Definition VNCoercion.cpp:90

int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)

This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...

Definition VNCoercion.cpp:255

Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)

Definition VNCoercion.cpp:456

Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)

If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...

Definition VNCoercion.cpp:375

int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)

This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...

Definition VNCoercion.cpp:269

static bool isFirstClassAggregateOrScalableType(Type *Ty)

Definition VNCoercion.cpp:12

bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)

Return true if CoerceAvailableValueToLoadType would succeed if it was called.

Definition VNCoercion.cpp:17

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)

Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.

LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)

ConstantFoldConstant - Fold the constant using the specified DataLayout.

LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)

Extract value of C at the given Offset reinterpreted as Ty.

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.

LLVM_ABI Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)

Return the value that a load from C with offset Offset would produce if it is constant and determinab...

LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....