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