blob: c1e29fc3d8b2969b5af46209d731df08c2c51b1a [file] [log] [blame]
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// \file
// This file implements a TargetTransformInfo analysis pass specific to the
// JS target machine. It uses the target's detailed information to provide
// more precise answers to certain TTI queries, while letting the target
// independent and default TTI implementations handle the rest.
//
//===----------------------------------------------------------------------===//
#include "JSTargetTransformInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/CostTable.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;
#define DEBUG_TYPE "JStti"
void JSTTIImpl::getUnrollingPreferences(Loop *L,
TTI::UnrollingPreferences &UP) {
// We generally don't want a lot of unrolling.
UP.Partial = false;
UP.Runtime = false;
}
unsigned JSTTIImpl::getNumberOfRegisters(bool Vector) {
if (Vector) return 16; // like NEON, x86_64, etc.
return 8; // like x86, thumb, etc.
}
unsigned JSTTIImpl::getRegisterBitWidth(bool Vector) {
if (Vector) {
return 128;
}
return 32;
}
static const unsigned Nope = 65536;
// Certain types are fine, but some vector types must be avoided at all Costs.
static bool isOkType(Type *Ty) {
if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
if (VTy->getNumElements() != 4 || !(VTy->getElementType()->isIntegerTy(1) ||
VTy->getElementType()->isIntegerTy(32) ||
VTy->getElementType()->isFloatTy())) {
return false;
}
}
return true;
}
unsigned JSTTIImpl::getArithmeticInstrCost(
unsigned Opcode, Type *Ty, TTI::OperandValueKind Opd1Info,
TTI::OperandValueKind Opd2Info, TTI::OperandValueProperties Opd1PropInfo,
TTI::OperandValueProperties Opd2PropInfo) {
unsigned Cost = BasicTTIImplBase<JSTTIImpl>::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info);
if (!isOkType(Ty))
return Nope;
if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
switch (Opcode) {
case Instruction::LShr:
case Instruction::AShr:
case Instruction::Shl:
// SIMD.js' shifts are currently only ByScalar.
if (Opd2Info != TTI::OK_UniformValue && Opd2Info != TTI::OK_UniformConstantValue)
Cost = Cost * VTy->getNumElements() + 100;
break;
}
}
return Cost;
}
unsigned JSTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
if (!isOkType(Val))
return Nope;
unsigned Cost = BasicTTIImplBase::getVectorInstrCost(Opcode, Val, Index);
// SIMD.js' insert/extract currently only take constant indices.
if (Index == -1u)
return Cost + 100;
return Cost;
}
unsigned JSTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
unsigned AddressSpace) {
if (!isOkType(Src))
return Nope;
return BasicTTIImplBase::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
}
unsigned JSTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) {
if (!isOkType(Src) || !isOkType(Dst))
return Nope;
return BasicTTIImplBase::getCastInstrCost(Opcode, Dst, Src);
}