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"
19 
20 #define GET_TARGET_REGBANK_IMPL
21 
22 #include "MipsGenRegisterBank.inc"
23 
24 namespace llvm {
25 namespace Mips {
31 };
32 
34  {0, 32, GPRBRegBank},
35  {0, 32, FPRBRegBank},
36  {0, 64, FPRBRegBank}
37 };
38 
41  GPRIdx = 1,
42  SPRIdx = 4,
43  DPRIdx = 7
44 };
45 
47  // invalid
48  {nullptr, 0},
49  // up to 3 operands in GPRs
50  {&PartMappings[PMI_GPR - PMI_Min], 1},
51  {&PartMappings[PMI_GPR - PMI_Min], 1},
52  {&PartMappings[PMI_GPR - PMI_Min], 1},
53  // up to 3 ops operands FPRs - single precission
54  {&PartMappings[PMI_SPR - PMI_Min], 1},
55  {&PartMappings[PMI_SPR - PMI_Min], 1},
56  {&PartMappings[PMI_SPR - PMI_Min], 1},
57  // up to 3 ops operands FPRs - double precission
58  {&PartMappings[PMI_DPR - PMI_Min], 1},
59  {&PartMappings[PMI_DPR - PMI_Min], 1},
61 };
62 
63 } // end namespace Mips
64 } // end namespace llvm
65 
66 using namespace llvm;
67 
70 
72  const TargetRegisterClass &RC) const {
73  using namespace Mips;
74 
75  switch (RC.getID()) {
76  case Mips::GPR32RegClassID:
77  case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
78  case Mips::GPRMM16MovePPairFirstRegClassID:
79  case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
80  case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
81  case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
82  case Mips::SP32RegClassID:
83  case Mips::GP32RegClassID:
84  return getRegBank(Mips::GPRBRegBankID);
85  case Mips::FGRCCRegClassID:
86  case Mips::FGR32RegClassID:
87  case Mips::FGR64RegClassID:
88  case Mips::AFGR64RegClassID:
89  return getRegBank(Mips::FPRBRegBankID);
90  default:
91  llvm_unreachable("Register class not supported");
92  }
93 }
94 
95 // Instructions where all register operands are floating point.
96 static bool isFloatingPointOpcode(unsigned Opc) {
97  switch (Opc) {
98  case TargetOpcode::G_FCONSTANT:
99  case TargetOpcode::G_FADD:
100  case TargetOpcode::G_FSUB:
101  case TargetOpcode::G_FMUL:
102  case TargetOpcode::G_FDIV:
103  case TargetOpcode::G_FABS:
104  case TargetOpcode::G_FSQRT:
105  case TargetOpcode::G_FCEIL:
106  case TargetOpcode::G_FFLOOR:
107  case TargetOpcode::G_FPEXT:
108  case TargetOpcode::G_FPTRUNC:
109  return true;
110  default:
111  return false;
112  }
113 }
114 
115 // Instructions where use operands are floating point registers.
116 // Def operands are general purpose.
117 static bool isFloatingPointOpcodeUse(unsigned Opc) {
118  switch (Opc) {
119  case TargetOpcode::G_FPTOSI:
120  case TargetOpcode::G_FPTOUI:
121  case TargetOpcode::G_FCMP:
122  case Mips::MFC1:
124  case Mips::ExtractElementF64_64:
125  return true;
126  default:
127  return isFloatingPointOpcode(Opc);
128  }
129 }
130 
131 // Instructions where def operands are floating point registers.
132 // Use operands are general purpose.
133 static bool isFloatingPointOpcodeDef(unsigned Opc) {
134  switch (Opc) {
135  case TargetOpcode::G_SITOFP:
136  case TargetOpcode::G_UITOFP:
137  case Mips::MTC1:
138  case Mips::BuildPairF64:
139  case Mips::BuildPairF64_64:
140  return true;
141  default:
142  return isFloatingPointOpcode(Opc);
143  }
144 }
145 
146 static bool isAmbiguous(unsigned Opc) {
147  switch (Opc) {
148  case TargetOpcode::G_LOAD:
149  case TargetOpcode::G_STORE:
150  case TargetOpcode::G_PHI:
151  case TargetOpcode::G_SELECT:
152  case TargetOpcode::G_IMPLICIT_DEF:
153  return true;
154  default:
155  return false;
156  }
157 }
158 
159 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
161  assert(!MRI.getType(Reg).isPointer() &&
162  "Pointers are gprb, they should not be considered as ambiguous.\n");
163  for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
164  MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
165  // Copy with many uses.
166  if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
167  !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg()))
168  addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
169  else
170  DefUses.push_back(skipCopiesOutgoing(&UseMI));
171  }
172 }
173 
174 void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
175  Register Reg, const MachineRegisterInfo &MRI) {
176  assert(!MRI.getType(Reg).isPointer() &&
177  "Pointers are gprb, they should not be considered as ambiguous.\n");
178  MachineInstr *DefMI = MRI.getVRegDef(Reg);
179  UseDefs.push_back(skipCopiesIncoming(DefMI));
180 }
181 
182 MachineInstr *
183 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
184  MachineInstr *MI) const {
185  const MachineFunction &MF = *MI->getParent()->getParent();
186  const MachineRegisterInfo &MRI = MF.getRegInfo();
187  MachineInstr *Ret = MI;
188  while (Ret->getOpcode() == TargetOpcode::COPY &&
190  MRI.hasOneUse(Ret->getOperand(0).getReg())) {
191  Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
192  }
193  return Ret;
194 }
195 
196 MachineInstr *
197 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
198  MachineInstr *MI) const {
199  const MachineFunction &MF = *MI->getParent()->getParent();
200  const MachineRegisterInfo &MRI = MF.getRegInfo();
201  MachineInstr *Ret = MI;
202  while (Ret->getOpcode() == TargetOpcode::COPY &&
204  Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
205  return Ret;
206 }
207 
208 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
209  const MachineInstr *MI) {
210  assert(isAmbiguous(MI->getOpcode()) &&
211  "Not implemented for non Ambiguous opcode.\n");
212 
213  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
214 
215  if (MI->getOpcode() == TargetOpcode::G_LOAD)
216  addDefUses(MI->getOperand(0).getReg(), MRI);
217 
218  if (MI->getOpcode() == TargetOpcode::G_STORE)
219  addUseDef(MI->getOperand(0).getReg(), MRI);
220 
221  if (MI->getOpcode() == TargetOpcode::G_PHI) {
222  addDefUses(MI->getOperand(0).getReg(), MRI);
223 
224  for (unsigned i = 1; i < MI->getNumOperands(); i += 2)
225  addUseDef(MI->getOperand(i).getReg(), MRI);
226  }
227 
228  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
229  addDefUses(MI->getOperand(0).getReg(), MRI);
230 
231  addUseDef(MI->getOperand(2).getReg(), MRI);
232  addUseDef(MI->getOperand(3).getReg(), MRI);
233  }
234 
235  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
236  addDefUses(MI->getOperand(0).getReg(), MRI);
237 }
238 
239 bool MipsRegisterBankInfo::TypeInfoForMF::visit(
240  const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI) {
241  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
242  if (wasVisited(MI))
243  return true; // InstType has already been determined for MI.
244 
245  startVisit(MI);
246  AmbiguousRegDefUseContainer DefUseContainer(MI);
247 
248  // Visit instructions where MI's DEF operands are USED.
249  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true))
250  return true;
251 
252  // Visit instructions that DEFINE MI's USE operands.
253  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false))
254  return true;
255 
256  // All MI's adjacent instructions, are ambiguous.
257  if (!WaitingForTypeOfMI) {
258  // This is chain of ambiguous instructions.
259  setTypes(MI, InstType::Ambiguous);
260  return true;
261  }
262  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
263  // instructions or has no other adjacent instructions. Anyway InstType could
264  // not be determined. There could be unexplored path from some of
265  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
266  // mapping available.
267  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
268  // this way when WaitingForTypeOfMI figures out its InstType same InstType
269  // will be assigned to all instructions in this branch.
270  addToWaitingQueue(WaitingForTypeOfMI, MI);
271  return false;
272 }
273 
274 bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
275  const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
276  bool isDefUse) {
277  while (!AdjacentInstrs.empty()) {
278  MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();
279 
280  if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
281  : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
282  setTypes(MI, InstType::FloatingPoint);
283  return true;
284  }
285 
286  // Determine InstType from register bank of phys register that is
287  // 'isDefUse ? def : use' of this copy.
288  if (AdjMI->getOpcode() == TargetOpcode::COPY) {
289  setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
290  return true;
291  }
292 
293  // Defaults to integer instruction. Includes G_MERGE_VALUES and
294  // G_UNMERGE_VALUES.
295  if (!isAmbiguous(AdjMI->getOpcode())) {
296  setTypes(MI, InstType::Integer);
297  return true;
298  }
299 
300  // When AdjMI was visited first, MI has to continue to explore remaining
301  // adjacent instructions and determine InstType without visiting AdjMI.
302  if (!wasVisited(AdjMI) ||
303  getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
304  if (visit(AdjMI, MI)) {
305  // InstType is successfully determined and is same as for AdjMI.
306  setTypes(MI, getRecordedTypeForInstr(AdjMI));
307  return true;
308  }
309  }
310  }
311  return false;
312 }
313 
314 void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
315  InstType InstTy) {
316  changeRecordedTypeForInstr(MI, InstTy);
317  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
318  setTypes(WaitingInstr, InstTy);
319  }
320 }
321 
322 void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
323  const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
325  "Copies of non physical registers should not be considered here.\n");
326 
327  const MachineFunction &MF = *CopyInst->getMF();
328  const MachineRegisterInfo &MRI = MF.getRegInfo();
329  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
330  const RegisterBankInfo &RBI =
331  *CopyInst->getMF()->getSubtarget().getRegBankInfo();
332  const RegisterBank *Bank =
333  RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);
334 
335  if (Bank == &Mips::FPRBRegBank)
336  setTypes(MI, InstType::FloatingPoint);
337  else if (Bank == &Mips::GPRBRegBank)
338  setTypes(MI, InstType::Integer);
339  else
340  llvm_unreachable("Unsupported register bank.\n");
341 }
342 
343 MipsRegisterBankInfo::InstType
344 MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
345  visit(MI, nullptr);
346  return getRecordedTypeForInstr(MI);
347 }
348 
349 void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
350  llvm::StringRef FunctionName) {
351  if (MFName != FunctionName) {
352  MFName = FunctionName;
353  WaitingQueues.clear();
354  Types.clear();
355  }
356 }
357 
360 
361  static TypeInfoForMF TI;
362 
363  // Reset TI internal data when MF changes.
364  TI.cleanupIfNewFunction(MI.getMF()->getName());
365 
366  unsigned Opc = MI.getOpcode();
367  const MachineFunction &MF = *MI.getParent()->getParent();
368  const MachineRegisterInfo &MRI = MF.getRegInfo();
369 
370  if (MI.getOpcode() != TargetOpcode::G_PHI) {
371  const RegisterBankInfo::InstructionMapping &Mapping =
373  if (Mapping.isValid())
374  return Mapping;
375  }
376 
377  using namespace TargetOpcode;
378 
379  unsigned NumOperands = MI.getNumOperands();
380  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
381  unsigned MappingID = DefaultMappingID;
382  const unsigned CustomMappingID = 1;
383 
384  switch (Opc) {
385  case G_TRUNC:
386  case G_ADD:
387  case G_SUB:
388  case G_MUL:
389  case G_UMULH:
390  case G_ZEXTLOAD:
391  case G_SEXTLOAD:
392  case G_GEP:
393  case G_INTTOPTR:
394  case G_PTRTOINT:
395  case G_AND:
396  case G_OR:
397  case G_XOR:
398  case G_SHL:
399  case G_ASHR:
400  case G_LSHR:
401  case G_SDIV:
402  case G_UDIV:
403  case G_SREM:
404  case G_UREM:
405  case G_BRINDIRECT:
406  OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
407  break;
408  case G_LOAD: {
409  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
410  InstType InstTy = InstType::Integer;
411  if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
412  InstTy = TI.determineInstType(&MI);
413  }
414 
415  if (InstTy == InstType::FloatingPoint ||
416  (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb
417  OperandsMapping =
421  break;
422  } else { // gprb
423  OperandsMapping =
427  if (Size == 64)
428  MappingID = CustomMappingID;
429  }
430 
431  break;
432  }
433  case G_STORE: {
434  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
435  InstType InstTy = InstType::Integer;
436  if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
437  InstTy = TI.determineInstType(&MI);
438  }
439 
440  if (InstTy == InstType::FloatingPoint ||
441  (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb
442  OperandsMapping =
446  break;
447  } else { // gprb
448  OperandsMapping =
452  if (Size == 64)
453  MappingID = CustomMappingID;
454  }
455  break;
456  }
457  case G_PHI: {
458  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
459  InstType InstTy = InstType::Integer;
460  if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
461  InstTy = TI.determineInstType(&MI);
462  }
463 
464  // PHI is copylike and should have one regbank in mapping for def register.
465  if (InstTy == InstType::Integer && Size == 64) { // fprb
466  OperandsMapping =
468  return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
469  /*NumOperands=*/1);
470  }
471  // Use default handling for PHI, i.e. set reg bank of def operand to match
472  // register banks of use operands.
473  const RegisterBankInfo::InstructionMapping &Mapping =
475  return Mapping;
476  }
477  case G_SELECT: {
478  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
479  InstType InstTy = InstType::Integer;
480  if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
481  InstTy = TI.determineInstType(&MI);
482  }
483 
484  if (InstTy == InstType::FloatingPoint ||
485  (Size == 64 && InstTy == InstType::Ambiguous)) { // fprb
486  const RegisterBankInfo::ValueMapping *Bank =
487  Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
489  OperandsMapping = getOperandsMapping(
490  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
491  break;
492  } else { // gprb
493  const RegisterBankInfo::ValueMapping *Bank =
494  Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx]
496  OperandsMapping = getOperandsMapping(
497  {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
498  if (Size == 64)
499  MappingID = CustomMappingID;
500  }
501  break;
502  }
503  case G_IMPLICIT_DEF: {
504  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
505  InstType InstTy = InstType::Integer;
506  if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
507  InstTy = TI.determineInstType(&MI);
508  }
509 
510  if (InstTy == InstType::FloatingPoint) { // fprb
511  OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
513  } else { // gprb
514  OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::GPRIdx]
516  if (Size == 64)
517  MappingID = CustomMappingID;
518  }
519  break;
520  }
521  case G_UNMERGE_VALUES: {
524  &Mips::ValueMappings[Mips::DPRIdx]});
525  MappingID = CustomMappingID;
526  break;
527  }
528  case G_MERGE_VALUES: {
531  &Mips::ValueMappings[Mips::GPRIdx]});
532  MappingID = CustomMappingID;
533  break;
534  }
535  case G_FADD:
536  case G_FSUB:
537  case G_FMUL:
538  case G_FDIV:
539  case G_FABS:
540  case G_FSQRT:{
541  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
542  assert((Size == 32 || Size == 64) && "Unsupported floating point size");
543  OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
545  break;
546  }
547  case G_FCONSTANT: {
548  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
549  assert((Size == 32 || Size == 64) && "Unsupported floating point size");
550  const RegisterBankInfo::ValueMapping *FPRValueMapping =
551  Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
553  OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
554  break;
555  }
556  case G_FCMP: {
557  unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
558  assert((Size == 32 || Size == 64) && "Unsupported floating point size");
559  const RegisterBankInfo::ValueMapping *FPRValueMapping =
560  Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
562  OperandsMapping =
564  FPRValueMapping, FPRValueMapping});
565  break;
566  }
567  case G_FPEXT:
570  break;
571  case G_FPTRUNC:
574  break;
575  case G_FPTOSI: {
576  unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
577  assert((MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 32) &&
578  "Unsupported integer size");
579  assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
580  OperandsMapping = getOperandsMapping({
582  SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
584  });
585  break;
586  }
587  case G_SITOFP: {
588  unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
589  unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
590  (void)SizeInt;
591  assert((SizeInt == 32) && "Unsupported integer size");
592  assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
593  OperandsMapping =
597  break;
598  }
599  case G_CONSTANT:
600  case G_FRAME_INDEX:
601  case G_GLOBAL_VALUE:
602  case G_JUMP_TABLE:
603  case G_BRCOND:
604  OperandsMapping =
606  break;
607  case G_BRJT:
608  OperandsMapping =
611  break;
612  case G_ICMP:
613  OperandsMapping =
616  &Mips::ValueMappings[Mips::GPRIdx]});
617  break;
618  default:
620  }
621 
622  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
623  NumOperands);
624 }
625 
627 namespace {
628 class InstManager : public GISelChangeObserver {
629  InstListTy &InstList;
630 
631 public:
632  InstManager(InstListTy &Insts) : InstList(Insts) {}
633 
634  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
635  void erasingInstr(MachineInstr &MI) override {}
636  void changingInstr(MachineInstr &MI) override {}
637  void changedInstr(MachineInstr &MI) override {}
638 };
639 } // end anonymous namespace
640 
641 /// Here we have to narrowScalar s64 operands to s32, combine away
642 /// G_MERGE/G_UNMERGE and erase instructions that became dead in the process.
643 /// We manually assign 32 bit gprb to register operands of all new instructions
644 /// that got created in the process since they will not end up in RegBankSelect
645 /// loop. Careful not to delete instruction after MI i.e. MI.getIterator()++.
647  const OperandsMapper &OpdMapper) const {
648  MachineInstr &MI = OpdMapper.getMI();
649  InstListTy NewInstrs;
650  MachineIRBuilder B(MI);
651  MachineFunction *MF = MI.getMF();
652  MachineRegisterInfo &MRI = OpdMapper.getMRI();
653 
654  InstManager NewInstrObserver(NewInstrs);
655  GISelObserverWrapper WrapperObserver(&NewInstrObserver);
656  LegalizerHelper Helper(*MF, WrapperObserver, B);
657  LegalizationArtifactCombiner ArtCombiner(
658  B, MF->getRegInfo(), *MF->getSubtarget().getLegalizerInfo());
659 
660  switch (MI.getOpcode()) {
661  case TargetOpcode::G_LOAD:
662  case TargetOpcode::G_STORE:
663  case TargetOpcode::G_PHI:
664  case TargetOpcode::G_SELECT:
665  case TargetOpcode::G_IMPLICIT_DEF: {
666  Helper.narrowScalar(MI, 0, LLT::scalar(32));
667  // Handle new instructions.
668  while (!NewInstrs.empty()) {
669  MachineInstr *NewMI = NewInstrs.pop_back_val();
670  // This is new G_UNMERGE that was created during narrowScalar and will
671  // not be considered for regbank selection. RegBankSelect for mips
672  // visits/makes corresponding G_MERGE first. Combine them here.
673  if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {
675  ArtCombiner.tryCombineMerges(*NewMI, DeadInstrs);
676  for (MachineInstr *DeadMI : DeadInstrs)
677  DeadMI->eraseFromParent();
678  }
679  // This G_MERGE will be combined away when its corresponding G_UNMERGE
680  // gets regBankSelected.
681  else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
682  continue;
683  else
684  // Manually set register banks for all register operands to 32 bit gprb.
685  for (auto Op : NewMI->operands()) {
686  if (Op.isReg()) {
687  assert(MRI.getType(Op.getReg()).getSizeInBits() == 32 &&
688  "Only 32 bit gprb is handled here.\n");
689  MRI.setRegBank(Op.getReg(), getRegBank(Mips::GPRBRegBankID));
690  }
691  }
692  }
693  return;
694  }
695  case TargetOpcode::G_UNMERGE_VALUES: {
697  ArtCombiner.tryCombineMerges(MI, DeadInstrs);
698  for (MachineInstr *DeadMI : DeadInstrs)
699  DeadMI->eraseFromParent();
700  return;
701  }
702  default:
703  break;
704  }
705 
706  return applyDefaultMapping(OpdMapper);
707 }
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End...
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...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
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...
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:477
LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
static bool isFloatingPointOpcodeUse(unsigned Opc)
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:414
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
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/G_UNMERGE and erase instructio...
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...
#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.
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
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:256
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:64
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)
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:416
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