1 | //===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===// |
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 file defines a pass that expands COPY and SUBREG_TO_REG pseudo |
10 | // instructions after register allocation. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "llvm/CodeGen/MachineFunctionPass.h" |
15 | #include "llvm/CodeGen/MachineInstr.h" |
16 | #include "llvm/CodeGen/Passes.h" |
17 | #include "llvm/CodeGen/TargetInstrInfo.h" |
18 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
19 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
20 | #include "llvm/InitializePasses.h" |
21 | #include "llvm/Support/Debug.h" |
22 | #include "llvm/Support/raw_ostream.h" |
23 | |
24 | using namespace llvm; |
25 | |
26 | #define DEBUG_TYPE "postrapseudos" |
27 | |
28 | namespace { |
29 | struct ExpandPostRA : public MachineFunctionPass { |
30 | private: |
31 | const TargetRegisterInfo *TRI = nullptr; |
32 | const TargetInstrInfo *TII = nullptr; |
33 | |
34 | public: |
35 | static char ID; // Pass identification, replacement for typeid |
36 | ExpandPostRA() : MachineFunctionPass(ID) {} |
37 | |
38 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
39 | AU.setPreservesCFG(); |
40 | AU.addPreservedID(ID&: MachineLoopInfoID); |
41 | AU.addPreservedID(ID&: MachineDominatorsID); |
42 | MachineFunctionPass::getAnalysisUsage(AU); |
43 | } |
44 | |
45 | /// runOnMachineFunction - pass entry point |
46 | bool runOnMachineFunction(MachineFunction&) override; |
47 | |
48 | private: |
49 | bool LowerSubregToReg(MachineInstr *MI); |
50 | }; |
51 | } // end anonymous namespace |
52 | |
53 | char ExpandPostRA::ID = 0; |
54 | char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID; |
55 | |
56 | INITIALIZE_PASS(ExpandPostRA, DEBUG_TYPE, |
57 | "Post-RA pseudo instruction expansion pass" , false, false) |
58 | |
59 | bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { |
60 | MachineBasicBlock *MBB = MI->getParent(); |
61 | assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && |
62 | MI->getOperand(1).isImm() && |
63 | (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && |
64 | MI->getOperand(3).isImm() && "Invalid subreg_to_reg" ); |
65 | |
66 | Register DstReg = MI->getOperand(i: 0).getReg(); |
67 | Register InsReg = MI->getOperand(i: 2).getReg(); |
68 | assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?" ); |
69 | unsigned SubIdx = MI->getOperand(i: 3).getImm(); |
70 | |
71 | assert(SubIdx != 0 && "Invalid index for insert_subreg" ); |
72 | Register DstSubReg = TRI->getSubReg(Reg: DstReg, Idx: SubIdx); |
73 | |
74 | assert(DstReg.isPhysical() && |
75 | "Insert destination must be in a physical register" ); |
76 | assert(InsReg.isPhysical() && |
77 | "Inserted value must be in a physical register" ); |
78 | |
79 | LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); |
80 | |
81 | if (MI->allDefsAreDead()) { |
82 | MI->setDesc(TII->get(Opcode: TargetOpcode::KILL)); |
83 | MI->removeOperand(OpNo: 3); // SubIdx |
84 | MI->removeOperand(OpNo: 1); // Imm |
85 | LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI); |
86 | return true; |
87 | } |
88 | |
89 | if (DstSubReg == InsReg) { |
90 | // No need to insert an identity copy instruction. |
91 | // Watch out for case like this: |
92 | // %rax = SUBREG_TO_REG 0, killed %eax, 3 |
93 | // We must leave %rax live. |
94 | if (DstReg != InsReg) { |
95 | MI->setDesc(TII->get(Opcode: TargetOpcode::KILL)); |
96 | MI->removeOperand(OpNo: 3); // SubIdx |
97 | MI->removeOperand(OpNo: 1); // Imm |
98 | LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI); |
99 | return true; |
100 | } |
101 | LLVM_DEBUG(dbgs() << "subreg: eliminated!" ); |
102 | } else { |
103 | TII->copyPhysReg(MBB&: *MBB, MI, DL: MI->getDebugLoc(), DestReg: DstSubReg, SrcReg: InsReg, |
104 | KillSrc: MI->getOperand(i: 2).isKill()); |
105 | |
106 | // Implicitly define DstReg for subsequent uses. |
107 | MachineBasicBlock::iterator CopyMI = MI; |
108 | --CopyMI; |
109 | CopyMI->addRegisterDefined(Reg: DstReg); |
110 | LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); |
111 | } |
112 | |
113 | LLVM_DEBUG(dbgs() << '\n'); |
114 | MBB->erase(I: MI); |
115 | return true; |
116 | } |
117 | |
118 | /// runOnMachineFunction - Reduce subregister inserts and extracts to register |
119 | /// copies. |
120 | /// |
121 | bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { |
122 | LLVM_DEBUG(dbgs() << "Machine Function\n" |
123 | << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" |
124 | << "********** Function: " << MF.getName() << '\n'); |
125 | TRI = MF.getSubtarget().getRegisterInfo(); |
126 | TII = MF.getSubtarget().getInstrInfo(); |
127 | |
128 | bool MadeChange = false; |
129 | |
130 | for (MachineBasicBlock &MBB : MF) { |
131 | for (MachineInstr &MI : llvm::make_early_inc_range(Range&: MBB)) { |
132 | // Only expand pseudos. |
133 | if (!MI.isPseudo()) |
134 | continue; |
135 | |
136 | // Give targets a chance to expand even standard pseudos. |
137 | if (TII->expandPostRAPseudo(MI)) { |
138 | MadeChange = true; |
139 | continue; |
140 | } |
141 | |
142 | // Expand standard pseudos. |
143 | switch (MI.getOpcode()) { |
144 | case TargetOpcode::SUBREG_TO_REG: |
145 | MadeChange |= LowerSubregToReg(MI: &MI); |
146 | break; |
147 | case TargetOpcode::COPY: |
148 | TII->lowerCopy(MI: &MI, TRI); |
149 | MadeChange = true; |
150 | break; |
151 | case TargetOpcode::DBG_VALUE: |
152 | continue; |
153 | case TargetOpcode::INSERT_SUBREG: |
154 | case TargetOpcode::EXTRACT_SUBREG: |
155 | llvm_unreachable("Sub-register pseudos should have been eliminated." ); |
156 | } |
157 | } |
158 | } |
159 | |
160 | return MadeChange; |
161 | } |
162 | |