/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86RegisterBankInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// \file |
10 | | /// This file implements the targeting of the RegisterBankInfo class for X86. |
11 | | /// \todo This should be generated by TableGen. |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "X86RegisterBankInfo.h" |
15 | | #include "X86InstrInfo.h" |
16 | | #include "llvm/CodeGen/GlobalISel/RegisterBank.h" |
17 | | #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" |
18 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
19 | | #include "llvm/Target/TargetRegisterInfo.h" |
20 | | |
21 | | #define GET_TARGET_REGBANK_IMPL |
22 | | #include "X86GenRegisterBank.inc" |
23 | | |
24 | | using namespace llvm; |
25 | | // This file will be TableGen'ed at some point. |
26 | | #define GET_TARGET_REGBANK_INFO_IMPL |
27 | | #include "X86GenRegisterBankInfo.def" |
28 | | |
29 | | X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI) |
30 | 9.65k | : X86GenRegisterBankInfo() { |
31 | 9.65k | |
32 | 9.65k | // validate RegBank initialization. |
33 | 9.65k | const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID); |
34 | 9.65k | (void)RBGPR; |
35 | 9.65k | assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization."); |
36 | 9.65k | |
37 | 9.65k | // The GPR register bank is fully defined by all the registers in |
38 | 9.65k | // GR64 + its subclasses. |
39 | 9.65k | assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) && |
40 | 9.65k | "Subclass not added?"); |
41 | 9.65k | assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit"); |
42 | 9.65k | } |
43 | | |
44 | | const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass( |
45 | 6.91k | const TargetRegisterClass &RC) const { |
46 | 6.91k | |
47 | 6.91k | if (X86::GR8RegClass.hasSubClassEq(&RC) || |
48 | 6.41k | X86::GR16RegClass.hasSubClassEq(&RC) || |
49 | 6.08k | X86::GR32RegClass.hasSubClassEq(&RC) || |
50 | 4.32k | X86::GR64RegClass.hasSubClassEq(&RC)) |
51 | 3.95k | return getRegBank(X86::GPRRegBankID); |
52 | 2.96k | |
53 | 2.96k | if (2.96k X86::FR32XRegClass.hasSubClassEq(&RC) || |
54 | 1.00k | X86::FR64XRegClass.hasSubClassEq(&RC) || |
55 | 1.00k | X86::VR128XRegClass.hasSubClassEq(&RC) || |
56 | 1.00k | X86::VR256XRegClass.hasSubClassEq(&RC) || |
57 | 292 | X86::VR512RegClass.hasSubClassEq(&RC)) |
58 | 2.96k | return getRegBank(X86::VECRRegBankID); |
59 | 0 |
|
60 | 0 | llvm_unreachable0 ("Unsupported register kind yet."); |
61 | 0 | } |
62 | | |
63 | | X86GenRegisterBankInfo::PartialMappingIdx |
64 | 1.98k | X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) { |
65 | 1.98k | if ((Ty.isScalar() && 1.98k !isFP1.05k ) || Ty.isPointer()1.02k ) { |
66 | 1.59k | switch (Ty.getSizeInBits()) { |
67 | 280 | case 1: |
68 | 280 | case 8: |
69 | 280 | return PMI_GPR8; |
70 | 69 | case 16: |
71 | 69 | return PMI_GPR16; |
72 | 779 | case 32: |
73 | 779 | return PMI_GPR32; |
74 | 467 | case 64: |
75 | 467 | return PMI_GPR64; |
76 | 0 | break; |
77 | 0 | default: |
78 | 0 | llvm_unreachable("Unsupported register size."); |
79 | 1.98k | } |
80 | 389 | } else if (389 Ty.isScalar()389 ) { |
81 | 88 | switch (Ty.getSizeInBits()) { |
82 | 55 | case 32: |
83 | 55 | return PMI_FP32; |
84 | 33 | case 64: |
85 | 33 | return PMI_FP64; |
86 | 0 | default: |
87 | 0 | llvm_unreachable("Unsupported register size."); |
88 | 389 | } |
89 | 301 | } else { |
90 | 301 | switch (Ty.getSizeInBits()) { |
91 | 161 | case 128: |
92 | 161 | return PMI_VEC128; |
93 | 95 | case 256: |
94 | 95 | return PMI_VEC256; |
95 | 45 | case 512: |
96 | 45 | return PMI_VEC512; |
97 | 0 | default: |
98 | 0 | llvm_unreachable("Unsupported register size."); |
99 | 0 | } |
100 | 0 | } |
101 | 0 |
|
102 | 0 | return PMI_None; |
103 | 0 | } |
104 | | |
105 | | void X86RegisterBankInfo::getInstrPartialMappingIdxs( |
106 | | const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP, |
107 | 956 | SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) { |
108 | 956 | |
109 | 956 | unsigned NumOperands = MI.getNumOperands(); |
110 | 3.03k | for (unsigned Idx = 0; Idx < NumOperands3.03k ; ++Idx2.07k ) { |
111 | 2.07k | auto &MO = MI.getOperand(Idx); |
112 | 2.07k | if (!MO.isReg()) |
113 | 282 | OpRegBankIdx[Idx] = PMI_None; |
114 | 2.07k | else |
115 | 1.79k | OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP); |
116 | 2.07k | } |
117 | 956 | } |
118 | | |
119 | | bool X86RegisterBankInfo::getInstrValueMapping( |
120 | | const MachineInstr &MI, |
121 | | const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx, |
122 | 956 | SmallVectorImpl<const ValueMapping *> &OpdsMapping) { |
123 | 956 | |
124 | 956 | unsigned NumOperands = MI.getNumOperands(); |
125 | 3.03k | for (unsigned Idx = 0; Idx < NumOperands3.03k ; ++Idx2.07k ) { |
126 | 2.07k | if (!MI.getOperand(Idx).isReg()) |
127 | 282 | continue; |
128 | 1.79k | |
129 | 1.79k | auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1); |
130 | 1.79k | if (!Mapping->isValid()) |
131 | 0 | return false; |
132 | 1.79k | |
133 | 1.79k | OpdsMapping[Idx] = Mapping; |
134 | 1.79k | } |
135 | 956 | return true; |
136 | 956 | } |
137 | | |
138 | | const RegisterBankInfo::InstructionMapping & |
139 | | X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, |
140 | 192 | bool isFP) const { |
141 | 192 | const MachineFunction &MF = *MI.getParent()->getParent(); |
142 | 192 | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
143 | 192 | |
144 | 192 | unsigned NumOperands = MI.getNumOperands(); |
145 | 192 | LLT Ty = MRI.getType(MI.getOperand(0).getReg()); |
146 | 192 | |
147 | 192 | if (NumOperands != 3 || 192 (Ty != MRI.getType(MI.getOperand(1).getReg()))192 || |
148 | 192 | (Ty != MRI.getType(MI.getOperand(2).getReg()))) |
149 | 0 | llvm_unreachable("Unsupported operand mapping yet."); |
150 | 192 | |
151 | 192 | auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3); |
152 | 192 | return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands); |
153 | 192 | } |
154 | | |
155 | | const RegisterBankInfo::InstructionMapping & |
156 | 2.18k | X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { |
157 | 2.18k | const MachineFunction &MF = *MI.getParent()->getParent(); |
158 | 2.18k | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
159 | 2.18k | auto Opc = MI.getOpcode(); |
160 | 2.18k | |
161 | 2.18k | // Try the default logic for non-generic instructions that are either copies |
162 | 2.18k | // or already have some operands assigned to banks. |
163 | 2.18k | if (!isPreISelGenericOpcode(Opc) || 2.18k Opc == TargetOpcode::G_PHI1.06k ) { |
164 | 1.12k | const InstructionMapping &Mapping = getInstrMappingImpl(MI); |
165 | 1.12k | if (Mapping.isValid()) |
166 | 1.07k | return Mapping; |
167 | 1.10k | } |
168 | 1.10k | |
169 | 1.10k | switch (Opc) { |
170 | 134 | case TargetOpcode::G_ADD: |
171 | 134 | case TargetOpcode::G_SUB: |
172 | 134 | return getSameOperandsMapping(MI, false); |
173 | 0 | break; |
174 | 58 | case TargetOpcode::G_FADD: |
175 | 58 | case TargetOpcode::G_FSUB: |
176 | 58 | case TargetOpcode::G_FMUL: |
177 | 58 | case TargetOpcode::G_FDIV: |
178 | 58 | return getSameOperandsMapping(MI, true); |
179 | 0 | break; |
180 | 916 | default: |
181 | 916 | break; |
182 | 916 | } |
183 | 916 | |
184 | 916 | unsigned NumOperands = MI.getNumOperands(); |
185 | 916 | SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands); |
186 | 916 | |
187 | 916 | switch (Opc) { |
188 | 12 | case TargetOpcode::G_FPEXT: |
189 | 12 | case TargetOpcode::G_FCONSTANT: |
190 | 12 | // Instruction having only floating-point operands (all scalars in VECRReg) |
191 | 12 | getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx); |
192 | 12 | break; |
193 | 904 | default: |
194 | 904 | // Track the bank of each register, use NotFP mapping (all scalars in GPRs) |
195 | 904 | getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx); |
196 | 904 | break; |
197 | 916 | } |
198 | 916 | |
199 | 916 | // Finally construct the computed mapping. |
200 | 916 | SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands); |
201 | 916 | if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping)) |
202 | 0 | return getInvalidInstructionMapping(); |
203 | 916 | |
204 | 916 | return getInstructionMapping(DefaultMappingID, /* Cost */ 1, |
205 | 916 | getOperandsMapping(OpdsMapping), NumOperands); |
206 | 916 | } |
207 | | |
208 | | void X86RegisterBankInfo::applyMappingImpl( |
209 | 4 | const OperandsMapper &OpdMapper) const { |
210 | 4 | return applyDefaultMapping(OpdMapper); |
211 | 4 | } |
212 | | |
213 | | RegisterBankInfo::InstructionMappings |
214 | 349 | X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const { |
215 | 349 | |
216 | 349 | const MachineFunction &MF = *MI.getParent()->getParent(); |
217 | 349 | const TargetSubtargetInfo &STI = MF.getSubtarget(); |
218 | 349 | const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); |
219 | 349 | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
220 | 349 | |
221 | 349 | switch (MI.getOpcode()) { |
222 | 74 | case TargetOpcode::G_LOAD: |
223 | 74 | case TargetOpcode::G_STORE: |
224 | 74 | case TargetOpcode::G_IMPLICIT_DEF: { |
225 | 74 | // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64 |
226 | 74 | unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI); |
227 | 74 | if (Size != 32 && 74 Size != 6444 ) |
228 | 34 | break; |
229 | 40 | |
230 | 40 | unsigned NumOperands = MI.getNumOperands(); |
231 | 40 | |
232 | 40 | // Track the bank of each register, use FP mapping (all scalars in VEC) |
233 | 40 | SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands); |
234 | 40 | getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx); |
235 | 40 | |
236 | 40 | // Finally construct the computed mapping. |
237 | 40 | SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands); |
238 | 40 | if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping)) |
239 | 0 | break; |
240 | 40 | |
241 | 40 | const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( |
242 | 40 | /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands); |
243 | 40 | InstructionMappings AltMappings; |
244 | 40 | AltMappings.push_back(&Mapping); |
245 | 40 | return AltMappings; |
246 | 40 | } |
247 | 275 | default: |
248 | 275 | break; |
249 | 309 | } |
250 | 309 | return RegisterBankInfo::getInstrAlternativeMappings(MI); |
251 | 309 | } |