LLVM 22.0.0git
PPCVSXWACCCopy.cpp
Go to the documentation of this file.
1//===--------- PPCVSXWACCCopy.cpp - VSX and WACC 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 and combines the wacc/wacc_hi copies when needed.
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// PPCVSXWACCCopy 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.
35struct PPCVSXWACCCopy : public MachineFunctionPass {
36 static char ID;
37 PPCVSXWACCCopy() : MachineFunctionPass(ID) {}
38
39 const TargetInstrInfo *TII;
40
41 bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
44 return RC->hasSubClassEq(MRI.getRegClass(Reg));
45 } else if (RC->contains(Reg)) {
46 return true;
47 }
48
49 return false;
50 }
51
52 bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
53 return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
54 }
55
56 bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
57 return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
58 }
59
60 bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
61 return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
62 }
63
64 bool IsVSFReg(unsigned Reg, MachineRegisterInfo &MRI) {
65 return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
66 }
67
68 bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
69 return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
70 }
71
72protected:
73 bool processBlock(MachineBasicBlock &MBB) {
74 bool Changed = false;
75
76 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
77 for (MachineInstr &MI : MBB) {
78 if (!MI.isFullCopy())
79 continue;
80
81 MachineOperand &DstMO = MI.getOperand(0);
82 MachineOperand &SrcMO = MI.getOperand(1);
83
84 if (IsVSReg(DstMO.getReg(), MRI) && !IsVSReg(SrcMO.getReg(), MRI)) {
85 // This is a copy *to* a VSX register from a non-VSX register.
86 Changed = true;
87
88 const TargetRegisterClass *SrcRC = &PPC::VSLRCRegClass;
89 assert((IsF8Reg(SrcMO.getReg(), MRI) || IsVSSReg(SrcMO.getReg(), MRI) ||
90 IsVSFReg(SrcMO.getReg(), MRI)) &&
91 "Unknown source for a VSX copy");
92
93 Register NewVReg = MRI.createVirtualRegister(SrcRC);
94 BuildMI(MBB, MI, MI.getDebugLoc(),
95 TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
96 .addImm(1) // add 1, not 0, because there is no implicit clearing
97 // of the high bits.
98 .add(SrcMO)
99 .addImm(PPC::sub_64);
100
101 // The source of the original copy is now the new virtual register.
102 SrcMO.setReg(NewVReg);
103 } else if (!IsVSReg(DstMO.getReg(), MRI) &&
104 IsVSReg(SrcMO.getReg(), MRI)) {
105 // This is a copy *from* a VSX register to a non-VSX register.
106 Changed = true;
107
108 const TargetRegisterClass *DstRC = &PPC::VSLRCRegClass;
109 assert((IsF8Reg(DstMO.getReg(), MRI) || IsVSFReg(DstMO.getReg(), MRI) ||
110 IsVSSReg(DstMO.getReg(), MRI)) &&
111 "Unknown destination for a VSX copy");
112
113 // Copy the VSX value into a new VSX register of the correct subclass.
114 Register NewVReg = MRI.createVirtualRegister(DstRC);
115 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(TargetOpcode::COPY),
116 NewVReg)
117 .add(SrcMO);
118
119 // Transform the original copy into a subregister extraction copy.
120 SrcMO.setReg(NewVReg);
121 SrcMO.setSubReg(PPC::sub_64);
122 } else if (IsRegInClass(DstMO.getReg(), &PPC::WACC_HIRCRegClass, MRI) &&
123 IsRegInClass(SrcMO.getReg(), &PPC::WACCRCRegClass, MRI)) {
124 // Matches the pattern:
125 // %a:waccrc = COPY %b.sub_wacc_hi:dmrrc
126 // %c:wacc_hirc = COPY %a:waccrc
127 // And replaces it with:
128 // %c:wacc_hirc = COPY %b.sub_wacc_hi:dmrrc
129 MachineInstr *DefMI = MRI.getUniqueVRegDef(SrcMO.getReg());
130 if (!DefMI || !DefMI->isCopy())
131 continue;
132
133 MachineOperand &OrigSrc = DefMI->getOperand(1);
134
135 if (!IsRegInClass(OrigSrc.getReg(), &PPC::DMRRCRegClass, MRI))
136 continue;
137
138 if (OrigSrc.getSubReg() != PPC::sub_wacc_hi)
139 continue;
140
141 // Rewrite the second copy to use the original register's subreg
142 SrcMO.setReg(OrigSrc.getReg());
143 SrcMO.setSubReg(PPC::sub_wacc_hi);
144 Changed = true;
145
146 // Remove the intermediate copy if safe
147 if (MRI.use_nodbg_empty(DefMI->getOperand(0).getReg()))
148 DefMI->eraseFromParent();
149 }
150 }
151
152 return Changed;
153 }
154
155public:
156 bool runOnMachineFunction(MachineFunction &MF) override {
157 // If we don't have VSX on the subtarget, don't do anything.
158 const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
159 if (!STI.hasVSX())
160 return false;
161 TII = STI.getInstrInfo();
162
163 bool Changed = false;
164
166 if (processBlock(B))
167 Changed = true;
168
169 return Changed;
170 }
171
172 void getAnalysisUsage(AnalysisUsage &AU) const override {
174 }
175};
176} // end anonymous namespace
177
178INITIALIZE_PASS(PPCVSXWACCCopy, DEBUG_TYPE, "PowerPC VSX Copy Legalization",
179 false, false)
180
181char PPCVSXWACCCopy::ID = 0;
182FunctionPass *llvm::createPPCVSXWACCCopyPass() { return new PPCVSXWACCCopy(); }
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register Reg
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
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:314
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
LLVM_ABI 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
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:61
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.
Changed
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.
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:626
FunctionPass * createPPCVSXWACCCopyPass()