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
16#include "PPC.h"
18#include "PPCInstrBuilder.h"
19#include "PPCInstrInfo.h"
21#include "PPCTargetMachine.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/Statistic.h"
29#include "llvm/MC/MCAsmInfo.h"
31#include "llvm/Support/Debug.h"
34
35using namespace llvm;
36
37#define DEBUG_TYPE "ppc-vsx-copy"
38
39namespace {
40 // PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
41 // (Altivec and scalar floating-point registers), we need to transform the
42 // copies into subregister copies with other restrictions.
43 struct PPCVSXCopy : public MachineFunctionPass {
44 static char ID;
45 PPCVSXCopy() : MachineFunctionPass(ID) {
47 }
48
49 const TargetInstrInfo *TII;
50
51 bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
54 return RC->hasSubClassEq(MRI.getRegClass(Reg));
55 } else if (RC->contains(Reg)) {
56 return true;
57 }
58
59 return false;
60 }
61
62 bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
63 return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
64 }
65
66 bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
67 return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
68 }
69
70 bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
71 return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
72 }
73
74 bool IsVSFReg(unsigned Reg, MachineRegisterInfo &MRI) {
75 return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
76 }
77
78 bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
79 return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
80 }
81
82protected:
83 bool processBlock(MachineBasicBlock &MBB) {
84 bool Changed = false;
85
87 for (MachineInstr &MI : MBB) {
88 if (!MI.isFullCopy())
89 continue;
90
91 MachineOperand &DstMO = MI.getOperand(0);
92 MachineOperand &SrcMO = MI.getOperand(1);
93
94 if ( IsVSReg(DstMO.getReg(), MRI) &&
95 !IsVSReg(SrcMO.getReg(), MRI)) {
96 // This is a copy *to* a VSX register from a non-VSX register.
97 Changed = true;
98
99 const TargetRegisterClass *SrcRC = &PPC::VSLRCRegClass;
100 assert((IsF8Reg(SrcMO.getReg(), MRI) ||
101 IsVSSReg(SrcMO.getReg(), MRI) ||
102 IsVSFReg(SrcMO.getReg(), MRI)) &&
103 "Unknown source for a VSX copy");
104
105 Register NewVReg = MRI.createVirtualRegister(SrcRC);
106 BuildMI(MBB, MI, MI.getDebugLoc(),
107 TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
108 .addImm(1) // add 1, not 0, because there is no implicit clearing
109 // of the high bits.
110 .add(SrcMO)
111 .addImm(PPC::sub_64);
112
113 // The source of the original copy is now the new virtual register.
114 SrcMO.setReg(NewVReg);
115 } else if (!IsVSReg(DstMO.getReg(), MRI) &&
116 IsVSReg(SrcMO.getReg(), MRI)) {
117 // This is a copy *from* a VSX register to a non-VSX register.
118 Changed = true;
119
120 const TargetRegisterClass *DstRC = &PPC::VSLRCRegClass;
121 assert((IsF8Reg(DstMO.getReg(), MRI) ||
122 IsVSFReg(DstMO.getReg(), MRI) ||
123 IsVSSReg(DstMO.getReg(), MRI)) &&
124 "Unknown destination for a VSX copy");
125
126 // Copy the VSX value into a new VSX register of the correct subclass.
127 Register NewVReg = MRI.createVirtualRegister(DstRC);
128 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(TargetOpcode::COPY),
129 NewVReg)
130 .add(SrcMO);
131
132 // Transform the original copy into a subregister extraction copy.
133 SrcMO.setReg(NewVReg);
134 SrcMO.setSubReg(PPC::sub_64);
135 }
136 }
137
138 return Changed;
139 }
140
141public:
142 bool runOnMachineFunction(MachineFunction &MF) override {
143 // If we don't have VSX on the subtarget, don't do anything.
144 const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
145 if (!STI.hasVSX())
146 return false;
147 TII = STI.getInstrInfo();
148
149 bool Changed = false;
150
152 if (processBlock(B))
153 Changed = true;
154
155 return Changed;
156 }
157
158 void getAnalysisUsage(AnalysisUsage &AU) const override {
160 }
161 };
162}
163
164INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
165 "PowerPC VSX Copy Legalization", false, false)
166
167char PPCVSXCopy::ID = 0;
169llvm::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:37
#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:146
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:656
void initializePPCVSXCopyPass(PassRegistry &)
FunctionPass * createPPCVSXCopyPass()