xref: /llvm-project/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp (revision ed8019d9fbed2e6a6b08f8f73e9fa54a24f3ed52)
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()
32     : MachineFunctionPass(ID), TII(nullptr), MRI(nullptr) {
33     initializeSystemZCopyPhysRegsPass(*PassRegistry::getPassRegistry());
34   }
35 
36   bool runOnMachineFunction(MachineFunction &MF) override;
37   void getAnalysisUsage(AnalysisUsage &AU) const override;
38 
39 private:
40 
41   bool visitMBB(MachineBasicBlock &MBB);
42 
43   const SystemZInstrInfo *TII;
44   MachineRegisterInfo *MRI;
45 };
46 
47 char SystemZCopyPhysRegs::ID = 0;
48 
49 } // end anonymous namespace
50 
51 INITIALIZE_PASS(SystemZCopyPhysRegs, "systemz-copy-physregs",
52                 "SystemZ Copy Physregs", false, false)
53 
54 FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) {
55   return new SystemZCopyPhysRegs();
56 }
57 
58 void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const {
59   AU.setPreservesCFG();
60   MachineFunctionPass::getAnalysisUsage(AU);
61 }
62 
63 bool SystemZCopyPhysRegs::visitMBB(MachineBasicBlock &MBB) {
64   bool Modified = false;
65 
66   // Certain special registers can only be copied from a subset of the
67   // default register class of the type. It is therefore necessary to create
68   // the target copy instructions before regalloc instead of in copyPhysReg().
69   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
70        MBBI != E; ) {
71     MachineInstr *MI = &*MBBI++;
72     if (!MI->isCopy())
73       continue;
74 
75     DebugLoc DL = MI->getDebugLoc();
76     Register SrcReg = MI->getOperand(1).getReg();
77     Register DstReg = MI->getOperand(0).getReg();
78     if (DstReg.isVirtual() &&
79         (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(SrcReg))) {
80       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
81       if (SrcReg == SystemZ::CC)
82         BuildMI(MBB, MI, DL, TII->get(SystemZ::IPM), Tmp);
83       else
84         BuildMI(MBB, MI, DL, TII->get(SystemZ::EAR), Tmp).addReg(SrcReg);
85       MI->getOperand(1).setReg(Tmp);
86       Modified = true;
87     }
88     else if (SrcReg.isVirtual() &&
89              SystemZ::AR32BitRegClass.contains(DstReg)) {
90       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
91       MI->getOperand(0).setReg(Tmp);
92       BuildMI(MBB, MBBI, DL, TII->get(SystemZ::SAR), DstReg).addReg(Tmp);
93       Modified = true;
94     }
95   }
96 
97   return Modified;
98 }
99 
100 bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) {
101   TII = F.getSubtarget<SystemZSubtarget>().getInstrInfo();
102   MRI = &F.getRegInfo();
103 
104   bool Modified = false;
105   for (auto &MBB : F)
106     Modified |= visitMBB(MBB);
107 
108   return Modified;
109 }
110 
111