21#define GET_TARGET_REGBANK_IMPL
23#include "MipsGenRegisterBank.inc"
40 {0, 128, FPRBRegBank}};
86 case TargetOpcode::G_FPTOSI:
87 case TargetOpcode::G_FPTOUI:
88 case TargetOpcode::G_FCMP:
99 case TargetOpcode::G_SITOFP:
100 case TargetOpcode::G_UITOFP:
108 if (
MI->getOpcode() == TargetOpcode::G_LOAD ||
109 MI->getOpcode() == TargetOpcode::G_STORE) {
110 auto MMO = *
MI->memoperands_begin();
113 (!MMO->getSize().hasValue() ||
114 MMO->getAlign() < MMO->getSize().getValue())))
122 case TargetOpcode::G_LOAD:
123 case TargetOpcode::G_STORE:
124 case TargetOpcode::G_PHI:
125 case TargetOpcode::G_SELECT:
126 case TargetOpcode::G_IMPLICIT_DEF:
127 case TargetOpcode::G_UNMERGE_VALUES:
128 case TargetOpcode::G_MERGE_VALUES:
135void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
138 "Pointers are gprb, they should not be considered as ambiguous.\n");
139 for (MachineInstr &
UseMI :
MRI.use_instructions(
Reg)) {
140 MachineInstr *NonCopyInstr = skipCopiesOutgoing(&
UseMI);
142 if (NonCopyInstr->
getOpcode() == TargetOpcode::COPY &&
146 DefUses.push_back(skipCopiesOutgoing(&
UseMI));
150void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
153 "Pointers are gprb, they should not be considered as ambiguous.\n");
155 UseDefs.push_back(skipCopiesIncoming(
DefMI));
159MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
160 MachineInstr *
MI)
const {
161 const MachineFunction &MF = *
MI->getParent()->getParent();
163 MachineInstr *Ret =
MI;
164 while (Ret->
getOpcode() == TargetOpcode::COPY &&
173MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
174 MachineInstr *
MI)
const {
175 const MachineFunction &MF = *
MI->getParent()->getParent();
177 MachineInstr *Ret =
MI;
178 while (Ret->
getOpcode() == TargetOpcode::COPY &&
184MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
185 const MachineInstr *
MI) {
187 "Not implemented for non Ambiguous opcode.\n");
189 const MachineRegisterInfo &
MRI =
MI->getMF()->getRegInfo();
191 if (
MI->getOpcode() == TargetOpcode::G_LOAD)
192 addDefUses(
MI->getOperand(0).getReg(),
MRI);
194 if (
MI->getOpcode() == TargetOpcode::G_STORE)
195 addUseDef(
MI->getOperand(0).getReg(),
MRI);
198 addDefUses(
PHI->getReg(0),
MRI);
200 for (
unsigned I = 1;
I <
PHI->getNumIncomingValues(); ++
I)
201 addUseDef(
PHI->getIncomingValue(
I),
MRI);
204 if (
MI->getOpcode() == TargetOpcode::G_SELECT) {
205 addDefUses(
MI->getOperand(0).getReg(),
MRI);
207 addUseDef(
MI->getOperand(2).getReg(),
MRI);
208 addUseDef(
MI->getOperand(3).getReg(),
MRI);
211 if (
MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
212 addDefUses(
MI->getOperand(0).getReg(),
MRI);
214 if (
MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
215 addUseDef(
MI->getOperand(
MI->getNumOperands() - 1).getReg(),
MRI);
217 if (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
218 addDefUses(
MI->getOperand(0).getReg(),
MRI);
221bool MipsRegisterBankInfo::TypeInfoForMF::visit(
222 const MachineInstr *
MI,
const MachineInstr *WaitingForTypeOfMI,
223 InstType &AmbiguousTy) {
229 AmbiguousRegDefUseContainer DefUseContainer(
MI);
232 setTypes(
MI, Integer);
236 if (AmbiguousTy == InstType::Ambiguous &&
237 (
MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
238 MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
239 AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
242 if (visitAdjacentInstrs(
MI, DefUseContainer.getDefUses(),
true, AmbiguousTy))
246 if (visitAdjacentInstrs(
MI, DefUseContainer.getUseDefs(),
false, AmbiguousTy))
250 if (!WaitingForTypeOfMI) {
252 setTypes(
MI, AmbiguousTy);
263 addToWaitingQueue(WaitingForTypeOfMI,
MI);
267bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
268 const MachineInstr *
MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
269 bool isDefUse, InstType &AmbiguousTy) {
270 while (!AdjacentInstrs.
empty()) {
275 setTypes(
MI, InstType::FloatingPoint);
281 if (AdjMI->
getOpcode() == TargetOpcode::COPY) {
282 setTypesAccordingToPhysicalRegister(
MI, AdjMI, isDefUse ? 0 : 1);
288 if ((!isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
289 (isDefUse && AdjMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
291 setTypes(
MI, InstType::Integer);
297 if (!wasVisited(AdjMI) ||
298 getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
299 if (
visit(AdjMI,
MI, AmbiguousTy)) {
301 setTypes(
MI, getRecordedTypeForInstr(AdjMI));
309void MipsRegisterBankInfo::TypeInfoForMF::setTypes(
const MachineInstr *
MI,
311 changeRecordedTypeForInstr(
MI, InstTy);
312 for (
const MachineInstr *WaitingInstr : getWaitingQueueFor(
MI)) {
313 setTypes(WaitingInstr, InstTy);
317void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
318 const MachineInstr *
MI,
const MachineInstr *CopyInst,
unsigned Op) {
320 "Copies of non physical registers should not be considered here.\n");
322 const MachineFunction &MF = *CopyInst->
getMF();
327 const RegisterBank *Bank =
330 if (Bank == &Mips::FPRBRegBank)
331 setTypes(
MI, InstType::FloatingPoint);
332 else if (Bank == &Mips::GPRBRegBank)
333 setTypes(
MI, InstType::Integer);
338MipsRegisterBankInfo::InstType
339MipsRegisterBankInfo::TypeInfoForMF::determineInstType(
const MachineInstr *
MI) {
340 InstType DefaultAmbiguousType = InstType::Ambiguous;
341 visit(
MI,
nullptr, DefaultAmbiguousType);
342 return getRecordedTypeForInstr(
MI);
345void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
346 llvm::StringRef FunctionName) {
347 if (MFName != FunctionName) {
348 MFName = std::string(FunctionName);
349 WaitingQueues.clear();
354static const MipsRegisterBankInfo::ValueMapping *
357 "MSA mapping not available on target without MSA.");
379const RegisterBankInfo::InstructionMapping &
382 static TypeInfoForMF TI;
385 TI.cleanupIfNewFunction(
MI.getMF()->getName());
387 unsigned Opc =
MI.getOpcode();
391 if (
MI.getOpcode() != TargetOpcode::G_PHI) {
400 unsigned NumOperands =
MI.getNumOperands();
403 assert((GPRSize == 32 || GPRSize == 64) &&
"Unexpected GPR size");
412 LLT RegTy =
MRI.getType(
Op.getReg());
423 const LLT Op0Ty =
MRI.getType(
MI.getOperand(0).getReg());
425 InstType InstTy = InstType::Integer;
445 OperandsMapping = GPRValueMapping;
454 OperandsMapping = GPRValueMapping;
460 if (Op0Size == 128) {
467 InstTy = TI.determineInstType(&
MI);
469 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
470 isAmbiguous_64(InstTy, Op0Size)) {
473 }
else if (InstTy == InstType::Integer) {
476 assert((isAmbiguous_32(InstTy, Op0Size) ||
477 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
478 "Unexpected Inst type");
487 InstTy = TI.determineInstType(&
MI);
490 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
493 TI.clearTypeInfoData(&
MI);
497 assert((isInteger_32(InstTy, Op0Size) || isInteger_64(InstTy, Op0Size) ||
498 isFloatingPoint_32or64(InstTy, Op0Size) ||
499 isAmbiguous_32or64(InstTy, Op0Size)) &&
500 "Unexpected Inst type");
507 InstTy = TI.determineInstType(&
MI);
509 if (isFloatingPoint_32or64(InstTy, Op0Size) ||
510 isAmbiguous_64(InstTy, Op0Size)) {
514 }
else if (InstTy == InstType::Integer) {
516 {GPRValueMapping, GPRValueMapping, GPRValueMapping, GPRValueMapping});
518 assert((isAmbiguous_32(InstTy, Op0Size) ||
519 isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
520 "Unexpected Inst type");
527 case G_IMPLICIT_DEF: {
529 InstTy = TI.determineInstType(&
MI);
531 if (isFloatingPoint_32or64(InstTy, Op0Size))
533 else if (InstTy == InstType::Integer) {
534 OperandsMapping = GPRValueMapping;
536 assert(isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) &&
537 "Unexpected Inst type");
541 case G_UNMERGE_VALUES: {
542 assert(
MI.getNumOperands() == 3 &&
"Unsupported G_UNMERGE_VALUES");
543 unsigned Op3Size =
MRI.getType(
MI.getOperand(2).getReg()).getSizeInBits();
544 InstTy = TI.determineInstType(&
MI);
545 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
546 isFloatingPoint_64(InstTy, Op3Size)) &&
547 "Unexpected Inst type");
550 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
554 case G_MERGE_VALUES: {
555 InstTy = TI.determineInstType(&
MI);
556 assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
557 isFloatingPoint_64(InstTy, Op0Size)) &&
558 "Unexpected Inst type");
561 if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
579 unsigned Op2Size =
MRI.getType(
MI.getOperand(2).getReg()).getSizeInBits();
594 unsigned SizeFP =
MRI.getType(
MI.getOperand(1).getReg()).getSizeInBits();
616 {GPRValueMapping,
nullptr, GPRValueMapping, GPRValueMapping});
623 TI.clearTypeInfoData(&
MI);
636 assert(!
B.isObservingChanges());
637 B.setChangeObserver(*
this);
640 ~InstManager()
override {
B.stopObservingChanges(); }
652 switch (
MI.getOpcode()) {
653 case TargetOpcode::G_STORE:
656 case TargetOpcode::G_CONSTANT:
657 case TargetOpcode::G_LOAD:
658 case TargetOpcode::G_SELECT:
659 case TargetOpcode::G_PHI:
660 case TargetOpcode::G_IMPLICIT_DEF: {
665 case TargetOpcode::G_PTR_ADD: {
666 assert(
MRI.getType(Dest).isPointer() &&
"Unexpected operand type.");
681 UpdatedDefs, Observer);
683 DeadMI->eraseFromParent();
689 Builder.setInstrAndDebugLoc(
MI);
696 InstManager NewInstrObserver(Builder, NewInstrs);
700 switch (
MI.getOpcode()) {
701 case TargetOpcode::G_LOAD:
702 case TargetOpcode::G_STORE:
703 case TargetOpcode::G_PHI:
704 case TargetOpcode::G_SELECT:
705 case TargetOpcode::G_IMPLICIT_DEF: {
708 while (!NewInstrs.
empty()) {
717 else if (NewMI->
getOpcode() == TargetOpcode::G_MERGE_VALUES)
725 case TargetOpcode::G_UNMERGE_VALUES:
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const unsigned CustomMappingID
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common code to allow clients to notify changes to machine instr.
GISelWorkList< 256 > InstListTy
Register const TargetRegisterInfo * TRI
Promote Memory to Register
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 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.
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
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)
LLVM_ABI 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.
LLVM_ABI 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.
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.
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.
RegisterBankInfo(const RegisterBank **RegBanks, unsigned NumRegBanks, const unsigned *Sizes, unsigned HwMode)
Create a RegisterBankInfo that can accommodate up to NumRegBanks RegisterBank instances.
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.
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 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...
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
virtual const LegalizerInfo * getLegalizerInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const RegisterBankInfo::ValueMapping ValueMappings[]
const RegisterBankInfo::PartialMapping PartMappings[]
Invariant opcodes: All instruction sets have these as their low opcodes.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
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.