1351278Sdim//===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim 9351278Sdim#include "RISCVTargetTransformInfo.h" 10351278Sdim#include "Utils/RISCVMatInt.h" 11351278Sdim#include "llvm/Analysis/TargetTransformInfo.h" 12351278Sdim#include "llvm/CodeGen/BasicTTIImpl.h" 13351278Sdim#include "llvm/CodeGen/TargetLowering.h" 14351278Sdimusing namespace llvm; 15351278Sdim 16351278Sdim#define DEBUG_TYPE "riscvtti" 17351278Sdim 18351278Sdimint RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) { 19351278Sdim assert(Ty->isIntegerTy() && 20351278Sdim "getIntImmCost can only estimate cost of materialising integers"); 21351278Sdim 22351278Sdim // We have a Zero register, so 0 is always free. 23351278Sdim if (Imm == 0) 24351278Sdim return TTI::TCC_Free; 25351278Sdim 26351278Sdim // Otherwise, we check how many instructions it will take to materialise. 27351278Sdim const DataLayout &DL = getDataLayout(); 28351278Sdim return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty), 29351278Sdim getST()->is64Bit()); 30351278Sdim} 31351278Sdim 32360784Sdimint RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, 33351278Sdim Type *Ty) { 34351278Sdim assert(Ty->isIntegerTy() && 35351278Sdim "getIntImmCost can only estimate cost of materialising integers"); 36351278Sdim 37351278Sdim // We have a Zero register, so 0 is always free. 38351278Sdim if (Imm == 0) 39351278Sdim return TTI::TCC_Free; 40351278Sdim 41351278Sdim // Some instructions in RISC-V can take a 12-bit immediate. Some of these are 42351278Sdim // commutative, in others the immediate comes from a specific argument index. 43351278Sdim bool Takes12BitImm = false; 44351278Sdim unsigned ImmArgIdx = ~0U; 45351278Sdim 46351278Sdim switch (Opcode) { 47351278Sdim case Instruction::GetElementPtr: 48351278Sdim // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will 49351278Sdim // split up large offsets in GEP into better parts than ConstantHoisting 50351278Sdim // can. 51351278Sdim return TTI::TCC_Free; 52351278Sdim case Instruction::Add: 53351278Sdim case Instruction::And: 54351278Sdim case Instruction::Or: 55351278Sdim case Instruction::Xor: 56351278Sdim case Instruction::Mul: 57351278Sdim Takes12BitImm = true; 58351278Sdim break; 59351278Sdim case Instruction::Sub: 60351278Sdim case Instruction::Shl: 61351278Sdim case Instruction::LShr: 62351278Sdim case Instruction::AShr: 63351278Sdim Takes12BitImm = true; 64351278Sdim ImmArgIdx = 1; 65351278Sdim break; 66351278Sdim default: 67351278Sdim break; 68351278Sdim } 69351278Sdim 70351278Sdim if (Takes12BitImm) { 71351278Sdim // Check immediate is the correct argument... 72351278Sdim if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) { 73351278Sdim // ... and fits into the 12-bit immediate. 74351278Sdim if (Imm.getMinSignedBits() <= 64 && 75351278Sdim getTLI()->isLegalAddImmediate(Imm.getSExtValue())) { 76351278Sdim return TTI::TCC_Free; 77351278Sdim } 78351278Sdim } 79351278Sdim 80351278Sdim // Otherwise, use the full materialisation cost. 81351278Sdim return getIntImmCost(Imm, Ty); 82351278Sdim } 83351278Sdim 84351278Sdim // By default, prevent hoisting. 85351278Sdim return TTI::TCC_Free; 86351278Sdim} 87351278Sdim 88360784Sdimint RISCVTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, 89360784Sdim const APInt &Imm, Type *Ty) { 90351278Sdim // Prevent hoisting in unknown cases. 91351278Sdim return TTI::TCC_Free; 92351278Sdim} 93