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