xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===---------- SystemZPhysRegCopy.cpp - Handle phys reg copies -----------===//
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 // This pass makes sure that a COPY of a physical register will be
10 // implementable after register allocation in copyPhysReg() (this could be
11 // done in EmitInstrWithCustomInserter() instead if COPY instructions would
12 // be passed to it).
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "SystemZTargetMachine.h"
17 #include "llvm/CodeGen/MachineDominators.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/TargetInstrInfo.h"
22 #include "llvm/CodeGen/TargetRegisterInfo.h"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 class SystemZCopyPhysRegs : public MachineFunctionPass {
29 public:
30   static char ID;
31   SystemZCopyPhysRegs() : MachineFunctionPass(ID), TII(nullptr), MRI(nullptr) {}
32 
33   bool runOnMachineFunction(MachineFunction &MF) override;
34   void getAnalysisUsage(AnalysisUsage &AU) const override;
35 
36 private:
37 
38   bool visitMBB(MachineBasicBlock &MBB);
39 
40   const SystemZInstrInfo *TII;
41   MachineRegisterInfo *MRI;
42 };
43 
44 char SystemZCopyPhysRegs::ID = 0;
45 
46 } // end anonymous namespace
47 
48 INITIALIZE_PASS(SystemZCopyPhysRegs, "systemz-copy-physregs",
49                 "SystemZ Copy Physregs", false, false)
50 
51 FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) {
52   return new SystemZCopyPhysRegs();
53 }
54 
55 void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const {
56   AU.setPreservesCFG();
57   MachineFunctionPass::getAnalysisUsage(AU);
58 }
59 
60 bool SystemZCopyPhysRegs::visitMBB(MachineBasicBlock &MBB) {
61   bool Modified = false;
62 
63   // Certain special registers can only be copied from a subset of the
64   // default register class of the type. It is therefore necessary to create
65   // the target copy instructions before regalloc instead of in copyPhysReg().
66   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
67        MBBI != E; ) {
68     MachineInstr *MI = &*MBBI++;
69     if (!MI->isCopy())
70       continue;
71 
72     DebugLoc DL = MI->getDebugLoc();
73     Register SrcReg = MI->getOperand(1).getReg();
74     Register DstReg = MI->getOperand(0).getReg();
75 
76     if (DstReg.isVirtual() &&
77         (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(SrcReg))) {
78       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
79       if (SrcReg == SystemZ::CC)
80         BuildMI(MBB, MI, DL, TII->get(SystemZ::IPM), Tmp);
81       else
82         BuildMI(MBB, MI, DL, TII->get(SystemZ::EAR), Tmp).addReg(SrcReg);
83       MI->getOperand(1).setReg(Tmp);
84       Modified = true;
85     }
86     else if (SrcReg.isVirtual() &&
87              SystemZ::AR32BitRegClass.contains(DstReg)) {
88       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
89       MI->getOperand(0).setReg(Tmp);
90       MachineInstr *NMI =
91           BuildMI(MBB, MBBI, DL, TII->get(SystemZ::SAR), DstReg).addReg(Tmp);
92       // SAR now writes the final value to DstReg, so update debug values.
93       MBB.getParent()->substituteDebugValuesForInst(*MI, *NMI);
94       Modified = true;
95     }
96   }
97 
98   return Modified;
99 }
100 
101 bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) {
102   TII = F.getSubtarget<SystemZSubtarget>().getInstrInfo();
103   MRI = &F.getRegInfo();
104 
105   bool Modified = false;
106   for (auto &MBB : F)
107     Modified |= visitMBB(MBB);
108 
109   return Modified;
110 }
111 
112