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:
111 case TargetOpcode::G_FPTOSI:
112 case TargetOpcode::G_FPTOUI:
113 case TargetOpcode::G_FCMP:
124 case TargetOpcode::G_SITOFP:
125 case TargetOpcode::G_UITOFP:
133 if (
MI->getOpcode() == TargetOpcode::G_LOAD ||
134 MI->getOpcode() == TargetOpcode::G_STORE) {
135 auto MMO = *
MI->memoperands_begin();
138 (!MMO->getSize().hasValue() ||
139 MMO->getAlign() < MMO->getSize().getValue())))
147 case TargetOpcode::G_LOAD:
148 case TargetOpcode::G_STORE:
149 case TargetOpcode::G_PHI:
150 case TargetOpcode::G_SELECT:
151 case TargetOpcode::G_IMPLICIT_DEF:
152 case TargetOpcode::G_UNMERGE_VALUES:
153 case TargetOpcode::G_MERGE_VALUES:
160void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
163 "Pointers are gprb, they should not be considered as ambiguous.\n");
167 if (NonCopyInstr->
getOpcode() == TargetOpcode::COPY &&
171 DefUses.push_back(skipCopiesOutgoing(&
UseMI));
175void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
178 "Pointers are gprb, they should not be considered as ambiguous.\n");
180 UseDefs.push_back(skipCopiesIncoming(
DefMI));
184MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
189 while (
Ret->getOpcode() == TargetOpcode::COPY &&
190 !
Ret->getOperand(0).getReg().isPhysical() &&
191 MRI.hasOneUse(
Ret->getOperand(0).getReg())) {
192 Ret = &(*
MRI.use_instr_begin(
Ret->getOperand(0).getReg()));
198MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
203 while (
Ret->getOpcode() == TargetOpcode::COPY &&
204 !
Ret->getOperand(1).getReg().isPhysical())
205 Ret =
MRI.getVRegDef(
Ret->getOperand(1).getReg());
209MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
212 "Not implemented for non Ambiguous opcode.\n");
216 if (
MI->getOpcode() == TargetOpcode::G_LOAD)
217 addDefUses(
MI->getOperand(0).getReg(),
MRI);
219 if (
MI->getOpcode() == TargetOpcode::G_STORE)
220 addUseDef(
MI->getOperand(0).getReg(),
MRI);
222 if (
auto *
PHI = dyn_cast<GPhi>(
MI)) {
223 addDefUses(
PHI->getReg(0),
MRI);
225 for (
unsigned I = 1;
I <
PHI->getNumIncomingValues(); ++
I)
226 addUseDef(
PHI->getIncomingValue(
I),
MRI);
229 if (
MI->getOpcode() == TargetOpcode::G_SELECT) {
230 addDefUses(
MI->getOperand(0).getReg(),
MRI);
232 addUseDef(
MI->getOperand(2).getReg(),
MRI);
233 addUseDef(
MI->getOperand(3).getReg(),
MRI);
236 if (
MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
237 addDefUses(
MI->getOperand(0).getReg(),
MRI);
239 if (
MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
240 addUseDef(
MI->getOperand(
MI->getNumOperands() - 1).getReg(),
MRI);
242 if (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
243 addDefUses(
MI->getOperand(0).getReg(),
MRI);
246bool MipsRegisterBankInfo::TypeInfoForMF::visit(
248 InstType &AmbiguousTy) {
254 AmbiguousRegDefUseContainer DefUseContainer(
MI);
261 if (AmbiguousTy == InstType::Ambiguous &&
262 (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
263 MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
264 AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
267 if (visitAdjacentInstrs(
MI, DefUseContainer.getDefUses(),
true, AmbiguousTy))
271 if (visitAdjacentInstrs(
MI, DefUseContainer.getUseDefs(),
false, AmbiguousTy))
275 if (!WaitingForTypeOfMI) {
277 setTypes(
MI, AmbiguousTy);
288 addToWaitingQueue(WaitingForTypeOfMI,
MI);
292bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
294 bool isDefUse, InstType &AmbiguousTy) {
295 while (!AdjacentInstrs.
empty()) {
300 setTypes(
MI, InstType::FloatingPoint);
306 if (AdjMI->
getOpcode() == TargetOpcode::COPY) {
307 setTypesAccordingToPhysicalRegister(
MI, AdjMI, isDefUse ? 0 : 1);
313 if ((!isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
314 (isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
316 setTypes(
MI, InstType::Integer);
322 if (!wasVisited(AdjMI) ||
323 getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
324 if (visit(AdjMI,
MI, AmbiguousTy)) {
326 setTypes(
MI, getRecordedTypeForInstr(AdjMI));
334void MipsRegisterBankInfo::TypeInfoForMF::setTypes(
const MachineInstr *
MI,
336 changeRecordedTypeForInstr(
MI, InstTy);
338 setTypes(WaitingInstr, InstTy);
342void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
345 "Copies of non physical registers should not be considered here.\n");
355 if (Bank == &Mips::FPRBRegBank)
356 setTypes(
MI, InstType::FloatingPoint);
357 else if (Bank == &Mips::GPRBRegBank)
358 setTypes(
MI, InstType::Integer);
363MipsRegisterBankInfo::InstType
364MipsRegisterBankInfo::TypeInfoForMF::determineInstType(
const MachineInstr *
MI) {
365 InstType DefaultAmbiguousType = InstType::Ambiguous;
366 visit(
MI,
nullptr, DefaultAmbiguousType);
367 return getRecordedTypeForInstr(
MI);
370void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
372 if (MFName != FunctionName) {
373 MFName = std::string(FunctionName);
374 WaitingQueues.clear();
382 "MSA mapping not available on target without MSA.");
407 static TypeInfoForMF TI;
410 TI.cleanupIfNewFunction(
MI.getMF()->getName());
412 unsigned Opc =
MI.getOpcode();
416 if (
MI.getOpcode() != TargetOpcode::G_PHI) {
423 using namespace TargetOpcode;
425 unsigned NumOperands =
MI.getNumOperands();
432 LLT RegTy =
MRI.getType(
Op.getReg());
443 const LLT Op0Ty =
MRI.getType(
MI.getOperand(0).getReg());
445 InstType InstTy = InstType::Integer;
480 if (Op0Size == 128) {
487 InstTy = TI.determineInstType(&
MI);
489 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
490 isAmbiguous_64(InstTy, Op0Size)) {
494 assert((isInteger_32(InstTy, Op0Size) ||
495 isAmbiguous_32(InstTy, Op0Size) ||
496 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
497 "Unexpected Inst type");
507 InstTy = TI.determineInstType(&
MI);
510 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
513 TI.clearTypeInfoData(&
MI);
517 assert((isInteger_32(InstTy, Op0Size) ||
518 isFloatingPoint_32or64(InstTy, Op0Size) ||
519 isAmbiguous_32or64(InstTy, Op0Size)) &&
520 "Unexpected Inst type");
527 InstTy = TI.determineInstType(&
MI);
528 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
529 isAmbiguous_64(InstTy, Op0Size)) {
535 assert((isInteger_32(InstTy, Op0Size) ||
536 isAmbiguous_32(InstTy, Op0Size) ||
537 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
538 "Unexpected Inst type");
546 case G_IMPLICIT_DEF: {
548 InstTy = TI.determineInstType(&
MI);
550 if (isFloatingPoint_32or64(InstTy, Op0Size))
553 assert((isInteger_32(InstTy, Op0Size) ||
554 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
555 "Unexpected Inst type");
559 case G_UNMERGE_VALUES: {
560 assert(
MI.getNumOperands() == 3 &&
"Unsupported G_UNMERGE_VALUES");
561 unsigned Op3Size =
MRI.getType(
MI.getOperand(2).getReg()).getSizeInBits();
562 InstTy = TI.determineInstType(&
MI);
563 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
564 isFloatingPoint_64(InstTy, Op3Size)) &&
565 "Unexpected Inst type");
569 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
573 case G_MERGE_VALUES: {
574 InstTy = TI.determineInstType(&
MI);
575 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
576 isFloatingPoint_64(InstTy, Op0Size)) &&
577 "Unexpected Inst type");
581 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
614 assert((Op0Size == 32) &&
"Unsupported integer size");
615 unsigned SizeFP =
MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits();
621 assert((
MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
622 "Unsupported integer size");
650 TI.clearTypeInfoData(&
MI);
663 assert(!
B.isObservingChanges());
664 B.setChangeObserver(*
this);
667 ~InstManager() {
B.stopObservingChanges(); }
679 switch (
MI.getOpcode()) {
680 case TargetOpcode::G_STORE:
683 case TargetOpcode::G_CONSTANT:
684 case TargetOpcode::G_LOAD:
685 case TargetOpcode::G_SELECT:
686 case TargetOpcode::G_PHI:
687 case TargetOpcode::G_IMPLICIT_DEF: {
692 case TargetOpcode::G_PTR_ADD: {
693 assert(
MRI.getType(Dest).isPointer() &&
"Unexpected operand type.");
708 UpdatedDefs, Observer);
710 DeadMI->eraseFromParent();
723 InstManager NewInstrObserver(Builder, NewInstrs);
727 switch (
MI.getOpcode()) {
728 case TargetOpcode::G_LOAD:
729 case TargetOpcode::G_STORE:
730 case TargetOpcode::G_PHI:
731 case TargetOpcode::G_SELECT:
732 case TargetOpcode::G_IMPLICIT_DEF: {
735 while (!NewInstrs.
empty()) {
740 if (
auto *Unmerge = dyn_cast<GUnmerge>(NewMI))
744 else if (NewMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES)
752 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 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.
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
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.
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.
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.
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.
const RegisterBankInfo::ValueMapping ValueMappings[]
const RegisterBankInfo::PartialMapping PartMappings[]
This is an optimization pass for GlobalISel generic memory operations.
bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
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.