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#include <optional>
25
26using namespace llvm;
27
28#define DEBUG_TYPE "loongarchtti"
29
30namespace {
31struct CostKindCosts {
32 unsigned LatencyCost = ~0U;
33 unsigned RecipThroughputCost = ~0U;
34 unsigned CodeSizeCost = ~0U;
35 unsigned SizeAndLatencyCost = ~0U;
36
37 std::optional<unsigned>
38 operator[](TargetTransformInfo::TargetCostKind Kind) const {
39 unsigned Cost = ~0U;
40 switch (Kind) {
42 Cost = LatencyCost;
43 break;
45 Cost = RecipThroughputCost;
46 break;
48 Cost = CodeSizeCost;
49 break;
51 Cost = SizeAndLatencyCost;
52 break;
53 }
54 if (Cost == ~0U)
55 return std::nullopt;
56 return Cost;
57 }
58};
59} // namespace
61
65 switch (K) {
67 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
69 if (ST->hasExtLASX())
70 return TypeSize::getFixed(256);
71 if (ST->hasExtLSX())
72 return TypeSize::getFixed(128);
73 [[fallthrough]];
75 return DefSize;
76 }
77
78 llvm_unreachable("Unsupported register kind");
79}
80
81unsigned LoongArchTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
82 switch (ClassID) {
83 case LoongArchRegisterClass::GPRRC:
84 // 30 = 32 GPRs - r0 (zero register) - r21 (non-allocatable)
85 return 30;
86 case LoongArchRegisterClass::FPRRC:
87 return ST->hasBasicF() ? 32 : 0;
88 case LoongArchRegisterClass::VRRC:
89 return ST->hasExtLSX() ? 32 : 0;
90 }
91 llvm_unreachable("unknown register class");
92}
93
95 Type *Ty) const {
96 if (Vector)
97 return LoongArchRegisterClass::VRRC;
98 if (!Ty)
99 return LoongArchRegisterClass::GPRRC;
100
101 Type *ScalarTy = Ty->getScalarType();
102 if ((ScalarTy->isFloatTy() && ST->hasBasicF()) ||
103 (ScalarTy->isDoubleTy() && ST->hasBasicD())) {
104 return LoongArchRegisterClass::FPRRC;
105 }
106
107 return LoongArchRegisterClass::GPRRC;
108}
109
110unsigned
112 bool HasUnorderedReductions) const {
113 return ST->getMaxInterleaveFactor();
114}
115
116const char *LoongArchTTIImpl::getRegisterClassName(unsigned ClassID) const {
117 switch (ClassID) {
118 case LoongArchRegisterClass::GPRRC:
119 return "LoongArch::GPRRC";
120 case LoongArchRegisterClass::FPRRC:
121 return "LoongArch::FPRRC";
122 case LoongArchRegisterClass::VRRC:
123 return "LoongArch::VRRC";
124 }
125 llvm_unreachable("unknown register class");
126}
127
129LoongArchTTIImpl::getPopcntSupport(unsigned TyWidth) const {
130 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
131 return ST->hasExtLSX() ? TTI::PSK_FastHardware : TTI::PSK_Software;
132}
133
134unsigned LoongArchTTIImpl::getCacheLineSize() const { return 64; }
135
136unsigned LoongArchTTIImpl::getPrefetchDistance() const { return 200; }
137
138bool LoongArchTTIImpl::enableWritePrefetching() const { return true; }
139
141 switch (II->getIntrinsicID()) {
142 default:
143 return true;
144 case Intrinsic::vector_reduce_add:
145 case Intrinsic::vector_reduce_and:
146 case Intrinsic::vector_reduce_or:
147 case Intrinsic::vector_reduce_smax:
148 case Intrinsic::vector_reduce_smin:
149 case Intrinsic::vector_reduce_umax:
150 case Intrinsic::vector_reduce_umin:
151 case Intrinsic::vector_reduce_xor:
152 return false;
153 }
154}
155
157LoongArchTTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
159
160 if (!ST->hasUAL())
161 return Options;
162
163 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
164 Options.NumLoadsPerBlock = IsZeroCmp ? Options.MaxNumLoads : 1;
165 Options.AllowOverlappingLoads = true;
166
167 // TODO: Support for vectors.
168 if (ST->is64Bit()) {
169 Options.LoadSizes = {8, 4, 2, 1};
170 Options.AllowedTailExpansions = {3, 5, 6};
171 } else {
172 Options.LoadSizes = {4, 2, 1};
173 Options.AllowedTailExpansions = {3};
174 }
175
176 return Options;
177}
178
180 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
182 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
183
184 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
185 int ISD = TLI->InstructionOpcodeToISD(Opcode);
186
187 // Vector multiply by pow2 will be simplified to shifts.
188 // Vector multiply by -pow2 will be simplified to shifts/negates.
189 if (ISD == ISD::MUL && Op2Info.isConstant() &&
190 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
192 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
193 Op1Info.getNoProps(), Op2Info.getNoProps());
194 if (Op2Info.isNegatedPowerOf2())
195 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
196 return Cost;
197 }
198
199 // On LoongArch, vector signed division by constants power-of-two are
200 // normally expanded to the sequence SRA + SRL + ADD + SRA.
201 // The OperandValue properties may not be the same as that of the previous
202 // operation; conservatively assume OP_None.
203 if ((ISD == ISD::SDIV || ISD == ISD::SREM) && Op2Info.isConstant() &&
204 Op2Info.isPowerOf2()) {
206 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
207 Op1Info.getNoProps(), Op2Info.getNoProps());
208 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
209 Op1Info.getNoProps(), Op2Info.getNoProps());
210 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
211 Op1Info.getNoProps(), Op2Info.getNoProps());
212
213 if (ISD == ISD::SREM) {
214 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
215 Cost +=
216 getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
217 Op1Info.getNoProps(), Op2Info.getNoProps());
218 Cost +=
219 getArithmeticInstrCost(Instruction::Sub, Ty, CostKind,
220 Op1Info.getNoProps(), Op2Info.getNoProps());
221 }
222
223 return Cost;
224 }
225 // Vector unsigned division/remainder will be simplified to shifts/masks.
226 if ((ISD == ISD::UDIV || ISD == ISD::UREM) && Op2Info.isConstant() &&
227 Op2Info.isPowerOf2()) {
228 if (ISD == ISD::UDIV)
229 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
230 Op1Info.getNoProps(), Op2Info.getNoProps());
231 // UREM
232 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
233 Op1Info.getNoProps(), Op2Info.getNoProps());
234 }
235
236 static const CostKindTblEntry LSXCostTable[]{
237 {ISD::ADD, MVT::v16i8, {1, 1}}, // vaddi.b/vadd.b
238 {ISD::ADD, MVT::v8i16, {1, 1}}, // vaddi.h/vadd.h
239 {ISD::ADD, MVT::v4i32, {1, 1}}, // vaddi.w/vadd.w
240 {ISD::ADD, MVT::v2i64, {1, 1}}, // vaddi.d/vadd.d
241
242 {ISD::SUB, MVT::v16i8, {1, 1}}, // vsubi.b/vsub.b
243 {ISD::SUB, MVT::v8i16, {1, 1}}, // vsubi.h/vsub.h
244 {ISD::SUB, MVT::v4i32, {1, 1}}, // vsubi.w/vsub.w
245 {ISD::SUB, MVT::v2i64, {1, 1}}, // vsubi.d/vsub.d
246
247 {ISD::MUL, MVT::v16i8, {4, 2}}, // vmul.b
248 {ISD::MUL, MVT::v8i16, {4, 2}}, // vmul.h
249 {ISD::MUL, MVT::v4i32, {4, 2}}, // vmul.w
250 {ISD::MUL, MVT::v2i64, {4, 2}}, // vmul.d
251
252 {ISD::SDIV, MVT::v16i8, {29, 62}}, // vdiv.b
253 {ISD::SDIV, MVT::v8i16, {17, 34}}, // vdiv.h
254 {ISD::SDIV, MVT::v4i32, {11, 22}}, // vdiv.w
255 {ISD::SDIV, MVT::v2i64, {8, 16}}, // vdiv.d
256
257 {ISD::UDIV, MVT::v16i8, {29, 66}}, // vdiv.bu
258 {ISD::UDIV, MVT::v8i16, {17, 36}}, // vdiv.hu
259 {ISD::UDIV, MVT::v4i32, {11, 22}}, // vdiv.wu
260 {ISD::UDIV, MVT::v2i64, {8, 16}}, // vdiv.du
261
262 {ISD::SREM, MVT::v16i8, {38, 76}}, // vmod.b
263 {ISD::SREM, MVT::v8i16, {24, 44}}, // vmod.h
264 {ISD::SREM, MVT::v4i32, {17, 27}}, // vmod.w
265 {ISD::SREM, MVT::v2i64, {14, 19}}, // vmod.d
266
267 {ISD::UREM, MVT::v16i8, {38, 80}}, // vmod.bu
268 {ISD::UREM, MVT::v8i16, {24, 44}}, // vmod.hu
269 {ISD::UREM, MVT::v4i32, {17, 28}}, // vmod.wu
270 {ISD::UREM, MVT::v2i64, {14, 19}}, // vmod.du
271
272 {ISD::SHL, MVT::v16i8, {1, 1}}, // vslli.b/vsll.b
273 {ISD::SHL, MVT::v8i16, {1, 1}}, // vslli.h/vsll.h
274 {ISD::SHL, MVT::v4i32, {1, 1}}, // vslli.w/vsll.w
275 {ISD::SHL, MVT::v2i64, {1, 1}}, // vslli.d/vsll.d
276
277 {ISD::SRL, MVT::v16i8, {1, 1}}, // vsrli.b/vsrl.b
278 {ISD::SRL, MVT::v8i16, {1, 1}}, // vsrli.h/vsrl.h
279 {ISD::SRL, MVT::v4i32, {1, 1}}, // vsrli.w/vsrl.w
280 {ISD::SRL, MVT::v2i64, {1, 1}}, // vsrli.d/vsrl.d
281
282 {ISD::SRA, MVT::v16i8, {1, 1}}, // vsrai.b/vsra.b
283 {ISD::SRA, MVT::v8i16, {1, 1}}, // vsrai.h/vsra.h
284 {ISD::SRA, MVT::v4i32, {1, 1}}, // vsrai.w/vsra.w
285 {ISD::SRA, MVT::v2i64, {1, 1}}, // vsrai.d/vsra.d
286
287 {ISD::AND, MVT::v16i8, {1, 1}}, // vand.b/vand.v
288 {ISD::AND, MVT::v8i16, {1, 1}}, // vand.v
289 {ISD::AND, MVT::v4i32, {1, 1}}, // vand.v
290 {ISD::AND, MVT::v2i64, {1, 1}}, // vand.v
291
292 {ISD::OR, MVT::v16i8, {1, 1}}, // vori.b/vor.v
293 {ISD::OR, MVT::v8i16, {1, 1}}, // vor.v
294 {ISD::OR, MVT::v4i32, {1, 1}}, // vor.v
295 {ISD::OR, MVT::v2i64, {1, 1}}, // vor.v
296
297 {ISD::XOR, MVT::v16i8, {1, 1}}, // vxori.b/vxor.v
298 {ISD::XOR, MVT::v8i16, {1, 1}}, // vxor.v
299 {ISD::XOR, MVT::v4i32, {1, 1}}, // vxor.v
300 {ISD::XOR, MVT::v2i64, {1, 1}}, // vxor.v
301
302 {ISD::FADD, MVT::v4f32, {3, 1}}, // vfadd.s
303 {ISD::FADD, MVT::v2f64, {3, 1}}, // vfadd.d
304
305 {ISD::FSUB, MVT::v4f32, {3, 1}}, // vfsub.s
306 {ISD::FSUB, MVT::v2f64, {3, 1}}, // vfsub.d
307
308 {ISD::FMUL, MVT::v4f32, {5, 2}}, // vfmul.s
309 {ISD::FMUL, MVT::v2f64, {5, 2}}, // vfmul.d
310
311 {ISD::FDIV, MVT::v4f32, {11, 22}}, // vfdiv.s
312 {ISD::FDIV, MVT::v2f64, {8, 16}}, // vfdiv.d
313 };
314
315 if (ST->hasExtLSX()) {
316 if (const auto *Entry = CostTableLookup(LSXCostTable, ISD, LT.second))
317 if (auto KindCost = Entry->Cost[CostKind])
318 return LT.first * *KindCost;
319 }
320
321 static const CostKindTblEntry LASXUniformConstCostTable[]{
322 {ISD::ADD, MVT::v32i8, {1, 1}}, // xvaddi.b/xvadd.b
323 {ISD::ADD, MVT::v16i16, {1, 1}}, // xvaddi.h/xvadd.h
324 {ISD::ADD, MVT::v8i32, {1, 1}}, // xvaddi.w/xvadd.w
325 {ISD::ADD, MVT::v4i64, {1, 1}}, // xvaddi.d/xvadd.d
326
327 {ISD::SUB, MVT::v32i8, {1, 1}}, // xvsubi.b/xvsub.b
328 {ISD::SUB, MVT::v16i16, {1, 1}}, // xvsubi.h/xvsub.h
329 {ISD::SUB, MVT::v8i32, {1, 1}}, // xvsubi.w/xvsub.w
330 {ISD::SUB, MVT::v4i64, {1, 1}}, // xvsubi.d/xvsub.d
331
332 {ISD::MUL, MVT::v32i8, {4, 2}}, // xvmul.b
333 {ISD::MUL, MVT::v16i16, {4, 2}}, // xvmul.h
334 {ISD::MUL, MVT::v8i32, {4, 2}}, // xvmul.w
335 {ISD::MUL, MVT::v4i64, {4, 2}}, // xvmul.d
336
337 {ISD::SDIV, MVT::v32i8, {29, 62}}, // xvdiv.b
338 {ISD::SDIV, MVT::v16i16, {17, 34}}, // xvdiv.h
339 {ISD::SDIV, MVT::v8i32, {11, 22}}, // xvdiv.w
340 {ISD::SDIV, MVT::v4i64, {8, 16}}, // xvdiv.d
341
342 {ISD::UDIV, MVT::v32i8, {29, 66}}, // xvdiv.bu
343 {ISD::UDIV, MVT::v16i16, {17, 36}}, // xvdiv.hu
344 {ISD::UDIV, MVT::v8i32, {11, 22}}, // xvdiv.wu
345 {ISD::UDIV, MVT::v4i64, {8, 16}}, // xvdiv.du
346
347 {ISD::SREM, MVT::v32i8, {38, 76}}, // xvmod.b
348 {ISD::SREM, MVT::v16i16, {24, 44}}, // xvmod.h
349 {ISD::SREM, MVT::v8i32, {17, 28}}, // xvmod.w
350 {ISD::SREM, MVT::v4i64, {14, 19}}, // xvmod.d
351
352 {ISD::UREM, MVT::v32i8, {38, 76}}, // xvmod.bu
353 {ISD::UREM, MVT::v16i16, {24, 43}}, // xvmod.hu
354 {ISD::UREM, MVT::v8i32, {17, 28}}, // xvmod.wu
355 {ISD::UREM, MVT::v4i64, {14, 19}}, // xvmod.du
356
357 {ISD::SHL, MVT::v32i8, {1, 1}}, // xvslli.b/xvsll.b
358 {ISD::SHL, MVT::v16i16, {1, 1}}, // xvslli.h/xvsll.h
359 {ISD::SHL, MVT::v8i32, {1, 1}}, // xvslli.w/xvsll.w
360 {ISD::SHL, MVT::v4i64, {1, 1}}, // xvslli.d/xvsll.d
361
362 {ISD::SRL, MVT::v32i8, {1, 1}}, // xvsrli.b/xvsrl.b
363 {ISD::SRL, MVT::v16i16, {1, 1}}, // xvsrli.h/xvsrl.h
364 {ISD::SRL, MVT::v8i32, {1, 1}}, // xvsrli.w/xvsrl.w
365 {ISD::SRL, MVT::v4i64, {1, 1}}, // xvsrli.d/xvsrl.d
366
367 {ISD::SRA, MVT::v32i8, {1, 1}}, // xvsrai.b/xvsra.b
368 {ISD::SRA, MVT::v16i16, {1, 1}}, // xvsrai.h/xvsra.h
369 {ISD::SRA, MVT::v8i32, {1, 1}}, // xvsrai.w/xvsra.w
370 {ISD::SRA, MVT::v4i64, {1, 1}}, // xvsrai.d/xvsra.d
371
372 {ISD::AND, MVT::v32i8, {1, 1}}, // xvandi.b/xvand.v
373 {ISD::AND, MVT::v16i16, {1, 1}}, // xvand.v
374 {ISD::AND, MVT::v8i32, {1, 1}}, // xvand.v
375 {ISD::AND, MVT::v4i64, {1, 1}}, // xvand.v
376
377 {ISD::OR, MVT::v32i8, {1, 1}}, // xvori.b/xvor.v
378 {ISD::OR, MVT::v16i16, {1, 1}}, // xvor.v
379 {ISD::OR, MVT::v8i32, {1, 1}}, // xvor.v
380 {ISD::OR, MVT::v4i64, {1, 1}}, // xvor.v
381
382 {ISD::XOR, MVT::v32i8, {1, 1}}, // xvxori.b/xvxor.v
383 {ISD::XOR, MVT::v16i16, {1, 1}}, // xvxor.v
384 {ISD::XOR, MVT::v8i32, {1, 1}}, // xvxor.v
385 {ISD::XOR, MVT::v4i64, {1, 1}}, // xvxor.v
386
387 {ISD::FADD, MVT::v8f32, {3, 1}}, // xvfadd.s
388 {ISD::FADD, MVT::v4f64, {3, 1}}, // xvfadd.d
389
390 {ISD::FSUB, MVT::v8f32, {3, 1}}, // xvfsub.s
391 {ISD::FSUB, MVT::v4f64, {3, 1}}, // xvfsub.d
392
393 {ISD::FMUL, MVT::v8f32, {5, 2}}, // xvfmul.s
394 {ISD::FMUL, MVT::v4f64, {5, 2}}, // xvfmul.d
395
396 {ISD::FDIV, MVT::v8f32, {11, 22}}, // xvfdiv.s
397 {ISD::FDIV, MVT::v4f64, {8, 16}}, // xvfdiv.d
398 };
399
400 if (ST->hasExtLASX()) {
401 if (const auto *Entry =
402 CostTableLookup(LASXUniformConstCostTable, ISD, LT.second))
403 if (auto KindCost = Entry->Cost[CostKind])
404 return LT.first * *KindCost;
405 }
406
407 static const CostKindTblEntry LA64CostTable[]{
408 {ISD::ADD, MVT::i64, {1, 1}}, // addi.d/add.d
409 {ISD::SUB, MVT::i64, {1, 1}}, // subi.d/sub.d
410 {ISD::MUL, MVT::i64, {4, 2}}, // mul.d
411
412 {ISD::SDIV, MVT::i64, {18, 26}}, // div.d
413 {ISD::UDIV, MVT::i64, {18, 26}}, // div.du
414 {ISD::SREM, MVT::i64, {18, 26}}, // mod.d
415 {ISD::UREM, MVT::i64, {18, 26}}, // mod.du
416
417 {ISD::SHL, MVT::i64, {1, 1}}, // slli.d/sll.d
418 {ISD::SRL, MVT::i64, {1, 1}}, // srli.d/srl.d
419 {ISD::SRA, MVT::i64, {1, 1}}, // srai.d/sra.d
420
421 {ISD::AND, MVT::i64, {1, 1}}, // andi.d/and.d
422 {ISD::OR, MVT::i64, {1, 1}}, // ori.d/or.d
423 {ISD::XOR, MVT::i64, {1, 1}}, // xori.d/xor.d
424
425 {ISD::FADD, MVT::f64, {3, 1}}, // fadd.d
426 {ISD::FSUB, MVT::f64, {3, 1}}, // fsub.d
427 {ISD::FMUL, MVT::f64, {5, 2}}, // fmul.d
428 {ISD::FDIV, MVT::f64, {12, 9}}, // fdiv.d
429 };
430
431 if (ST->is64Bit()) {
432 if (const auto *Entry = CostTableLookup(LA64CostTable, ISD, LT.second))
433 if (auto KindCost = Entry->Cost[CostKind])
434 return LT.first * *KindCost;
435 }
436
437 static const CostKindTblEntry LA32CostTable[]{
438 {ISD::ADD, MVT::i32, {1, 1}}, // addi.w/add.w
439 {ISD::SUB, MVT::i32, {1, 1}}, // subi.w/sub.w
440 {ISD::MUL, MVT::i32, {4, 2}}, // mul.w
441
442 {ISD::SDIV, MVT::i32, {11, 24}}, // div.w
443 {ISD::UDIV, MVT::i32, {12, 24}}, // div.wu
444 {ISD::SREM, MVT::i32, {11, 24}}, // mod.w
445 {ISD::UREM, MVT::i32, {12, 24}}, // mod.wu
446
447 {ISD::SHL, MVT::i32, {1, 1}}, // slli.w/sll.w
448 {ISD::SRL, MVT::i32, {1, 1}}, // srli.w/srl.w
449 {ISD::SRA, MVT::i32, {1, 1}}, // srai.w/sra.w
450
451 {ISD::AND, MVT::i32, {1, 1}}, // andi.w/and.w
452 {ISD::OR, MVT::i32, {1, 1}}, // ori.w/or.w
453 {ISD::XOR, MVT::i32, {1, 1}}, // xori.w/xor.w
454
455 {ISD::FADD, MVT::f32, {3, 1}}, // fadd.s
456 {ISD::FSUB, MVT::f32, {3, 1}}, // fsub.s
457 {ISD::FMUL, MVT::f32, {5, 2}}, // fmul.s
458 {ISD::FDIV, MVT::f32, {9, 8}}, // fdiv.s
459 };
460
461 if (const auto *Entry = CostTableLookup(LA32CostTable, ISD, LT.second))
462 if (auto KindCost = Entry->Cost[CostKind])
463 return LT.first * *KindCost;
464
465 // Fallback to the default implementation.
466 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
467 Args, CxtI);
468}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
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
This file a TargetTransformInfoImplBase conforming object specific to the LoongArch target machine.
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
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
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
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
const char * getRegisterClassName(unsigned ClassID) const override
unsigned getNumberOfRegisters(unsigned ClassID) 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.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCK_Latency
The latency of instruction.
PopcntSupportKind
Flags indicating the kind of support for population count.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
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
#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
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
Cost Table Entry.
Definition CostTable.h:26
Returns options for expansion of memcmp. IsZeroCmp is.