0f5676f432
build glue.
246 lines
7.8 KiB
C++
246 lines
7.8 KiB
C++
//===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
|
|
//
|
|
// 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 the targeting of the RegisterBankInfo class for X86.
|
|
/// \todo This should be generated by TableGen.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "X86RegisterBankInfo.h"
|
|
#include "X86InstrInfo.h"
|
|
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
|
|
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
|
|
|
#define GET_TARGET_REGBANK_IMPL
|
|
#include "X86GenRegisterBank.inc"
|
|
|
|
using namespace llvm;
|
|
// This file will be TableGen'ed at some point.
|
|
#define GET_TARGET_REGBANK_INFO_IMPL
|
|
#include "X86GenRegisterBankInfo.def"
|
|
|
|
#ifndef LLVM_BUILD_GLOBAL_ISEL
|
|
#error "You shouldn't build this"
|
|
#endif
|
|
|
|
X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
|
|
: X86GenRegisterBankInfo() {
|
|
|
|
// validate RegBank initialization.
|
|
const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
|
|
(void)RBGPR;
|
|
assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
|
|
|
|
// The GPR register bank is fully defined by all the registers in
|
|
// GR64 + its subclasses.
|
|
assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
|
|
"Subclass not added?");
|
|
assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
|
|
}
|
|
|
|
const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
|
|
const TargetRegisterClass &RC) const {
|
|
|
|
if (X86::GR8RegClass.hasSubClassEq(&RC) ||
|
|
X86::GR16RegClass.hasSubClassEq(&RC) ||
|
|
X86::GR32RegClass.hasSubClassEq(&RC) ||
|
|
X86::GR64RegClass.hasSubClassEq(&RC))
|
|
return getRegBank(X86::GPRRegBankID);
|
|
|
|
if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
|
|
X86::FR64XRegClass.hasSubClassEq(&RC) ||
|
|
X86::VR128XRegClass.hasSubClassEq(&RC) ||
|
|
X86::VR256XRegClass.hasSubClassEq(&RC) ||
|
|
X86::VR512RegClass.hasSubClassEq(&RC))
|
|
return getRegBank(X86::VECRRegBankID);
|
|
|
|
llvm_unreachable("Unsupported register kind yet.");
|
|
}
|
|
|
|
X86GenRegisterBankInfo::PartialMappingIdx
|
|
X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) {
|
|
if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
|
|
switch (Ty.getSizeInBits()) {
|
|
case 1:
|
|
case 8:
|
|
return PMI_GPR8;
|
|
case 16:
|
|
return PMI_GPR16;
|
|
case 32:
|
|
return PMI_GPR32;
|
|
case 64:
|
|
return PMI_GPR64;
|
|
break;
|
|
default:
|
|
llvm_unreachable("Unsupported register size.");
|
|
}
|
|
} else if (Ty.isScalar()) {
|
|
switch (Ty.getSizeInBits()) {
|
|
case 32:
|
|
return PMI_FP32;
|
|
case 64:
|
|
return PMI_FP64;
|
|
default:
|
|
llvm_unreachable("Unsupported register size.");
|
|
}
|
|
} else {
|
|
switch (Ty.getSizeInBits()) {
|
|
case 128:
|
|
return PMI_VEC128;
|
|
case 256:
|
|
return PMI_VEC256;
|
|
case 512:
|
|
return PMI_VEC512;
|
|
default:
|
|
llvm_unreachable("Unsupported register size.");
|
|
}
|
|
}
|
|
|
|
return PMI_None;
|
|
}
|
|
|
|
void X86RegisterBankInfo::getInstrPartialMappingIdxs(
|
|
const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
|
|
SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
|
|
|
|
unsigned NumOperands = MI.getNumOperands();
|
|
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
|
|
auto &MO = MI.getOperand(Idx);
|
|
if (!MO.isReg())
|
|
OpRegBankIdx[Idx] = PMI_None;
|
|
else
|
|
OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
|
|
}
|
|
}
|
|
|
|
bool X86RegisterBankInfo::getInstrValueMapping(
|
|
const MachineInstr &MI,
|
|
const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
|
|
SmallVectorImpl<const ValueMapping *> &OpdsMapping) {
|
|
|
|
unsigned NumOperands = MI.getNumOperands();
|
|
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
|
|
if (!MI.getOperand(Idx).isReg())
|
|
continue;
|
|
|
|
auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
|
|
if (!Mapping->isValid())
|
|
return false;
|
|
|
|
OpdsMapping[Idx] = Mapping;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const RegisterBankInfo::InstructionMapping &
|
|
X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
|
|
bool isFP) const {
|
|
const MachineFunction &MF = *MI.getParent()->getParent();
|
|
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
|
|
unsigned NumOperands = MI.getNumOperands();
|
|
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
|
|
|
|
if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
|
|
(Ty != MRI.getType(MI.getOperand(2).getReg())))
|
|
llvm_unreachable("Unsupported operand mapping yet.");
|
|
|
|
auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
|
|
return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
|
|
}
|
|
|
|
const RegisterBankInfo::InstructionMapping &
|
|
X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
|
const MachineFunction &MF = *MI.getParent()->getParent();
|
|
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
auto Opc = MI.getOpcode();
|
|
|
|
// Try the default logic for non-generic instructions that are either copies
|
|
// or already have some operands assigned to banks.
|
|
if (!isPreISelGenericOpcode(Opc)) {
|
|
const InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
|
if (Mapping.isValid())
|
|
return Mapping;
|
|
}
|
|
|
|
switch (Opc) {
|
|
case TargetOpcode::G_ADD:
|
|
case TargetOpcode::G_SUB:
|
|
return getSameOperandsMapping(MI, false);
|
|
break;
|
|
case TargetOpcode::G_FADD:
|
|
case TargetOpcode::G_FSUB:
|
|
case TargetOpcode::G_FMUL:
|
|
case TargetOpcode::G_FDIV:
|
|
return getSameOperandsMapping(MI, true);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
unsigned NumOperands = MI.getNumOperands();
|
|
|
|
// Track the bank of each register, use NotFP mapping (all scalars in GPRs)
|
|
SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
|
|
getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
|
|
|
|
// Finally construct the computed mapping.
|
|
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
|
|
if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
|
|
return getInvalidInstructionMapping();
|
|
|
|
return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
|
|
getOperandsMapping(OpdsMapping), NumOperands);
|
|
}
|
|
|
|
void X86RegisterBankInfo::applyMappingImpl(
|
|
const OperandsMapper &OpdMapper) const {
|
|
return applyDefaultMapping(OpdMapper);
|
|
}
|
|
|
|
RegisterBankInfo::InstructionMappings
|
|
X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
|
|
|
|
const MachineFunction &MF = *MI.getParent()->getParent();
|
|
const TargetSubtargetInfo &STI = MF.getSubtarget();
|
|
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
|
|
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
|
|
switch (MI.getOpcode()) {
|
|
case TargetOpcode::G_LOAD:
|
|
case TargetOpcode::G_STORE: {
|
|
// we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
|
|
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
|
|
if (Size != 32 && Size != 64)
|
|
break;
|
|
|
|
unsigned NumOperands = MI.getNumOperands();
|
|
|
|
// Track the bank of each register, use FP mapping (all scalars in VEC)
|
|
SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
|
|
getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
|
|
|
|
// Finally construct the computed mapping.
|
|
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
|
|
if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
|
|
break;
|
|
|
|
const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
|
|
/*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
|
|
InstructionMappings AltMappings;
|
|
AltMappings.push_back(&Mapping);
|
|
return AltMappings;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return RegisterBankInfo::getInstrAlternativeMappings(MI);
|
|
}
|