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 | |
16 | #include "llvm/CodeGen/RegisterBankInfo.h" |
17 | |
18 | #define GET_REGBANK_DECLARATIONS |
19 | #include "MipsGenRegisterBank.inc" |
20 | |
21 | namespace llvm { |
22 | |
23 | class TargetRegisterInfo; |
24 | |
25 | class MipsGenRegisterBankInfo : public RegisterBankInfo { |
26 | #define GET_TARGET_REGBANK_CLASS |
27 | #include "MipsGenRegisterBank.inc" |
28 | }; |
29 | |
30 | /// This class provides the information for the target register banks. |
31 | class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo { |
32 | public: |
33 | MipsRegisterBankInfo(const TargetRegisterInfo &TRI); |
34 | |
35 | const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, |
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(MachineIRBuilder &Builder, |
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. |
51 | void setRegBank(MachineInstr &MI, MachineRegisterInfo &MRI) const; |
52 | |
53 | private: |
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 { |
126 | SmallVector<MachineInstr *, 2> DefUses; |
127 | SmallVector<MachineInstr *, 2> UseDefs; |
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. |
157 | DenseMap<const MachineInstr *, SmallVector<const MachineInstr *, 2>> |
158 | WaitingQueues; |
159 | /// Recorded InstTypes for visited instructions. |
160 | DenseMap<const MachineInstr *, InstType> Types; |
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(Key: MI, Args: InstType::NotDetermined); |
184 | WaitingQueues.try_emplace(Key: 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(Val: 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(Val: 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(Val: MI)->getSecond() = InstTy; |
201 | }; |
202 | |
203 | /// Returns WaitingQueue for instruction. |
204 | const SmallVectorImpl<const MachineInstr *> & |
205 | getWaitingQueueFor(const MachineInstr *MI) const { |
206 | assert(WaitingQueues.count(MI) && "Instruction was not visited!" ); |
207 | return WaitingQueues.find(Val: 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(Val: MI)->getSecond().push_back(Elt: 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(Val: MI); |
226 | WaitingQueues.erase(Val: MI); |
227 | }; |
228 | }; |
229 | }; |
230 | } // end namespace llvm |
231 | #endif |
232 | |