LLVM 22.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 bool isInteger_64(InstType InstTy, unsigned OpSize) const {
117 return InstTy == InstType::Integer && OpSize == 64;
118 }
119
120 /// Some generic instructions have operands that can be mapped to either fprb
121 /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1
122 /// is always gprb since it is a pointer.
123 /// This class provides containers for MI's ambiguous:
124 /// DefUses : MachineInstrs that use one of MI's ambiguous def operands.
125 /// UseDefs : MachineInstrs that define MI's ambiguous use operands.
126 class AmbiguousRegDefUseContainer {
129
130 void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
131 void addUseDef(Register Reg, const MachineRegisterInfo &MRI);
132
133 /// Skip copy instructions until we get to a non-copy instruction or to a
134 /// copy with phys register as def. Used during search for DefUses.
135 /// MI : %5 = COPY %4
136 /// %6 = COPY %5
137 /// $v0 = COPY %6 <- we want this one.
138 MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const;
139
140 /// Skip copy instructions until we get to a non-copy instruction or to a
141 /// copy with phys register as use. Used during search for UseDefs.
142 /// %1 = COPY $a1 <- we want this one.
143 /// %2 = COPY %1
144 /// MI = %3 = COPY %2
145 MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;
146
147 public:
148 AmbiguousRegDefUseContainer(const MachineInstr *MI);
149 SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
150 SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; }
151 };
152
153 class TypeInfoForMF {
154 /// MachineFunction name is used to recognise when MF changes.
155 std::string MFName;
156 /// <key, value> : value is vector of all MachineInstrs that are waiting for
157 /// key to figure out type of some of its ambiguous operands.
159 WaitingQueues;
160 /// Recorded InstTypes for visited instructions.
162
163 /// Recursively visit MI's adjacent instructions and find MI's InstType.
164 bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
165 InstType &AmbiguousTy);
166
167 /// Visit MI's adjacent UseDefs or DefUses.
168 bool visitAdjacentInstrs(const MachineInstr *MI,
169 SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
170 bool isDefUse, InstType &AmbiguousTy);
171
172 /// Set type for MI, and recursively for all instructions that are
173 /// waiting for MI's type.
174 void setTypes(const MachineInstr *MI, InstType ITy);
175
176 /// InstType for MI is determined, set it to InstType that corresponds to
177 /// physical regisiter that is operand number Op in CopyInst.
178 void setTypesAccordingToPhysicalRegister(const MachineInstr *MI,
179 const MachineInstr *CopyInst,
180 unsigned Op);
181
182 /// Set default values for MI in order to start visit.
183 void startVisit(const MachineInstr *MI) {
184 Types.try_emplace(MI, InstType::NotDetermined);
185 WaitingQueues.try_emplace(MI);
186 }
187
188 /// Returns true if instruction was already visited. Type might not be
189 /// determined at this point but will be when visit(..., nullptr) finishes.
190 bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); };
191
192 /// Returns recorded type for instruction.
193 const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const {
194 assert(wasVisited(MI) && "Instruction was not visited!");
195 return Types.find(MI)->getSecond();
196 };
197
198 /// Change recorded type for instruction.
199 void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) {
200 assert(wasVisited(MI) && "Instruction was not visited!");
201 Types.find(MI)->getSecond() = InstTy;
202 };
203
204 /// Returns WaitingQueue for instruction.
206 getWaitingQueueFor(const MachineInstr *MI) const {
207 assert(WaitingQueues.count(MI) && "Instruction was not visited!");
208 return WaitingQueues.find(MI)->getSecond();
209 };
210
211 /// Add WaitingForMI to MI's WaitingQueue.
212 void addToWaitingQueue(const MachineInstr *MI,
213 const MachineInstr *WaitingForMI) {
214 assert(WaitingQueues.count(MI) && "Instruction was not visited!");
215 WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI);
216 };
217
218 public:
219 InstType determineInstType(const MachineInstr *MI);
220
221 void cleanupIfNewFunction(llvm::StringRef FunctionName);
222
223 /// MI is about to get destroyed (using narrow scalar). Internal data is
224 /// saved based on MI's address, clear it since it is no longer valid.
225 void clearTypeInfoData(const MachineInstr *MI) {
226 Types.erase(MI);
227 WaitingQueues.erase(MI);
228 };
229 };
230};
231} // end namespace llvm
232#endif
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:256
bool erase(const KeyT &Val)
Definition DenseMap.h:330
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:174
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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...
MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
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...
RegisterBankInfo(const RegisterBank **RegBanks, unsigned NumRegBanks, const unsigned *Sizes, unsigned HwMode)
Create a RegisterBankInfo that can accommodate up to NumRegBanks RegisterBank instances.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
DWARFExpression::Operation Op