LLVM  13.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 
78 
79 const RegisterBank &
81  LLT) const {
82  using namespace Mips;
83 
84  switch (RC.getID()) {
85  case Mips::GPR32RegClassID:
86  case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
87  case Mips::GPRMM16MovePPairFirstRegClassID:
88  case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
89  case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
90  case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
91  case Mips::SP32RegClassID:
92  case Mips::GP32RegClassID:
93  return getRegBank(Mips::GPRBRegBankID);
94  case Mips::FGRCCRegClassID:
95  case Mips::FGR32RegClassID:
96  case Mips::FGR64RegClassID:
97  case Mips::AFGR64RegClassID:
98  case Mips::MSA128BRegClassID:
99  case Mips::MSA128HRegClassID:
100  case Mips::MSA128WRegClassID:
101  case Mips::MSA128DRegClassID:
102  return getRegBank(Mips::FPRBRegBankID);
103  default:
104  llvm_unreachable("Register class not supported");
105  }
106 }
107 
108 // Instructions where all register operands are floating point.
109 static bool isFloatingPointOpcode(unsigned Opc) {
110  switch (Opc) {
111  case TargetOpcode::G_FCONSTANT:
112  case TargetOpcode::G_FADD:
113  case TargetOpcode::G_FSUB:
114  case TargetOpcode::G_FMUL:
115  case TargetOpcode::G_FDIV:
116  case TargetOpcode::G_FABS:
117  case TargetOpcode::G_FSQRT:
118  case TargetOpcode::G_FCEIL:
119  case TargetOpcode::G_FFLOOR:
120  case TargetOpcode::G_FPEXT:
121  case TargetOpcode::G_FPTRUNC:
122  return true;
123  default:
124  return false;
125  }
126 }
127 
128 // Instructions where use operands are floating point registers.
129 // Def operands are general purpose.
130 static bool isFloatingPointOpcodeUse(unsigned Opc) {
131  switch (Opc) {
132  case TargetOpcode::G_FPTOSI:
133  case TargetOpcode::G_FPTOUI:
134  case TargetOpcode::G_FCMP:
135  return true;
136  default:
137  return isFloatingPointOpcode(Opc);
138  }
139 }
140 
141 // Instructions where def operands are floating point registers.
142 // Use operands are general purpose.
143 static bool isFloatingPointOpcodeDef(unsigned Opc) {
144  switch (Opc) {
145  case TargetOpcode::G_SITOFP:
146  case TargetOpcode::G_UITOFP:
147  return true;
148  default:
149  return isFloatingPointOpcode(Opc);
150  }
151 }
152 
154  if (MI->getOpcode() == TargetOpcode::G_LOAD ||
155  MI->getOpcode() == TargetOpcode::G_STORE) {
156  auto MMO = *MI->memoperands_begin();
157  const MipsSubtarget &STI =
158  static_cast<const MipsSubtarget &>(MI->getMF()->getSubtarget());
159  if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() &&
160  MMO->getAlign() < MMO->getSize()))
161  return true;
162  }
163  return false;
164 }
165 
166 static bool isAmbiguous(unsigned Opc) {
167  switch (Opc) {
168  case TargetOpcode::G_LOAD:
169  case TargetOpcode::G_STORE:
170  case TargetOpcode::G_PHI:
171  case TargetOpcode::G_SELECT:
172  case TargetOpcode::G_IMPLICIT_DEF:
173  case TargetOpcode::G_UNMERGE_VALUES:
174  case TargetOpcode::G_MERGE_VALUES:
175  return true;
176  default:
177  return false;
178  }
179 }
180 
181 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
184  "Pointers are gprb, they should not be considered as ambiguous.\n");
186  MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
187  // Copy with many uses.
188  if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
189  !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg()))
190  addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
191  else
192  DefUses.push_back(skipCopiesOutgoing(&UseMI));
193  }
194 }
195 
196 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
199  "Pointers are gprb, they should not be considered as ambiguous.\n");
201  UseDefs.push_back(skipCopiesIncoming(DefMI));
202 }
203 
204 MachineInstr *
205 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
206  MachineInstr *MI) const {
207  const MachineFunction &MF = *MI->getParent()->getParent();
208  const MachineRegisterInfo &MRI = MF.getRegInfo();
209  MachineInstr *Ret = MI;
210  while (Ret->getOpcode() == TargetOpcode::COPY &&
211  !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) &&
212  MRI.hasOneUse(Ret->getOperand(0).getReg())) {
213  Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
214  }
215  return Ret;
216 }
217 
218 MachineInstr *
219 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
220  MachineInstr *MI) const {
221  const MachineFunction &MF = *MI->getParent()->getParent();
222  const MachineRegisterInfo &MRI = MF.getRegInfo();
223  MachineInstr *Ret = MI;
224  while (Ret->getOpcode() == TargetOpcode::COPY &&
225  !Register::isPhysicalRegister(Ret->getOperand(1).getReg()))
226  Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
227  return Ret;
228 }
229 
230 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
231  const MachineInstr *MI) {
232  assert(isAmbiguous(MI->getOpcode()) &&
233  "Not implemented for non Ambiguous opcode.\n");
234 
235  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
236 
237  if (MI->getOpcode() == TargetOpcode::G_LOAD)
238  addDefUses(MI->getOperand(0).getReg(), MRI);
239 
240  if (MI->getOpcode() == TargetOpcode::G_STORE)
241  addUseDef(MI->getOperand(0).getReg(), MRI);
242 
243  if (MI->getOpcode() == TargetOpcode::G_PHI) {
244  addDefUses(MI->getOperand(0).getReg(), MRI);
245 
246  for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
247  addUseDef(MI->getOperand(i).getReg(), MRI);
248  }
249 
250  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
251  addDefUses(MI->getOperand(0).getReg(), MRI);
252 
253  addUseDef(MI->getOperand(2).getReg(), MRI);
254  addUseDef(MI->getOperand(3).getReg(), MRI);
255  }
256 
257  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
258  addDefUses(MI->getOperand(0).getReg(), MRI);
259 
260  if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
261  addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);
262 
263  if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
264  addDefUses(MI->getOperand(0).getReg(), MRI);
265 }
266 
267 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
268  const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
269  InstType &AmbiguousTy) {
270  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
271  if (wasVisited(MI))
272  return true; // InstType has already been determined for MI.
273 
274  startVisit(MI);
275  AmbiguousRegDefUseContainer DefUseContainer(MI);
276 
278  setTypes(MI, Integer);
279  return true;
280  }
281 
282  if (AmbiguousTy == InstType::Ambiguous &&
283  (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
284  MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
285  AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;
286 
287  // Visit instructions where MI's DEF operands are USED.
288  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
289  return true;
290 
291  // Visit instructions that DEFINE MI's USE operands.
292  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
293  return true;
294 
295  // All MI's adjacent instructions, are ambiguous.
296  if (!WaitingForTypeOfMI) {
297  // This is chain of ambiguous instructions.
298  setTypes(MI, AmbiguousTy);
299  return true;
300  }
301  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
302  // instructions or has no other adjacent instructions. Anyway InstType could
303  // not be determined. There could be unexplored path from some of
304  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
305  // mapping available.
306  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
307  // this way when WaitingForTypeOfMI figures out its InstType same InstType
308  // will be assigned to all instructions in this branch.
309  addToWaitingQueue(WaitingForTypeOfMI, MI);
310  return false;
311 }
312 
313 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
314  const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
315  bool isDefUse, InstType &AmbiguousTy) {
316  while (!AdjacentInstrs.empty()) {
317  MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
318 
319  if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
320  : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
321  setTypes(MI, InstType::FloatingPoint);
322  return true;
323  }
324 
325  // Determine InstType from register bank of phys register that is
326  // 'isDefUse ? def : use' of this copy.
327  if (AdjMI->getOpcode() == TargetOpcode::COPY) {
328  setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
329  return true;
330  }
331 
332  // Defaults to integer instruction. Small registers in G_MERGE (uses) and
333  // G_UNMERGE (defs) will always be gprb.
334  if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
335  (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
336  !isAmbiguous(AdjMI->getOpcode())) {
337  setTypes(MI, InstType::Integer);
338  return true;
339  }
340 
341  // When AdjMI was visited first, MI has to continue to explore remaining
342  // adjacent instructions and determine InstType without visiting AdjMI.
343  if (!wasVisited(AdjMI) ||
344  getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
345  if (visit(AdjMI, MI, AmbiguousTy)) {
346  // InstType is successfully determined and is same as for AdjMI.
347  setTypes(MI, getRecordedTypeForInstr(AdjMI));
348  return true;
349  }
350  }
351  }
352  return false;
353 }
354 
355 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
356  InstType InstTy) {
357  changeRecordedTypeForInstr(MI, InstTy);
358  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
359  setTypes(WaitingInstr, InstTy);
360  }
361 }
362 
363 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
364  const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
366  "Copies of non physical registers should not be considered here.\n");
367 
368  const MachineFunction &MF = *CopyInst->getMF();
369  const MachineRegisterInfo &MRI = MF.getRegInfo();
371  const RegisterBankInfo &RBI =
372  *CopyInst->getMF()->getSubtarget().getRegBankInfo();
373  const RegisterBank *Bank =
374  RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
375 
376  if (Bank == &Mips::FPRBRegBank)
377  setTypes(MI, InstType::FloatingPoint);
378  else if (Bank == &Mips::GPRBRegBank)
379  setTypes(MI, InstType::Integer);
380  else
381  llvm_unreachable("Unsupported register bank.\n");
382 }
383 
384 MipsRegisterBankInfo::InstType
385 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
386  InstType DefaultAmbiguousType = InstType::Ambiguous;
387  visit(MI, nullptr, DefaultAmbiguousType);
388  return getRecordedTypeForInstr(MI);
389 }
390 
391 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
392  llvm::StringRef FunctionName) {
393  if (MFName != FunctionName) {
394  MFName = std::string(FunctionName);
395  WaitingQueues.clear();
396  Types.clear();
397  }
398 }
399 
400 static const MipsRegisterBankInfo::ValueMapping *
402  assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() &&
403  "MSA mapping not available on target without MSA.");
405 }
406 
407 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
408  return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
410 }
411 
412 static const unsigned CustomMappingID = 1;
413 
414 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
415 // will be split into two 32 bit registers in gprb.
416 static const MipsRegisterBankInfo::ValueMapping *
417 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
418  if (Size == 32)
420 
421  MappingID = CustomMappingID;
423 }
424 
427 
428  static TypeInfoForMF TI;
429 
430  // Reset TI internal data when MF changes.
431  TI.cleanupIfNewFunction(MI.getMF()->getName());
432 
433  unsigned Opc = MI.getOpcode();
434  const MachineFunction &MF = *MI.getParent()->getParent();
435  const MachineRegisterInfo &MRI = MF.getRegInfo();
436 
437  if (MI.getOpcode() != TargetOpcode::G_PHI) {
438  const RegisterBankInfo::InstructionMapping &Mapping =
440  if (Mapping.isValid())
441  return Mapping;
442  }
443 
444  using namespace TargetOpcode;
445 
446  unsigned NumOperands = MI.getNumOperands();
447  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
448  unsigned MappingID = DefaultMappingID;
449 
450  // Check if LLT sizes match sizes of available register banks.
451  for (const MachineOperand &Op : MI.operands()) {
452  if (Op.isReg()) {
453  LLT RegTy = MRI.getType(Op.getReg());
454 
455  if (RegTy.isScalar() &&
456  (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
458 
459  if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
461  }
462  }
463 
464  const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
465  unsigned Op0Size = Op0Ty.getSizeInBits();
466  InstType InstTy = InstType::Integer;
467 
468  switch (Opc) {
469  case G_TRUNC:
470  case G_UMULH:
471  case G_ZEXTLOAD:
472  case G_SEXTLOAD:
473  case G_PTR_ADD:
474  case G_INTTOPTR:
475  case G_PTRTOINT:
476  case G_AND:
477  case G_OR:
478  case G_XOR:
479  case G_SHL:
480  case G_ASHR:
481  case G_LSHR:
482  case G_BRINDIRECT:
483  case G_VASTART:
484  case G_BSWAP:
485  case G_CTLZ:
486  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
487  break;
488  case G_ADD:
489  case G_SUB:
490  case G_MUL:
491  case G_SDIV:
492  case G_SREM:
493  case G_UDIV:
494  case G_UREM:
495  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
496  if (Op0Size == 128)
497  OperandsMapping = getMSAMapping(MF);
498  break;
499  case G_STORE:
500  case G_LOAD: {
501  if (Op0Size == 128) {
502  OperandsMapping = getOperandsMapping(
504  break;
505  }
506 
507  if (!Op0Ty.isPointer())
508  InstTy = TI.determineInstType(&MI);
509 
510  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
511  isAmbiguous_64(InstTy, Op0Size)) {
512  OperandsMapping = getOperandsMapping(
514  } else {
515  assert((isInteger_32(InstTy, Op0Size) ||
516  isAmbiguous_32(InstTy, Op0Size) ||
517  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
518  "Unexpected Inst type");
519  OperandsMapping =
520  getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
522  }
523 
524  break;
525  }
526  case G_PHI: {
527  if (!Op0Ty.isPointer())
528  InstTy = TI.determineInstType(&MI);
529 
530  // PHI is copylike and should have one regbank in mapping for def register.
531  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
532  OperandsMapping =
534  TI.clearTypeInfoData(&MI);
535  return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
536  /*NumOperands=*/1);
537  }
538  assert((isInteger_32(InstTy, Op0Size) ||
539  isFloatingPoint_32or64(InstTy, Op0Size) ||
540  isAmbiguous_32or64(InstTy, Op0Size)) &&
541  "Unexpected Inst type");
542  // Use default handling for PHI, i.e. set reg bank of def operand to match
543  // register banks of use operands.
544  return getInstrMappingImpl(MI);
545  }
546  case G_SELECT: {
547  if (!Op0Ty.isPointer())
548  InstTy = TI.determineInstType(&MI);
549  if (isFloatingPoint_32or64(InstTy, Op0Size) ||
550  isAmbiguous_64(InstTy, Op0Size)) {
551  const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
552  OperandsMapping = getOperandsMapping(
553  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
554  break;
555  } else {
556  assert((isInteger_32(InstTy, Op0Size) ||
557  isAmbiguous_32(InstTy, Op0Size) ||
558  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
559  "Unexpected Inst type");
560  const RegisterBankInfo::ValueMapping *Bank =
561  getGprbOrCustomMapping(Op0Size, MappingID);
562  OperandsMapping = getOperandsMapping(
563  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
564  }
565  break;
566  }
567  case G_IMPLICIT_DEF: {
568  if (!Op0Ty.isPointer())
569  InstTy = TI.determineInstType(&MI);
570 
571  if (isFloatingPoint_32or64(InstTy, Op0Size))
572  OperandsMapping = getFprbMapping(Op0Size);
573  else {
574  assert((isInteger_32(InstTy, Op0Size) ||
575  isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
576  "Unexpected Inst type");
577  OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
578  }
579  } break;
580  case G_UNMERGE_VALUES: {
581  assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES");
582  unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
583  InstTy = TI.determineInstType(&MI);
584  assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
585  isFloatingPoint_64(InstTy, Op3Size)) &&
586  "Unexpected Inst type");
590  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
591  MappingID = CustomMappingID;
592  break;
593  }
594  case G_MERGE_VALUES: {
595  InstTy = TI.determineInstType(&MI);
596  assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
597  isFloatingPoint_64(InstTy, Op0Size)) &&
598  "Unexpected Inst type");
602  if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
603  MappingID = CustomMappingID;
604  break;
605  }
606  case G_FADD:
607  case G_FSUB:
608  case G_FMUL:
609  case G_FDIV:
610  case G_FABS:
611  case G_FSQRT:
612  OperandsMapping = getFprbMapping(Op0Size);
613  if (Op0Size == 128)
614  OperandsMapping = getMSAMapping(MF);
615  break;
616  case G_FCONSTANT:
617  OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
618  break;
619  case G_FCMP: {
620  unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
621  OperandsMapping =
623  getFprbMapping(Op2Size), getFprbMapping(Op2Size)});
624  break;
625  }
626  case G_FPEXT:
629  break;
630  case G_FPTRUNC:
633  break;
634  case G_FPTOSI: {
635  assert((Op0Size == 32) && "Unsupported integer size");
636  unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
637  OperandsMapping = getOperandsMapping(
639  break;
640  }
641  case G_SITOFP:
642  assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
643  "Unsupported integer size");
644  OperandsMapping = getOperandsMapping(
646  break;
647  case G_CONSTANT:
648  case G_FRAME_INDEX:
649  case G_GLOBAL_VALUE:
650  case G_JUMP_TABLE:
651  case G_BRCOND:
652  OperandsMapping =
654  break;
655  case G_BRJT:
656  OperandsMapping =
659  break;
660  case G_ICMP:
661  OperandsMapping =
665  break;
666  default:
668  }
669 
670  if (MappingID == CustomMappingID)
671  TI.clearTypeInfoData(&MI);
672  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
673  NumOperands);
674 }
675 
677 namespace {
678 class InstManager : public GISelChangeObserver {
679  InstListTy &InstList;
680 
681 public:
682  InstManager(InstListTy &Insts) : InstList(Insts) {}
683 
684  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
685  void erasingInstr(MachineInstr &MI) override {}
686  void changingInstr(MachineInstr &MI) override {}
687  void changedInstr(MachineInstr &MI) override {}
688 };
689 } // end anonymous namespace
690 
692  MachineRegisterInfo &MRI) const {
693  Register Dest = MI.getOperand(0).getReg();
694  switch (MI.getOpcode()) {
695  case TargetOpcode::G_STORE:
696  // No def operands, skip this instruction.
697  break;
698  case TargetOpcode::G_CONSTANT:
699  case TargetOpcode::G_LOAD:
700  case TargetOpcode::G_SELECT:
701  case TargetOpcode::G_PHI:
702  case TargetOpcode::G_IMPLICIT_DEF: {
703  assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type.");
704  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
705  break;
706  }
707  case TargetOpcode::G_PTR_ADD: {
708  assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
709  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
710  break;
711  }
712  default:
713  llvm_unreachable("Unexpected opcode.");
714  }
715 }
716 
717 static void
719  MachineInstr &MI, GISelChangeObserver &Observer) {
720  SmallVector<Register, 4> UpdatedDefs;
722  ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs, 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 (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
754  combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI, 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, MI, NewInstrObserver);
767  return;
768  default:
769  break;
770  }
771 
772  return applyDefaultMapping(OpdMapper);
773 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
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:102
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:69
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:102
isFloatingPointOpcodeDef
static bool isFloatingPointOpcodeDef(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:143
llvm::RegisterBankInfo::getInstrMappingImpl
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Definition: RegisterBankInfo.cpp:162
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::LegalizationArtifactCombiner::tryCombineUnmergeValues
bool tryCombineUnmergeValues(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelChangeObserver &Observer)
Definition: LegalizationArtifactCombiner.h:748
llvm::RegisterBankInfo::OperandsMapper::getMRI
MachineRegisterInfo & getMRI() const
The MachineRegisterInfo we used to realize the mapping.
Definition: RegisterBankInfo.h:335
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MipsSubtarget::systemSupportsUnalignedAccess
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
Definition: MipsSubtarget.h:373
llvm::RegisterBankInfo::getRegBank
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Definition: RegisterBankInfo.h:432
llvm::RegisterBankInfo::applyDefaultMapping
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
Definition: RegisterBankInfo.cpp:438
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:124
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
llvm::MachineRegisterInfo::use_instructions
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
Definition: MachineRegisterInfo.h:485
isGprbTwoInstrUnalignedLoadOrStore
static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI)
Definition: MipsRegisterBankInfo.cpp:153
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:663
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
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:254
MipsTargetMachine.h
llvm::LegalizerHelper
Definition: LegalizerHelper.h:39
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
LegalizationArtifactCombiner.h
MachineRegisterInfo.h
getFprbMapping
static const MipsRegisterBankInfo::ValueMapping * getFprbMapping(unsigned Size)
Definition: MipsRegisterBankInfo.cpp:407
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:632
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:499
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:153
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:822
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:412
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:49
Integer
So we should use XX3Form_Rcr to implement instrinsic 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
isFloatingPointOpcode
static bool isFloatingPointOpcode(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:109
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:400
combineAwayG_UNMERGE_VALUES
static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, MachineInstr &MI, GISelChangeObserver &Observer)
Definition: MipsRegisterBankInfo.cpp:718
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:280
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:622
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:220
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:691
llvm::Mips::PMI_MSA
@ PMI_MSA
Definition: MipsRegisterBankInfo.cpp:31
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineRegisterInfo::setRegBank
void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
Definition: MachineRegisterInfo.cpp:63
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:417
llvm::MachineRegisterInfo::use_instr_begin
use_instr_iterator use_instr_begin(Register RegNo) const
Definition: MachineRegisterInfo.h:477
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:332
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:123
isAmbiguous
static bool isAmbiguous(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:166
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:121
llvm::RegisterBankInfo::OperandsMapper::getMI
MachineInstr & getMI() const
Definition: RegisterBankInfo.h:329
llvm::Mips::DPRIdx
@ DPRIdx
Definition: MipsRegisterBankInfo.cpp:46
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
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:426
llvm::Mips::MSAIdx
@ MSAIdx
Definition: MipsRegisterBankInfo.cpp:47
llvm::LLT::isScalar
bool isScalar() const
Definition: LowLevelTypeImpl.h:119
llvm::TargetSubtargetInfo::getRegBankInfo
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
Definition: TargetSubtargetInfo.h:128
llvm::MachineFunction
Definition: MachineFunction.h:230
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:526
llvm::GISelWorkList::pop_back_val
MachineInstr * pop_back_val()
Definition: GISelWorkList.h:99
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:489
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
getMSAMapping
static const MipsRegisterBankInfo::ValueMapping * getMSAMapping(const MachineFunction &MF)
Definition: MipsRegisterBankInfo.cpp:401
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::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MipsSubtarget::hasMSA
bool hasMSA() const
Definition: MipsSubtarget.h:319
llvm::GISelWorkList::insert
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
Definition: GISelWorkList.h:75
llvm::TargetSubtargetInfo::getLegalizerInfo
virtual const LegalizerInfo * getLegalizerInfo() const
Definition: TargetSubtargetInfo.h:120
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
isFloatingPointOpcodeUse
static bool isFloatingPointOpcodeUse(unsigned Opc)
Definition: MipsRegisterBankInfo.cpp:130
llvm::RegisterBankInfo::getInvalidInstructionMapping
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
Definition: RegisterBankInfo.h:534
LegalizerHelper.h
MipsInstrInfo.h
llvm::LegalizationArtifactCombiner
Definition: LegalizationArtifactCombiner.h:30
llvm::MachineRegisterInfo::hasOneUse
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
Definition: MachineRegisterInfo.h:510
llvm::GISelWorkList
Definition: GISelWorkList.h:28
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:732
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:103
llvm::SmallVectorImpl< MachineInstr * >
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1083
GISelChangeObserver.h
llvm::MipsRegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
Definition: MipsRegisterBankInfo.cpp:80
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
llvm::GISelWorkList::empty
bool empty() const
Definition: GISelWorkList.h:39
llvm::MipsGenRegisterBankInfo
Definition: MipsRegisterBankInfo.h:25
llvm::Mips::PartialMappingIdx
PartialMappingIdx
Definition: MipsRegisterBankInfo.cpp:27
llvm::LLT
Definition: LowLevelTypeImpl.h:40