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