LLVM  14.0.0git
MipsRegisterBankInfo.h
Go to the documentation of this file.
1 //===- MipsRegisterBankInfo.h -----------------------------------*- 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 declares the targeting of the RegisterBankInfo class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H
14 #define LLVM_LIB_TARGET_MIPS_MIPSREGISTERBANKINFO_H
15 
17 
18 #define GET_REGBANK_DECLARATIONS
19 #include "MipsGenRegisterBank.inc"
20 
21 namespace llvm {
22 
23 class TargetRegisterInfo;
24 
26 #define GET_TARGET_REGBANK_CLASS
27 #include "MipsGenRegisterBank.inc"
28 };
29 
30 /// This class provides the information for the target register banks.
32 public:
34 
36  LLT) const override;
37 
38  const InstructionMapping &
39  getInstrMapping(const MachineInstr &MI) const override;
40 
41  /// Here we have to narrowScalar s64 operands to s32, combine away G_MERGE or
42  /// G_UNMERGE and erase instructions that became dead in the process. We
43  /// manually assign bank to def operand of all new instructions that were
44  /// created in the process since they will not end up in RegBankSelect loop.
45  void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
46 
47  /// RegBankSelect determined that s64 operand is better to be split into two
48  /// s32 operands in gprb. Here we manually set register banks of def operands
49  /// of newly created instructions since they will not get regbankselected.
51 
52 private:
53  /// Some instructions are used with both floating point and integer operands.
54  /// We assign InstType to such instructions as it helps us to avoid cross bank
55  /// copies. InstType deppends on context.
56  enum InstType {
57  /// Temporary type, when visit(..., nullptr) finishes will convert to one of
58  /// the remaining types: Integer, FloatingPoint or Ambiguous.
59  NotDetermined,
60  /// Connected with instruction that interprets 'bags of bits' as integers.
61  /// Select gprb to avoid cross bank copies.
62  Integer,
63  /// Connected with instruction that interprets 'bags of bits' as floating
64  /// point numbers. Select fprb to avoid cross bank copies.
65  FloatingPoint,
66  /// Represents moving 'bags of bits' around. Select same bank for entire
67  /// chain to avoid cross bank copies. Currently we select fprb for s64 and
68  /// gprb for s32 Ambiguous operands.
69  Ambiguous,
70  /// Only used for s64. Unlike Ambiguous s64, AmbiguousWithMergeOrUnmerge s64
71  /// is mapped to gprb (legalized using narrow scalar to s32).
72  AmbiguousWithMergeOrUnmerge
73  };
74 
75  bool isAmbiguous_64(InstType InstTy, unsigned OpSize) const {
76  if (InstTy == InstType::Ambiguous && OpSize == 64)
77  return true;
78  return false;
79  }
80 
81  bool isAmbiguous_32(InstType InstTy, unsigned OpSize) const {
82  if (InstTy == InstType::Ambiguous && OpSize == 32)
83  return true;
84  return false;
85  }
86 
87  bool isAmbiguous_32or64(InstType InstTy, unsigned OpSize) const {
88  if (InstTy == InstType::Ambiguous && (OpSize == 32 || OpSize == 64))
89  return true;
90  return false;
91  }
92 
93  bool isAmbiguousWithMergeOrUnmerge_64(InstType InstTy,
94  unsigned OpSize) const {
95  if (InstTy == InstType::AmbiguousWithMergeOrUnmerge && OpSize == 64)
96  return true;
97  return false;
98  }
99 
100  bool isFloatingPoint_32or64(InstType InstTy, unsigned OpSize) const {
101  if (InstTy == InstType::FloatingPoint && (OpSize == 32 || OpSize == 64))
102  return true;
103  return false;
104  }
105 
106  bool isFloatingPoint_64(InstType InstTy, unsigned OpSize) const {
107  if (InstTy == InstType::FloatingPoint && OpSize == 64)
108  return true;
109  return false;
110  }
111 
112  bool isInteger_32(InstType InstTy, unsigned OpSize) const {
113  if (InstTy == InstType::Integer && OpSize == 32)
114  return true;
115  return false;
116  }
117 
118  /// Some generic instructions have operands that can be mapped to either fprb
119  /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
120  /// is always gprb since it is a pointer.
121  /// This class provides containers for MI's ambiguous:
122  /// DefUses : MachineInstrs that use one of MI's ambiguous def operands.
123  /// UseDefs : MachineInstrs that define MI's ambiguous use operands.
124  class AmbiguousRegDefUseContainer {
127 
128  void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
129  void addUseDef(Register Reg, const MachineRegisterInfo &MRI);
130 
131  /// Skip copy instructions until we get to a non-copy instruction or to a
132  /// copy with phys register as def. Used during search for DefUses.
133  /// MI : %5 = COPY %4
134  /// %6 = COPY %5
135  /// $v0 = COPY %6 <- we want this one.
136  MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const;
137 
138  /// Skip copy instructions until we get to a non-copy instruction or to a
139  /// copy with phys register as use. Used during search for UseDefs.
140  /// %1 = COPY $a1 <- we want this one.
141  /// %2 = COPY %1
142  /// MI = %3 = COPY %2
143  MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;
144 
145  public:
146  AmbiguousRegDefUseContainer(const MachineInstr *MI);
147  SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
148  SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
149  };
150 
151  class TypeInfoForMF {
152  /// MachineFunction name is used to recognise when MF changes.
153  std::string MFName;
154  /// <key, value> : value is vector of all MachineInstrs that are waiting for
155  /// key to figure out type of some of its ambiguous operands.
157  WaitingQueues;
158  /// Recorded InstTypes for visited instructions.
160 
161  /// Recursively visit MI's adjacent instructions and find MI's InstType.
162  bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
163  InstType &AmbiguousTy);
164 
165  /// Visit MI's adjacent UseDefs or DefUses.
166  bool visitAdjacentInstrs(const MachineInstr *MI,
167  SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
168  bool isDefUse, InstType &AmbiguousTy);
169 
170  /// Set type for MI, and recursively for all instructions that are
171  /// waiting for MI's type.
172  void setTypes(const MachineInstr *MI, InstType ITy);
173 
174  /// InstType for MI is determined, set it to InstType that corresponds to
175  /// physical regisiter that is operand number Op in CopyInst.
176  void setTypesAccordingToPhysicalRegister(const MachineInstr *MI,
177  const MachineInstr *CopyInst,
178  unsigned Op);
179 
180  /// Set default values for MI in order to start visit.
181  void startVisit(const MachineInstr *MI) {
182  Types.try_emplace(MI, InstType::NotDetermined);
183  WaitingQueues.try_emplace(MI);
184  }
185 
186  /// Returns true if instruction was already visited. Type might not be
187  /// determined at this point but will be when visit(..., nullptr) finishes.
188  bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); };
189 
190  /// Returns recorded type for instruction.
191  const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const {
192  assert(wasVisited(MI) && "Instruction was not visited!");
193  return Types.find(MI)->getSecond();
194  };
195 
196  /// Change recorded type for instruction.
197  void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) {
198  assert(wasVisited(MI) && "Instruction was not visited!");
199  Types.find(MI)->getSecond() = InstTy;
200  };
201 
202  /// Returns WaitingQueue for instruction.
204  getWaitingQueueFor(const MachineInstr *MI) const {
205  assert(WaitingQueues.count(MI) && "Instruction was not visited!");
206  return WaitingQueues.find(MI)->getSecond();
207  };
208 
209  /// Add WaitingForMI to MI's WaitingQueue.
210  void addToWaitingQueue(const MachineInstr *MI,
211  const MachineInstr *WaitingForMI) {
212  assert(WaitingQueues.count(MI) && "Instruction was not visited!");
213  WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI);
214  };
215 
216  public:
217  InstType determineInstType(const MachineInstr *MI);
218 
219  void cleanupIfNewFunction(llvm::StringRef FunctionName);
220 
221  /// MI is about to get destroyed (using narrow scalar). Internal data is
222  /// saved based on MI's address, clear it since it is no longer valid.
223  void clearTypeInfoData(const MachineInstr *MI) {
224  Types.erase(MI);
225  WaitingQueues.erase(MI);
226  };
227  };
228 };
229 } // end namespace llvm
230 #endif
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:728
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1558
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
RegisterBankInfo.h
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::MipsRegisterBankInfo::MipsRegisterBankInfo
MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
Definition: MipsRegisterBankInfo.cpp:76
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
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
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::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
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::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
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
llvm::DenseMap
Definition: DenseMap.h:714
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:325
llvm::MipsRegisterBankInfo
This class provides the information for the target register banks.
Definition: MipsRegisterBankInfo.h:31
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::try_emplace
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:222
llvm::SmallVectorImpl< MachineInstr * >
llvm::MipsRegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
Definition: MipsRegisterBankInfo.cpp:80
llvm::MipsGenRegisterBankInfo
Definition: MipsRegisterBankInfo.h:25
llvm::LLT
Definition: LowLevelTypeImpl.h:40