LLVM  10.0.0svn
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 
80  const TargetRegisterClass &RC) 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  case Mips::MFC1:
136  case Mips::ExtractElementF64_64:
137  return true;
138  default:
139  return isFloatingPointOpcode(Opc);
140  }
141 }
142 
143 // Instructions where def operands are floating point registers.
144 // Use operands are general purpose.
145 static bool isFloatingPointOpcodeDef(unsigned Opc) {
146  switch (Opc) {
147  case TargetOpcode::G_SITOFP:
148  case TargetOpcode::G_UITOFP:
149  case Mips::MTC1:
150  case Mips::BuildPairF64:
151  case Mips::BuildPairF64_64:
152  return true;
153  default:
154  return isFloatingPointOpcode(Opc);
155  }
156 }
157 
158 static bool isAmbiguous(unsigned Opc) {
159  switch (Opc) {
160  case TargetOpcode::G_LOAD:
161  case TargetOpcode::G_STORE:
162  case TargetOpcode::G_PHI:
163  case TargetOpcode::G_SELECT:
164  case TargetOpcode::G_IMPLICIT_DEF:
165  return true;
166  default:
167  return false;
168  }
169 }
170 
171 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
173  assert(!MRI.getType(Reg).isPointer() &&
174  "Pointers are gprb, they should not be considered as ambiguous.\n");
175  for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
176  MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
177  // Copy with many uses.
178  if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
179  !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg()))
180  addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
181  else
182  DefUses.push_back(skipCopiesOutgoing(&UseMI));
183  }
184 }
185 
186 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
187  Register Reg, const MachineRegisterInfo &MRI) {
188  assert(!MRI.getType(Reg).isPointer() &&
189  "Pointers are gprb, they should not be considered as ambiguous.\n");
190  MachineInstr *DefMI = MRI.getVRegDef(Reg);
191  UseDefs.push_back(skipCopiesIncoming(DefMI));
192 }
193 
194 MachineInstr *
195 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
196  MachineInstr *MI) const {
197  const MachineFunction &MF = *MI->getParent()->getParent();
198  const MachineRegisterInfo &MRI = MF.getRegInfo();
199  MachineInstr *Ret = MI;
200  while (Ret->getOpcode() == TargetOpcode::COPY &&
202  MRI.hasOneUse(Ret->getOperand(0).getReg())) {
203  Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
204  }
205  return Ret;
206 }
207 
208 MachineInstr *
209 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
210  MachineInstr *MI) const {
211  const MachineFunction &MF = *MI->getParent()->getParent();
212  const MachineRegisterInfo &MRI = MF.getRegInfo();
213  MachineInstr *Ret = MI;
214  while (Ret->getOpcode() == TargetOpcode::COPY &&
216  Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
217  return Ret;
218 }
219 
220 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
221  const MachineInstr *MI) {
222  assert(isAmbiguous(MI->getOpcode()) &&
223  "Not implemented for non Ambiguous opcode.\n");
224 
225  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
226 
227  if (MI->getOpcode() == TargetOpcode::G_LOAD)
228  addDefUses(MI->getOperand(0).getReg(), MRI);
229 
230  if (MI->getOpcode() == TargetOpcode::G_STORE)
231  addUseDef(MI->getOperand(0).getReg(), MRI);
232 
233  if (MI->getOpcode() == TargetOpcode::G_PHI) {
234  addDefUses(MI->getOperand(0).getReg(), MRI);
235 
236  for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
237  addUseDef(MI->getOperand(i).getReg(), MRI);
238  }
239 
240  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
241  addDefUses(MI->getOperand(0).getReg(), MRI);
242 
243  addUseDef(MI->getOperand(2).getReg(), MRI);
244  addUseDef(MI->getOperand(3).getReg(), MRI);
245  }
246 
247  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
248  addDefUses(MI->getOperand(0).getReg(), MRI);
249 }
250 
251 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
252  const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) {
253  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
254  if (wasVisited(MI))
255  return true; // InstType has already been determined for MI.
256 
257  startVisit(MI);
258  AmbiguousRegDefUseContainer DefUseContainer(MI);
259 
260  // Visit instructions where MI's DEF operands are USED.
261  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true))
262  return true;
263 
264  // Visit instructions that DEFINE MI's USE operands.
265  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false))
266  return true;
267 
268  // All MI's adjacent instructions, are ambiguous.
269  if (!WaitingForTypeOfMI) {
270  // This is chain of ambiguous instructions.
271  setTypes(MI, InstType::Ambiguous);
272  return true;
273  }
274  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
275  // instructions or has no other adjacent instructions. Anyway InstType could
276  // not be determined. There could be unexplored path from some of
277  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
278  // mapping available.
279  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
280  // this way when WaitingForTypeOfMI figures out its InstType same InstType
281  // will be assigned to all instructions in this branch.
282  addToWaitingQueue(WaitingForTypeOfMI, MI);
283  return false;
284 }
285 
286 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
287  const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
288  bool isDefUse) {
289  while (!AdjacentInstrs.empty()) {
290  MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
291 
292  if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
293  : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
294  setTypes(MI, InstType::FloatingPoint);
295  return true;
296  }
297 
298  // Determine InstType from register bank of phys register that is
299  // 'isDefUse ? def : use' of this copy.
300  if (AdjMI->getOpcode() == TargetOpcode::COPY) {
301  setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
302  return true;
303  }
304 
305  // Defaults to integer instruction. Includes G_MERGE_VALUES and
306  // G_UNMERGE_VALUES.
307  if (!isAmbiguous(AdjMI->getOpcode())) {
308  setTypes(MI, InstType::Integer);
309  return true;
310  }
311 
312  // When AdjMI was visited first, MI has to continue to explore remaining
313  // adjacent instructions and determine InstType without visiting AdjMI.
314  if (!wasVisited(AdjMI) ||
315  getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
316  if (visit(AdjMI, MI)) {
317  // InstType is successfully determined and is same as for AdjMI.
318  setTypes(MI, getRecordedTypeForInstr(AdjMI));
319  return true;
320  }
321  }
322  }
323  return false;
324 }
325 
326 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
327  InstType InstTy) {
328  changeRecordedTypeForInstr(MI, InstTy);
329  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
330  setTypes(WaitingInstr, InstTy);
331  }
332 }
333 
334 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
335  const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
337  "Copies of non physical registers should not be considered here.\n");
338 
339  const MachineFunction &MF = *CopyInst->getMF();
340  const MachineRegisterInfo &MRI = MF.getRegInfo();
341  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
342  const RegisterBankInfo &RBI =
343  *CopyInst->getMF()->getSubtarget().getRegBankInfo();
344  const RegisterBank *Bank =
345  RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
346 
347  if (Bank == &Mips::FPRBRegBank)
348  setTypes(MI, InstType::FloatingPoint);
349  else if (Bank == &Mips::GPRBRegBank)
350  setTypes(MI, InstType::Integer);
351  else
352  llvm_unreachable("Unsupported register bank.\n");
353 }
354 
355 MipsRegisterBankInfo::InstType
356 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
357  visit(MI, nullptr);
358  return getRecordedTypeForInstr(MI);
359 }
360 
361 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
362  llvm::StringRef FunctionName) {
363  if (MFName != FunctionName) {
364  MFName = FunctionName;
365  WaitingQueues.clear();
366  Types.clear();
367  }
368 }
369 
370 static const MipsRegisterBankInfo::ValueMapping *
372  assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() &&
373  "MSA mapping not available on target without MSA.");
375 }
376 
377 static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
378  return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
380 }
381 
382 static const unsigned CustomMappingID = 1;
383 
384 // Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
385 // will be split into two 32 bit registers in gprb.
386 static const MipsRegisterBankInfo::ValueMapping *
387 getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
388  if (Size == 32)
390 
391  MappingID = CustomMappingID;
393 }
394 
397 
398  static TypeInfoForMF TI;
399 
400  // Reset TI internal data when MF changes.
401  TI.cleanupIfNewFunction(MI.getMF()->getName());
402 
403  unsigned Opc = MI.getOpcode();
404  const MachineFunction &MF = *MI.getParent()->getParent();
405  const MachineRegisterInfo &MRI = MF.getRegInfo();
406 
407  if (MI.getOpcode() != TargetOpcode::G_PHI) {
408  const RegisterBankInfo::InstructionMapping &Mapping =
410  if (Mapping.isValid())
411  return Mapping;
412  }
413 
414  using namespace TargetOpcode;
415 
416  unsigned NumOperands = MI.getNumOperands();
417  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
418  unsigned MappingID = DefaultMappingID;
419 
420  // Check if LLT sizes match sizes of available register banks.
421  for (const MachineOperand &Op : MI.operands()) {
422  if (Op.isReg()) {
423  LLT RegTy = MRI.getType(Op.getReg());
424 
425  if (RegTy.isScalar() &&
426  (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
428 
429  if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
431  }
432  }
433 
434  const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
435  unsigned Op0Size = Op0Ty.getSizeInBits();
436  InstType InstTy = InstType::Integer;
437 
438  switch (Opc) {
439  case G_TRUNC:
440  case G_SUB:
441  case G_MUL:
442  case G_UMULH:
443  case G_ZEXTLOAD:
444  case G_SEXTLOAD:
445  case G_GEP:
446  case G_INTTOPTR:
447  case G_PTRTOINT:
448  case G_AND:
449  case G_OR:
450  case G_XOR:
451  case G_SHL:
452  case G_ASHR:
453  case G_LSHR:
454  case G_SDIV:
455  case G_UDIV:
456  case G_SREM:
457  case G_UREM:
458  case G_BRINDIRECT:
459  case G_VASTART:
460  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
461  break;
462  case G_ADD:
463  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
464  if (Op0Size == 128)
465  OperandsMapping = getMSAMapping(MF);
466  break;
467  case G_STORE:
468  case G_LOAD:
469  if (Op0Size == 128) {
470  OperandsMapping = getOperandsMapping(
472  break;
473  }
474 
475  if (!Op0Ty.isPointer())
476  InstTy = TI.determineInstType(&MI);
477 
478  if (InstTy == InstType::FloatingPoint ||
479  (Op0Size == 64 && InstTy == InstType::Ambiguous))
480  OperandsMapping = getOperandsMapping(
482  else
483  OperandsMapping =
484  getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID),
486 
487  break;
488  case G_PHI:
489  if (!Op0Ty.isPointer())
490  InstTy = TI.determineInstType(&MI);
491 
492  // PHI is copylike and should have one regbank in mapping for def register.
493  if (InstTy == InstType::Integer && Op0Size == 64) {
494  OperandsMapping =
496  return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
497  /*NumOperands=*/1);
498  }
499  // Use default handling for PHI, i.e. set reg bank of def operand to match
500  // register banks of use operands.
501  return getInstrMappingImpl(MI);
502  case G_SELECT: {
503  if (!Op0Ty.isPointer())
504  InstTy = TI.determineInstType(&MI);
505 
506  if (InstTy == InstType::FloatingPoint ||
507  (Op0Size == 64 && InstTy == InstType::Ambiguous)) {
508  const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
509  OperandsMapping = getOperandsMapping(
510  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
511  break;
512  } else {
513  const RegisterBankInfo::ValueMapping *Bank =
514  getGprbOrCustomMapping(Op0Size, MappingID);
515  OperandsMapping = getOperandsMapping(
516  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
517  }
518  break;
519  }
520  case G_IMPLICIT_DEF:
521  if (!Op0Ty.isPointer())
522  InstTy = TI.determineInstType(&MI);
523 
524  if (InstTy == InstType::FloatingPoint)
525  OperandsMapping = getFprbMapping(Op0Size);
526  else
527  OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
528 
529  break;
530  case G_UNMERGE_VALUES:
533  &Mips::ValueMappings[Mips::DPRIdx]});
534  MappingID = CustomMappingID;
535  break;
536  case G_MERGE_VALUES:
539  &Mips::ValueMappings[Mips::GPRIdx]});
540  MappingID = CustomMappingID;
541  break;
542  case G_FADD:
543  case G_FSUB:
544  case G_FMUL:
545  case G_FDIV:
546  case G_FABS:
547  case G_FSQRT:
548  OperandsMapping = getFprbMapping(Op0Size);
549  break;
550  case G_FCONSTANT:
551  OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
552  break;
553  case G_FCMP: {
554  unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
555  OperandsMapping =
557  getFprbMapping(Op2Size), getFprbMapping(Op2Size)});
558  break;
559  }
560  case G_FPEXT:
563  break;
564  case G_FPTRUNC:
567  break;
568  case G_FPTOSI: {
569  assert((Op0Size == 32) && "Unsupported integer size");
570  unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
571  OperandsMapping = getOperandsMapping(
573  break;
574  }
575  case G_SITOFP:
576  assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) &&
577  "Unsupported integer size");
578  OperandsMapping = getOperandsMapping(
580  break;
581  case G_CONSTANT:
582  case G_FRAME_INDEX:
583  case G_GLOBAL_VALUE:
584  case G_JUMP_TABLE:
585  case G_BRCOND:
586  OperandsMapping =
588  break;
589  case G_BRJT:
590  OperandsMapping =
593  break;
594  case G_ICMP:
595  OperandsMapping =
598  &Mips::ValueMappings[Mips::GPRIdx]});
599  break;
600  default:
602  }
603 
604  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
605  NumOperands);
606 }
607 
609 namespace {
610 class InstManager : public GISelChangeObserver {
611  InstListTy &InstList;
612 
613 public:
614  InstManager(InstListTy &Insts) : InstList(Insts) {}
615 
616  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
617  void erasingInstr(MachineInstr &MI) override {}
618  void changingInstr(MachineInstr &MI) override {}
619  void changedInstr(MachineInstr &MI) override {}
620 };
621 } // end anonymous namespace
622 
624  MachineRegisterInfo &MRI) const {
625  Register Dest = MI.getOperand(0).getReg();
626  switch (MI.getOpcode()) {
627  case TargetOpcode::G_STORE:
628  // No def operands, skip this instruction.
629  break;
630  case TargetOpcode::G_CONSTANT:
631  case TargetOpcode::G_LOAD:
632  case TargetOpcode::G_SELECT:
633  case TargetOpcode::G_PHI:
634  case TargetOpcode::G_IMPLICIT_DEF: {
635  assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type.");
636  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
637  break;
638  }
639  case TargetOpcode::G_GEP: {
640  assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
641  MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
642  break;
643  }
644  default:
645  llvm_unreachable("Unexpected opcode.");
646  }
647 }
648 
649 static void
651  MachineInstr &MI) {
653  ArtCombiner.tryCombineMerges(MI, DeadInstrs);
654  for (MachineInstr *DeadMI : DeadInstrs)
655  DeadMI->eraseFromParent();
656 }
657 
659  const OperandsMapper &OpdMapper) const {
660  MachineInstr &MI = OpdMapper.getMI();
661  InstListTy NewInstrs;
662  MachineIRBuilder B(MI);
663  MachineFunction *MF = MI.getMF();
664  MachineRegisterInfo &MRI = OpdMapper.getMRI();
665  const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo();
666 
667  InstManager NewInstrObserver(NewInstrs);
668  GISelObserverWrapper WrapperObserver(&NewInstrObserver);
669  LegalizerHelper Helper(*MF, WrapperObserver, B);
670  LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo);
671 
672  switch (MI.getOpcode()) {
673  case TargetOpcode::G_LOAD:
674  case TargetOpcode::G_STORE:
675  case TargetOpcode::G_PHI:
676  case TargetOpcode::G_SELECT:
677  case TargetOpcode::G_IMPLICIT_DEF: {
678  Helper.narrowScalar(MI, 0, LLT::scalar(32));
679  // Handle new instructions.
680  while (!NewInstrs.empty()) {
681  MachineInstr *NewMI = NewInstrs.pop_back_val();
682  // This is new G_UNMERGE that was created during narrowScalar and will
683  // not be considered for regbank selection. RegBankSelect for mips
684  // visits/makes corresponding G_MERGE first. Combine them here.
685  if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
686  combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI);
687  // This G_MERGE will be combined away when its corresponding G_UNMERGE
688  // gets regBankSelected.
689  else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
690  continue;
691  else
692  // Manually set register banks for def operands to 32 bit gprb.
693  setRegBank(*NewMI, MRI);
694  }
695  return;
696  }
697  case TargetOpcode::G_UNMERGE_VALUES:
698  combineAwayG_UNMERGE_VALUES(ArtCombiner, MI);
699  return;
700  default:
701  break;
702  }
703 
704  return applyDefaultMapping(OpdMapper);
705 }
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End...
void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const
RegBankSelect determined that s64 operand is better to be split into two s32 operands in gprb...
static const MipsRegisterBankInfo::ValueMapping * getGprbOrCustomMapping(unsigned Size, unsigned &MappingID)
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
RegisterBankInfo::ValueMapping ValueMappings[]
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Helper class that represents how the value of an instruction may be mapped and what is the related co...
bool isScalar() const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
bool tryCombineMerges(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
bool empty() const
Definition: GISelWorkList.h:42
unsigned Reg
MachineRegisterInfo & getMRI() const
The MachineRegisterInfo we used to realize the mapping.
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
static const MipsRegisterBankInfo::ValueMapping * getMSAMapping(const MachineFunction &MF)
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
unsigned const TargetRegisterInfo * TRI
void setRegBank(unsigned Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:476
static const unsigned CustomMappingID
static bool isFloatingPointOpcodeUse(unsigned Opc)
bool isVector() const
static bool isFloatingPointOpcode(unsigned Opc)
Holds all the information related to register banks.
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:413
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:410
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
static bool isFloatingPointOpcodeDef(unsigned Opc)
unsigned getID() const
Return the register class ID number.
static bool isAmbiguous(unsigned Opc)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
This file declares the targeting of the RegisterBankInfo class for Mips.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
virtual const LegalizerInfo * getLegalizerInfo() const
Abstract class that contains various methods for clients to notify about changes. ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstrBuilder & UseMI
Helper struct that represents how a value is partially mapped into a register.
Helper class to build MachineInstr.
use_instr_iterator use_instr_begin(unsigned RegNo) const
RegisterBankInfo::PartialMapping PartMappings[]
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...
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static const MipsRegisterBankInfo::ValueMapping * getFprbMapping(unsigned Size)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isValid() const
Check whether this object is valid.
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:374
MachineInstr * pop_back_val()
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn&#39;t already in it.
Definition: GISelWorkList.h:78
This class implements the register bank concept.
Definition: RegisterBank.h:28
Helper struct that represents how a value is mapped through different register banks.
bool isPointer() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:255
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
uint32_t Size
Definition: Profile.cpp:46
iterator_range< use_instr_iterator > use_instructions(unsigned Reg) const
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, MachineInstr &MI)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Simple wrapper observer that takes several observers, and calls each one for each event...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override
Get a register bank that covers RC.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19