LLVM 20.0.0git
PPCVSXCopy.cpp
Go to the documentation of this file.
1//===-------------- PPCVSXCopy.cpp - VSX Copy Legalization ----------------===//
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//
9// A pass which deals with the complexity of generating legal VSX register
10// copies to/from register classes which partially overlap with the VSX
11// register file.
12//
13//===----------------------------------------------------------------------===//
14
15#include "PPC.h"
16#include "PPCInstrInfo.h"
17#include "PPCTargetMachine.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/Statistic.h"
26
27using namespace llvm;
28
29#define DEBUG_TYPE "ppc-vsx-copy"
30
31namespace {
32 // PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
33 // (Altivec and scalar floating-point registers), we need to transform the
34 // copies into subregister copies with other restrictions.
35 struct PPCVSXCopy : public MachineFunctionPass {
36 static char ID;
37 PPCVSXCopy() : MachineFunctionPass(ID) {
39 }
40
41 const TargetInstrInfo *TII;
42
43 bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
46 return RC->hasSubClassEq(MRI.getRegClass(Reg));
47 } else if (RC->contains(Reg)) {
48 return true;
49 }
50
51 return false;
52 }
53
54 bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
55 return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
56 }
57
58 bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
59 return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
60 }
61
62 bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
63 return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
64 }
65
66 bool IsVSFReg(unsigned Reg, MachineRegisterInfo &MRI) {
67 return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
68 }
69
70 bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
71 return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
72 }
73
74protected:
75 bool processBlock(MachineBasicBlock &MBB) {
76 bool Changed = false;
77
79 for (MachineInstr &MI : MBB) {
80 if (!MI.isFullCopy())
81 continue;
82
83 MachineOperand &DstMO = MI.getOperand(0);
84 MachineOperand &SrcMO = MI.getOperand(1);
85
86 if ( IsVSReg(DstMO.getReg(), MRI) &&
87 !IsVSReg(SrcMO.getReg(), MRI)) {
88 // This is a copy *to* a VSX register from a non-VSX register.
89 Changed = true;
90
91 const TargetRegisterClass *SrcRC = &PPC::VSLRCRegClass;
92 assert((IsF8Reg(SrcMO.getReg(), MRI) ||
93 IsVSSReg(SrcMO.getReg(), MRI) ||
94 IsVSFReg(SrcMO.getReg(), MRI)) &&
95 "Unknown source for a VSX copy");
96
97 Register NewVReg = MRI.createVirtualRegister(SrcRC);
98 BuildMI(MBB, MI, MI.getDebugLoc(),
99 TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
100 .addImm(1) // add 1, not 0, because there is no implicit clearing
101 // of the high bits.
102 .add(SrcMO)
103 .addImm(PPC::sub_64);
104
105 // The source of the original copy is now the new virtual register.
106 SrcMO.setReg(NewVReg);
107 } else if (!IsVSReg(DstMO.getReg(), MRI) &&
108 IsVSReg(SrcMO.getReg(), MRI)) {
109 // This is a copy *from* a VSX register to a non-VSX register.
110 Changed = true;
111
112 const TargetRegisterClass *DstRC = &PPC::VSLRCRegClass;
113 assert((IsF8Reg(DstMO.getReg(), MRI) ||
114 IsVSFReg(DstMO.getReg(), MRI) ||
115 IsVSSReg(DstMO.getReg(), MRI)) &&
116 "Unknown destination for a VSX copy");
117
118 // Copy the VSX value into a new VSX register of the correct subclass.
119 Register NewVReg = MRI.createVirtualRegister(DstRC);
120 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(TargetOpcode::COPY),
121 NewVReg)
122 .add(SrcMO);
123
124 // Transform the original copy into a subregister extraction copy.
125 SrcMO.setReg(NewVReg);
126 SrcMO.setSubReg(PPC::sub_64);
127 }
128 }
129
130 return Changed;
131 }
132
133public:
134 bool runOnMachineFunction(MachineFunction &MF) override {
135 // If we don't have VSX on the subtarget, don't do anything.
136 const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
137 if (!STI.hasVSX())
138 return false;
139 TII = STI.getInstrInfo();
140
141 bool Changed = false;
142
144 if (processBlock(B))
145 Changed = true;
146
147 return Changed;
148 }
149
150 void getAnalysisUsage(AnalysisUsage &AU) const override {
152 }
153 };
154}
155
156INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
157 "PowerPC VSX Copy Legalization", false, false)
158
159char PPCVSXCopy::ID = 0;
161llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define DEBUG_TYPE
Definition: PPCVSXCopy.cpp:29
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const PPCInstrInfo * getInstrInfo() const override
Definition: PPCSubtarget.h:150
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
TargetInstrInfo - Interface to description of machine instruction set.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
void initializePPCVSXCopyPass(PassRegistry &)
FunctionPass * createPPCVSXCopyPass()