forked from OSchip/llvm-project
91 lines
2.8 KiB
C++
91 lines
2.8 KiB
C++
|
//===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include "RISCVTargetTransformInfo.h"
|
||
|
#include "Utils/RISCVMatInt.h"
|
||
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||
|
#include "llvm/CodeGen/BasicTTIImpl.h"
|
||
|
#include "llvm/CodeGen/TargetLowering.h"
|
||
|
using namespace llvm;
|
||
|
|
||
|
#define DEBUG_TYPE "riscvtti"
|
||
|
|
||
|
int RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) {
|
||
|
assert(Ty->isIntegerTy() &&
|
||
|
"getIntImmCost can only estimate cost of materialising integers");
|
||
|
|
||
|
// We have a Zero register, so 0 is always free.
|
||
|
if (Imm == 0)
|
||
|
return TTI::TCC_Free;
|
||
|
|
||
|
// Otherwise, we check how many instructions it will take to materialise.
|
||
|
const DataLayout &DL = getDataLayout();
|
||
|
return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty),
|
||
|
getST()->is64Bit());
|
||
|
}
|
||
|
|
||
|
int RISCVTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
|
||
|
Type *Ty) {
|
||
|
assert(Ty->isIntegerTy() &&
|
||
|
"getIntImmCost can only estimate cost of materialising integers");
|
||
|
|
||
|
// We have a Zero register, so 0 is always free.
|
||
|
if (Imm == 0)
|
||
|
return TTI::TCC_Free;
|
||
|
|
||
|
// Some instructions in RISC-V can take a 12-bit immediate. Some of these are
|
||
|
// commutative, in others the immediate comes from a specific argument index.
|
||
|
bool Takes12BitImm = false;
|
||
|
unsigned ImmArgIdx = ~0U;
|
||
|
|
||
|
switch (Opcode) {
|
||
|
case Instruction::GetElementPtr:
|
||
|
// Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
|
||
|
// split up large offsets in GEP into better parts than ConstantHoisting
|
||
|
// can.
|
||
|
return TTI::TCC_Free;
|
||
|
case Instruction::Add:
|
||
|
case Instruction::And:
|
||
|
case Instruction::Or:
|
||
|
case Instruction::Xor:
|
||
|
case Instruction::Mul:
|
||
|
Takes12BitImm = true;
|
||
|
break;
|
||
|
case Instruction::Sub:
|
||
|
case Instruction::Shl:
|
||
|
case Instruction::LShr:
|
||
|
case Instruction::AShr:
|
||
|
Takes12BitImm = true;
|
||
|
ImmArgIdx = 1;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Takes12BitImm) {
|
||
|
// Check immediate is the correct argument...
|
||
|
if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
|
||
|
// ... and fits into the 12-bit immediate.
|
||
|
if (getTLI()->isLegalAddImmediate(Imm.getSExtValue()))
|
||
|
return TTI::TCC_Free;
|
||
|
}
|
||
|
|
||
|
// Otherwise, use the full materialisation cost.
|
||
|
return getIntImmCost(Imm, Ty);
|
||
|
}
|
||
|
|
||
|
// By default, prevent hoisting.
|
||
|
return TTI::TCC_Free;
|
||
|
}
|
||
|
|
||
|
int RISCVTTIImpl::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
|
||
|
const APInt &Imm, Type *Ty) {
|
||
|
// Prevent hoisting in unknown cases.
|
||
|
return TTI::TCC_Free;
|
||
|
}
|