22#include "llvm/IR/IntrinsicsX86.h"
24#define GET_TARGET_REGBANK_IMPL
25#include "X86GenRegisterBank.inc"
29#define GET_TARGET_REGBANK_INFO_IMPL
30#include "X86GenRegisterBankInfo.def"
37 assert(&X86::GPRRegBank == &RBGPR &&
"Incorrect RegBanks inizalization.");
42 "Subclass not added?");
44 "GPRs should hold up to 64-bit");
55 case Intrinsic::x86_sse_rcp_ss:
56 case Intrinsic::x86_sse_rcp_ps:
57 case Intrinsic::x86_sse_rsqrt_ss:
58 case Intrinsic::x86_sse_rsqrt_ps:
59 case Intrinsic::x86_sse_min_ss:
60 case Intrinsic::x86_sse_min_ps:
61 case Intrinsic::x86_sse_max_ss:
62 case Intrinsic::x86_sse_max_ps:
71 unsigned Depth)
const {
72 unsigned Op =
MI.getOpcode();
82 if (
Op != TargetOpcode::COPY && !
MI.isPHI() &&
97 if (!
MI.isPHI() ||
Depth > MaxFPRSearchDepth)
100 return any_of(
MI.explicit_uses(), [&](
const MachineOperand &
Op) {
102 onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
109 unsigned Depth)
const {
110 switch (
MI.getOpcode()) {
111 case TargetOpcode::G_FPTOSI:
112 case TargetOpcode::G_FPTOUI:
113 case TargetOpcode::G_FCMP:
115 case TargetOpcode::G_LROUND:
116 case TargetOpcode::G_LLROUND:
117 case TargetOpcode::G_INTRINSIC_TRUNC:
118 case TargetOpcode::G_INTRINSIC_ROUND:
129 unsigned Depth)
const {
130 switch (
MI.getOpcode()) {
131 case TargetOpcode::G_SITOFP:
132 case TargetOpcode::G_UITOFP:
141X86GenRegisterBankInfo::PartialMappingIdx
143 const LLT &Ty,
bool isFP) {
146 bool HasSSE1 = ST->hasSSE1();
147 bool HasSSE2 = ST->hasSSE2();
149 if (Ty.getSizeInBits() == 80)
151 if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
152 switch (Ty.getSizeInBits()) {
168 }
else if (Ty.isScalar()) {
169 switch (Ty.getSizeInBits()) {
171 return HasSSE1 ? PMI_FP32 : PMI_PSR32;
173 return HasSSE2 ? PMI_FP64 : PMI_PSR64;
182 switch (Ty.getSizeInBits()) {
197void X86RegisterBankInfo::getInstrPartialMappingIdxs(
201 unsigned NumOperands =
MI.getNumOperands();
202 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
203 auto &MO =
MI.getOperand(Idx);
204 if (!MO.isReg() || !MO.getReg())
205 OpRegBankIdx[Idx] = PMI_None;
212bool X86RegisterBankInfo::getInstrValueMapping(
217 unsigned NumOperands =
MI.getNumOperands();
218 for (
unsigned Idx = 0; Idx < NumOperands; ++Idx) {
219 if (!
MI.getOperand(Idx).isReg())
221 if (!
MI.getOperand(Idx).getReg())
225 if (!Mapping->isValid())
228 OpdsMapping[Idx] = Mapping;
234X86RegisterBankInfo::getSameOperandsMapping(
const MachineInstr &
MI,
236 const MachineFunction &MF = *
MI.getParent()->getParent();
239 unsigned NumOperands =
MI.getNumOperands();
240 LLT Ty =
MRI.getType(
MI.getOperand(0).getReg());
242 if (NumOperands != 3 || (Ty !=
MRI.getType(
MI.getOperand(1).getReg())) ||
243 (Ty !=
MRI.getType(
MI.getOperand(2).getReg())))
256 unsigned Opc =
MI.getOpcode();
267 case TargetOpcode::G_ADD:
268 case TargetOpcode::G_SUB:
269 case TargetOpcode::G_MUL:
270 return getSameOperandsMapping(
MI,
false);
271 case TargetOpcode::G_FADD:
272 case TargetOpcode::G_FSUB:
273 case TargetOpcode::G_FMUL:
274 case TargetOpcode::G_FDIV:
275 return getSameOperandsMapping(
MI,
true);
276 case TargetOpcode::G_SHL:
277 case TargetOpcode::G_LSHR:
278 case TargetOpcode::G_ASHR: {
279 unsigned NumOperands =
MI.getNumOperands();
280 LLT Ty =
MRI.getType(
MI.getOperand(0).getReg());
289 unsigned NumOperands =
MI.getNumOperands();
293 case TargetOpcode::G_FSQRT:
294 case TargetOpcode::G_FPEXT:
295 case TargetOpcode::G_FPTRUNC:
296 case TargetOpcode::G_FCONSTANT:
299 getInstrPartialMappingIdxs(
MI,
MRI,
true, OpRegBankIdx);
303 auto &Op0 =
MI.getOperand(0);
304 auto &Op1 =
MI.getOperand(1);
305 const LLT Ty0 =
MRI.getType(Op0.getReg());
306 const LLT Ty1 =
MRI.getType(Op1.getReg());
311 case TargetOpcode::G_SITOFP:
312 case TargetOpcode::G_FPTOSI:
313 case TargetOpcode::G_UITOFP:
314 case TargetOpcode::G_FPTOUI: {
317 auto &Op0 =
MI.getOperand(0);
318 auto &Op1 =
MI.getOperand(1);
319 const LLT Ty0 =
MRI.getType(Op0.getReg());
320 const LLT Ty1 =
MRI.getType(Op1.getReg());
323 Opc == TargetOpcode::G_SITOFP ||
Opc == TargetOpcode::G_UITOFP;
328 case TargetOpcode::G_FCMP: {
329 LLT Ty1 =
MRI.getType(
MI.getOperand(2).getReg());
330 LLT Ty2 =
MRI.getType(
MI.getOperand(3).getReg());
333 "Mismatched operand sizes for G_FCMP");
338 "Unsupported size for G_FCMP");
340 OpRegBankIdx = {PMI_GPR8,
341 PMI_None, FpRegBank, FpRegBank};
344 case TargetOpcode::G_FABS:
345 case TargetOpcode::G_TRUNC:
346 case TargetOpcode::G_ANYEXT: {
347 auto &Op0 =
MI.getOperand(0);
348 auto &Op1 =
MI.getOperand(1);
349 const LLT Ty0 =
MRI.getType(Op0.getReg());
350 const LLT Ty1 =
MRI.getType(Op1.getReg());
357 Opc == TargetOpcode::G_ANYEXT;
358 bool isFAbs = (
Opc == TargetOpcode::G_FABS);
359 getInstrPartialMappingIdxs(
360 MI,
MRI, isFPTrunc || isFPAnyExt || isFAbs, OpRegBankIdx);
363 case TargetOpcode::G_LOAD: {
373 return onlyUsesFP(UseMI, MRI, TRI);
375 getInstrPartialMappingIdxs(
MI,
MRI, IsFP, OpRegBankIdx);
378 case TargetOpcode::G_STORE: {
385 getInstrPartialMappingIdxs(
MI,
MRI, IsFP, OpRegBankIdx);
391 getInstrPartialMappingIdxs(
MI,
MRI,
false, OpRegBankIdx);
397 if (!getInstrValueMapping(
MI, OpRegBankIdx, OpdsMapping))
417 switch (
MI.getOpcode()) {
418 case TargetOpcode::G_LOAD:
419 case TargetOpcode::G_STORE:
420 case TargetOpcode::G_IMPLICIT_DEF: {
426 unsigned NumOperands =
MI.getNumOperands();
430 getInstrPartialMappingIdxs(
MI,
MRI,
true, OpRegBankIdx);
434 if (!getInstrValueMapping(
MI, OpRegBankIdx, OpdsMapping))
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static unsigned getIntrinsicID(const SDNode *N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isFPIntrinsic(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Register const TargetRegisterInfo * TRI
This file declares the targeting of the RegisterBankInfo class for X86.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Helper class that represents how the value of an instruction may be mapped and what is the related co...
bool isValid() const
Check whether this object is valid.
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getMaximumSize(unsigned RegBankID) const
Get the maximum size in bits that fits in the given register bank.
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
SmallVector< const InstructionMapping *, 4 > InstructionMappings
Convenient type to represent the alternatives for mapping an instruction.
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
This class implements the register bank concept.
LLVM_ABI bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
static PartialMappingIdx getPartialMappingIdx(const MachineInstr &MI, const LLT &Ty, bool isFP)
static const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx Idx, unsigned NumOperands)
X86RegisterBankInfo(const TargetRegisterInfo &TRI)
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
void applyMappingImpl(MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const override
See RegisterBankInfo::applyMapping.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
bool isPreISelGenericOptimizationHint(unsigned Opcode)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...