LLVM: lib/Target/SPIRV/SPIRVLegalizerInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

22

23using namespace llvm;

26

27

29 TargetOpcode::G_ADD,

30 TargetOpcode::G_FADD,

31 TargetOpcode::G_STRICT_FADD,

32 TargetOpcode::G_SUB,

33 TargetOpcode::G_FSUB,

34 TargetOpcode::G_STRICT_FSUB,

35 TargetOpcode::G_MUL,

36 TargetOpcode::G_FMUL,

37 TargetOpcode::G_STRICT_FMUL,

38 TargetOpcode::G_SDIV,

39 TargetOpcode::G_UDIV,

40 TargetOpcode::G_FDIV,

41 TargetOpcode::G_STRICT_FDIV,

42 TargetOpcode::G_SREM,

43 TargetOpcode::G_UREM,

44 TargetOpcode::G_FREM,

45 TargetOpcode::G_STRICT_FREM,

46 TargetOpcode::G_FNEG,

47 TargetOpcode::G_CONSTANT,

48 TargetOpcode::G_FCONSTANT,

49 TargetOpcode::G_AND,

50 TargetOpcode::G_OR,

51 TargetOpcode::G_XOR,

52 TargetOpcode::G_SHL,

53 TargetOpcode::G_ASHR,

54 TargetOpcode::G_LSHR,

55 TargetOpcode::G_SELECT,

56 TargetOpcode::G_EXTRACT_VECTOR_ELT,

57};

58

59

62}

63

65 return [IsExtendedInts, TypeIdx](const LegalityQuery &Query) {

66 const LLT Ty = Query.Types[TypeIdx];

68 };

69}

70

72 using namespace TargetOpcode;

73

74 this->ST = &ST;

75 GR = ST.getSPIRVGlobalRegistry();

76

82

88

94

100

106

112

113 const unsigned PSize = ST.getPointerSize();

116 const LLT p2 = LLT::pointer(2, PSize);

119 const LLT p5 =

120 LLT::pointer(5, PSize);

121 const LLT p6 = LLT::pointer(6, PSize);

125

126

127 auto allPtrsScalarsAndVectors = {

128 p0, p1, p2, p3, p4, p5, p6, p7, p8, p10,

129 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,

130 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,

131 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};

132

133 auto allVectors = {v2s1, v2s8, v2s16, v2s32, v2s64, v3s1, v3s8,

134 v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32,

135 v4s64, v8s1, v8s8, v8s16, v8s32, v8s64, v16s1,

136 v16s8, v16s16, v16s32, v16s64};

137

138 auto allScalarsAndVectors = {

139 s1, s8, s16, s32, s64, v2s1, v2s8, v2s16, v2s32, v2s64,

140 v3s1, v3s8, v3s16, v3s32, v3s64, v4s1, v4s8, v4s16, v4s32, v4s64,

141 v8s1, v8s8, v8s16, v8s32, v8s64, v16s1, v16s8, v16s16, v16s32, v16s64};

142

143 auto allIntScalarsAndVectors = {s8, s16, s32, s64, v2s8, v2s16,

144 v2s32, v2s64, v3s8, v3s16, v3s32, v3s64,

145 v4s8, v4s16, v4s32, v4s64, v8s8, v8s16,

146 v8s32, v8s64, v16s8, v16s16, v16s32, v16s64};

147

148 auto allBoolScalarsAndVectors = {s1, v2s1, v3s1, v4s1, v8s1, v16s1};

149

150 auto allIntScalars = {s8, s16, s32, s64};

151

152 auto allFloatScalars = {s16, s32, s64};

153

154 auto allFloatScalarsAndVectors = {

155 s16, s32, s64, v2s16, v2s32, v2s64, v3s16, v3s32, v3s64,

156 v4s16, v4s32, v4s64, v8s16, v8s32, v8s64, v16s16, v16s32, v16s64};

157

158 auto allFloatAndIntScalarsAndPtrs = {s8, s16, s32, s64, p0, p1, p2,

159 p3, p4, p5, p6, p7, p8, p10};

160

161 auto allPtrs = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p10};

162

163 bool IsExtendedInts =

164 ST.canUseExtension(

165 SPIRV::Extension::SPV_INTEL_arbitrary_precision_integers) ||

166 ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions);

167 auto extendedScalarsAndVectors =

169 const LLT Ty = Query.Types[0];

171 };

172 auto extendedScalarsAndVectorsProduct = [IsExtendedInts](

174 const LLT Ty1 = Query.Types[0], Ty2 = Query.Types[1];

175 return IsExtendedInts && Ty1.isValid() && Ty2.isValid() &&

177 };

178 auto extendedPtrsScalarsAndVectors =

180 const LLT Ty = Query.Types[0];

181 return IsExtendedInts && Ty.isValid();

182 };

183

186

188

189

191 {G_BUILD_VECTOR, G_SHUFFLE_VECTOR, G_SPLAT_VECTOR})

192 .alwaysLegal();

193

194

196 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX,

197 G_VECREDUCE_ADD, G_VECREDUCE_MUL, G_VECREDUCE_FMUL, G_VECREDUCE_FMIN,

198 G_VECREDUCE_FMAX, G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM,

199 G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})

200 .legalFor(allVectors)

203

206 .lower();

207

208

209

211

214

217

220

222

224 G_BITREVERSE, G_SADDSAT, G_UADDSAT, G_SSUBSAT,

225 G_USUBSAT, G_SCMP, G_UCMP})

226 .legalFor(allIntScalarsAndVectors)

227 .legalIf(extendedScalarsAndVectors);

228

230 .legalFor(allFloatScalarsAndVectors);

231

234

236 .legalForCartesianProduct(allIntScalarsAndVectors,

237 allFloatScalarsAndVectors);

238

240 .legalForCartesianProduct(allFloatScalarsAndVectors,

241 allScalarsAndVectors);

242

245 .legalIf(extendedScalarsAndVectorsProduct);

246

247

249 .legalForCartesianProduct(allScalarsAndVectors)

250 .legalIf(extendedScalarsAndVectorsProduct);

251

253 .legalFor(allPtrsScalarsAndVectors)

254 .legalIf(extendedPtrsScalarsAndVectors);

255

258 typeInSet(1, allPtrsScalarsAndVectors)));

259

261

263

276

277

278

281 typeInSet(1, allPtrsScalarsAndVectors)));

282

285 typeInSet(1, allFloatScalarsAndVectors)));

286

288 G_ATOMICRMW_MAX, G_ATOMICRMW_MIN,

289 G_ATOMICRMW_SUB, G_ATOMICRMW_XOR,

290 G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})

291 .legalForCartesianProduct(allIntScalars, allPtrs);

292

294 {G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB, G_ATOMICRMW_FMIN, G_ATOMICRMW_FMAX})

295 .legalForCartesianProduct(allFloatScalars, allPtrs);

296

299

301

303

305 {G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_UMULO, G_SMULO})

306 .alwaysLegal();

307

308

310 .legalForCartesianProduct(allFloatScalarsAndVectors);

311

312

314

315

317

318

319

320

321

323 G_FPOW,

324 G_FEXP,

325 G_FEXP2,

326 G_FLOG,

327 G_FLOG2,

328 G_FLOG10,

329 G_FABS,

330 G_FMINNUM,

331 G_FMAXNUM,

332 G_FCEIL,

333 G_FCOS,

334 G_FSIN,

335 G_FTAN,

336 G_FACOS,

337 G_FASIN,

338 G_FATAN,

339 G_FATAN2,

340 G_FCOSH,

341 G_FSINH,

342 G_FTANH,

343 G_FSQRT,

344 G_FFLOOR,

345 G_FRINT,

346 G_FNEARBYINT,

347 G_INTRINSIC_ROUND,

348 G_INTRINSIC_TRUNC,

349 G_FMINIMUM,

350 G_FMAXIMUM,

351 G_INTRINSIC_ROUNDEVEN})

352 .legalFor(allFloatScalarsAndVectors);

353

356 allFloatScalarsAndVectors);

357

359 allFloatScalarsAndVectors, allIntScalarsAndVectors);

360

361 if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) {

363 {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF})

364 .legalForCartesianProduct(allIntScalarsAndVectors,

365 allIntScalarsAndVectors);

366

367

369 }

370

372 verify(*ST.getInstrInfo());

373}

374

379 Register ConvReg = MRI.createGenericVirtualRegister(ConvTy);

385 return ConvReg;

386}

387

391 auto Opc = MI.getOpcode();

394 assert(Opc == TargetOpcode::G_ICMP);

396 auto &Op0 = MI.getOperand(2);

397 auto &Op1 = MI.getOperand(3);

398 Register Reg0 = Op0.getReg();

399 Register Reg1 = Op1.getReg();

404 MRI.getType(Reg0).isPointer() && MRI.getType(Reg1).isPointer()) {

411 }

412 return true;

413 }

414

415 return true;

416}

unsigned const MachineRegisterInfo * MRI

static void scalarize(BinaryOperator *BO, SmallVectorImpl< BinaryOperator * > &Replace)

This file declares the MachineIRBuilder class.

const SmallVectorImpl< MachineOperand > & Cond

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

bool isTypeFoldingSupported(unsigned Opcode)

static const std::set< unsigned > TypeFoldingSupportingOpcs

static Register convertPtrToInt(Register Reg, LLT ConvTy, SPIRVType *SpvType, LegalizerHelper &Helper, MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR)

bool isTypeFoldingSupported(unsigned Opcode)

LegalityPredicate typeOfExtendedScalars(unsigned TypeIdx, bool IsExtendedInts)

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

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

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

constexpr bool isScalar() const

static constexpr LLT scalar(unsigned SizeInBits)

Get a low-level scalar or aggregate "bag of bits".

constexpr bool isValid() const

static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)

Get a low-level pointer in the given address space.

static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)

Get a low-level fixed-width vector of some number of elements and element width.

constexpr bool isPointerOrPointerVector() const

void computeTables()

Compute any ancillary tables needed to quickly decide how an operation should be handled.

LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)

The instruction is legal when type index 0 is any type in the given list.

LegalizeRuleSet & lower()

The instruction is lowered.

LegalizeRuleSet & custom()

Unconditionally custom lower.

LegalizeRuleSet & alwaysLegal()

LegalizeRuleSet & customIf(LegalityPredicate Predicate)

LegalizeRuleSet & scalarize(unsigned TypeIdx)

LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)

The instruction is legal when type indexes 0 and 1 are both in the given list.

LegalizeRuleSet & legalIf(LegalityPredicate Predicate)

The instruction is legal if predicate is true.

MachineIRBuilder & MIRBuilder

Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.

LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)

Get the action definition builder for the given opcode.

const LegacyLegalizerInfo & getLegacyLegalizerInfo() const

MachineInstrBuilder buildInstr(unsigned Opcode)

Build and insert = Opcode .

MachineFunction & getMF()

Getter for the function we currently build.

const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register use operand.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const

void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)

SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)

const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const

SPIRVLegalizerInfo(const SPIRVSubtarget &ST)

bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override

Called for instructions with the Custom LegalizationAction.

unsigned getPointerSize() const

bool canDirectlyComparePointers() const

The instances of the Type class are immutable: once they are created, they are never changed.

LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)

True iff the given type index is one of the specified types.

Predicate all(Predicate P0, Predicate P1)

True iff P0 and P1 are true.

This is an optimization pass for GlobalISel generic memory operations.

std::function< bool(const LegalityQuery &)> LegalityPredicate

The LegalityQuery object bundles together all the information that's needed to decide whether a given...