You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
8.3 KiB
259 lines
8.3 KiB
//===-- SystemZTargetTransformInfo.cpp - SystemZ-specific TTI -------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements a TargetTransformInfo analysis pass specific to the
|
|
// SystemZ 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 "SystemZTargetTransformInfo.h"
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
#include "llvm/CodeGen/BasicTTIImpl.h"
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Target/CostTable.h"
|
|
#include "llvm/Target/TargetLowering.h"
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "systemztti"
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// SystemZ cost model.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
int SystemZTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) {
|
|
assert(Ty->isIntegerTy());
|
|
|
|
unsigned BitSize = Ty->getPrimitiveSizeInBits();
|
|
// There is no cost model for constants with a bit size of 0. Return TCC_Free
|
|
// here, so that constant hoisting will ignore this constant.
|
|
if (BitSize == 0)
|
|
return TTI::TCC_Free;
|
|
// No cost model for operations on integers larger than 64 bit implemented yet.
|
|
if (BitSize > 64)
|
|
return TTI::TCC_Free;
|
|
|
|
if (Imm == 0)
|
|
return TTI::TCC_Free;
|
|
|
|
if (Imm.getBitWidth() <= 64) {
|
|
// Constants loaded via lgfi.
|
|
if (isInt<32>(Imm.getSExtValue()))
|
|
return TTI::TCC_Basic;
|
|
// Constants loaded via llilf.
|
|
if (isUInt<32>(Imm.getZExtValue()))
|
|
return TTI::TCC_Basic;
|
|
// Constants loaded via llihf:
|
|
if ((Imm.getZExtValue() & 0xffffffff) == 0)
|
|
return TTI::TCC_Basic;
|
|
|
|
return 2 * TTI::TCC_Basic;
|
|
}
|
|
|
|
return 4 * TTI::TCC_Basic;
|
|
}
|
|
|
|
int SystemZTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx,
|
|
const APInt &Imm, Type *Ty) {
|
|
assert(Ty->isIntegerTy());
|
|
|
|
unsigned BitSize = Ty->getPrimitiveSizeInBits();
|
|
// There is no cost model for constants with a bit size of 0. Return TCC_Free
|
|
// here, so that constant hoisting will ignore this constant.
|
|
if (BitSize == 0)
|
|
return TTI::TCC_Free;
|
|
// No cost model for operations on integers larger than 64 bit implemented yet.
|
|
if (BitSize > 64)
|
|
return TTI::TCC_Free;
|
|
|
|
switch (Opcode) {
|
|
default:
|
|
return TTI::TCC_Free;
|
|
case Instruction::GetElementPtr:
|
|
// Always hoist the base address of a GetElementPtr. This prevents the
|
|
// creation of new constants for every base constant that gets constant
|
|
// folded with the offset.
|
|
if (Idx == 0)
|
|
return 2 * TTI::TCC_Basic;
|
|
return TTI::TCC_Free;
|
|
case Instruction::Store:
|
|
if (Idx == 0 && Imm.getBitWidth() <= 64) {
|
|
// Any 8-bit immediate store can by implemented via mvi.
|
|
if (BitSize == 8)
|
|
return TTI::TCC_Free;
|
|
// 16-bit immediate values can be stored via mvhhi/mvhi/mvghi.
|
|
if (isInt<16>(Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::ICmp:
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
// Comparisons against signed 32-bit immediates implemented via cgfi.
|
|
if (isInt<32>(Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
// Comparisons against unsigned 32-bit immediates implemented via clgfi.
|
|
if (isUInt<32>(Imm.getZExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::Add:
|
|
case Instruction::Sub:
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
// We use algfi/slgfi to add/subtract 32-bit unsigned immediates.
|
|
if (isUInt<32>(Imm.getZExtValue()))
|
|
return TTI::TCC_Free;
|
|
// Or their negation, by swapping addition vs. subtraction.
|
|
if (isUInt<32>(-Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::Mul:
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
// We use msgfi to multiply by 32-bit signed immediates.
|
|
if (isInt<32>(Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::Or:
|
|
case Instruction::Xor:
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
// Masks supported by oilf/xilf.
|
|
if (isUInt<32>(Imm.getZExtValue()))
|
|
return TTI::TCC_Free;
|
|
// Masks supported by oihf/xihf.
|
|
if ((Imm.getZExtValue() & 0xffffffff) == 0)
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::And:
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
// Any 32-bit AND operation can by implemented via nilf.
|
|
if (BitSize <= 32)
|
|
return TTI::TCC_Free;
|
|
// 64-bit masks supported by nilf.
|
|
if (isUInt<32>(~Imm.getZExtValue()))
|
|
return TTI::TCC_Free;
|
|
// 64-bit masks supported by nilh.
|
|
if ((Imm.getZExtValue() & 0xffffffff) == 0xffffffff)
|
|
return TTI::TCC_Free;
|
|
// Some 64-bit AND operations can be implemented via risbg.
|
|
const SystemZInstrInfo *TII = ST->getInstrInfo();
|
|
unsigned Start, End;
|
|
if (TII->isRxSBGMask(Imm.getZExtValue(), BitSize, Start, End))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Instruction::Shl:
|
|
case Instruction::LShr:
|
|
case Instruction::AShr:
|
|
// Always return TCC_Free for the shift value of a shift instruction.
|
|
if (Idx == 1)
|
|
return TTI::TCC_Free;
|
|
break;
|
|
case Instruction::UDiv:
|
|
case Instruction::SDiv:
|
|
case Instruction::URem:
|
|
case Instruction::SRem:
|
|
case Instruction::Trunc:
|
|
case Instruction::ZExt:
|
|
case Instruction::SExt:
|
|
case Instruction::IntToPtr:
|
|
case Instruction::PtrToInt:
|
|
case Instruction::BitCast:
|
|
case Instruction::PHI:
|
|
case Instruction::Call:
|
|
case Instruction::Select:
|
|
case Instruction::Ret:
|
|
case Instruction::Load:
|
|
break;
|
|
}
|
|
|
|
return SystemZTTIImpl::getIntImmCost(Imm, Ty);
|
|
}
|
|
|
|
int SystemZTTIImpl::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
|
|
const APInt &Imm, Type *Ty) {
|
|
assert(Ty->isIntegerTy());
|
|
|
|
unsigned BitSize = Ty->getPrimitiveSizeInBits();
|
|
// There is no cost model for constants with a bit size of 0. Return TCC_Free
|
|
// here, so that constant hoisting will ignore this constant.
|
|
if (BitSize == 0)
|
|
return TTI::TCC_Free;
|
|
// No cost model for operations on integers larger than 64 bit implemented yet.
|
|
if (BitSize > 64)
|
|
return TTI::TCC_Free;
|
|
|
|
switch (IID) {
|
|
default:
|
|
return TTI::TCC_Free;
|
|
case Intrinsic::sadd_with_overflow:
|
|
case Intrinsic::uadd_with_overflow:
|
|
case Intrinsic::ssub_with_overflow:
|
|
case Intrinsic::usub_with_overflow:
|
|
// These get expanded to include a normal addition/subtraction.
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
if (isUInt<32>(Imm.getZExtValue()))
|
|
return TTI::TCC_Free;
|
|
if (isUInt<32>(-Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Intrinsic::smul_with_overflow:
|
|
case Intrinsic::umul_with_overflow:
|
|
// These get expanded to include a normal multiplication.
|
|
if (Idx == 1 && Imm.getBitWidth() <= 64) {
|
|
if (isInt<32>(Imm.getSExtValue()))
|
|
return TTI::TCC_Free;
|
|
}
|
|
break;
|
|
case Intrinsic::experimental_stackmap:
|
|
if ((Idx < 2) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
|
|
return TTI::TCC_Free;
|
|
break;
|
|
case Intrinsic::experimental_patchpoint_void:
|
|
case Intrinsic::experimental_patchpoint_i64:
|
|
if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
|
|
return TTI::TCC_Free;
|
|
break;
|
|
}
|
|
return SystemZTTIImpl::getIntImmCost(Imm, Ty);
|
|
}
|
|
|
|
TargetTransformInfo::PopcntSupportKind
|
|
SystemZTTIImpl::getPopcntSupport(unsigned TyWidth) {
|
|
assert(isPowerOf2_32(TyWidth) && "Type width must be power of 2");
|
|
if (ST->hasPopulationCount() && TyWidth <= 64)
|
|
return TTI::PSK_FastHardware;
|
|
return TTI::PSK_Software;
|
|
}
|
|
|
|
unsigned SystemZTTIImpl::getNumberOfRegisters(bool Vector) {
|
|
if (!Vector)
|
|
// Discount the stack pointer. Also leave out %r0, since it can't
|
|
// be used in an address.
|
|
return 14;
|
|
if (ST->hasVector())
|
|
return 32;
|
|
return 0;
|
|
}
|
|
|
|
unsigned SystemZTTIImpl::getRegisterBitWidth(bool Vector) {
|
|
if (!Vector)
|
|
return 64;
|
|
if (ST->hasVector())
|
|
return 128;
|
|
return 0;
|
|
}
|
|
|