[PowerPC] Do not emit record-form rotates when record-form andi/andis suffices
[llvm-core.git] / lib / Target / X86 / X86RegisterBankInfo.cpp
blob355291916ee8b41d97af9d58ffccff7e8676d26f
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 //===----------------------------------------------------------------------===//
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/CodeGen/TargetRegisterInfo.h"
21 #define GET_TARGET_REGBANK_IMPL
22 #include "X86GenRegisterBank.inc"
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"
29 X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
30 : X86GenRegisterBankInfo() {
32 // validate RegBank initialization.
33 const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
34 (void)RBGPR;
35 assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
37 // The GPR register bank is fully defined by all the registers in
38 // GR64 + its subclasses.
39 assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
40 "Subclass not added?");
41 assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
44 const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
45 const TargetRegisterClass &RC) const {
47 if (X86::GR8RegClass.hasSubClassEq(&RC) ||
48 X86::GR16RegClass.hasSubClassEq(&RC) ||
49 X86::GR32RegClass.hasSubClassEq(&RC) ||
50 X86::GR64RegClass.hasSubClassEq(&RC))
51 return getRegBank(X86::GPRRegBankID);
53 if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
54 X86::FR64XRegClass.hasSubClassEq(&RC) ||
55 X86::VR128XRegClass.hasSubClassEq(&RC) ||
56 X86::VR256XRegClass.hasSubClassEq(&RC) ||
57 X86::VR512RegClass.hasSubClassEq(&RC))
58 return getRegBank(X86::VECRRegBankID);
60 llvm_unreachable("Unsupported register kind yet.");
63 X86GenRegisterBankInfo::PartialMappingIdx
64 X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) {
65 if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
66 switch (Ty.getSizeInBits()) {
67 case 1:
68 case 8:
69 return PMI_GPR8;
70 case 16:
71 return PMI_GPR16;
72 case 32:
73 return PMI_GPR32;
74 case 64:
75 return PMI_GPR64;
76 case 128:
77 return PMI_VEC128;
78 break;
79 default:
80 llvm_unreachable("Unsupported register size.");
82 } else if (Ty.isScalar()) {
83 switch (Ty.getSizeInBits()) {
84 case 32:
85 return PMI_FP32;
86 case 64:
87 return PMI_FP64;
88 case 128:
89 return PMI_VEC128;
90 default:
91 llvm_unreachable("Unsupported register size.");
93 } else {
94 switch (Ty.getSizeInBits()) {
95 case 128:
96 return PMI_VEC128;
97 case 256:
98 return PMI_VEC256;
99 case 512:
100 return PMI_VEC512;
101 default:
102 llvm_unreachable("Unsupported register size.");
106 return PMI_None;
109 void X86RegisterBankInfo::getInstrPartialMappingIdxs(
110 const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
111 SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
113 unsigned NumOperands = MI.getNumOperands();
114 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
115 auto &MO = MI.getOperand(Idx);
116 if (!MO.isReg())
117 OpRegBankIdx[Idx] = PMI_None;
118 else
119 OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
123 bool X86RegisterBankInfo::getInstrValueMapping(
124 const MachineInstr &MI,
125 const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
126 SmallVectorImpl<const ValueMapping *> &OpdsMapping) {
128 unsigned NumOperands = MI.getNumOperands();
129 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
130 if (!MI.getOperand(Idx).isReg())
131 continue;
133 auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
134 if (!Mapping->isValid())
135 return false;
137 OpdsMapping[Idx] = Mapping;
139 return true;
142 const RegisterBankInfo::InstructionMapping &
143 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
144 bool isFP) const {
145 const MachineFunction &MF = *MI.getParent()->getParent();
146 const MachineRegisterInfo &MRI = MF.getRegInfo();
148 unsigned NumOperands = MI.getNumOperands();
149 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
151 if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
152 (Ty != MRI.getType(MI.getOperand(2).getReg())))
153 llvm_unreachable("Unsupported operand mapping yet.");
155 auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
156 return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
159 const RegisterBankInfo::InstructionMapping &
160 X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
161 const MachineFunction &MF = *MI.getParent()->getParent();
162 const MachineRegisterInfo &MRI = MF.getRegInfo();
163 auto Opc = MI.getOpcode();
165 // Try the default logic for non-generic instructions that are either copies
166 // or already have some operands assigned to banks.
167 if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
168 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
169 if (Mapping.isValid())
170 return Mapping;
173 switch (Opc) {
174 case TargetOpcode::G_ADD:
175 case TargetOpcode::G_SUB:
176 case TargetOpcode::G_MUL:
177 case TargetOpcode::G_SHL:
178 case TargetOpcode::G_LSHR:
179 case TargetOpcode::G_ASHR:
180 return getSameOperandsMapping(MI, false);
181 break;
182 case TargetOpcode::G_FADD:
183 case TargetOpcode::G_FSUB:
184 case TargetOpcode::G_FMUL:
185 case TargetOpcode::G_FDIV:
186 return getSameOperandsMapping(MI, true);
187 break;
188 default:
189 break;
192 unsigned NumOperands = MI.getNumOperands();
193 SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
195 switch (Opc) {
196 case TargetOpcode::G_FPEXT:
197 case TargetOpcode::G_FPTRUNC:
198 case TargetOpcode::G_FCONSTANT:
199 // Instruction having only floating-point operands (all scalars in VECRReg)
200 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
201 break;
202 case TargetOpcode::G_SITOFP:
203 case TargetOpcode::G_FPTOSI: {
204 // Some of the floating-point instructions have mixed GPR and FP operands:
205 // fine-tune the computed mapping.
206 auto &Op0 = MI.getOperand(0);
207 auto &Op1 = MI.getOperand(1);
208 const LLT Ty0 = MRI.getType(Op0.getReg());
209 const LLT Ty1 = MRI.getType(Op1.getReg());
211 bool FirstArgIsFP = Opc == TargetOpcode::G_SITOFP;
212 bool SecondArgIsFP = Opc == TargetOpcode::G_FPTOSI;
213 OpRegBankIdx[0] = getPartialMappingIdx(Ty0, /* isFP */ FirstArgIsFP);
214 OpRegBankIdx[1] = getPartialMappingIdx(Ty1, /* isFP */ SecondArgIsFP);
215 break;
217 case TargetOpcode::G_FCMP: {
218 LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
219 LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
220 (void)Ty2;
221 assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
222 "Mismatched operand sizes for G_FCMP");
224 unsigned Size = Ty1.getSizeInBits();
225 (void)Size;
226 assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
228 auto FpRegBank = getPartialMappingIdx(Ty1, /* isFP */ true);
229 OpRegBankIdx = {PMI_GPR8,
230 /* Predicate */ PMI_None, FpRegBank, FpRegBank};
231 break;
233 case TargetOpcode::G_TRUNC:
234 case TargetOpcode::G_ANYEXT: {
235 auto &Op0 = MI.getOperand(0);
236 auto &Op1 = MI.getOperand(1);
237 const LLT Ty0 = MRI.getType(Op0.getReg());
238 const LLT Ty1 = MRI.getType(Op1.getReg());
240 bool isFPTrunc = (Ty0.getSizeInBits() == 32 || Ty0.getSizeInBits() == 64) &&
241 Ty1.getSizeInBits() == 128 && Opc == TargetOpcode::G_TRUNC;
242 bool isFPAnyExt =
243 Ty0.getSizeInBits() == 128 &&
244 (Ty1.getSizeInBits() == 32 || Ty1.getSizeInBits() == 64) &&
245 Opc == TargetOpcode::G_ANYEXT;
247 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ isFPTrunc || isFPAnyExt,
248 OpRegBankIdx);
249 } break;
250 default:
251 // Track the bank of each register, use NotFP mapping (all scalars in GPRs)
252 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
253 break;
256 // Finally construct the computed mapping.
257 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
258 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
259 return getInvalidInstructionMapping();
261 return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
262 getOperandsMapping(OpdsMapping), NumOperands);
265 void X86RegisterBankInfo::applyMappingImpl(
266 const OperandsMapper &OpdMapper) const {
267 return applyDefaultMapping(OpdMapper);
270 RegisterBankInfo::InstructionMappings
271 X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
273 const MachineFunction &MF = *MI.getParent()->getParent();
274 const TargetSubtargetInfo &STI = MF.getSubtarget();
275 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
276 const MachineRegisterInfo &MRI = MF.getRegInfo();
278 switch (MI.getOpcode()) {
279 case TargetOpcode::G_LOAD:
280 case TargetOpcode::G_STORE:
281 case TargetOpcode::G_IMPLICIT_DEF: {
282 // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
283 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
284 if (Size != 32 && Size != 64)
285 break;
287 unsigned NumOperands = MI.getNumOperands();
289 // Track the bank of each register, use FP mapping (all scalars in VEC)
290 SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
291 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
293 // Finally construct the computed mapping.
294 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
295 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
296 break;
298 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
299 /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
300 InstructionMappings AltMappings;
301 AltMappings.push_back(&Mapping);
302 return AltMappings;
304 default:
305 break;
307 return RegisterBankInfo::getInstrAlternativeMappings(MI);