1285163Sdim//===-- WebAssemblyTargetTransformInfo.cpp - WebAssembly-specific TTI -----===// 2285163Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6285163Sdim// 7285163Sdim//===----------------------------------------------------------------------===// 8285163Sdim/// 9285163Sdim/// \file 10341825Sdim/// This file defines the WebAssembly-specific TargetTransformInfo 11285163Sdim/// implementation. 12285163Sdim/// 13285163Sdim//===----------------------------------------------------------------------===// 14285163Sdim 15285163Sdim#include "WebAssemblyTargetTransformInfo.h" 16327952Sdim#include "llvm/CodeGen/CostTable.h" 17285163Sdim#include "llvm/Support/Debug.h" 18285163Sdimusing namespace llvm; 19285163Sdim 20285163Sdim#define DEBUG_TYPE "wasmtti" 21285163Sdim 22285163SdimTargetTransformInfo::PopcntSupportKind 23296417SdimWebAssemblyTTIImpl::getPopcntSupport(unsigned TyWidth) const { 24285163Sdim assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); 25296417Sdim return TargetTransformInfo::PSK_FastHardware; 26285163Sdim} 27309124Sdim 28360784Sdimunsigned WebAssemblyTTIImpl::getNumberOfRegisters(unsigned ClassID) const { 29360784Sdim unsigned Result = BaseT::getNumberOfRegisters(ClassID); 30309124Sdim 31309124Sdim // For SIMD, use at least 16 registers, as a rough guess. 32360784Sdim bool Vector = (ClassID == 1); 33309124Sdim if (Vector) 34309124Sdim Result = std::max(Result, 16u); 35309124Sdim 36309124Sdim return Result; 37309124Sdim} 38309124Sdim 39321369Sdimunsigned WebAssemblyTTIImpl::getRegisterBitWidth(bool Vector) const { 40309124Sdim if (Vector && getST()->hasSIMD128()) 41309124Sdim return 128; 42309124Sdim 43309124Sdim return 64; 44309124Sdim} 45309124Sdim 46309124Sdimunsigned WebAssemblyTTIImpl::getArithmeticInstrCost( 47309124Sdim unsigned Opcode, Type *Ty, TTI::OperandValueKind Opd1Info, 48309124Sdim TTI::OperandValueKind Opd2Info, TTI::OperandValueProperties Opd1PropInfo, 49360784Sdim TTI::OperandValueProperties Opd2PropInfo, ArrayRef<const Value *> Args, 50360784Sdim const Instruction *CxtI) { 51309124Sdim 52309124Sdim unsigned Cost = BasicTTIImplBase<WebAssemblyTTIImpl>::getArithmeticInstrCost( 53309124Sdim Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo); 54309124Sdim 55353358Sdim if (auto *VTy = dyn_cast<VectorType>(Ty)) { 56309124Sdim switch (Opcode) { 57309124Sdim case Instruction::LShr: 58309124Sdim case Instruction::AShr: 59309124Sdim case Instruction::Shl: 60309124Sdim // SIMD128's shifts currently only accept a scalar shift count. For each 61309124Sdim // element, we'll need to extract, op, insert. The following is a rough 62309124Sdim // approxmation. 63309124Sdim if (Opd2Info != TTI::OK_UniformValue && 64309124Sdim Opd2Info != TTI::OK_UniformConstantValue) 65309124Sdim Cost = VTy->getNumElements() * 66309124Sdim (TargetTransformInfo::TCC_Basic + 67309124Sdim getArithmeticInstrCost(Opcode, VTy->getElementType()) + 68309124Sdim TargetTransformInfo::TCC_Basic); 69309124Sdim break; 70309124Sdim } 71309124Sdim } 72309124Sdim return Cost; 73309124Sdim} 74309124Sdim 75309124Sdimunsigned WebAssemblyTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, 76309124Sdim unsigned Index) { 77309124Sdim unsigned Cost = BasicTTIImplBase::getVectorInstrCost(Opcode, Val, Index); 78309124Sdim 79309124Sdim // SIMD128's insert/extract currently only take constant indices. 80309124Sdim if (Index == -1u) 81309124Sdim return Cost + 25 * TargetTransformInfo::TCC_Expensive; 82309124Sdim 83309124Sdim return Cost; 84309124Sdim} 85