21#define GET_TARGET_REGBANK_IMPL
23#include "MipsGenRegisterBank.inc"
84 case Mips::GPR32RegClassID:
85 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
86 case Mips::GPRMM16MovePPairFirstRegClassID:
87 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
88 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
89 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
90 case Mips::SP32RegClassID:
91 case Mips::GP32RegClassID:
93 case Mips::FGRCCRegClassID:
94 case Mips::FGR32RegClassID:
95 case Mips::FGR64RegClassID:
96 case Mips::AFGR64RegClassID:
97 case Mips::MSA128BRegClassID:
98 case Mips::MSA128HRegClassID:
99 case Mips::MSA128WRegClassID:
100 case Mips::MSA128DRegClassID:
110 case TargetOpcode::G_FCONSTANT:
111 case TargetOpcode::G_FADD:
112 case TargetOpcode::G_FSUB:
113 case TargetOpcode::G_FMUL:
114 case TargetOpcode::G_FDIV:
115 case TargetOpcode::G_FABS:
116 case TargetOpcode::G_FSQRT:
117 case TargetOpcode::G_FCEIL:
118 case TargetOpcode::G_FFLOOR:
119 case TargetOpcode::G_FPEXT:
120 case TargetOpcode::G_FPTRUNC:
131 case TargetOpcode::G_FPTOSI:
132 case TargetOpcode::G_FPTOUI:
133 case TargetOpcode::G_FCMP:
144 case TargetOpcode::G_SITOFP:
145 case TargetOpcode::G_UITOFP:
153 if (
MI->getOpcode() == TargetOpcode::G_LOAD ||
154 MI->getOpcode() == TargetOpcode::G_STORE) {
155 auto MMO = *
MI->memoperands_begin();
158 MMO->getAlign() < MMO->getSize()))
166 case TargetOpcode::G_LOAD:
167 case TargetOpcode::G_STORE:
168 case TargetOpcode::G_PHI:
169 case TargetOpcode::G_SELECT:
170 case TargetOpcode::G_IMPLICIT_DEF:
171 case TargetOpcode::G_UNMERGE_VALUES:
172 case TargetOpcode::G_MERGE_VALUES:
179void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
182 "Pointers are gprb, they should not be considered as ambiguous.\n");
186 if (NonCopyInstr->
getOpcode() == TargetOpcode::COPY &&
190 DefUses.push_back(skipCopiesOutgoing(&
UseMI));
194void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
197 "Pointers are gprb, they should not be considered as ambiguous.\n");
199 UseDefs.push_back(skipCopiesIncoming(
DefMI));
203MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
208 while (
Ret->getOpcode() == TargetOpcode::COPY &&
209 !
Ret->getOperand(0).getReg().isPhysical() &&
210 MRI.hasOneUse(
Ret->getOperand(0).getReg())) {
211 Ret = &(*
MRI.use_instr_begin(
Ret->getOperand(0).getReg()));
217MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
222 while (
Ret->getOpcode() == TargetOpcode::COPY &&
223 !
Ret->getOperand(1).getReg().isPhysical())
224 Ret =
MRI.getVRegDef(
Ret->getOperand(1).getReg());
228MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
231 "Not implemented for non Ambiguous opcode.\n");
235 if (
MI->getOpcode() == TargetOpcode::G_LOAD)
236 addDefUses(
MI->getOperand(0).getReg(),
MRI);
238 if (
MI->getOpcode() == TargetOpcode::G_STORE)
239 addUseDef(
MI->getOperand(0).getReg(),
MRI);
241 if (
MI->getOpcode() == TargetOpcode::G_PHI) {
242 addDefUses(
MI->getOperand(0).getReg(),
MRI);
244 for (
unsigned i = 1; i <
MI->getNumOperands(); i += 2)
245 addUseDef(
MI->getOperand(i).getReg(),
MRI);
248 if (
MI->getOpcode() == TargetOpcode::G_SELECT) {
249 addDefUses(
MI->getOperand(0).getReg(),
MRI);
251 addUseDef(
MI->getOperand(2).getReg(),
MRI);
252 addUseDef(
MI->getOperand(3).getReg(),
MRI);
255 if (
MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
256 addDefUses(
MI->getOperand(0).getReg(),
MRI);
258 if (
MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
259 addUseDef(
MI->getOperand(
MI->getNumOperands() - 1).getReg(),
MRI);
261 if (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
262 addDefUses(
MI->getOperand(0).getReg(),
MRI);
265bool MipsRegisterBankInfo::TypeInfoForMF::visit(
267 InstType &AmbiguousTy) {
273 AmbiguousRegDefUseContainer DefUseContainer(
MI);
280 if (AmbiguousTy == InstType::Ambiguous &&
281 (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
282 MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
283 AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
286 if (visitAdjacentInstrs(
MI, DefUseContainer.getDefUses(),
true, AmbiguousTy))
290 if (visitAdjacentInstrs(
MI, DefUseContainer.getUseDefs(),
false, AmbiguousTy))
294 if (!WaitingForTypeOfMI) {
296 setTypes(
MI, AmbiguousTy);
307 addToWaitingQueue(WaitingForTypeOfMI,
MI);
311bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
313 bool isDefUse, InstType &AmbiguousTy) {
314 while (!AdjacentInstrs.
empty()) {
319 setTypes(
MI, InstType::FloatingPoint);
325 if (AdjMI->
getOpcode() == TargetOpcode::COPY) {
326 setTypesAccordingToPhysicalRegister(
MI, AdjMI, isDefUse ? 0 : 1);
332 if ((!isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
333 (isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
335 setTypes(
MI, InstType::Integer);
341 if (!wasVisited(AdjMI) ||
342 getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
343 if (visit(AdjMI,
MI, AmbiguousTy)) {
345 setTypes(
MI, getRecordedTypeForInstr(AdjMI));
353void MipsRegisterBankInfo::TypeInfoForMF::setTypes(
const MachineInstr *
MI,
355 changeRecordedTypeForInstr(
MI, InstTy);
357 setTypes(WaitingInstr, InstTy);
361void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
364 "Copies of non physical registers should not be considered here.\n");
374 if (Bank == &Mips::FPRBRegBank)
375 setTypes(
MI, InstType::FloatingPoint);
376 else if (Bank == &Mips::GPRBRegBank)
377 setTypes(
MI, InstType::Integer);
382MipsRegisterBankInfo::InstType
383MipsRegisterBankInfo::TypeInfoForMF::determineInstType(
const MachineInstr *
MI) {
384 InstType DefaultAmbiguousType = InstType::Ambiguous;
385 visit(
MI,
nullptr, DefaultAmbiguousType);
386 return getRecordedTypeForInstr(
MI);
389void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
391 if (MFName != FunctionName) {
392 MFName = std::string(FunctionName);
393 WaitingQueues.clear();
401 "MSA mapping not available on target without MSA.");
426 static TypeInfoForMF TI;
429 TI.cleanupIfNewFunction(
MI.getMF()->getName());
431 unsigned Opc =
MI.getOpcode();
435 if (
MI.getOpcode() != TargetOpcode::G_PHI) {
442 using namespace TargetOpcode;
444 unsigned NumOperands =
MI.getNumOperands();
451 LLT RegTy =
MRI.getType(
Op.getReg());
462 const LLT Op0Ty =
MRI.getType(
MI.getOperand(0).getReg());
464 InstType InstTy = InstType::Integer;
499 if (Op0Size == 128) {
506 InstTy = TI.determineInstType(&
MI);
508 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
509 isAmbiguous_64(InstTy, Op0Size)) {
513 assert((isInteger_32(InstTy, Op0Size) ||
514 isAmbiguous_32(InstTy, Op0Size) ||
515 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
516 "Unexpected Inst type");
526 InstTy = TI.determineInstType(&
MI);
529 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
532 TI.clearTypeInfoData(&
MI);
536 assert((isInteger_32(InstTy, Op0Size) ||
537 isFloatingPoint_32or64(InstTy, Op0Size) ||
538 isAmbiguous_32or64(InstTy, Op0Size)) &&
539 "Unexpected Inst type");
546 InstTy = TI.determineInstType(&
MI);
547 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
548 isAmbiguous_64(InstTy, Op0Size)) {
554 assert((isInteger_32(InstTy, Op0Size) ||
555 isAmbiguous_32(InstTy, Op0Size) ||
556 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
557 "Unexpected Inst type");
565 case G_IMPLICIT_DEF: {
567 InstTy = TI.determineInstType(&
MI);
569 if (isFloatingPoint_32or64(InstTy, Op0Size))
572 assert((isInteger_32(InstTy, Op0Size) ||
573 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
574 "Unexpected Inst type");
578 case G_UNMERGE_VALUES: {
579 assert(
MI.getNumOperands() == 3 &&
"Unsupported G_UNMERGE_VALUES");
580 unsigned Op3Size =
MRI.getType(
MI.getOperand(2).getReg()).getSizeInBits();
581 InstTy = TI.determineInstType(&
MI);
582 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
583 isFloatingPoint_64(InstTy, Op3Size)) &&
584 "Unexpected Inst type");
588 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
592 case G_MERGE_VALUES: {
593 InstTy = TI.determineInstType(&
MI);
594 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
595 isFloatingPoint_64(InstTy, Op0Size)) &&
596 "Unexpected Inst type");
600 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
633 assert((Op0Size == 32) &&
"Unsupported integer size");
634 unsigned SizeFP =
MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits();
640 assert((
MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
641 "Unsupported integer size");
669 TI.clearTypeInfoData(&
MI);
682 assert(!
B.isObservingChanges());
683 B.setChangeObserver(*
this);
686 ~InstManager() {
B.stopObservingChanges(); }
698 switch (
MI.getOpcode()) {
699 case TargetOpcode::G_STORE:
702 case TargetOpcode::G_CONSTANT:
703 case TargetOpcode::G_LOAD:
704 case TargetOpcode::G_SELECT:
705 case TargetOpcode::G_PHI:
706 case TargetOpcode::G_IMPLICIT_DEF: {
711 case TargetOpcode::G_PTR_ADD: {
712 assert(
MRI.getType(Dest).isPointer() &&
"Unexpected operand type.");
727 UpdatedDefs, Observer);
729 DeadMI->eraseFromParent();
742 InstManager NewInstrObserver(
Builder, NewInstrs);
746 switch (
MI.getOpcode()) {
747 case TargetOpcode::G_LOAD:
748 case TargetOpcode::G_STORE:
749 case TargetOpcode::G_PHI:
750 case TargetOpcode::G_SELECT:
751 case TargetOpcode::G_IMPLICIT_DEF: {
754 while (!NewInstrs.
empty()) {
759 if (
auto *Unmerge = dyn_cast<GUnmerge>(NewMI))
763 else if (NewMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES)
771 case TargetOpcode::G_UNMERGE_VALUES:
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common code to allow clients to notify changes to machine instr.
unsigned const TargetRegisterInfo * TRI
static const MipsRegisterBankInfo::ValueMapping * getGprbOrCustomMapping(unsigned Size, unsigned &MappingID)
static bool isFloatingPointOpcodeUse(unsigned Opc)
static bool isFloatingPointOpcode(unsigned Opc)
static bool isFloatingPointOpcodeDef(unsigned Opc)
static const MipsRegisterBankInfo::ValueMapping * getMSAMapping(const MachineFunction &MF)
static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI)
static bool isAmbiguous(unsigned Opc)
static const unsigned CustomMappingID
static const MipsRegisterBankInfo::ValueMapping * getFprbMapping(unsigned Size)
static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, GUnmerge &MI, GISelChangeObserver &Observer)
This file declares the targeting of the RegisterBankInfo class for Mips.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an Operation in the Expression.
Abstract class that contains various methods for clients to notify about changes.
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
MachineInstr * pop_back_val()
Represents a G_UNMERGE_VALUES.
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
bool tryCombineUnmergeValues(GUnmerge &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelChangeObserver &Observer)
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void applyMappingImpl(MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const override
Here we have to narrowScalar s64 operands to s32, combine away G_MERGE or G_UNMERGE and erase instruc...
MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const
RegBankSelect determined that s64 operand is better to be split into two s32 operands in gprb.
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
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...
MachineInstr & getMI() const
MachineRegisterInfo & getMRI() const
The MachineRegisterInfo we used to realize the mapping.
Holds all the information related to register banks.
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
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.
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.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
virtual const LegalizerInfo * getLegalizerInfo() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
RegisterBankInfo::PartialMapping PartMappings[]
RegisterBankInfo::ValueMapping ValueMappings[]
This is an optimization pass for GlobalISel generic memory operations.
Helper struct that represents how a value is partially mapped into a register.
Helper struct that represents how a value is mapped through different register banks.