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");
51 if (X86::GR8RegClass.hasSubClassEq(&RC) ||
52 X86::GR16RegClass.hasSubClassEq(&RC) ||
53 X86::GR32RegClass.hasSubClassEq(&RC) ||
54 X86::GR64RegClass.hasSubClassEq(&RC) ||
55 X86::LOW32_ADDR_ACCESSRegClass.hasSubClassEq(&RC) ||
56 X86::LOW32_ADDR_ACCESS_RBPRegClass.hasSubClassEq(&RC))
59 if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
60 X86::FR64XRegClass.hasSubClassEq(&RC) ||
61 X86::VR128XRegClass.hasSubClassEq(&RC) ||
62 X86::VR256XRegClass.hasSubClassEq(&RC) ||
63 X86::VR512RegClass.hasSubClassEq(&RC))
66 if (X86::RFP80RegClass.hasSubClassEq(&RC) ||
67 X86::RFP32RegClass.hasSubClassEq(&RC) ||
68 X86::RFP64RegClass.hasSubClassEq(&RC))
82 case Intrinsic::x86_sse_rcp_ss:
83 case Intrinsic::x86_sse_rcp_ps:
84 case Intrinsic::x86_sse_rsqrt_ss:
85 case Intrinsic::x86_sse_rsqrt_ps:
86 case Intrinsic::x86_sse_min_ss:
87 case Intrinsic::x86_sse_min_ps:
88 case Intrinsic::x86_sse_max_ss:
89 case Intrinsic::x86_sse_max_ps:
98 unsigned Depth)
const {
99 unsigned Op =
MI.getOpcode();
109 if (
Op != TargetOpcode::COPY && !
MI.isPHI() &&
124 if (!
MI.isPHI() ||
Depth > MaxFPRSearchDepth)
129 onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
136 unsigned Depth)
const {
137 switch (
MI.getOpcode()) {
138 case TargetOpcode::G_FPTOSI:
139 case TargetOpcode::G_FPTOUI:
140 case TargetOpcode::G_FCMP:
141 case TargetOpcode::G_LROUND:
142 case TargetOpcode::G_LLROUND:
143 case TargetOpcode::G_INTRINSIC_TRUNC:
144 case TargetOpcode::G_INTRINSIC_ROUND:
155 unsigned Depth)
const {
156 switch (
MI.getOpcode()) {
157 case TargetOpcode::G_SITOFP:
158 case TargetOpcode::G_UITOFP:
166X86GenRegisterBankInfo::PartialMappingIdx
168 const LLT &Ty,
bool isFP) {
171 bool HasSSE1 = ST->hasSSE1();
172 bool HasSSE2 = ST->hasSSE2();
196 return HasSSE1 ? PMI_FP32 : PMI_PSR32;
198 return HasSSE2 ? PMI_FP64 : PMI_PSR64;
222void X86RegisterBankInfo::getInstrPartialMappingIdxs(
226 unsigned NumOperands =
MI.getNumOperands();
227 for (
unsigned Idx = 0;
Idx < NumOperands; ++
Idx) {
228 auto &MO =
MI.getOperand(
Idx);
229 if (!MO.isReg() || !MO.getReg())
230 OpRegBankIdx[
Idx] = PMI_None;
237bool X86RegisterBankInfo::getInstrValueMapping(
242 unsigned NumOperands =
MI.getNumOperands();
243 for (
unsigned Idx = 0;
Idx < NumOperands; ++
Idx) {
244 if (!
MI.getOperand(
Idx).isReg())
246 if (!
MI.getOperand(
Idx).getReg())
250 if (!Mapping->isValid())
253 OpdsMapping[
Idx] = Mapping;
259X86RegisterBankInfo::getSameOperandsMapping(
const MachineInstr &
MI,
264 unsigned NumOperands =
MI.getNumOperands();
265 LLT Ty =
MRI.getType(
MI.getOperand(0).getReg());
267 if (NumOperands != 3 || (Ty !=
MRI.getType(
MI.getOperand(1).getReg())) ||
268 (Ty !=
MRI.getType(
MI.getOperand(2).getReg())))
281 unsigned Opc =
MI.getOpcode();
292 case TargetOpcode::G_ADD:
293 case TargetOpcode::G_SUB:
294 case TargetOpcode::G_MUL:
295 return getSameOperandsMapping(
MI,
false);
296 case TargetOpcode::G_FADD:
297 case TargetOpcode::G_FSUB:
298 case TargetOpcode::G_FMUL:
299 case TargetOpcode::G_FDIV:
300 return getSameOperandsMapping(
MI,
true);
301 case TargetOpcode::G_SHL:
302 case TargetOpcode::G_LSHR:
303 case TargetOpcode::G_ASHR: {
304 unsigned NumOperands =
MI.getNumOperands();
305 LLT Ty =
MRI.getType(
MI.getOperand(0).getReg());
314 unsigned NumOperands =
MI.getNumOperands();
318 case TargetOpcode::G_FPEXT:
319 case TargetOpcode::G_FPTRUNC:
320 case TargetOpcode::G_FCONSTANT:
323 getInstrPartialMappingIdxs(
MI,
MRI,
true, OpRegBankIdx);
325 case TargetOpcode::G_SITOFP:
326 case TargetOpcode::G_FPTOSI: {
329 auto &Op0 =
MI.getOperand(0);
330 auto &Op1 =
MI.getOperand(1);
331 const LLT Ty0 =
MRI.getType(Op0.getReg());
332 const LLT Ty1 =
MRI.getType(Op1.getReg());
334 bool FirstArgIsFP = Opc == TargetOpcode::G_SITOFP;
335 bool SecondArgIsFP = Opc == TargetOpcode::G_FPTOSI;
340 case TargetOpcode::G_FCMP: {
341 LLT Ty1 =
MRI.getType(
MI.getOperand(2).getReg());
342 LLT Ty2 =
MRI.getType(
MI.getOperand(3).getReg());
345 "Mismatched operand sizes for G_FCMP");
349 assert((
Size == 32 ||
Size == 64) &&
"Unsupported size for G_FCMP");
352 OpRegBankIdx = {PMI_GPR8,
353 PMI_None, FpRegBank, FpRegBank};
356 case TargetOpcode::G_TRUNC:
357 case TargetOpcode::G_ANYEXT: {
358 auto &Op0 =
MI.getOperand(0);
359 auto &Op1 =
MI.getOperand(1);
360 const LLT Ty0 =
MRI.getType(Op0.getReg());
361 const LLT Ty1 =
MRI.getType(Op1.getReg());
368 Opc == TargetOpcode::G_ANYEXT;
370 getInstrPartialMappingIdxs(
MI,
MRI, isFPTrunc || isFPAnyExt,
374 case TargetOpcode::G_LOAD: {
378 bool IsFP =
any_of(
MRI.use_nodbg_instructions(cast<GLoad>(
MI).getDstReg()),
384 return onlyUsesFP(UseMI, MRI, TRI);
386 getInstrPartialMappingIdxs(
MI,
MRI, IsFP, OpRegBankIdx);
389 case TargetOpcode::G_STORE: {
391 Register VReg = cast<GStore>(
MI).getValueReg();
396 getInstrPartialMappingIdxs(
MI,
MRI, IsFP, OpRegBankIdx);
402 getInstrPartialMappingIdxs(
MI,
MRI,
false, OpRegBankIdx);
408 if (!getInstrValueMapping(
MI, OpRegBankIdx, OpdsMapping))
428 switch (
MI.getOpcode()) {
429 case TargetOpcode::G_LOAD:
430 case TargetOpcode::G_STORE:
431 case TargetOpcode::G_IMPLICIT_DEF: {
437 unsigned NumOperands =
MI.getNumOperands();
441 getInstrPartialMappingIdxs(
MI,
MRI,
true, OpRegBankIdx);
445 if (!getInstrValueMapping(
MI, OpRegBankIdx, OpdsMapping))
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static unsigned getIntrinsicID(const SDNode *N)
static bool isFPIntrinsic(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file declares the targeting of the RegisterBankInfo class for X86.
This class represents an Operation in the Expression.
constexpr bool isScalar() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
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.
MachineOperand class - Representation of each machine instruction operand.
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...
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
This class implements the register bank concept.
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
getRegisterInfo - If register information is available, return it.
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 RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
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.
bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...