LLVM  10.0.0svn
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"
17 #include "PPCHazardRecognizers.h"
18 #include "PPCInstrBuilder.h"
19 #include "PPCInstrInfo.h"
20 #include "PPCMachineFunctionInfo.h"
21 #include "PPCTargetMachine.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/Statistic.h"
29 #include "llvm/MC/MCAsmInfo.h"
30 #include "llvm/Support/Debug.h"
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "ppc-vsx-copy"
38 
39 namespace {
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,
53  if (Register::isVirtualRegister(Reg)) {
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 
82 protected:
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 
141 public:
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 
151  for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
152  MachineBasicBlock &B = *I++;
153  if (processBlock(B))
154  Changed = true;
155  }
156 
157  return Changed;
158  }
159 
160  void getAnalysisUsage(AnalysisUsage &AU) const override {
162  }
163  };
164 }
165 
166 INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
167  "PowerPC VSX Copy Legalization", false, false)
168 
169 char PPCVSXCopy::ID = 0;
171 llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }
172 
void initializePPCVSXCopyPass(PassRegistry &)
const MachineInstrBuilder & add(const MachineOperand &MO) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool contains(unsigned Reg) const
Return true if the specified register is included in this register class.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned Reg
bool hasVSX() const
Definition: PPCSubtarget.h:252
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void setReg(Register Reg)
Change the register this operand corresponds to.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
#define DEBUG_TYPE
Definition: PPCVSXCopy.cpp:37
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
FunctionPass * createPPCVSXCopyPass()
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:33
Iterator for intrusive lists based on ilist_node.
const PPCInstrInfo * getInstrInfo() const override
Definition: PPCSubtarget.h:184
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:215
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:44
#define I(x, y, z)
Definition: MD5.cpp:58
void setSubReg(unsigned subReg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:69
IRTranslator LLVM IR MI
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19