LLVM  14.0.0git
X86RegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- X86RegisterBankInfo.cpp -----------------------------------*- 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 implements the targeting of the RegisterBankInfo class for X86.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "X86RegisterBankInfo.h"
14 #include "X86InstrInfo.h"
19 
20 #define GET_TARGET_REGBANK_IMPL
21 #include "X86GenRegisterBank.inc"
22 
23 using namespace llvm;
24 // This file will be TableGen'ed at some point.
25 #define GET_TARGET_REGBANK_INFO_IMPL
26 #include "X86GenRegisterBankInfo.def"
27 
30 
31  // validate RegBank initialization.
32  const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
33  (void)RBGPR;
34  assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
35 
36  // The GPR register bank is fully defined by all the registers in
37  // GR64 + its subclasses.
38  assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
39  "Subclass not added?");
40  assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
41 }
42 
43 const RegisterBank &
45  LLT) const {
46 
47  if (X86::GR8RegClass.hasSubClassEq(&RC) ||
48  X86::GR16RegClass.hasSubClassEq(&RC) ||
49  X86::GR32RegClass.hasSubClassEq(&RC) ||
50  X86::GR64RegClass.hasSubClassEq(&RC) ||
51  X86::LOW32_ADDR_ACCESSRegClass.hasSubClassEq(&RC) ||
52  X86::LOW32_ADDR_ACCESS_RBPRegClass.hasSubClassEq(&RC))
53  return getRegBank(X86::GPRRegBankID);
54 
55  if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
56  X86::FR64XRegClass.hasSubClassEq(&RC) ||
57  X86::VR128XRegClass.hasSubClassEq(&RC) ||
58  X86::VR256XRegClass.hasSubClassEq(&RC) ||
59  X86::VR512RegClass.hasSubClassEq(&RC))
60  return getRegBank(X86::VECRRegBankID);
61 
62  llvm_unreachable("Unsupported register kind yet.");
63 }
64 
67  if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
68  switch (Ty.getSizeInBits()) {
69  case 1:
70  case 8:
71  return PMI_GPR8;
72  case 16:
73  return PMI_GPR16;
74  case 32:
75  return PMI_GPR32;
76  case 64:
77  return PMI_GPR64;
78  case 128:
79  return PMI_VEC128;
80  break;
81  default:
82  llvm_unreachable("Unsupported register size.");
83  }
84  } else if (Ty.isScalar()) {
85  switch (Ty.getSizeInBits()) {
86  case 32:
87  return PMI_FP32;
88  case 64:
89  return PMI_FP64;
90  case 128:
91  return PMI_VEC128;
92  default:
93  llvm_unreachable("Unsupported register size.");
94  }
95  } else {
96  switch (Ty.getSizeInBits()) {
97  case 128:
98  return PMI_VEC128;
99  case 256:
100  return PMI_VEC256;
101  case 512:
102  return PMI_VEC512;
103  default:
104  llvm_unreachable("Unsupported register size.");
105  }
106  }
107 
108  return PMI_None;
109 }
110 
111 void X86RegisterBankInfo::getInstrPartialMappingIdxs(
112  const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
113  SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx) {
114 
115  unsigned NumOperands = MI.getNumOperands();
116  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
117  auto &MO = MI.getOperand(Idx);
118  if (!MO.isReg())
119  OpRegBankIdx[Idx] = PMI_None;
120  else
121  OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
122  }
123 }
124 
125 bool X86RegisterBankInfo::getInstrValueMapping(
126  const MachineInstr &MI,
127  const SmallVectorImpl<PartialMappingIdx> &OpRegBankIdx,
129 
130  unsigned NumOperands = MI.getNumOperands();
131  for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
132  if (!MI.getOperand(Idx).isReg())
133  continue;
134 
135  auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
136  if (!Mapping->isValid())
137  return false;
138 
139  OpdsMapping[Idx] = Mapping;
140  }
141  return true;
142 }
143 
145 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
146  bool isFP) const {
147  const MachineFunction &MF = *MI.getParent()->getParent();
148  const MachineRegisterInfo &MRI = MF.getRegInfo();
149 
150  unsigned NumOperands = MI.getNumOperands();
151  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
152 
153  if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
154  (Ty != MRI.getType(MI.getOperand(2).getReg())))
155  llvm_unreachable("Unsupported operand mapping yet.");
156 
157  auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
158  return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
159 }
160 
163  const MachineFunction &MF = *MI.getParent()->getParent();
164  const MachineRegisterInfo &MRI = MF.getRegInfo();
165  unsigned Opc = MI.getOpcode();
166 
167  // Try the default logic for non-generic instructions that are either copies
168  // or already have some operands assigned to banks.
169  if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
170  const InstructionMapping &Mapping = getInstrMappingImpl(MI);
171  if (Mapping.isValid())
172  return Mapping;
173  }
174 
175  switch (Opc) {
176  case TargetOpcode::G_ADD:
177  case TargetOpcode::G_SUB:
178  case TargetOpcode::G_MUL:
179  return getSameOperandsMapping(MI, false);
180  case TargetOpcode::G_FADD:
181  case TargetOpcode::G_FSUB:
182  case TargetOpcode::G_FMUL:
183  case TargetOpcode::G_FDIV:
184  return getSameOperandsMapping(MI, true);
185  case TargetOpcode::G_SHL:
186  case TargetOpcode::G_LSHR:
187  case TargetOpcode::G_ASHR: {
188  unsigned NumOperands = MI.getNumOperands();
189  LLT Ty = MRI.getType(MI.getOperand(0).getReg());
190 
191  auto Mapping = getValueMapping(getPartialMappingIdx(Ty, false), 3);
192  return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
193 
194  }
195  default:
196  break;
197  }
198 
199  unsigned NumOperands = MI.getNumOperands();
200  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
201 
202  switch (Opc) {
203  case TargetOpcode::G_FPEXT:
204  case TargetOpcode::G_FPTRUNC:
205  case TargetOpcode::G_FCONSTANT:
206  // Instruction having only floating-point operands (all scalars in VECRReg)
207  getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
208  break;
209  case TargetOpcode::G_SITOFP:
210  case TargetOpcode::G_FPTOSI: {
211  // Some of the floating-point instructions have mixed GPR and FP operands:
212  // fine-tune the computed mapping.
213  auto &Op0 = MI.getOperand(0);
214  auto &Op1 = MI.getOperand(1);
215  const LLT Ty0 = MRI.getType(Op0.getReg());
216  const LLT Ty1 = MRI.getType(Op1.getReg());
217 
218  bool FirstArgIsFP = Opc == TargetOpcode::G_SITOFP;
219  bool SecondArgIsFP = Opc == TargetOpcode::G_FPTOSI;
220  OpRegBankIdx[0] = getPartialMappingIdx(Ty0, /* isFP */ FirstArgIsFP);
221  OpRegBankIdx[1] = getPartialMappingIdx(Ty1, /* isFP */ SecondArgIsFP);
222  break;
223  }
224  case TargetOpcode::G_FCMP: {
225  LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
226  LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
227  (void)Ty2;
228  assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
229  "Mismatched operand sizes for G_FCMP");
230 
231  unsigned Size = Ty1.getSizeInBits();
232  (void)Size;
233  assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
234 
235  auto FpRegBank = getPartialMappingIdx(Ty1, /* isFP */ true);
236  OpRegBankIdx = {PMI_GPR8,
237  /* Predicate */ PMI_None, FpRegBank, FpRegBank};
238  break;
239  }
240  case TargetOpcode::G_TRUNC:
241  case TargetOpcode::G_ANYEXT: {
242  auto &Op0 = MI.getOperand(0);
243  auto &Op1 = MI.getOperand(1);
244  const LLT Ty0 = MRI.getType(Op0.getReg());
245  const LLT Ty1 = MRI.getType(Op1.getReg());
246 
247  bool isFPTrunc = (Ty0.getSizeInBits() == 32 || Ty0.getSizeInBits() == 64) &&
248  Ty1.getSizeInBits() == 128 && Opc == TargetOpcode::G_TRUNC;
249  bool isFPAnyExt =
250  Ty0.getSizeInBits() == 128 &&
251  (Ty1.getSizeInBits() == 32 || Ty1.getSizeInBits() == 64) &&
252  Opc == TargetOpcode::G_ANYEXT;
253 
254  getInstrPartialMappingIdxs(MI, MRI, /* isFP */ isFPTrunc || isFPAnyExt,
255  OpRegBankIdx);
256  } break;
257  default:
258  // Track the bank of each register, use NotFP mapping (all scalars in GPRs)
259  getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
260  break;
261  }
262 
263  // Finally construct the computed mapping.
264  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
265  if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
267 
268  return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
269  getOperandsMapping(OpdsMapping), NumOperands);
270 }
271 
273  const OperandsMapper &OpdMapper) const {
274  return applyDefaultMapping(OpdMapper);
275 }
276 
279 
280  const MachineFunction &MF = *MI.getParent()->getParent();
281  const TargetSubtargetInfo &STI = MF.getSubtarget();
282  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
283  const MachineRegisterInfo &MRI = MF.getRegInfo();
284 
285  switch (MI.getOpcode()) {
286  case TargetOpcode::G_LOAD:
287  case TargetOpcode::G_STORE:
288  case TargetOpcode::G_IMPLICIT_DEF: {
289  // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
290  unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
291  if (Size != 32 && Size != 64)
292  break;
293 
294  unsigned NumOperands = MI.getNumOperands();
295 
296  // Track the bank of each register, use FP mapping (all scalars in VEC)
297  SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands);
298  getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
299 
300  // Finally construct the computed mapping.
301  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
302  if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
303  break;
304 
306  /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
307  InstructionMappings AltMappings;
308  AltMappings.push_back(&Mapping);
309  return AltMappings;
310  }
311  default:
312  break;
313  }
315 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::X86RegisterBankInfo::applyMappingImpl
void applyMappingImpl(const OperandsMapper &OpdMapper) const override
See RegisterBankInfo::applyMapping.
Definition: X86RegisterBankInfo.cpp:272
llvm::RegisterBankInfo::getInstrMappingImpl
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Definition: RegisterBankInfo.cpp:162
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::isPreISelGenericOpcode
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
llvm::RegisterBankInfo::getRegBank
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Definition: RegisterBankInfo.h:432
RegisterBankInfo.h
llvm::RegisterBankInfo::applyDefaultMapping
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
Definition: RegisterBankInfo.cpp:438
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::RegisterBankInfo::InstructionMapping::isValid
bool isValid() const
Check whether this object is valid.
Definition: RegisterBankInfo.h:254
llvm::X86RegisterBankInfo::getInstrMapping
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Definition: X86RegisterBankInfo.cpp:162
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
llvm::X86GenRegisterBankInfo::getPartialMappingIdx
static PartialMappingIdx getPartialMappingIdx(const LLT &Ty, bool isFP)
Definition: X86RegisterBankInfo.cpp:66
MachineRegisterInfo.h
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:644
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::LLT::getSizeInBits
TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:153
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::X86RegisterBankInfo::X86RegisterBankInfo
X86RegisterBankInfo(const TargetRegisterInfo &TRI)
Definition: X86RegisterBankInfo.cpp:28
llvm::RegisterBankInfo::getInstrAlternativeMappings
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
Definition: RegisterBankInfo.cpp:433
llvm::RegisterBankInfo::getSizeInBits
unsigned getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
Definition: RegisterBankInfo.cpp:493
llvm::RegisterBankInfo::OperandsMapper
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
Definition: RegisterBankInfo.h:280
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
llvm::TargetRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Definition: TargetRegisterInfo.h:739
llvm::X86RegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT) const override
Get a register bank that covers RC.
Definition: X86RegisterBankInfo.cpp:44
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::RegisterBankInfo::InstructionMapping
Helper class that represents how the value of an instruction may be mapped and what is the related co...
Definition: RegisterBankInfo.h:189
X86RegisterBankInfo.h
llvm::RegisterBankInfo::DefaultMappingID
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
Definition: RegisterBankInfo.h:652
llvm::RegisterBankInfo::getOperandsMapping
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
Definition: RegisterBankInfo.cpp:332
llvm::RegisterBank::covers
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
Definition: RegisterBank.cpp:61
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LLT::isPointer
bool isPointer() const
Definition: LowLevelTypeImpl.h:121
llvm::X86GenRegisterBankInfo::getValueMapping
static const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx Idx, unsigned NumOperands)
llvm::LLT::isScalar
bool isScalar() const
Definition: LowLevelTypeImpl.h:119
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::RegisterBankInfo::getInstructionMapping
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
Definition: RegisterBankInfo.h:526
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::X86RegisterBankInfo::getInstrAlternativeMappings
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
Definition: X86RegisterBankInfo.cpp:278
llvm::RegisterBank::getSize
unsigned getSize() const
Get the maximal size in bits that fits in this register bank.
Definition: RegisterBank.h:54
llvm::RegisterBankInfo::getInvalidInstructionMapping
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
Definition: RegisterBankInfo.h:534
llvm::X86GenRegisterBankInfo
Definition: X86RegisterBankInfo.h:25
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
RegisterBank.h
llvm::ARM::PartialMappingIdx
PartialMappingIdx
Definition: ARMRegisterBankInfo.cpp:31
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
X86InstrInfo.h
TargetRegisterInfo.h
llvm::LLT
Definition: LowLevelTypeImpl.h:40