LLVM  15.0.0git
MipsRegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the RegisterBankInfo class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsRegisterBankInfo.h"
14 #include "MipsInstrInfo.h"
15 #include "MipsTargetMachine.h"
20 
21 #define GET_TARGET_REGBANK_IMPL
22 
23 #include "MipsGenRegisterBank.inc"
24 
25 namespace llvm {
26 namespace Mips {
33 };
34 
36  {0, 32, GPRBRegBank},
37  {0, 32, FPRBRegBank},
38  {0, 64, FPRBRegBank},
39  {0, 128, FPRBRegBank}
40 };
41 
44  GPRIdx = 1,
45  SPRIdx = 4,
46  DPRIdx = 7,
47  MSAIdx = 10
48 };
49 
51  // invalid
52  {nullptr, 0},
53  // up to 3 operands in GPRs
54  {&PartMappings[PMI_GPR - PMI_Min], 1},
55  {&PartMappings[PMI_GPR - PMI_Min], 1},
56  {&PartMappings[PMI_GPR - PMI_Min], 1},
57  // up to 3 operands in FPRs - single precission
58  {&PartMappings[PMI_SPR - PMI_Min], 1},
59  {&PartMappings[PMI_SPR - PMI_Min], 1},
60  {&PartMappings[PMI_SPR - PMI_Min], 1},
61  // up to 3 operands in FPRs - double precission
62  {&PartMappings[PMI_DPR - PMI_Min], 1},
63  {&PartMappings[PMI_DPR - PMI_Min], 1},
64  {&PartMappings[PMI_DPR - PMI_Min], 1},
65  // up to 3 operands in FPRs - MSA
66  {&PartMappings[PMI_MSA - PMI_Min], 1},
67  {&PartMappings[PMI_MSA - PMI_Min], 1},
69 };
70 
71 } // end namespace Mips
72 } // end namespace llvm
73 
74 using namespace llvm;
75 
77 
78 const RegisterBank &
80  LLT) const {
81  using namespace Mips;
82 
83  switch (RC.getID()) {
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:
92  return getRegBank(Mips::GPRBRegBankID);
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:
101  return getRegBank(Mips::FPRBRegBankID);
102  default:
103  llvm_unreachable("Register class not supported");
104  }
105 }
106 
107 // Instructions where all register operands are floating point.
108 static bool isFloatingPointOpcode(unsigned Opc) {
109  switch (Opc) {
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:
121  return true;
122  default:
123  return false;
124  }
125 }
126 
127 // Instructions where use operands are floating point registers.
128 // Def operands are general purpose.
129 static bool isFloatingPointOpcodeUse(unsigned Opc) {
130  switch (Opc) {
131  case TargetOpcode::G_FPTOSI:
132  case TargetOpcode::G_FPTOUI:
133  case TargetOpcode::G_FCMP:
134  return true;
135  default:
136  return isFloatingPointOpcode(Opc);
137  }
138 }
139 
140 // Instructions where def operands are floating point registers.
141 // Use operands are general purpose.
142 static bool isFloatingPointOpcodeDef(unsigned Opc) {
143  switch (Opc) {
144  case TargetOpcode::G_SITOFP:
145  case TargetOpcode::G_UITOFP:
146  return true;
147  default:
148  return isFloatingPointOpcode(Opc);
149  }
150 }
151 
153  if (MI->getOpcode() == TargetOpcode::G_LOAD ||
154  MI->getOpcode() == TargetOpcode::G_STORE) {
155  auto MMO = *MI->memoperands_begin();
156  const MipsSubtarget &STI =
157  static_cast<const MipsSubtarget &>(MI->getMF()->getSubtarget());
158  if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() &&
159  MMO->getAlign() < MMO->getSize()))
160  return true;
161  }
162  return false;
163 }
164 
165 static bool isAmbiguous(unsigned Opc) {
166  switch (Opc) {
167  case TargetOpcode::G_LOAD:
168  case TargetOpcode::G_STORE:
169  case TargetOpcode::G_PHI:
170  case TargetOpcode::G_SELECT:
171  case TargetOpcode::G_IMPLICIT_DEF:
172  case TargetOpcode::G_UNMERGE_VALUES:
173  case TargetOpcode::G_MERGE_VALUES:
174  return true;
175  default:
176  return false;
177  }
178 }
179 
180 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
183  "Pointers are gprb, they should not be considered as ambiguous.\n");
185  MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
186  // Copy with many uses.
187  if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
188  !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg()))
189  addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
190  else
191  DefUses.push_back(skipCopiesOutgoing(&UseMI));
192  }
193 }
194 
195 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
198  "Pointers are gprb, they should not be considered as ambiguous.\n");
200  UseDefs.push_back(skipCopiesIncoming(DefMI));
201 }
202 
203 MachineInstr *
204 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
205  MachineInstr *MI) const {
206  const MachineFunction &MF = *MI->getParent()->getParent();
207  const MachineRegisterInfo &MRI = MF.getRegInfo();
208  MachineInstr *Ret = MI;
209  while (Ret->getOpcode() == TargetOpcode::COPY &&
210  !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) &&
211  MRI.hasOneUse(Ret->getOperand(0).getReg())) {
212  Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
213  }
214  return Ret;
215 }
216 
217 MachineInstr *
218 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
219  MachineInstr *MI) const {
220  const MachineFunction &MF = *MI->getParent()->getParent();
221  const MachineRegisterInfo &MRI = MF.getRegInfo();
222  MachineInstr *Ret = MI;
223  while (Ret->getOpcode() == TargetOpcode::COPY &&
224  !Register::isPhysicalRegister(Ret->getOperand(1).getReg()))
225  Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
226  return Ret;
227 }
228 
229 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
230  const MachineInstr *MI) {
231  assert(isAmbiguous(MI->getOpcode()) &&
232  "Not implemented for non Ambiguous opcode.\n");
233 
234  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
235 
236  if (MI->getOpcode() == TargetOpcode::G_LOAD)
237  addDefUses(MI->getOperand(0).getReg(), MRI);
238 
239  if (MI->getOpcode() == TargetOpcode::G_STORE)
240  addUseDef(MI->getOperand(0).getReg(), MRI);
241 
242  if (MI->getOpcode() == TargetOpcode::G_PHI) {
243  addDefUses(MI->getOperand(0).getReg(), MRI);
244 
245  for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
246  addUseDef(MI->getOperand(i).getReg(), MRI);
247  }
248 
249  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
250  addDefUses(MI->getOperand(0).getReg(), MRI);
251 
252  addUseDef(MI->getOperand(2).getReg(), MRI);
253  addUseDef(MI->getOperand(3).getReg(), MRI);
254  }
255 
256  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
257  addDefUses(MI->getOperand(0).getReg(), MRI);
258 
259  if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
260  addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);
261 
262  if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
263  addDefUses(MI->getOperand(0).getReg(), MRI);
264 }
265 
266 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
267  const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
268  InstType &AmbiguousTy) {
269  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
270  if (wasVisited(MI))
271  return true; // InstType has already been determined for MI.
272 
273  startVisit(MI);
274  AmbiguousRegDefUseContainer DefUseContainer(MI);
275 
277  setTypes(MI, Integer);
278  return true;
279  }
280 
281  if (AmbiguousTy == InstType::Ambiguous &&
282  (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
283  MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
284  AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
285 
286  // Visit instructions where MI's DEF operands are USED.
287  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
288  return true;
289 
290  // Visit instructions that DEFINE MI's USE operands.
291  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
292  return true;
293 
294  // All MI's adjacent instructions, are ambiguous.
295  if (!WaitingForTypeOfMI) {
296  // This is chain of ambiguous instructions.
297  setTypes(MI, AmbiguousTy);
298  return true;
299  }
300  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
301  // instructions or has no other adjacent instructions. Anyway InstType could
302  // not be determined. There could be unexplored path from some of
303  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
304  // mapping available.
305  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
306  // this way when WaitingForTypeOfMI figures out its InstType same InstType
307  // will be assigned to all instructions in this branch.
308  addToWaitingQueue(WaitingForTypeOfMI, MI);
309  return false;
310 }
311 
312 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
313  const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
314  bool isDefUse, InstType &AmbiguousTy) {
315  while (!AdjacentInstrs.empty()) {
316  MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
317 
318  if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
319  : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
320  setTypes(MI, InstType::FloatingPoint);
321  return true;
322  }
323 
324  // Determine InstType from register bank of phys register that is
325  // 'isDefUse ? def : use' of this copy.
326  if (AdjMI->getOpcode() == TargetOpcode::COPY) {
327  setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
328  return true;
329  }
330 
331  // Defaults to integer instruction. Small registers in G_MERGE (uses) and
332  // G_UNMERGE (defs) will always be gprb.
333  if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
334  (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
335  !isAmbiguous(AdjMI->getOpcode())) {
336  setTypes(MI, InstType::Integer);
337  return true;
338  }
339 
340  // When AdjMI was visited first, MI has to continue to explore remaining
341  // adjacent instructions and determine InstType without visiting AdjMI.
342  if (!wasVisited(AdjMI) ||
343  getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
344  if (visit(AdjMI, MI, AmbiguousTy)) {
345  // InstType is successfully determined and is same as for AdjMI.
346  setTypes(MI, getRecordedTypeForInstr(AdjMI));
347  return true;
348  }
349  }
350  }
351  return false;
352 }
353 
354 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
355  InstType InstTy) {
356  changeRecordedTypeForInstr(MI, InstTy);
357  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
358  setTypes(WaitingInstr, InstTy);
359  }
360 }
361 
362 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
363  const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
365  "Copies of non physical registers should not be considered here.\n");
366 
367  const MachineFunction &MF = *CopyInst->getMF();
368  const MachineRegisterInfo &MRI = MF.getRegInfo();
370  const RegisterBankInfo &RBI =
371  *CopyInst->getMF()->getSubtarget().getRegBankInfo();
372  const RegisterBank *Bank =
373  RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
374 
375  if (Bank == &Mips::FPRBRegBank)
376  setTypes(MI, InstType::FloatingPoint);
377  else if (Bank == &Mips::GPRBRegBank)
378  setTypes(MI, InstType::Integer);
379  else
380  llvm_unreachable("Unsupported register bank.\n");
381 }
382 
383 MipsRegisterBankInfo::InstType
384 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
385  InstType DefaultAmbiguousType = InstType::Ambiguous;
386  visit(MI, nullptr, DefaultAmbiguousType);
387  return getRecordedTypeForInstr(MI);
388 }
389 
390 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
391  llvm::StringRef FunctionName) {
392  if (MFName != FunctionName) {
393  MFName = std::string(FunctionName);
394  WaitingQueues.clear();
395  Types.clear();
396  }
397 }
398 
399 static const MipsRegisterBankInfo::ValueMapping *
401  assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() &&
402  "MSA mapping not available on target without MSA.");
404 }
405 
406 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
407  return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
409 }
410 
411 static const unsigned CustomMappingID = 1;
412 
413 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
414 // will be split into two 32 bit registers in gprb.
415 static const MipsRegisterBankInfo::ValueMapping *
416 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
417  if (Size == 32)
419 
420  MappingID = CustomMappingID;
422 }
423 
426 
427  static TypeInfoForMF TI;
428 
429  // Reset TI internal data when MF changes.
430  TI.cleanupIfNewFunction(MI.getMF()->getName());
431 
432  unsigned Opc = MI.getOpcode();
433  const MachineFunction &MF = *MI.getParent()->getParent();
434  const MachineRegisterInfo &MRI = MF.getRegInfo();
435 
436  if (MI.getOpcode() != TargetOpcode::G_PHI) {
437  const RegisterBankInfo::InstructionMapping &Mapping =
439  if (Mapping.isValid())
440  return Mapping;
441  }
442 
443  using namespace TargetOpcode;
444 
445  unsigned NumOperands = MI.getNumOperands();
446  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
447  unsigned MappingID = DefaultMappingID;
448 
449  // Check if LLT sizes match sizes of available register banks.
450  for (const MachineOperand &Op : MI.operands()) {
451  if (Op.isReg()) {
452  LLT RegTy = MRI.getType(Op.getReg());
453 
454  if (RegTy.isScalar() &&
455  (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
457 
458  if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
460  }
461  }
462 
463  const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
464  unsigned Op0Size = Op0Ty.getSizeInBits();
465  InstType InstTy = InstType::Integer;
466 
467  switch (Opc) {
468  case G_TRUNC:
469  case G_UMULH:
470  case G_ZEXTLOAD:
471  case G_SEXTLOAD:
472  case G_PTR_ADD:
473  case G_INTTOPTR:
474  case G_PTRTOINT:
475  case G_AND:
476  case G_OR:
477  case G_XOR:
478  case G_SHL:
479  case G_ASHR:
480  case G_LSHR:
481  case G_BRINDIRECT:
482  case G_VASTART:
483  case G_BSWAP:
484  case G_CTLZ:
485  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
486  break;
487  case G_ADD:
488  case G_SUB:
489  case G_MUL:
490  case G_SDIV:
491  case G_SREM:
492  case G_UDIV:
493  case G_UREM:
494  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
495  if (Op0Size == 128)
496  OperandsMapping = getMSAMapping(MF);
497  break;
498  case G_STORE:
499  case G_LOAD: {
500  if (Op0Size == 128) {
501  OperandsMapping = getOperandsMapping(
503  break;
504  }
505 
506  if (!Op0Ty.isPointer())
507  InstTy = TI.determineInstType(&MI);
508 
509  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
510  isAmbiguous_64(InstTy, Op0Size)) {
511  OperandsMapping = getOperandsMapping(
513  } else {
514  assert((isInteger_32(InstTy, Op0Size) ||
515  isAmbiguous_32(InstTy, Op0Size) ||
516  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
517  "Unexpected Inst type");
518  OperandsMapping =
519  getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
521  }
522 
523  break;
524  }
525  case G_PHI: {
526  if (!Op0Ty.isPointer())
527  InstTy = TI.determineInstType(&MI);
528 
529  // PHI is copylike and should have one regbank in mapping for def register.
530  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
531  OperandsMapping =
533  TI.clearTypeInfoData(&MI);
534  return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
535  /*NumOperands=*/1);
536  }
537  assert((isInteger_32(InstTy, Op0Size) ||
538  isFloatingPoint_32or64(InstTy, Op0Size) ||
539  isAmbiguous_32or64(InstTy, Op0Size)) &&
540  "Unexpected Inst type");
541  // Use default handling for PHI, i.e. set reg bank of def operand to match
542  // register banks of use operands.
543  return getInstrMappingImpl(MI);
544  }
545  case G_SELECT: {
546  if (!Op0Ty.isPointer())
547  InstTy = TI.determineInstType(&MI);
548  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
549  isAmbiguous_64(InstTy, Op0Size)) {
550  const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
551  OperandsMapping = getOperandsMapping(
552  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
553  break;
554  } else {
555  assert((isInteger_32(InstTy, Op0Size) ||
556  isAmbiguous_32(InstTy, Op0Size) ||
557  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
558  "Unexpected Inst type");
559  const RegisterBankInfo::ValueMapping *Bank =
560  getGprbOrCustomMapping(Op0Size, MappingID);
561  OperandsMapping = getOperandsMapping(
562  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
563  }
564  break;
565  }
566  case G_IMPLICIT_DEF: {
567  if (!Op0Ty.isPointer())
568  InstTy = TI.determineInstType(&MI);
569 
570  if (isFloatingPoint_32or64(InstTy, Op0Size))
571  OperandsMapping = getFprbMapping(Op0Size);
572  else {
573  assert((isInteger_32(InstTy, Op0Size) ||
574  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
575  "Unexpected Inst type");
576  OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
577  }
578  } break;
579  case G_UNMERGE_VALUES: {
580  assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES");
581  unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
582  InstTy = TI.determineInstType(&MI);
583  assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
584  isFloatingPoint_64(InstTy, Op3Size)) &&
585  "Unexpected Inst type");
589  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
590  MappingID = CustomMappingID;
591  break;
592  }
593  case G_MERGE_VALUES: {
594  InstTy = TI.determineInstType(&MI);
595  assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
596  isFloatingPoint_64(InstTy, Op0Size)) &&
597  "Unexpected Inst type");
601  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
602  MappingID = CustomMappingID;
603  break;
604  }
605  case G_FADD:
606  case G_FSUB:
607  case G_FMUL:
608  case G_FDIV:
609  case G_FABS:
610  case G_FSQRT:
611  OperandsMapping = getFprbMapping(Op0Size);
612  if (Op0Size == 128)
613  OperandsMapping = getMSAMapping(MF);
614  break;
615  case G_FCONSTANT:
616  OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
617  break;
618  case G_FCMP: {
619  unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
620  OperandsMapping =
622  getFprbMapping(Op2Size), getFprbMapping(Op2Size)});
623  break;
624  }
625  case G_FPEXT:
628  break;
629  case G_FPTRUNC:
632  break;
633  case G_FPTOSI: {
634  assert((Op0Size == 32) && "Unsupported integer size");
635  unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
636  OperandsMapping = getOperandsMapping(
638  break;
639  }
640  case G_SITOFP:
641  assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
642  "Unsupported integer size");
643  OperandsMapping = getOperandsMapping(
645  break;
646  case G_CONSTANT:
647  case G_FRAME_INDEX:
648  case G_GLOBAL_VALUE:
649  case G_JUMP_TABLE:
650  case G_BRCOND:
651  OperandsMapping =
653  break;
654  case G_BRJT:
655  OperandsMapping =
658  break;
659  case G_ICMP:
660  OperandsMapping =
664  break;
665  default:
667  }
668 
669  if (MappingID == CustomMappingID)
670  TI.clearTypeInfoData(&MI);
671  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
672  NumOperands);
673 }
674 
676 namespace {
677 class InstManager : public GISelChangeObserver {
678  InstListTy &InstList;
679 
680 public:
681  InstManager(InstListTy &Insts) : InstList(Insts) {}
682 
683  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
684  void erasingInstr(MachineInstr &MI) override {}
685  void changingInstr(MachineInstr &MI) override {}
686  void changedInstr(MachineInstr &MI) override {}
687 };
688 } // end anonymous namespace
689 
691  MachineRegisterInfo &MRI) const {
692  Register Dest = MI.getOperand(0).getReg();
693  switch (MI.getOpcode()) {
694  case TargetOpcode::G_STORE:
695  // No def operands, skip this instruction.
696  break;
697  case TargetOpcode::G_CONSTANT:
698  case TargetOpcode::G_LOAD:
699  case TargetOpcode::G_SELECT:
700  case TargetOpcode::G_PHI:
701  case TargetOpcode::G_IMPLICIT_DEF: {
702  assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type.");
703  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
704  break;
705  }
706  case TargetOpcode::G_PTR_ADD: {
707  assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
708  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
709  break;
710  }
711  default:
712  llvm_unreachable("Unexpected opcode.");
713  }
714 }
715 
716 static void
718  GUnmerge &MI, GISelChangeObserver &Observer) {
719  SmallVector<Register, 4> UpdatedDefs;
721  ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs,
722  UpdatedDefs, Observer);
723  for (MachineInstr *DeadMI : DeadInstrs)
724  DeadMI->eraseFromParent();
725 }
726 
728  const OperandsMapper &OpdMapper) const {
729  MachineInstr &MI = OpdMapper.getMI();
730  InstListTy NewInstrs;
731  MachineFunction *MF = MI.getMF();
732  MachineRegisterInfo &MRI = OpdMapper.getMRI();
733  const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo();
734 
735  InstManager NewInstrObserver(NewInstrs);
736  MachineIRBuilder B(MI, NewInstrObserver);
737  LegalizerHelper Helper(*MF, NewInstrObserver, B);
738  LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo);
739 
740  switch (MI.getOpcode()) {
741  case TargetOpcode::G_LOAD:
742  case TargetOpcode::G_STORE:
743  case TargetOpcode::G_PHI:
744  case TargetOpcode::G_SELECT:
745  case TargetOpcode::G_IMPLICIT_DEF: {
746  Helper.narrowScalar(MI, 0, LLT::scalar(32));
747  // Handle new instructions.
748  while (!NewInstrs.empty()) {
749  MachineInstr *NewMI = NewInstrs.pop_back_val();
750  // This is new G_UNMERGE that was created during narrowScalar and will
751  // not be considered for regbank selection. RegBankSelect for mips
752  // visits/makes corresponding G_MERGE first. Combine them here.
753  if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI))
754  combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver);
755  // This G_MERGE will be combined away when its corresponding G_UNMERGE
756  // gets regBankSelected.
757  else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
758  continue;
759  else
760  // Manually set register banks for def operands to 32 bit gprb.
761  setRegBank(*NewMI, MRI);
762  }
763  return;
764  }
765  case TargetOpcode::G_UNMERGE_VALUES:
766  combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI),
767  NewInstrObserver);
768  return;
769  default:
770  break;
771  }
772 
773  return applyDefaultMapping(OpdMapper);
774 }
llvm::MipsRegisterBankInfo::applyMappingImpl
void applyMappingImpl(const OperandsMapper &OpdMapper) const override
Here we have to narrowScalar s64 operands to s32, combine away G_MERGE or G_UNMERGE and erase instruc...
Definition: MipsRegisterBankInfo.cpp:727
i
i
Definition: README.txt:29
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:70
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:103
isFloatingPointOpcodeDef
static bool isFloatingPointOpcodeDef(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:142
llvm::RegisterBankInfo::getInstrMappingImpl
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Definition: RegisterBankInfo.cpp:159
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::RegisterBankInfo::OperandsMapper::getMRI
MachineRegisterInfo & getMRI() const
The MachineRegisterInfo we used to realize the mapping.
Definition: RegisterBankInfo.h:334
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::MipsSubtarget::systemSupportsUnalignedAccess
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
Definition: MipsSubtarget.h:376
llvm::RegisterBankInfo::getRegBank
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Definition: RegisterBankInfo.h:431
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::RegisterBankInfo::applyDefaultMapping
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
Definition: RegisterBankInfo.cpp:435
llvm::Mips::ValueMappings
RegisterBankInfo::ValueMapping ValueMappings[]
Definition: MipsRegisterBankInfo.cpp:50
llvm::Mips::ValueMappingIdx
ValueMappingIdx
Definition: MipsRegisterBankInfo.cpp:42
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:125
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:232
llvm::MachineRegisterInfo::use_instructions
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
Definition: MachineRegisterInfo.h:493
isGprbTwoInstrUnalignedLoadOrStore
static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI)
Definition: MipsRegisterBankInfo.cpp:152
Integer
So we should use XX3Form_Rcr to implement intrinsic Convert DP outs ins xscvdpsp No builtin are required Round &Convert QP DP(dword[1] is set to zero) No builtin are required Round to Quad Precision Integer
Definition: README_P9.txt:366
llvm::Mips::PMI_Min
@ PMI_Min
Definition: MipsRegisterBankInfo.cpp:32
llvm::MachineInstr::getMF
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
Definition: MachineInstr.cpp:636
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:654
llvm::Mips::PMI_SPR
@ PMI_SPR
Definition: MipsRegisterBankInfo.cpp:29
llvm::RegisterBankInfo::InstructionMapping::isValid
bool isValid() const
Check whether this object is valid.
Definition: RegisterBankInfo.h:253
MipsTargetMachine.h
llvm::LegalizerHelper
Definition: LegalizerHelper.h:46
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1618
LegalizationArtifactCombiner.h
MachineRegisterInfo.h
getFprbMapping
static const MipsRegisterBankInfo::ValueMapping * getFprbMapping(unsigned Size)
Definition: MipsRegisterBankInfo.cpp:406
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:650
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::Mips::SPRIdx
@ SPRIdx
Definition: MipsRegisterBankInfo.cpp:45
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:501
llvm::MipsRegisterBankInfo::MipsRegisterBankInfo
MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
Definition: MipsRegisterBankInfo.cpp:76
llvm::LLT::getSizeInBits
TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:152
llvm::LegalizerHelper::narrowScalar
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
Definition: LegalizerHelper.cpp:899
llvm::RegisterBankInfo::PartialMapping
Helper struct that represents how a value is partially mapped into a register.
Definition: RegisterBankInfo.h:48
llvm::Register::isPhysicalRegister
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::Mips::PartMappings
RegisterBankInfo::PartialMapping PartMappings[]
Definition: MipsRegisterBankInfo.cpp:35
CustomMappingID
static const unsigned CustomMappingID
Definition: MipsRegisterBankInfo.cpp:411
llvm::Mips::GPRIdx
@ GPRIdx
Definition: MipsRegisterBankInfo.cpp:44
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
isFloatingPointOpcode
static bool isFloatingPointOpcode(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:108
llvm::LegalizationArtifactCombiner::tryCombineUnmergeValues
bool tryCombineUnmergeValues(GUnmerge &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelChangeObserver &Observer)
Definition: LegalizationArtifactCombiner.h:813
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:396
llvm::RegisterBankInfo::getSizeInBits
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Definition: RegisterBankInfo.cpp:490
llvm::RegisterBankInfo::OperandsMapper
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
Definition: RegisterBankInfo.h:279
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:640
MipsRegisterBankInfo.h
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
llvm::Mips::PMI_GPR
@ PMI_GPR
Definition: MipsRegisterBankInfo.cpp:28
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:219
llvm::MipsRegisterBankInfo::setRegBank
void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const
RegBankSelect determined that s64 operand is better to be split into two s32 operands in gprb.
Definition: MipsRegisterBankInfo.cpp:690
llvm::Mips::PMI_MSA
@ PMI_MSA
Definition: MipsRegisterBankInfo.cpp:31
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::MachineRegisterInfo::setRegBank
void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
Definition: MachineRegisterInfo.cpp:61
llvm::RegisterBankInfo::InstructionMapping
Helper class that represents how the value of an instruction may be mapped and what is the related co...
Definition: RegisterBankInfo.h:189
getGprbOrCustomMapping
static const MipsRegisterBankInfo::ValueMapping * getGprbOrCustomMapping(unsigned Size, unsigned &MappingID)
Definition: MipsRegisterBankInfo.cpp:416
llvm::MachineRegisterInfo::use_instr_begin
use_instr_iterator use_instr_begin(Register RegNo) const
Definition: MachineRegisterInfo.h:485
llvm::RegisterBankInfo::DefaultMappingID
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
Definition: RegisterBankInfo.h:652
llvm::RegisterBankInfo::getOperandsMapping
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
Definition: RegisterBankInfo.cpp:329
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:122
isAmbiguous
static bool isAmbiguous(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:165
llvm::Mips::PMI_DPR
@ PMI_DPR
Definition: MipsRegisterBankInfo.cpp:30
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LLT::isPointer
bool isPointer() const
Definition: LowLevelTypeImpl.h:120
llvm::RegisterBankInfo::OperandsMapper::getMI
MachineInstr & getMI() const
Definition: RegisterBankInfo.h:328
llvm::Mips::DPRIdx
@ DPRIdx
Definition: MipsRegisterBankInfo.cpp:46
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MipsRegisterBankInfo::getInstrMapping
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Definition: MipsRegisterBankInfo.cpp:425
llvm::Mips::MSAIdx
@ MSAIdx
Definition: MipsRegisterBankInfo.cpp:47
llvm::LLT::isScalar
bool isScalar() const
Definition: LowLevelTypeImpl.h:118
llvm::TargetSubtargetInfo::getRegBankInfo
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
Definition: TargetSubtargetInfo.h:129
llvm::MachineFunction
Definition: MachineFunction.h:241
llvm::RegisterBankInfo::getInstructionMapping
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
Definition: RegisterBankInfo.h:525
llvm::GISelWorkList::pop_back_val
MachineInstr * pop_back_val()
Definition: GISelWorkList.h:102
llvm::RegisterBankInfo::ValueMapping
Helper struct that represents how a value is mapped through different register banks.
Definition: RegisterBankInfo.h:145
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:491
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
getMSAMapping
static const MipsRegisterBankInfo::ValueMapping * getMSAMapping(const MachineFunction &MF)
Definition: MipsRegisterBankInfo.cpp:400
llvm::Mips::InvalidIdx
@ InvalidIdx
Definition: MipsRegisterBankInfo.cpp:43
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::GISelChangeObserver
Abstract class that contains various methods for clients to notify about changes.
Definition: GISelChangeObserver.h:29
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::GUnmerge
Represents a G_UNMERGE_VALUES.
Definition: GenericMachineInstrs.h:141
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MipsSubtarget::hasMSA
bool hasMSA() const
Definition: MipsSubtarget.h:322
llvm::GISelWorkList::insert
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
Definition: GISelWorkList.h:74
llvm::TargetSubtargetInfo::getLegalizerInfo
virtual const LegalizerInfo * getLegalizerInfo() const
Definition: TargetSubtargetInfo.h:121
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:326
isFloatingPointOpcodeUse
static bool isFloatingPointOpcodeUse(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:129
llvm::RegisterBankInfo::getInvalidInstructionMapping
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
Definition: RegisterBankInfo.h:533
LegalizerHelper.h
MipsInstrInfo.h
llvm::LegalizationArtifactCombiner
Definition: LegalizationArtifactCombiner.h:33
llvm::MachineRegisterInfo::hasOneUse
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
Definition: MachineRegisterInfo.h:518
llvm::GISelWorkList
Definition: GISelWorkList.h:27
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:740
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:104
llvm::SmallVectorImpl< MachineInstr * >
combineAwayG_UNMERGE_VALUES
static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, GUnmerge &MI, GISelChangeObserver &Observer)
Definition: MipsRegisterBankInfo.cpp:717
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1180
GISelChangeObserver.h
llvm::MipsRegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
Definition: MipsRegisterBankInfo.cpp:79
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:42
llvm::GISelWorkList::empty
bool empty() const
Definition: GISelWorkList.h:38
llvm::Mips::PartialMappingIdx
PartialMappingIdx
Definition: MipsRegisterBankInfo.cpp:27
llvm::LLT
Definition: LowLevelTypeImpl.h:39