183 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// A pass which deals with the complexity of generating legal VSX register10// copies to/from register classes which partially overlap with the VSX11// 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"20#include "llvm/CodeGen/MachineFrameInfo.h"21#include "llvm/CodeGen/MachineFunctionPass.h"22#include "llvm/CodeGen/MachineInstrBuilder.h"23#include "llvm/CodeGen/MachineMemOperand.h"24#include "llvm/CodeGen/MachineRegisterInfo.h"25#include "llvm/Support/ErrorHandling.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 registers33// (Altivec and scalar floating-point registers), we need to transform the34// 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,42 MachineRegisterInfo &MRI) {43 if (Register::isVirtualRegister(Reg)) {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 clearing97 // 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:dmrrc126 // %c:wacc_hirc = COPY %a:waccrc127 // And replaces it with:128 // %c:wacc_hirc = COPY %b.sub_wacc_hi:dmrrc129 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 subreg142 SrcMO.setReg(OrigSrc.getReg());143 SrcMO.setSubReg(PPC::sub_wacc_hi);144 Changed = true;145 146 // Remove the intermediate copy if safe147 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 165 for (MachineBasicBlock &B : llvm::make_early_inc_range(MF))166 if (processBlock(B))167 Changed = true;168 169 return Changed;170 }171 172 void getAnalysisUsage(AnalysisUsage &AU) const override {173 MachineFunctionPass::getAnalysisUsage(AU);174 }175};176} // end anonymous namespace177 178INITIALIZE_PASS(PPCVSXWACCCopy, DEBUG_TYPE, "PowerPC VSX Copy Legalization",179 false, false)180 181char PPCVSXWACCCopy::ID = 0;182FunctionPass *llvm::createPPCVSXWACCCopyPass() { return new PPCVSXWACCCopy(); }183