13dac3a9bSDimitry Andric //===-- WebAssemblyTargetTransformInfo.cpp - WebAssembly-specific TTI -----===//
23dac3a9bSDimitry Andric //
33dac3a9bSDimitry Andric // The LLVM Compiler Infrastructure
43dac3a9bSDimitry Andric //
53dac3a9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
63dac3a9bSDimitry Andric // License. See LICENSE.TXT for details.
73dac3a9bSDimitry Andric //
83dac3a9bSDimitry Andric //===----------------------------------------------------------------------===//
93dac3a9bSDimitry Andric ///
103dac3a9bSDimitry Andric /// \file
11*4ba319b5SDimitry Andric /// This file defines the WebAssembly-specific TargetTransformInfo
123dac3a9bSDimitry Andric /// implementation.
133dac3a9bSDimitry Andric ///
143dac3a9bSDimitry Andric //===----------------------------------------------------------------------===//
153dac3a9bSDimitry Andric
163dac3a9bSDimitry Andric #include "WebAssemblyTargetTransformInfo.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/CostTable.h"
183dac3a9bSDimitry Andric #include "llvm/Support/Debug.h"
193dac3a9bSDimitry Andric using namespace llvm;
203dac3a9bSDimitry Andric
213dac3a9bSDimitry Andric #define DEBUG_TYPE "wasmtti"
223dac3a9bSDimitry Andric
233dac3a9bSDimitry Andric TargetTransformInfo::PopcntSupportKind
getPopcntSupport(unsigned TyWidth) const247d523365SDimitry Andric WebAssemblyTTIImpl::getPopcntSupport(unsigned TyWidth) const {
253dac3a9bSDimitry Andric assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
267d523365SDimitry Andric return TargetTransformInfo::PSK_FastHardware;
273dac3a9bSDimitry Andric }
283ca95b02SDimitry Andric
getNumberOfRegisters(bool Vector)293ca95b02SDimitry Andric unsigned WebAssemblyTTIImpl::getNumberOfRegisters(bool Vector) {
303ca95b02SDimitry Andric unsigned Result = BaseT::getNumberOfRegisters(Vector);
313ca95b02SDimitry Andric
323ca95b02SDimitry Andric // For SIMD, use at least 16 registers, as a rough guess.
333ca95b02SDimitry Andric if (Vector)
343ca95b02SDimitry Andric Result = std::max(Result, 16u);
353ca95b02SDimitry Andric
363ca95b02SDimitry Andric return Result;
373ca95b02SDimitry Andric }
383ca95b02SDimitry Andric
getRegisterBitWidth(bool Vector) const3924d58133SDimitry Andric unsigned WebAssemblyTTIImpl::getRegisterBitWidth(bool Vector) const {
403ca95b02SDimitry Andric if (Vector && getST()->hasSIMD128())
413ca95b02SDimitry Andric return 128;
423ca95b02SDimitry Andric
433ca95b02SDimitry Andric return 64;
443ca95b02SDimitry Andric }
453ca95b02SDimitry Andric
getArithmeticInstrCost(unsigned Opcode,Type * Ty,TTI::OperandValueKind Opd1Info,TTI::OperandValueKind Opd2Info,TTI::OperandValueProperties Opd1PropInfo,TTI::OperandValueProperties Opd2PropInfo,ArrayRef<const Value * > Args)463ca95b02SDimitry Andric unsigned WebAssemblyTTIImpl::getArithmeticInstrCost(
473ca95b02SDimitry Andric unsigned Opcode, Type *Ty, TTI::OperandValueKind Opd1Info,
483ca95b02SDimitry Andric TTI::OperandValueKind Opd2Info, TTI::OperandValueProperties Opd1PropInfo,
49f1a29dd3SDimitry Andric TTI::OperandValueProperties Opd2PropInfo, ArrayRef<const Value *> Args) {
503ca95b02SDimitry Andric
513ca95b02SDimitry Andric unsigned Cost = BasicTTIImplBase<WebAssemblyTTIImpl>::getArithmeticInstrCost(
523ca95b02SDimitry Andric Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo);
533ca95b02SDimitry Andric
543ca95b02SDimitry Andric if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
553ca95b02SDimitry Andric switch (Opcode) {
563ca95b02SDimitry Andric case Instruction::LShr:
573ca95b02SDimitry Andric case Instruction::AShr:
583ca95b02SDimitry Andric case Instruction::Shl:
593ca95b02SDimitry Andric // SIMD128's shifts currently only accept a scalar shift count. For each
603ca95b02SDimitry Andric // element, we'll need to extract, op, insert. The following is a rough
613ca95b02SDimitry Andric // approxmation.
623ca95b02SDimitry Andric if (Opd2Info != TTI::OK_UniformValue &&
633ca95b02SDimitry Andric Opd2Info != TTI::OK_UniformConstantValue)
643ca95b02SDimitry Andric Cost = VTy->getNumElements() *
653ca95b02SDimitry Andric (TargetTransformInfo::TCC_Basic +
663ca95b02SDimitry Andric getArithmeticInstrCost(Opcode, VTy->getElementType()) +
673ca95b02SDimitry Andric TargetTransformInfo::TCC_Basic);
683ca95b02SDimitry Andric break;
693ca95b02SDimitry Andric }
703ca95b02SDimitry Andric }
713ca95b02SDimitry Andric return Cost;
723ca95b02SDimitry Andric }
733ca95b02SDimitry Andric
getVectorInstrCost(unsigned Opcode,Type * Val,unsigned Index)743ca95b02SDimitry Andric unsigned WebAssemblyTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val,
753ca95b02SDimitry Andric unsigned Index) {
763ca95b02SDimitry Andric unsigned Cost = BasicTTIImplBase::getVectorInstrCost(Opcode, Val, Index);
773ca95b02SDimitry Andric
783ca95b02SDimitry Andric // SIMD128's insert/extract currently only take constant indices.
793ca95b02SDimitry Andric if (Index == -1u)
803ca95b02SDimitry Andric return Cost + 25 * TargetTransformInfo::TCC_Expensive;
813ca95b02SDimitry Andric
823ca95b02SDimitry Andric return Cost;
833ca95b02SDimitry Andric }
84