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