]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86RegisterBankInfo.cpp
Update OpenSSL to 1.1.1.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86RegisterBankInfo.cpp
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/CodeGen/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     : X86GenRegisterBankInfo() {
31
32   // validate RegBank initialization.
33   const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
34   (void)RBGPR;
35   assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
36
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");
42 }
43
44 const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
45     const TargetRegisterClass &RC) const {
46
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);
52
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);
59
60   llvm_unreachable("Unsupported register kind yet.");
61 }
62
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       break;
77     default:
78       llvm_unreachable("Unsupported register size.");
79     }
80   } else if (Ty.isScalar()) {
81     switch (Ty.getSizeInBits()) {
82     case 32:
83       return PMI_FP32;
84     case 64:
85       return PMI_FP64;
86     default:
87       llvm_unreachable("Unsupported register size.");
88     }
89   } else {
90     switch (Ty.getSizeInBits()) {
91     case 128:
92       return PMI_VEC128;
93     case 256:
94       return PMI_VEC256;
95     case 512:
96       return PMI_VEC512;
97     default:
98       llvm_unreachable("Unsupported register size.");
99     }
100   }
101
102   return PMI_None;
103 }
104
105 void X86RegisterBankInfo::getInstrPartialMappingIdxs(
106     const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
107     SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
108
109   unsigned NumOperands = MI.getNumOperands();
110   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
111     auto &MO = MI.getOperand(Idx);
112     if (!MO.isReg())
113       OpRegBankIdx[Idx] = PMI_None;
114     else
115       OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
116   }
117 }
118
119 bool X86RegisterBankInfo::getInstrValueMapping(
120     const MachineInstr &MI,
121     const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
122     SmallVectorImpl<const ValueMapping *> &OpdsMapping) {
123
124   unsigned NumOperands = MI.getNumOperands();
125   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
126     if (!MI.getOperand(Idx).isReg())
127       continue;
128
129     auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
130     if (!Mapping->isValid())
131       return false;
132
133     OpdsMapping[Idx] = Mapping;
134   }
135   return true;
136 }
137
138 const RegisterBankInfo::InstructionMapping &
139 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
140                                             bool isFP) const {
141   const MachineFunction &MF = *MI.getParent()->getParent();
142   const MachineRegisterInfo &MRI = MF.getRegInfo();
143
144   unsigned NumOperands = MI.getNumOperands();
145   LLT Ty = MRI.getType(MI.getOperand(0).getReg());
146
147   if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
148       (Ty != MRI.getType(MI.getOperand(2).getReg())))
149     llvm_unreachable("Unsupported operand mapping yet.");
150
151   auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
152   return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
153 }
154
155 const RegisterBankInfo::InstructionMapping &
156 X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
157   const MachineFunction &MF = *MI.getParent()->getParent();
158   const MachineRegisterInfo &MRI = MF.getRegInfo();
159   auto Opc = MI.getOpcode();
160
161   // Try the default logic for non-generic instructions that are either copies
162   // or already have some operands assigned to banks.
163   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
164     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
165     if (Mapping.isValid())
166       return Mapping;
167   }
168
169   switch (Opc) {
170   case TargetOpcode::G_ADD:
171   case TargetOpcode::G_SUB:
172     return getSameOperandsMapping(MI, false);
173     break;
174   case TargetOpcode::G_FADD:
175   case TargetOpcode::G_FSUB:
176   case TargetOpcode::G_FMUL:
177   case TargetOpcode::G_FDIV:
178     return getSameOperandsMapping(MI, true);
179     break;
180   default:
181     break;
182   }
183
184   unsigned NumOperands = MI.getNumOperands();
185   SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
186
187   switch (Opc) {
188   case TargetOpcode::G_FPEXT:
189   case TargetOpcode::G_FCONSTANT:
190     // Instruction having only floating-point operands (all scalars in VECRReg)
191     getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
192     break;
193   default:
194     // Track the bank of each register, use NotFP mapping (all scalars in GPRs)
195     getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
196     break;
197   }
198
199   // Finally construct the computed mapping.
200   SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
201   if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
202     return getInvalidInstructionMapping();
203
204   return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
205                                getOperandsMapping(OpdsMapping), NumOperands);
206 }
207
208 void X86RegisterBankInfo::applyMappingImpl(
209     const OperandsMapper &OpdMapper) const {
210   return applyDefaultMapping(OpdMapper);
211 }
212
213 RegisterBankInfo::InstructionMappings
214 X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
215
216   const MachineFunction &MF = *MI.getParent()->getParent();
217   const TargetSubtargetInfo &STI = MF.getSubtarget();
218   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
219   const MachineRegisterInfo &MRI = MF.getRegInfo();
220
221   switch (MI.getOpcode()) {
222   case TargetOpcode::G_LOAD:
223   case TargetOpcode::G_STORE:
224   case TargetOpcode::G_IMPLICIT_DEF: {
225     // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
226     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
227     if (Size != 32 && Size != 64)
228       break;
229
230     unsigned NumOperands = MI.getNumOperands();
231
232     // Track the bank of each register, use FP mapping (all scalars in VEC)
233     SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
234     getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
235
236     // Finally construct the computed mapping.
237     SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
238     if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
239       break;
240
241     const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
242         /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
243     InstructionMappings AltMappings;
244     AltMappings.push_back(&Mapping);
245     return AltMappings;
246   }
247   default:
248     break;
249   }
250   return RegisterBankInfo::getInstrAlternativeMappings(MI);
251 }