LLVM 24.0.0git
LoongArchTargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- LoongArchTargetTransformInfo.cpp - LoongArch specific TTI ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// LoongArch target machine. It uses the target's detailed information to
11/// provide more precise answers to certain TTI queries, while letting the
12/// target independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
21#include "llvm/IR/InstrTypes.h"
22#include "llvm/IR/Intrinsics.h"
24
25using namespace llvm;
26
27#define DEBUG_TYPE "loongarchtti"
28
30
34 switch (K) {
36 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
38 if (ST->hasExtLASX())
39 return TypeSize::getFixed(256);
40 if (ST->hasExtLSX())
41 return TypeSize::getFixed(128);
42 [[fallthrough]];
44 return DefSize;
45 }
46
47 llvm_unreachable("Unsupported register kind");
48}
49
50unsigned LoongArchTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
51 switch (ClassID) {
52 case LoongArchRegisterClass::GPRRC:
53 // 30 = 32 GPRs - r0 (zero register) - r21 (non-allocatable)
54 return 30;
55 case LoongArchRegisterClass::FPRRC:
56 return ST->hasBasicF() ? 32 : 0;
57 case LoongArchRegisterClass::VRRC:
58 return ST->hasExtLSX() ? 32 : 0;
59 }
60 llvm_unreachable("unknown register class");
61}
62
64 Type *Ty) const {
65 if (Vector)
66 return LoongArchRegisterClass::VRRC;
67 if (!Ty)
68 return LoongArchRegisterClass::GPRRC;
69
70 Type *ScalarTy = Ty->getScalarType();
71 if ((ScalarTy->isFloatTy() && ST->hasBasicF()) ||
72 (ScalarTy->isDoubleTy() && ST->hasBasicD())) {
73 return LoongArchRegisterClass::FPRRC;
74 }
75
76 return LoongArchRegisterClass::GPRRC;
77}
78
79unsigned
81 bool HasUnorderedReductions) const {
82 return ST->getMaxInterleaveFactor();
83}
84
85const char *LoongArchTTIImpl::getRegisterClassName(unsigned ClassID) const {
86 switch (ClassID) {
87 case LoongArchRegisterClass::GPRRC:
88 return "LoongArch::GPRRC";
89 case LoongArchRegisterClass::FPRRC:
90 return "LoongArch::FPRRC";
91 case LoongArchRegisterClass::VRRC:
92 return "LoongArch::VRRC";
93 }
94 llvm_unreachable("unknown register class");
95}
96
98LoongArchTTIImpl::getPopcntSupport(unsigned TyWidth) const {
99 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
100 return ST->hasExtLSX() ? TTI::PSK_FastHardware : TTI::PSK_Software;
101}
102
103unsigned LoongArchTTIImpl::getCacheLineSize() const { return 64; }
104
105unsigned LoongArchTTIImpl::getPrefetchDistance() const { return 200; }
106
107bool LoongArchTTIImpl::enableWritePrefetching() const { return true; }
108
110 switch (II->getIntrinsicID()) {
111 default:
112 return true;
113 case Intrinsic::vector_reduce_add:
114 case Intrinsic::vector_reduce_and:
115 case Intrinsic::vector_reduce_or:
116 case Intrinsic::vector_reduce_smax:
117 case Intrinsic::vector_reduce_smin:
118 case Intrinsic::vector_reduce_umax:
119 case Intrinsic::vector_reduce_umin:
120 case Intrinsic::vector_reduce_xor:
121 return false;
122 }
123}
124
126 Align Alignment,
127 unsigned AddressSpace,
128 TTI::TargetCostKind CostKind,
130 const Instruction *I) const {
131 // Vectors narrower than 128 bits are widened, and on LA64 loading or storing
132 // one takes a single instruction: FLD.{S/D} or VLDREPL.{B/H} for loads, and
133 // VSTELM.{B/H/W/D} for stores. The generic model costs them as scalarized.
134 // TODO: LA32 splits 64-bit loads and doesn't use VSTELM.{W/D} for stores.
135 auto *VTy = dyn_cast<FixedVectorType>(Src);
136 if (CostKind == TTI::TCK_RecipThroughput && ST->is64Bit() &&
137 ST->hasExtLSX() && VTy && isPowerOf2_32(VTy->getNumElements())) {
138 unsigned Size = VTy->getPrimitiveSizeInBits().getFixedValue();
139 EVT VT = getTLI()->getValueType(DL, Src);
140 if (Size >= 16 && Size < 128 &&
141 getTLI()->getTypeAction(Src->getContext(), VT) ==
143 getTLI()->allowsMemoryAccessForAlignment(Src->getContext(), DL, VT,
144 AddressSpace, Alignment))
145 return 1;
146 }
147
148 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, CostKind,
149 OpInfo, I);
150}
151
153LoongArchTTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
155
156 if (!ST->hasUAL())
157 return Options;
158
159 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
160 Options.NumLoadsPerBlock = IsZeroCmp ? Options.MaxNumLoads : 1;
161 Options.AllowOverlappingLoads = true;
162
163 // TODO: Support for vectors.
164 if (ST->is64Bit()) {
165 Options.LoadSizes = {8, 4, 2, 1};
166 Options.AllowedTailExpansions = {3, 5, 6};
167 } else {
168 Options.LoadSizes = {4, 2, 1};
169 Options.AllowedTailExpansions = {3};
170 }
171
172 return Options;
173}
174
176 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
178 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
179
180 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
181 int ISD = TLI->InstructionOpcodeToISD(Opcode);
182
183 // Vector multiply by pow2 will be simplified to shifts.
184 // Vector multiply by -pow2 will be simplified to shifts/negates.
185 if (ISD == ISD::MUL && Op2Info.isConstant() &&
186 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
188 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
189 Op1Info.getNoProps(), Op2Info.getNoProps());
190 if (Op2Info.isNegatedPowerOf2())
191 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
192 return Cost;
193 }
194
195 // On LoongArch, vector signed division by constants power-of-two are
196 // normally expanded to the sequence SRA + SRL + ADD + SRA.
197 // The OperandValue properties may not be the same as that of the previous
198 // operation; conservatively assume OP_None.
199 if ((ISD == ISD::SDIV || ISD == ISD::SREM) && Op2Info.isConstant() &&
200 Op2Info.isPowerOf2()) {
202 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
203 Op1Info.getNoProps(), Op2Info.getNoProps());
204 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
205 Op1Info.getNoProps(), Op2Info.getNoProps());
206 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
207 Op1Info.getNoProps(), Op2Info.getNoProps());
208
209 if (ISD == ISD::SREM) {
210 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
211 Cost +=
212 getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
213 Op1Info.getNoProps(), Op2Info.getNoProps());
214 Cost +=
215 getArithmeticInstrCost(Instruction::Sub, Ty, CostKind,
216 Op1Info.getNoProps(), Op2Info.getNoProps());
217 }
218
219 return Cost;
220 }
221 // Vector unsigned division/remainder will be simplified to shifts/masks.
222 if ((ISD == ISD::UDIV || ISD == ISD::UREM) && Op2Info.isConstant() &&
223 Op2Info.isPowerOf2()) {
224 if (ISD == ISD::UDIV)
225 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
226 Op1Info.getNoProps(), Op2Info.getNoProps());
227 // UREM
228 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
229 Op1Info.getNoProps(), Op2Info.getNoProps());
230 }
231
232 static const CostKindTblEntry LSXCostTable[]{
233 {ISD::ADD, MVT::v16i8, {1, 1}}, // vaddi.b/vadd.b
234 {ISD::ADD, MVT::v8i16, {1, 1}}, // vaddi.h/vadd.h
235 {ISD::ADD, MVT::v4i32, {1, 1}}, // vaddi.w/vadd.w
236 {ISD::ADD, MVT::v2i64, {1, 1}}, // vaddi.d/vadd.d
237
238 {ISD::SUB, MVT::v16i8, {1, 1}}, // vsubi.b/vsub.b
239 {ISD::SUB, MVT::v8i16, {1, 1}}, // vsubi.h/vsub.h
240 {ISD::SUB, MVT::v4i32, {1, 1}}, // vsubi.w/vsub.w
241 {ISD::SUB, MVT::v2i64, {1, 1}}, // vsubi.d/vsub.d
242
243 {ISD::MUL, MVT::v16i8, {2, 4}}, // vmul.b
244 {ISD::MUL, MVT::v8i16, {2, 4}}, // vmul.h
245 {ISD::MUL, MVT::v4i32, {2, 4}}, // vmul.w
246 {ISD::MUL, MVT::v2i64, {2, 4}}, // vmul.d
247
248 {ISD::SDIV, MVT::v16i8, {62, 29}}, // vdiv.b
249 {ISD::SDIV, MVT::v8i16, {34, 17}}, // vdiv.h
250 {ISD::SDIV, MVT::v4i32, {22, 11}}, // vdiv.w
251 {ISD::SDIV, MVT::v2i64, {16, 8}}, // vdiv.d
252
253 {ISD::UDIV, MVT::v16i8, {66, 29}}, // vdiv.bu
254 {ISD::UDIV, MVT::v8i16, {36, 17}}, // vdiv.hu
255 {ISD::UDIV, MVT::v4i32, {22, 11}}, // vdiv.wu
256 {ISD::UDIV, MVT::v2i64, {16, 8}}, // vdiv.du
257
258 {ISD::SREM, MVT::v16i8, {76, 38}}, // vmod.b
259 {ISD::SREM, MVT::v8i16, {44, 24}}, // vmod.h
260 {ISD::SREM, MVT::v4i32, {27, 17}}, // vmod.w
261 {ISD::SREM, MVT::v2i64, {19, 14}}, // vmod.d
262
263 {ISD::UREM, MVT::v16i8, {80, 38}}, // vmod.bu
264 {ISD::UREM, MVT::v8i16, {44, 24}}, // vmod.hu
265 {ISD::UREM, MVT::v4i32, {28, 17}}, // vmod.wu
266 {ISD::UREM, MVT::v2i64, {19, 14}}, // vmod.du
267
268 {ISD::SHL, MVT::v16i8, {1, 1}}, // vslli.b/vsll.b
269 {ISD::SHL, MVT::v8i16, {1, 1}}, // vslli.h/vsll.h
270 {ISD::SHL, MVT::v4i32, {1, 1}}, // vslli.w/vsll.w
271 {ISD::SHL, MVT::v2i64, {1, 1}}, // vslli.d/vsll.d
272
273 {ISD::SRL, MVT::v16i8, {1, 1}}, // vsrli.b/vsrl.b
274 {ISD::SRL, MVT::v8i16, {1, 1}}, // vsrli.h/vsrl.h
275 {ISD::SRL, MVT::v4i32, {1, 1}}, // vsrli.w/vsrl.w
276 {ISD::SRL, MVT::v2i64, {1, 1}}, // vsrli.d/vsrl.d
277
278 {ISD::SRA, MVT::v16i8, {1, 1}}, // vsrai.b/vsra.b
279 {ISD::SRA, MVT::v8i16, {1, 1}}, // vsrai.h/vsra.h
280 {ISD::SRA, MVT::v4i32, {1, 1}}, // vsrai.w/vsra.w
281 {ISD::SRA, MVT::v2i64, {1, 1}}, // vsrai.d/vsra.d
282
283 {ISD::AND, MVT::v16i8, {1, 1}}, // vand.b/vand.v
284 {ISD::AND, MVT::v8i16, {1, 1}}, // vand.v
285 {ISD::AND, MVT::v4i32, {1, 1}}, // vand.v
286 {ISD::AND, MVT::v2i64, {1, 1}}, // vand.v
287
288 {ISD::OR, MVT::v16i8, {1, 1}}, // vori.b/vor.v
289 {ISD::OR, MVT::v8i16, {1, 1}}, // vor.v
290 {ISD::OR, MVT::v4i32, {1, 1}}, // vor.v
291 {ISD::OR, MVT::v2i64, {1, 1}}, // vor.v
292
293 {ISD::XOR, MVT::v16i8, {1, 1}}, // vxori.b/vxor.v
294 {ISD::XOR, MVT::v8i16, {1, 1}}, // vxor.v
295 {ISD::XOR, MVT::v4i32, {1, 1}}, // vxor.v
296 {ISD::XOR, MVT::v2i64, {1, 1}}, // vxor.v
297
298 {ISD::FADD, MVT::v4f32, {1, 3}}, // vfadd.s
299 {ISD::FADD, MVT::v2f64, {1, 3}}, // vfadd.d
300
301 {ISD::FSUB, MVT::v4f32, {1, 3}}, // vfsub.s
302 {ISD::FSUB, MVT::v2f64, {1, 3}}, // vfsub.d
303
304 {ISD::FMUL, MVT::v4f32, {2, 5}}, // vfmul.s
305 {ISD::FMUL, MVT::v2f64, {2, 5}}, // vfmul.d
306
307 {ISD::FDIV, MVT::v4f32, {22, 11}}, // vfdiv.s
308 {ISD::FDIV, MVT::v2f64, {16, 8}}, // vfdiv.d
309 };
310
311 if (ST->hasExtLSX()) {
312 if (const auto *Entry = CostTableLookup(LSXCostTable, ISD, LT.second))
313 if (auto KindCost = Entry->Cost[CostKind])
314 return LT.first * *KindCost;
315 }
316
317 static const CostKindTblEntry LASXUniformConstCostTable[]{
318 {ISD::ADD, MVT::v32i8, {1, 1}}, // xvaddi.b/xvadd.b
319 {ISD::ADD, MVT::v16i16, {1, 1}}, // xvaddi.h/xvadd.h
320 {ISD::ADD, MVT::v8i32, {1, 1}}, // xvaddi.w/xvadd.w
321 {ISD::ADD, MVT::v4i64, {1, 1}}, // xvaddi.d/xvadd.d
322
323 {ISD::SUB, MVT::v32i8, {1, 1}}, // xvsubi.b/xvsub.b
324 {ISD::SUB, MVT::v16i16, {1, 1}}, // xvsubi.h/xvsub.h
325 {ISD::SUB, MVT::v8i32, {1, 1}}, // xvsubi.w/xvsub.w
326 {ISD::SUB, MVT::v4i64, {1, 1}}, // xvsubi.d/xvsub.d
327
328 {ISD::MUL, MVT::v32i8, {2, 4}}, // xvmul.b
329 {ISD::MUL, MVT::v16i16, {2, 4}}, // xvmul.h
330 {ISD::MUL, MVT::v8i32, {2, 4}}, // xvmul.w
331 {ISD::MUL, MVT::v4i64, {2, 4}}, // xvmul.d
332
333 {ISD::SDIV, MVT::v32i8, {62, 29}}, // xvdiv.b
334 {ISD::SDIV, MVT::v16i16, {34, 17}}, // xvdiv.h
335 {ISD::SDIV, MVT::v8i32, {22, 11}}, // xvdiv.w
336 {ISD::SDIV, MVT::v4i64, {16, 8}}, // xvdiv.d
337
338 {ISD::UDIV, MVT::v32i8, {66, 29}}, // xvdiv.bu
339 {ISD::UDIV, MVT::v16i16, {36, 17}}, // xvdiv.hu
340 {ISD::UDIV, MVT::v8i32, {22, 11}}, // xvdiv.wu
341 {ISD::UDIV, MVT::v4i64, {16, 8}}, // xvdiv.du
342
343 {ISD::SREM, MVT::v32i8, {76, 38}}, // xvmod.b
344 {ISD::SREM, MVT::v16i16, {44, 24}}, // xvmod.h
345 {ISD::SREM, MVT::v8i32, {28, 17}}, // xvmod.w
346 {ISD::SREM, MVT::v4i64, {19, 14}}, // xvmod.d
347
348 {ISD::UREM, MVT::v32i8, {76, 38}}, // xvmod.bu
349 {ISD::UREM, MVT::v16i16, {43, 24}}, // xvmod.hu
350 {ISD::UREM, MVT::v8i32, {28, 17}}, // xvmod.wu
351 {ISD::UREM, MVT::v4i64, {19, 14}}, // xvmod.du
352
353 {ISD::SHL, MVT::v32i8, {1, 1}}, // xvslli.b/xvsll.b
354 {ISD::SHL, MVT::v16i16, {1, 1}}, // xvslli.h/xvsll.h
355 {ISD::SHL, MVT::v8i32, {1, 1}}, // xvslli.w/xvsll.w
356 {ISD::SHL, MVT::v4i64, {1, 1}}, // xvslli.d/xvsll.d
357
358 {ISD::SRL, MVT::v32i8, {1, 1}}, // xvsrli.b/xvsrl.b
359 {ISD::SRL, MVT::v16i16, {1, 1}}, // xvsrli.h/xvsrl.h
360 {ISD::SRL, MVT::v8i32, {1, 1}}, // xvsrli.w/xvsrl.w
361 {ISD::SRL, MVT::v4i64, {1, 1}}, // xvsrli.d/xvsrl.d
362
363 {ISD::SRA, MVT::v32i8, {1, 1}}, // xvsrai.b/xvsra.b
364 {ISD::SRA, MVT::v16i16, {1, 1}}, // xvsrai.h/xvsra.h
365 {ISD::SRA, MVT::v8i32, {1, 1}}, // xvsrai.w/xvsra.w
366 {ISD::SRA, MVT::v4i64, {1, 1}}, // xvsrai.d/xvsra.d
367
368 {ISD::AND, MVT::v32i8, {1, 1}}, // xvandi.b/xvand.v
369 {ISD::AND, MVT::v16i16, {1, 1}}, // xvand.v
370 {ISD::AND, MVT::v8i32, {1, 1}}, // xvand.v
371 {ISD::AND, MVT::v4i64, {1, 1}}, // xvand.v
372
373 {ISD::OR, MVT::v32i8, {1, 1}}, // xvori.b/xvor.v
374 {ISD::OR, MVT::v16i16, {1, 1}}, // xvor.v
375 {ISD::OR, MVT::v8i32, {1, 1}}, // xvor.v
376 {ISD::OR, MVT::v4i64, {1, 1}}, // xvor.v
377
378 {ISD::XOR, MVT::v32i8, {1, 1}}, // xvxori.b/xvxor.v
379 {ISD::XOR, MVT::v16i16, {1, 1}}, // xvxor.v
380 {ISD::XOR, MVT::v8i32, {1, 1}}, // xvxor.v
381 {ISD::XOR, MVT::v4i64, {1, 1}}, // xvxor.v
382
383 {ISD::FADD, MVT::v8f32, {1, 3}}, // xvfadd.s
384 {ISD::FADD, MVT::v4f64, {1, 3}}, // xvfadd.d
385
386 {ISD::FSUB, MVT::v8f32, {1, 3}}, // xvfsub.s
387 {ISD::FSUB, MVT::v4f64, {1, 3}}, // xvfsub.d
388
389 {ISD::FMUL, MVT::v8f32, {2, 5}}, // xvfmul.s
390 {ISD::FMUL, MVT::v4f64, {2, 5}}, // xvfmul.d
391
392 {ISD::FDIV, MVT::v8f32, {22, 11}}, // xvfdiv.s
393 {ISD::FDIV, MVT::v4f64, {16, 8}}, // xvfdiv.d
394 };
395
396 if (ST->hasExtLASX()) {
397 if (const auto *Entry =
398 CostTableLookup(LASXUniformConstCostTable, ISD, LT.second))
399 if (auto KindCost = Entry->Cost[CostKind])
400 return LT.first * *KindCost;
401 }
402
403 static const CostKindTblEntry LA64CostTable[]{
404 {ISD::ADD, MVT::i64, {1, 1}}, // addi.d/add.d
405 {ISD::SUB, MVT::i64, {1, 1}}, // subi.d/sub.d
406 {ISD::MUL, MVT::i64, {2, 4}}, // mul.d
407
408 {ISD::SDIV, MVT::i64, {26, 18}}, // div.d
409 {ISD::UDIV, MVT::i64, {26, 18}}, // div.du
410 {ISD::SREM, MVT::i64, {26, 18}}, // mod.d
411 {ISD::UREM, MVT::i64, {26, 18}}, // mod.du
412
413 {ISD::SHL, MVT::i64, {1, 1}}, // slli.d/sll.d
414 {ISD::SRL, MVT::i64, {1, 1}}, // srli.d/srl.d
415 {ISD::SRA, MVT::i64, {1, 1}}, // srai.d/sra.d
416
417 {ISD::AND, MVT::i64, {1, 1}}, // andi.d/and.d
418 {ISD::OR, MVT::i64, {1, 1}}, // ori.d/or.d
419 {ISD::XOR, MVT::i64, {1, 1}}, // xori.d/xor.d
420
421 {ISD::FADD, MVT::f64, {1, 3}}, // fadd.d
422 {ISD::FSUB, MVT::f64, {1, 3}}, // fsub.d
423 {ISD::FMUL, MVT::f64, {2, 5}}, // fmul.d
424 {ISD::FDIV, MVT::f64, {9, 12}}, // fdiv.d
425 };
426
427 if (ST->is64Bit()) {
428 if (const auto *Entry = CostTableLookup(LA64CostTable, ISD, LT.second))
429 if (auto KindCost = Entry->Cost[CostKind])
430 return LT.first * *KindCost;
431 }
432
433 static const CostKindTblEntry LA32CostTable[]{
434 {ISD::ADD, MVT::i32, {1, 1}}, // addi.w/add.w
435 {ISD::SUB, MVT::i32, {1, 1}}, // subi.w/sub.w
436 {ISD::MUL, MVT::i32, {2, 4}}, // mul.w
437
438 {ISD::SDIV, MVT::i32, {24, 11}}, // div.w
439 {ISD::UDIV, MVT::i32, {24, 12}}, // div.wu
440 {ISD::SREM, MVT::i32, {24, 11}}, // mod.w
441 {ISD::UREM, MVT::i32, {24, 12}}, // mod.wu
442
443 {ISD::SHL, MVT::i32, {1, 1}}, // slli.w/sll.w
444 {ISD::SRL, MVT::i32, {1, 1}}, // srli.w/srl.w
445 {ISD::SRA, MVT::i32, {1, 1}}, // srai.w/sra.w
446
447 {ISD::AND, MVT::i32, {1, 1}}, // andi.w/and.w
448 {ISD::OR, MVT::i32, {1, 1}}, // ori.w/or.w
449 {ISD::XOR, MVT::i32, {1, 1}}, // xori.w/xor.w
450
451 {ISD::FADD, MVT::f32, {1, 3}}, // fadd.s
452 {ISD::FSUB, MVT::f32, {1, 3}}, // fsub.s
453 {ISD::FMUL, MVT::f32, {2, 5}}, // fmul.s
454 {ISD::FDIV, MVT::f32, {8, 9}}, // fdiv.s
455 };
456
457 if (const auto *Entry = CostTableLookup(LA32CostTable, ISD, LT.second))
458 if (auto KindCost = Entry->Cost[CostKind])
459 return LT.first * *KindCost;
460
461 // Fallback to the default implementation.
462 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
463 Args, CxtI);
464}
465
466// Returns true if Ty is a fixed vector type held in a single LSX/LASX register.
467static bool isSingleVRegType(const LoongArchSubtarget *ST, Type *Ty) {
468 auto *VTy = dyn_cast<FixedVectorType>(Ty);
469 if (!VTy)
470 return false;
471 unsigned Bits = VTy->getPrimitiveSizeInBits().getFixedValue();
472 return (Bits == 128 && ST->hasExtLSX()) || (Bits == 256 && ST->hasExtLASX());
473}
474
476 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
477 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
478 // Element 0 of a floating-point vector is the aliased FPR, so extracting it
479 // is free.
480 if (Opcode == Instruction::ExtractElement && Index == 0 &&
482 return 0;
483 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1, VIC);
484}
485
487 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
488 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
489 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CxtI,
490 TTI::VectorInstrContext VIC) const {
491 if (isSingleVRegType(ST, SrcTy) && DstTy == SrcTy) {
492 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
493 unsigned EltBits = SrcTy->getScalarSizeInBits();
494 bool Is128 = SrcTy->getPrimitiveSizeInBits().getFixedValue() == 128;
495 switch (Kind) {
497 // [x]vreplvei.{b/h/w/d}, xvreplve0.{b/h/w/d}, [x]vreplgr2vr.{b/h/w/d}.
498 return 1;
499 case TTI::SK_Reverse:
501 // vshuf4i.{w/d} handles any single-source permutation of 32/64-bit
502 // elements within a 128-bit register.
503 if (Is128 && EltBits >= 32)
504 return 1;
505 break;
506 default:
507 break;
508 }
509 }
510 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index, SubTp,
511 Args, CxtI, VIC);
512}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Cost tables and simple lookup functions.
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
static LVOptions Options
Definition LVOptions.cpp:25
CostTblEntryT< CostKindCosts > CostKindTblEntry
static bool isSingleVRegType(const LoongArchSubtarget *ST, Type *Ty)
This file a TargetTransformInfoImplBase conforming object specific to the LoongArch target machine.
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
This pass exposes codegen information to IR-level passes.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
A wrapper class for inspecting calls to intrinsic functions.
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
unsigned getCacheLineSize() const override
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
unsigned getRegisterClassForType(bool Vector, Type *Ty=nullptr) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
const char * getRegisterClassName(unsigned ClassID) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
unsigned getPrefetchDistance() const override
bool enableWritePrefetching() const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
virtual TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
PopcntSupportKind
Flags indicating the kind of support for population count.
llvm::VectorInstrContext VectorInstrContext
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_Reverse
Reverse the order of the vector.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:352
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
LLVM Value Representation.
Definition Value.h:75
Base class of all SIMD vector types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:26
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
This is an optimization pass for GlobalISel generic memory operations.
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition CostTable.h:36
InstructionCost Cost
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Cost Table Entry.
Definition CostTable.h:26
Extended Value Type.
Definition ValueTypes.h:35
Returns options for expansion of memcmp. IsZeroCmp is.