LLVM  17.0.0git
PPCRegisterBankInfo.cpp
Go to the documentation of this file.
1 //===- PPCRegisterBankInfo.cpp --------------------------------------------===//
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
10 /// PowerPC.
11 //===----------------------------------------------------------------------===//
12 
13 #include "PPCRegisterBankInfo.h"
14 #include "PPCRegisterInfo.h"
17 #include "llvm/Support/Debug.h"
18 
19 #define DEBUG_TYPE "ppc-reg-bank-info"
20 
21 #define GET_TARGET_REGBANK_IMPL
22 #include "PPCGenRegisterBank.inc"
23 
24 // This file will be TableGen'ed at some point.
25 #include "PPCGenRegisterBankInfo.def"
26 
27 using namespace llvm;
28 
30 
31 const RegisterBank &
33  LLT Ty) const {
34  switch (RC.getID()) {
35  case PPC::G8RCRegClassID:
36  case PPC::G8RC_NOX0RegClassID:
37  case PPC::G8RC_and_G8RC_NOX0RegClassID:
38  case PPC::GPRCRegClassID:
39  case PPC::GPRC_NOR0RegClassID:
40  case PPC::GPRC_and_GPRC_NOR0RegClassID:
41  return getRegBank(PPC::GPRRegBankID);
42  case PPC::VSFRCRegClassID:
43  case PPC::SPILLTOVSRRC_and_VSFRCRegClassID:
44  case PPC::SPILLTOVSRRC_and_VFRCRegClassID:
45  case PPC::SPILLTOVSRRC_and_F4RCRegClassID:
46  case PPC::F8RCRegClassID:
47  case PPC::VFRCRegClassID:
48  case PPC::VSSRCRegClassID:
49  case PPC::F4RCRegClassID:
50  return getRegBank(PPC::FPRRegBankID);
51  case PPC::CRRCRegClassID:
52  case PPC::CRBITRCRegClassID:
53  return getRegBank(PPC::CRRegBankID);
54  default:
55  llvm_unreachable("Unexpected register class");
56  }
57 }
58 
61  const unsigned Opc = MI.getOpcode();
62 
63  // Try the default logic for non-generic instructions that are either copies
64  // or already have some operands assigned to banks.
65  if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
68  if (Mapping.isValid())
69  return Mapping;
70  }
71 
72  const MachineFunction &MF = *MI.getParent()->getParent();
73  const MachineRegisterInfo &MRI = MF.getRegInfo();
74  const TargetSubtargetInfo &STI = MF.getSubtarget();
75  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
76 
77  unsigned NumOperands = MI.getNumOperands();
78  const ValueMapping *OperandsMapping = nullptr;
79  unsigned Cost = 1;
80  unsigned MappingID = DefaultMappingID;
81 
82  switch (Opc) {
83  // Arithmetic ops.
84  case TargetOpcode::G_ADD:
85  case TargetOpcode::G_SUB:
86  // Bitwise ops.
87  case TargetOpcode::G_AND:
88  case TargetOpcode::G_OR:
89  case TargetOpcode::G_XOR:
90  // Extension ops.
91  case TargetOpcode::G_SEXT:
92  case TargetOpcode::G_ZEXT:
93  case TargetOpcode::G_ANYEXT:
94  assert(NumOperands <= 3 &&
95  "This code is for instructions with 3 or less operands");
96  OperandsMapping = getValueMapping(PMI_GPR64);
97  break;
98  case TargetOpcode::G_FADD:
99  case TargetOpcode::G_FSUB:
100  case TargetOpcode::G_FMUL:
101  case TargetOpcode::G_FDIV: {
102  Register SrcReg = MI.getOperand(1).getReg();
103  unsigned Size = getSizeInBits(SrcReg, MRI, TRI);
104 
105  assert((Size == 32 || Size == 64) && "Unsupported floating point types!\n");
106  OperandsMapping = getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64);
107  break;
108  }
109  case TargetOpcode::G_FCMP: {
110  unsigned CmpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
111 
112  OperandsMapping = getOperandsMapping(
113  {getValueMapping(PMI_CR), nullptr,
114  getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64),
115  getValueMapping(CmpSize == 32 ? PMI_FPR32 : PMI_FPR64)});
116  break;
117  }
118  case TargetOpcode::G_CONSTANT:
119  OperandsMapping = getOperandsMapping({getValueMapping(PMI_GPR64), nullptr});
120  break;
121  case TargetOpcode::G_FPTOUI:
122  case TargetOpcode::G_FPTOSI: {
123  Register SrcReg = MI.getOperand(1).getReg();
124  unsigned Size = getSizeInBits(SrcReg, MRI, TRI);
125 
126  OperandsMapping = getOperandsMapping(
128  getValueMapping(Size == 32 ? PMI_FPR32 : PMI_FPR64)});
129  break;
130  }
131  case TargetOpcode::G_UITOFP:
132  case TargetOpcode::G_SITOFP: {
133  Register SrcReg = MI.getOperand(0).getReg();
134  unsigned Size = getSizeInBits(SrcReg, MRI, TRI);
135 
136  OperandsMapping =
139  break;
140  }
141  case TargetOpcode::G_LOAD: {
142  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
143  // Check if that load feeds fp instructions.
144  if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
145  [&](const MachineInstr &UseMI) {
146  // If we have at least one direct use in a FP instruction,
147  // assume this was a floating point load in the IR. If it was
148  // not, we would have had a bitcast before reaching that
149  // instruction.
150  //
151  // Int->FP conversion operations are also captured in
152  // onlyDefinesFP().
153  return onlyUsesFP(UseMI, MRI, TRI);
154  }))
155  OperandsMapping = getOperandsMapping(
156  {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),
158  else
159  OperandsMapping = getOperandsMapping(
160  {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),
162  break;
163  }
164  case TargetOpcode::G_STORE: {
165  // Check if the store is fed by fp instructions.
166  MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg());
167  unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
168  if (onlyDefinesFP(*DefMI, MRI, TRI))
169  OperandsMapping = getOperandsMapping(
170  {getValueMapping(Size == 64 ? PMI_FPR64 : PMI_FPR32),
172  else
173  OperandsMapping = getOperandsMapping(
174  {getValueMapping(Size == 64 ? PMI_GPR64 : PMI_GPR32),
176  break;
177  }
178  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: {
179  // FIXME: We have to check every operand in this MI and compute value
180  // mapping accordingly.
181  SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
182  OperandsMapping = getOperandsMapping(OpdsMapping);
183  break;
184  }
185  default:
187  }
188 
189  return getInstructionMapping(MappingID, Cost, OperandsMapping, NumOperands);
190 }
191 
192 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
193 /// having only floating-point operands.
194 /// FIXME: this is copied from target AArch64. Needs some code refactor here to
195 /// put this function in GlobalISel/Utils.cpp.
196 static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
197  switch (Opc) {
198  case TargetOpcode::G_FADD:
199  case TargetOpcode::G_FSUB:
200  case TargetOpcode::G_FMUL:
201  case TargetOpcode::G_FMA:
202  case TargetOpcode::G_FDIV:
203  case TargetOpcode::G_FCONSTANT:
204  case TargetOpcode::G_FPEXT:
205  case TargetOpcode::G_FPTRUNC:
206  case TargetOpcode::G_FCEIL:
207  case TargetOpcode::G_FFLOOR:
208  case TargetOpcode::G_FNEARBYINT:
209  case TargetOpcode::G_FNEG:
210  case TargetOpcode::G_FCOS:
211  case TargetOpcode::G_FSIN:
212  case TargetOpcode::G_FLOG10:
213  case TargetOpcode::G_FLOG:
214  case TargetOpcode::G_FLOG2:
215  case TargetOpcode::G_FSQRT:
216  case TargetOpcode::G_FABS:
217  case TargetOpcode::G_FEXP:
218  case TargetOpcode::G_FRINT:
219  case TargetOpcode::G_INTRINSIC_TRUNC:
220  case TargetOpcode::G_INTRINSIC_ROUND:
221  case TargetOpcode::G_FMAXNUM:
222  case TargetOpcode::G_FMINNUM:
223  case TargetOpcode::G_FMAXIMUM:
224  case TargetOpcode::G_FMINIMUM:
225  return true;
226  }
227  return false;
228 }
229 
230 /// \returns true if a given intrinsic \p ID only uses and defines FPRs.
231 static bool isFPIntrinsic(unsigned ID) {
232  // TODO: Add more intrinsics.
233  return false;
234 }
235 
236 /// FIXME: this is copied from target AArch64. Needs some code refactor here to
237 /// put this function in class RegisterBankInfo.
238 bool PPCRegisterBankInfo::hasFPConstraints(const MachineInstr &MI,
239  const MachineRegisterInfo &MRI,
240  const TargetRegisterInfo &TRI,
241  unsigned Depth) const {
242  unsigned Op = MI.getOpcode();
243  if (Op == TargetOpcode::G_INTRINSIC && isFPIntrinsic(MI.getIntrinsicID()))
244  return true;
245 
246  // Do we have an explicit floating point instruction?
248  return true;
249 
250  // No. Check if we have a copy-like instruction. If we do, then we could
251  // still be fed by floating point instructions.
252  if (Op != TargetOpcode::COPY && !MI.isPHI() &&
254  return false;
255 
256  // Check if we already know the register bank.
257  auto *RB = getRegBank(MI.getOperand(0).getReg(), MRI, TRI);
258  if (RB == &PPC::FPRRegBank)
259  return true;
260  if (RB == &PPC::GPRRegBank)
261  return false;
262 
263  // We don't know anything.
264  //
265  // If we have a phi, we may be able to infer that it will be assigned a FPR
266  // based off of its inputs.
267  if (!MI.isPHI() || Depth > MaxFPRSearchDepth)
268  return false;
269 
270  return any_of(MI.explicit_uses(), [&](const MachineOperand &Op) {
271  return Op.isReg() &&
272  onlyDefinesFP(*MRI.getVRegDef(Op.getReg()), MRI, TRI, Depth + 1);
273  });
274 }
275 
276 /// FIXME: this is copied from target AArch64. Needs some code refactor here to
277 /// put this function in class RegisterBankInfo.
278 bool PPCRegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
279  const MachineRegisterInfo &MRI,
280  const TargetRegisterInfo &TRI,
281  unsigned Depth) const {
282  switch (MI.getOpcode()) {
283  case TargetOpcode::G_FPTOSI:
284  case TargetOpcode::G_FPTOUI:
285  case TargetOpcode::G_FCMP:
286  case TargetOpcode::G_LROUND:
287  case TargetOpcode::G_LLROUND:
288  return true;
289  default:
290  break;
291  }
292  return hasFPConstraints(MI, MRI, TRI, Depth);
293 }
294 
295 /// FIXME: this is copied from target AArch64. Needs some code refactor here to
296 /// put this function in class RegisterBankInfo.
297 bool PPCRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
298  const MachineRegisterInfo &MRI,
299  const TargetRegisterInfo &TRI,
300  unsigned Depth) const {
301  switch (MI.getOpcode()) {
302  case TargetOpcode::G_SITOFP:
303  case TargetOpcode::G_UITOFP:
304  return true;
305  default:
306  break;
307  }
308  return hasFPConstraints(MI, MRI, TRI, Depth);
309 }
310 
313  // TODO Implement.
315 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:74
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:107
llvm::PPCRegisterBankInfo::getRegBankFromRegClass
const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override
Get a register bank that covers RC.
Definition: PPCRegisterBankInfo.cpp:32
PPCRegisterInfo.h
llvm::PPCGenRegisterBankInfo::PMI_CR
@ PMI_CR
Definition: PPCRegisterBankInfo.h:35
llvm::RegisterBankInfo::getInstrMappingImpl
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
Definition: RegisterBankInfo.cpp:159
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:51
llvm::isPreISelGenericOptimizationHint
bool isPreISelGenericOptimizationHint(unsigned Opcode)
Definition: TargetOpcodes.h:42
llvm::PPCRegisterBankInfo::getInstrMapping
const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override
Get the mapping of the different operands of MI on the register bank.
Definition: PPCRegisterBankInfo.cpp:60
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
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:431
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:127
llvm::MachineRegisterInfo::use_nodbg_instructions
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
Definition: MachineRegisterInfo.h:565
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:236
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::RegisterBankInfo::InstructionMapping::isValid
bool isValid() const
Check whether this object is valid.
Definition: RegisterBankInfo.h:253
llvm::PPCGenRegisterBankInfo::PMI_GPR64
@ PMI_GPR64
Definition: PPCRegisterBankInfo.h:32
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
PPCRegisterBankInfo.h
MachineRegisterInfo.h
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:682
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::PPCGenRegisterBankInfo::PMI_GPR32
@ PMI_GPR32
Definition: PPCRegisterBankInfo.h:31
isPreISelGenericFloatingPointOpcode
static bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Definition: PPCRegisterBankInfo.cpp:196
InlinePriorityMode::Cost
@ Cost
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:398
llvm::RegisterBankInfo::getInstrAlternativeMappings
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
Definition: RegisterBankInfo.cpp:430
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::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::LLT::getSizeInBits
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:159
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:672
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
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
isFPIntrinsic
static bool isFPIntrinsic(unsigned ID)
Definition: PPCRegisterBankInfo.cpp:231
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:329
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction
Definition: MachineFunction.h:258
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:525
llvm::RegisterBankInfo::ValueMapping
Helper struct that represents how a value is mapped through different register banks.
Definition: RegisterBankInfo.h:145
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1742
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:62
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::PPCGenRegisterBankInfo::getValueMapping
static const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx RBIdx)
Get the pointer to the ValueMapping representing the RegisterBank at RBIdx.
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:354
llvm::PPCRegisterBankInfo::getInstrAlternativeMappings
InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override
Get the alternative mappings for MI.
Definition: PPCRegisterBankInfo.cpp:312
llvm::RegisterBankInfo::getInvalidInstructionMapping
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
Definition: RegisterBankInfo.h:533
llvm::PPCRegisterBankInfo::PPCRegisterBankInfo
PPCRegisterBankInfo(const TargetRegisterInfo &TRI)
Definition: PPCRegisterBankInfo.cpp:29
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:759
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:108
llvm::PPCGenRegisterBankInfo::PMI_FPR32
@ PMI_FPR32
Definition: PPCRegisterBankInfo.h:33
MachineFunction.h
Debug.h
llvm::PPCGenRegisterBankInfo::PMI_FPR64
@ PMI_FPR64
Definition: PPCRegisterBankInfo.h:34
llvm::LLT
Definition: LowLevelTypeImpl.h:39