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(i: 1).getReg(); |
74 | Register DstReg = MI->getOperand(i: 0).getReg(); |
75 | |
76 | if (DstReg.isVirtual() && |
77 | (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(Reg: SrcReg))) { |
78 | Register Tmp = MRI->createVirtualRegister(RegClass: &SystemZ::GR32BitRegClass); |
79 | if (SrcReg == SystemZ::CC) |
80 | BuildMI(BB&: MBB, I: MI, MIMD: DL, MCID: TII->get(Opcode: SystemZ::IPM), DestReg: Tmp); |
81 | else |
82 | BuildMI(BB&: MBB, I: MI, MIMD: DL, MCID: TII->get(Opcode: SystemZ::EAR), DestReg: Tmp).addReg(RegNo: SrcReg); |
83 | MI->getOperand(i: 1).setReg(Tmp); |
84 | Modified = true; |
85 | } |
86 | else if (SrcReg.isVirtual() && |
87 | SystemZ::AR32BitRegClass.contains(Reg: DstReg)) { |
88 | Register Tmp = MRI->createVirtualRegister(RegClass: &SystemZ::GR32BitRegClass); |
89 | MI->getOperand(i: 0).setReg(Tmp); |
90 | MachineInstr *NMI = |
91 | BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII->get(Opcode: SystemZ::SAR), DestReg: DstReg).addReg(RegNo: Tmp); |
92 | // SAR now writes the final value to DstReg, so update debug values. |
93 | MBB.getParent()->substituteDebugValuesForInst(Old: *MI, New&: *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 | |