xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===-- LoongArchTargetTransformInfo.cpp - LoongArch specific TTI ---------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric /// \file
906c3fb27SDimitry Andric /// This file implements a TargetTransformInfo analysis pass specific to the
1006c3fb27SDimitry Andric /// LoongArch target machine. It uses the target's detailed information to
1106c3fb27SDimitry Andric /// provide more precise answers to certain TTI queries, while letting the
1206c3fb27SDimitry Andric /// target independent and default TTI implementations handle the rest.
1306c3fb27SDimitry Andric ///
1406c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
1506c3fb27SDimitry Andric 
1606c3fb27SDimitry Andric #include "LoongArchTargetTransformInfo.h"
1706c3fb27SDimitry Andric 
1806c3fb27SDimitry Andric using namespace llvm;
1906c3fb27SDimitry Andric 
2006c3fb27SDimitry Andric #define DEBUG_TYPE "loongarchtti"
2106c3fb27SDimitry Andric 
227a6dacacSDimitry Andric TypeSize LoongArchTTIImpl::getRegisterBitWidth(
237a6dacacSDimitry Andric     TargetTransformInfo::RegisterKind K) const {
24b3edf446SDimitry Andric   TypeSize DefSize = TargetTransformInfoImplBase::getRegisterBitWidth(K);
257a6dacacSDimitry Andric   switch (K) {
267a6dacacSDimitry Andric   case TargetTransformInfo::RGK_Scalar:
277a6dacacSDimitry Andric     return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
287a6dacacSDimitry Andric   case TargetTransformInfo::RGK_FixedWidthVector:
29b3edf446SDimitry Andric     if (ST->hasExtLASX())
307a6dacacSDimitry Andric       return TypeSize::getFixed(256);
31b3edf446SDimitry Andric     if (ST->hasExtLSX())
327a6dacacSDimitry Andric       return TypeSize::getFixed(128);
33b3edf446SDimitry Andric     [[fallthrough]];
347a6dacacSDimitry Andric   case TargetTransformInfo::RGK_ScalableVector:
35b3edf446SDimitry Andric     return DefSize;
367a6dacacSDimitry Andric   }
377a6dacacSDimitry Andric 
387a6dacacSDimitry Andric   llvm_unreachable("Unsupported register kind");
397a6dacacSDimitry Andric }
407a6dacacSDimitry Andric 
41*0fca6ea1SDimitry Andric unsigned LoongArchTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
42*0fca6ea1SDimitry Andric   switch (ClassID) {
43*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::GPRRC:
44*0fca6ea1SDimitry Andric     // 30 = 32 GPRs - r0 (zero register) - r21 (non-allocatable)
45*0fca6ea1SDimitry Andric     return 30;
46*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::FPRRC:
47*0fca6ea1SDimitry Andric     return ST->hasBasicF() ? 32 : 0;
48*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::VRRC:
49*0fca6ea1SDimitry Andric     return ST->hasExtLSX() ? 32 : 0;
50*0fca6ea1SDimitry Andric   }
51*0fca6ea1SDimitry Andric   llvm_unreachable("unknown register class");
52*0fca6ea1SDimitry Andric }
53*0fca6ea1SDimitry Andric 
54*0fca6ea1SDimitry Andric unsigned LoongArchTTIImpl::getRegisterClassForType(bool Vector,
55*0fca6ea1SDimitry Andric                                                    Type *Ty) const {
56*0fca6ea1SDimitry Andric   if (Vector)
57*0fca6ea1SDimitry Andric     return LoongArchRegisterClass::VRRC;
58*0fca6ea1SDimitry Andric   if (!Ty)
59*0fca6ea1SDimitry Andric     return LoongArchRegisterClass::GPRRC;
60*0fca6ea1SDimitry Andric 
61*0fca6ea1SDimitry Andric   Type *ScalarTy = Ty->getScalarType();
62*0fca6ea1SDimitry Andric   if ((ScalarTy->isFloatTy() && ST->hasBasicF()) ||
63*0fca6ea1SDimitry Andric       (ScalarTy->isDoubleTy() && ST->hasBasicD())) {
64*0fca6ea1SDimitry Andric     return LoongArchRegisterClass::FPRRC;
65*0fca6ea1SDimitry Andric   }
66*0fca6ea1SDimitry Andric 
67*0fca6ea1SDimitry Andric   return LoongArchRegisterClass::GPRRC;
68*0fca6ea1SDimitry Andric }
69*0fca6ea1SDimitry Andric 
70*0fca6ea1SDimitry Andric unsigned LoongArchTTIImpl::getMaxInterleaveFactor(ElementCount VF) {
71*0fca6ea1SDimitry Andric   return ST->getMaxInterleaveFactor();
72*0fca6ea1SDimitry Andric }
73*0fca6ea1SDimitry Andric 
74*0fca6ea1SDimitry Andric const char *LoongArchTTIImpl::getRegisterClassName(unsigned ClassID) const {
75*0fca6ea1SDimitry Andric   switch (ClassID) {
76*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::GPRRC:
77*0fca6ea1SDimitry Andric     return "LoongArch::GPRRC";
78*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::FPRRC:
79*0fca6ea1SDimitry Andric     return "LoongArch::FPRRC";
80*0fca6ea1SDimitry Andric   case LoongArchRegisterClass::VRRC:
81*0fca6ea1SDimitry Andric     return "LoongArch::VRRC";
82*0fca6ea1SDimitry Andric   }
83*0fca6ea1SDimitry Andric   llvm_unreachable("unknown register class");
84*0fca6ea1SDimitry Andric }
85*0fca6ea1SDimitry Andric 
8606c3fb27SDimitry Andric // TODO: Implement more hooks to provide TTI machinery for LoongArch.
87