LLVM  16.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 = MI->getMF()->getSubtarget<MipsSubtarget>();
157  if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() &&
158  MMO->getAlign() < MMO->getSize()))
159  return true;
160  }
161  return false;
162 }
163 
164 static bool isAmbiguous(unsigned Opc) {
165  switch (Opc) {
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:
173  return true;
174  default:
175  return false;
176  }
177 }
178 
179 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
182  "Pointers are gprb, they should not be considered as ambiguous.\n");
184  MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
185  // Copy with many uses.
186  if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
187  !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg()))
188  addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
189  else
190  DefUses.push_back(skipCopiesOutgoing(&UseMI));
191  }
192 }
193 
194 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
197  "Pointers are gprb, they should not be considered as ambiguous.\n");
199  UseDefs.push_back(skipCopiesIncoming(DefMI));
200 }
201 
202 MachineInstr *
203 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
204  MachineInstr *MI) const {
205  const MachineFunction &MF = *MI->getParent()->getParent();
206  const MachineRegisterInfo &MRI = MF.getRegInfo();
207  MachineInstr *Ret = MI;
208  while (Ret->getOpcode() == TargetOpcode::COPY &&
209  !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) &&
210  MRI.hasOneUse(Ret->getOperand(0).getReg())) {
211  Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
212  }
213  return Ret;
214 }
215 
216 MachineInstr *
217 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
218  MachineInstr *MI) const {
219  const MachineFunction &MF = *MI->getParent()->getParent();
220  const MachineRegisterInfo &MRI = MF.getRegInfo();
221  MachineInstr *Ret = MI;
222  while (Ret->getOpcode() == TargetOpcode::COPY &&
223  !Register::isPhysicalRegister(Ret->getOperand(1).getReg()))
224  Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
225  return Ret;
226 }
227 
228 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
229  const MachineInstr *MI) {
230  assert(isAmbiguous(MI->getOpcode()) &&
231  "Not implemented for non Ambiguous opcode.\n");
232 
233  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
234 
235  if (MI->getOpcode() == TargetOpcode::G_LOAD)
236  addDefUses(MI->getOperand(0).getReg(), MRI);
237 
238  if (MI->getOpcode() == TargetOpcode::G_STORE)
239  addUseDef(MI->getOperand(0).getReg(), MRI);
240 
241  if (MI->getOpcode() == TargetOpcode::G_PHI) {
242  addDefUses(MI->getOperand(0).getReg(), MRI);
243 
244  for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
245  addUseDef(MI->getOperand(i).getReg(), MRI);
246  }
247 
248  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
249  addDefUses(MI->getOperand(0).getReg(), MRI);
250 
251  addUseDef(MI->getOperand(2).getReg(), MRI);
252  addUseDef(MI->getOperand(3).getReg(), MRI);
253  }
254 
255  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
256  addDefUses(MI->getOperand(0).getReg(), MRI);
257 
258  if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
259  addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);
260 
261  if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
262  addDefUses(MI->getOperand(0).getReg(), MRI);
263 }
264 
265 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
266  const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
267  InstType &AmbiguousTy) {
268  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
269  if (wasVisited(MI))
270  return true; // InstType has already been determined for MI.
271 
272  startVisit(MI);
273  AmbiguousRegDefUseContainer DefUseContainer(MI);
274 
276  setTypes(MI, Integer);
277  return true;
278  }
279 
280  if (AmbiguousTy == InstType::Ambiguous &&
281  (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
282  MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
283  AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
284 
285  // Visit instructions where MI's DEF operands are USED.
286  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
287  return true;
288 
289  // Visit instructions that DEFINE MI's USE operands.
290  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
291  return true;
292 
293  // All MI's adjacent instructions, are ambiguous.
294  if (!WaitingForTypeOfMI) {
295  // This is chain of ambiguous instructions.
296  setTypes(MI, AmbiguousTy);
297  return true;
298  }
299  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
300  // instructions or has no other adjacent instructions. Anyway InstType could
301  // not be determined. There could be unexplored path from some of
302  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
303  // mapping available.
304  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
305  // this way when WaitingForTypeOfMI figures out its InstType same InstType
306  // will be assigned to all instructions in this branch.
307  addToWaitingQueue(WaitingForTypeOfMI, MI);
308  return false;
309 }
310 
311 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
312  const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
313  bool isDefUse, InstType &AmbiguousTy) {
314  while (!AdjacentInstrs.empty()) {
315  MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
316 
317  if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
318  : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
319  setTypes(MI, InstType::FloatingPoint);
320  return true;
321  }
322 
323  // Determine InstType from register bank of phys register that is
324  // 'isDefUse ? def : use' of this copy.
325  if (AdjMI->getOpcode() == TargetOpcode::COPY) {
326  setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
327  return true;
328  }
329 
330  // Defaults to integer instruction. Small registers in G_MERGE (uses) and
331  // G_UNMERGE (defs) will always be gprb.
332  if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
333  (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
334  !isAmbiguous(AdjMI->getOpcode())) {
335  setTypes(MI, InstType::Integer);
336  return true;
337  }
338 
339  // When AdjMI was visited first, MI has to continue to explore remaining
340  // adjacent instructions and determine InstType without visiting AdjMI.
341  if (!wasVisited(AdjMI) ||
342  getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
343  if (visit(AdjMI, MI, AmbiguousTy)) {
344  // InstType is successfully determined and is same as for AdjMI.
345  setTypes(MI, getRecordedTypeForInstr(AdjMI));
346  return true;
347  }
348  }
349  }
350  return false;
351 }
352 
353 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
354  InstType InstTy) {
355  changeRecordedTypeForInstr(MI, InstTy);
356  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
357  setTypes(WaitingInstr, InstTy);
358  }
359 }
360 
361 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
362  const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
364  "Copies of non physical registers should not be considered here.\n");
365 
366  const MachineFunction &MF = *CopyInst->getMF();
367  const MachineRegisterInfo &MRI = MF.getRegInfo();
369  const RegisterBankInfo &RBI =
370  *CopyInst->getMF()->getSubtarget().getRegBankInfo();
371  const RegisterBank *Bank =
372  RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
373 
374  if (Bank == &Mips::FPRBRegBank)
375  setTypes(MI, InstType::FloatingPoint);
376  else if (Bank == &Mips::GPRBRegBank)
377  setTypes(MI, InstType::Integer);
378  else
379  llvm_unreachable("Unsupported register bank.\n");
380 }
381 
382 MipsRegisterBankInfo::InstType
383 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
384  InstType DefaultAmbiguousType = InstType::Ambiguous;
385  visit(MI, nullptr, DefaultAmbiguousType);
386  return getRecordedTypeForInstr(MI);
387 }
388 
389 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
390  llvm::StringRef FunctionName) {
391  if (MFName != FunctionName) {
392  MFName = std::string(FunctionName);
393  WaitingQueues.clear();
394  Types.clear();
395  }
396 }
397 
398 static const MipsRegisterBankInfo::ValueMapping *
401  "MSA mapping not available on target without MSA.");
403 }
404 
405 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
406  return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
408 }
409 
410 static const unsigned CustomMappingID = 1;
411 
412 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
413 // will be split into two 32 bit registers in gprb.
414 static const MipsRegisterBankInfo::ValueMapping *
415 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
416  if (Size == 32)
418 
419  MappingID = CustomMappingID;
421 }
422 
425 
426  static TypeInfoForMF TI;
427 
428  // Reset TI internal data when MF changes.
429  TI.cleanupIfNewFunction(MI.getMF()->getName());
430 
431  unsigned Opc = MI.getOpcode();
432  const MachineFunction &MF = *MI.getParent()->getParent();
433  const MachineRegisterInfo &MRI = MF.getRegInfo();
434 
435  if (MI.getOpcode() != TargetOpcode::G_PHI) {
436  const RegisterBankInfo::InstructionMapping &Mapping =
438  if (Mapping.isValid())
439  return Mapping;
440  }
441 
442  using namespace TargetOpcode;
443 
444  unsigned NumOperands = MI.getNumOperands();
445  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
446  unsigned MappingID = DefaultMappingID;
447 
448  // Check if LLT sizes match sizes of available register banks.
449  for (const MachineOperand &Op : MI.operands()) {
450  if (Op.isReg()) {
451  LLT RegTy = MRI.getType(Op.getReg());
452 
453  if (RegTy.isScalar() &&
454  (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
456 
457  if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
459  }
460  }
461 
462  const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
463  unsigned Op0Size = Op0Ty.getSizeInBits();
464  InstType InstTy = InstType::Integer;
465 
466  switch (Opc) {
467  case G_TRUNC:
468  case G_UMULH:
469  case G_ZEXTLOAD:
470  case G_SEXTLOAD:
471  case G_PTR_ADD:
472  case G_INTTOPTR:
473  case G_PTRTOINT:
474  case G_AND:
475  case G_OR:
476  case G_XOR:
477  case G_SHL:
478  case G_ASHR:
479  case G_LSHR:
480  case G_BRINDIRECT:
481  case G_VASTART:
482  case G_BSWAP:
483  case G_CTLZ:
484  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
485  break;
486  case G_ADD:
487  case G_SUB:
488  case G_MUL:
489  case G_SDIV:
490  case G_SREM:
491  case G_UDIV:
492  case G_UREM:
493  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
494  if (Op0Size == 128)
495  OperandsMapping = getMSAMapping(MF);
496  break;
497  case G_STORE:
498  case G_LOAD: {
499  if (Op0Size == 128) {
500  OperandsMapping = getOperandsMapping(
502  break;
503  }
504 
505  if (!Op0Ty.isPointer())
506  InstTy = TI.determineInstType(&MI);
507 
508  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
509  isAmbiguous_64(InstTy, Op0Size)) {
510  OperandsMapping = getOperandsMapping(
512  } else {
513  assert((isInteger_32(InstTy, Op0Size) ||
514  isAmbiguous_32(InstTy, Op0Size) ||
515  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
516  "Unexpected Inst type");
517  OperandsMapping =
518  getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
520  }
521 
522  break;
523  }
524  case G_PHI: {
525  if (!Op0Ty.isPointer())
526  InstTy = TI.determineInstType(&MI);
527 
528  // PHI is copylike and should have one regbank in mapping for def register.
529  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
530  OperandsMapping =
532  TI.clearTypeInfoData(&MI);
533  return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
534  /*NumOperands=*/1);
535  }
536  assert((isInteger_32(InstTy, Op0Size) ||
537  isFloatingPoint_32or64(InstTy, Op0Size) ||
538  isAmbiguous_32or64(InstTy, Op0Size)) &&
539  "Unexpected Inst type");
540  // Use default handling for PHI, i.e. set reg bank of def operand to match
541  // register banks of use operands.
542  return getInstrMappingImpl(MI);
543  }
544  case G_SELECT: {
545  if (!Op0Ty.isPointer())
546  InstTy = TI.determineInstType(&MI);
547  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
548  isAmbiguous_64(InstTy, Op0Size)) {
549  const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
550  OperandsMapping = getOperandsMapping(
551  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
552  break;
553  } else {
554  assert((isInteger_32(InstTy, Op0Size) ||
555  isAmbiguous_32(InstTy, Op0Size) ||
556  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
557  "Unexpected Inst type");
558  const RegisterBankInfo::ValueMapping *Bank =
559  getGprbOrCustomMapping(Op0Size, MappingID);
560  OperandsMapping = getOperandsMapping(
561  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
562  }
563  break;
564  }
565  case G_IMPLICIT_DEF: {
566  if (!Op0Ty.isPointer())
567  InstTy = TI.determineInstType(&MI);
568 
569  if (isFloatingPoint_32or64(InstTy, Op0Size))
570  OperandsMapping = getFprbMapping(Op0Size);
571  else {
572  assert((isInteger_32(InstTy, Op0Size) ||
573  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
574  "Unexpected Inst type");
575  OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
576  }
577  } break;
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))
589  MappingID = CustomMappingID;
590  break;
591  }
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))
601  MappingID = CustomMappingID;
602  break;
603  }
604  case G_FADD:
605  case G_FSUB:
606  case G_FMUL:
607  case G_FDIV:
608  case G_FABS:
609  case G_FSQRT:
610  OperandsMapping = getFprbMapping(Op0Size);
611  if (Op0Size == 128)
612  OperandsMapping = getMSAMapping(MF);
613  break;
614  case G_FCONSTANT:
615  OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
616  break;
617  case G_FCMP: {
618  unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
619  OperandsMapping =
621  getFprbMapping(Op2Size), getFprbMapping(Op2Size)});
622  break;
623  }
624  case G_FPEXT:
627  break;
628  case G_FPTRUNC:
631  break;
632  case G_FPTOSI: {
633  assert((Op0Size == 32) && "Unsupported integer size");
634  unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
635  OperandsMapping = getOperandsMapping(
637  break;
638  }
639  case G_SITOFP:
640  assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
641  "Unsupported integer size");
642  OperandsMapping = getOperandsMapping(
644  break;
645  case G_CONSTANT:
646  case G_FRAME_INDEX:
647  case G_GLOBAL_VALUE:
648  case G_JUMP_TABLE:
649  case G_BRCOND:
650  OperandsMapping =
652  break;
653  case G_BRJT:
654  OperandsMapping =
657  break;
658  case G_ICMP:
659  OperandsMapping =
663  break;
664  default:
666  }
667 
668  if (MappingID == CustomMappingID)
669  TI.clearTypeInfoData(&MI);
670  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
671  NumOperands);
672 }
673 
675 namespace {
676 class InstManager : public GISelChangeObserver {
677  InstListTy &InstList;
678 
679 public:
680  InstManager(InstListTy &Insts) : InstList(Insts) {}
681 
682  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
683  void erasingInstr(MachineInstr &MI) override {}
684  void changingInstr(MachineInstr &MI) override {}
685  void changedInstr(MachineInstr &MI) override {}
686 };
687 } // end anonymous namespace
688 
690  MachineRegisterInfo &MRI) const {
691  Register Dest = MI.getOperand(0).getReg();
692  switch (MI.getOpcode()) {
693  case TargetOpcode::G_STORE:
694  // No def operands, skip this instruction.
695  break;
696  case TargetOpcode::G_CONSTANT:
697  case TargetOpcode::G_LOAD:
698  case TargetOpcode::G_SELECT:
699  case TargetOpcode::G_PHI:
700  case TargetOpcode::G_IMPLICIT_DEF: {
701  assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type.");
702  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
703  break;
704  }
705  case TargetOpcode::G_PTR_ADD: {
706  assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
707  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
708  break;
709  }
710  default:
711  llvm_unreachable("Unexpected opcode.");
712  }
713 }
714 
715 static void
717  GUnmerge &MI, GISelChangeObserver &Observer) {
718  SmallVector<Register, 4> UpdatedDefs;
720  ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs,
721  UpdatedDefs, Observer);
722  for (MachineInstr *DeadMI : DeadInstrs)
723  DeadMI->eraseFromParent();
724 }
725 
727  const OperandsMapper &OpdMapper) const {
728  MachineInstr &MI = OpdMapper.getMI();
729  InstListTy NewInstrs;
730  MachineFunction *MF = MI.getMF();
731  MachineRegisterInfo &MRI = OpdMapper.getMRI();
732  const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo();
733 
734  InstManager NewInstrObserver(NewInstrs);
735  MachineIRBuilder B(MI, NewInstrObserver);
736  LegalizerHelper Helper(*MF, NewInstrObserver, B);
737  LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo);
738 
739  switch (MI.getOpcode()) {
740  case TargetOpcode::G_LOAD:
741  case TargetOpcode::G_STORE:
742  case TargetOpcode::G_PHI:
743  case TargetOpcode::G_SELECT:
744  case TargetOpcode::G_IMPLICIT_DEF: {
745  Helper.narrowScalar(MI, 0, LLT::scalar(32));
746  // Handle new instructions.
747  while (!NewInstrs.empty()) {
748  MachineInstr *NewMI = NewInstrs.pop_back_val();
749  // This is new G_UNMERGE that was created during narrowScalar and will
750  // not be considered for regbank selection. RegBankSelect for mips
751  // visits/makes corresponding G_MERGE first. Combine them here.
752  if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI))
753  combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver);
754  // This G_MERGE will be combined away when its corresponding G_UNMERGE
755  // gets regBankSelected.
756  else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
757  continue;
758  else
759  // Manually set register banks for def operands to 32 bit gprb.
760  setRegBank(*NewMI, MRI);
761  }
762  return;
763  }
764  case TargetOpcode::G_UNMERGE_VALUES:
765  combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI),
766  NewInstrObserver);
767  return;
768  default:
769  break;
770  }
771 
772  return applyDefaultMapping(OpdMapper);
773 }
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:726
i
i
Definition: README.txt:29
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:75
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:107
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:1199
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:127
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:237
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:678
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
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:1628
LegalizationArtifactCombiner.h
MachineRegisterInfo.h
getFprbMapping
static const MipsRegisterBankInfo::ValueMapping * getFprbMapping(unsigned Size)
Definition: MipsRegisterBankInfo.cpp:405
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
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:526
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:904
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:46
llvm::Mips::PartMappings
RegisterBankInfo::PartialMapping PartMappings[]
Definition: MipsRegisterBankInfo.cpp:35
CustomMappingID
static const unsigned CustomMappingID
Definition: MipsRegisterBankInfo.cpp:410
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:944
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:493
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:657
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:221
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:689
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:415
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:164
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:424
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:131
llvm::MachineFunction
Definition: MachineFunction.h:257
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::logicalview::LVCompareKind::Types
@ Types
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
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:399
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:123
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
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:745
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:108
llvm::SmallVectorImpl::pop_back_val
T pop_back_val()
Definition: SmallVector.h:677
llvm::SmallVectorImpl< MachineInstr * >
combineAwayG_UNMERGE_VALUES
static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, GUnmerge &MI, GISelChangeObserver &Observer)
Definition: MipsRegisterBankInfo.cpp:716
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1182
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