xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/ExpandPostRAPseudos.cpp (revision 62ff619dcc3540659a319be71c9a489f1659e14a)
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/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/CodeGen/TargetInstrInfo.h"
20 #include "llvm/CodeGen/TargetRegisterInfo.h"
21 #include "llvm/CodeGen/TargetSubtargetInfo.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "postrapseudos"
29 
30 namespace {
31 struct ExpandPostRA : public MachineFunctionPass {
32 private:
33   const TargetRegisterInfo *TRI;
34   const TargetInstrInfo *TII;
35 
36 public:
37   static char ID; // Pass identification, replacement for typeid
38   ExpandPostRA() : MachineFunctionPass(ID) {}
39 
40   void getAnalysisUsage(AnalysisUsage &AU) const override {
41     AU.setPreservesCFG();
42     AU.addPreservedID(MachineLoopInfoID);
43     AU.addPreservedID(MachineDominatorsID);
44     MachineFunctionPass::getAnalysisUsage(AU);
45   }
46 
47   /// runOnMachineFunction - pass entry point
48   bool runOnMachineFunction(MachineFunction&) override;
49 
50 private:
51   bool LowerSubregToReg(MachineInstr *MI);
52   bool LowerCopy(MachineInstr *MI);
53 
54   void TransferImplicitOperands(MachineInstr *MI);
55 };
56 } // end anonymous namespace
57 
58 char ExpandPostRA::ID = 0;
59 char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID;
60 
61 INITIALIZE_PASS(ExpandPostRA, DEBUG_TYPE,
62                 "Post-RA pseudo instruction expansion pass", false, false)
63 
64 /// TransferImplicitOperands - MI is a pseudo-instruction, and the lowered
65 /// replacement instructions immediately precede it.  Copy any implicit
66 /// operands from MI to the replacement instruction.
67 void ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) {
68   MachineBasicBlock::iterator CopyMI = MI;
69   --CopyMI;
70 
71   Register DstReg = MI->getOperand(0).getReg();
72   for (const MachineOperand &MO : MI->implicit_operands()) {
73     CopyMI->addOperand(MO);
74 
75     // Be conservative about preserving kills when subregister defs are
76     // involved. If there was implicit kill of a super-register overlapping the
77     // copy result, we would kill the subregisters previous copies defined.
78     if (MO.isKill() && TRI->regsOverlap(DstReg, MO.getReg()))
79       CopyMI->getOperand(CopyMI->getNumOperands() - 1).setIsKill(false);
80   }
81 }
82 
83 bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
84   MachineBasicBlock *MBB = MI->getParent();
85   assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
86          MI->getOperand(1).isImm() &&
87          (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&
88           MI->getOperand(3).isImm() && "Invalid subreg_to_reg");
89 
90   Register DstReg = MI->getOperand(0).getReg();
91   Register InsReg = MI->getOperand(2).getReg();
92   assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?");
93   unsigned SubIdx  = MI->getOperand(3).getImm();
94 
95   assert(SubIdx != 0 && "Invalid index for insert_subreg");
96   Register DstSubReg = TRI->getSubReg(DstReg, SubIdx);
97 
98   assert(Register::isPhysicalRegister(DstReg) &&
99          "Insert destination must be in a physical register");
100   assert(Register::isPhysicalRegister(InsReg) &&
101          "Inserted value must be in a physical register");
102 
103   LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);
104 
105   if (MI->allDefsAreDead()) {
106     MI->setDesc(TII->get(TargetOpcode::KILL));
107     MI->RemoveOperand(3); // SubIdx
108     MI->RemoveOperand(1); // Imm
109     LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI);
110     return true;
111   }
112 
113   if (DstSubReg == InsReg) {
114     // No need to insert an identity copy instruction.
115     // Watch out for case like this:
116     // %rax = SUBREG_TO_REG 0, killed %eax, 3
117     // We must leave %rax live.
118     if (DstReg != InsReg) {
119       MI->setDesc(TII->get(TargetOpcode::KILL));
120       MI->RemoveOperand(3);     // SubIdx
121       MI->RemoveOperand(1);     // Imm
122       LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI);
123       return true;
124     }
125     LLVM_DEBUG(dbgs() << "subreg: eliminated!");
126   } else {
127     TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,
128                      MI->getOperand(2).isKill());
129 
130     // Implicitly define DstReg for subsequent uses.
131     MachineBasicBlock::iterator CopyMI = MI;
132     --CopyMI;
133     CopyMI->addRegisterDefined(DstReg);
134     LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI);
135   }
136 
137   LLVM_DEBUG(dbgs() << '\n');
138   MBB->erase(MI);
139   return true;
140 }
141 
142 bool ExpandPostRA::LowerCopy(MachineInstr *MI) {
143 
144   if (MI->allDefsAreDead()) {
145     LLVM_DEBUG(dbgs() << "dead copy: " << *MI);
146     MI->setDesc(TII->get(TargetOpcode::KILL));
147     LLVM_DEBUG(dbgs() << "replaced by: " << *MI);
148     return true;
149   }
150 
151   MachineOperand &DstMO = MI->getOperand(0);
152   MachineOperand &SrcMO = MI->getOperand(1);
153 
154   bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg());
155   if (IdentityCopy || SrcMO.isUndef()) {
156     LLVM_DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy:    ")
157                       << *MI);
158     // No need to insert an identity copy instruction, but replace with a KILL
159     // if liveness is changed.
160     if (SrcMO.isUndef() || MI->getNumOperands() > 2) {
161       // We must make sure the super-register gets killed. Replace the
162       // instruction with KILL.
163       MI->setDesc(TII->get(TargetOpcode::KILL));
164       LLVM_DEBUG(dbgs() << "replaced by:   " << *MI);
165       return true;
166     }
167     // Vanilla identity copy.
168     MI->eraseFromParent();
169     return true;
170   }
171 
172   LLVM_DEBUG(dbgs() << "real copy:   " << *MI);
173   TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(),
174                    DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill());
175 
176   if (MI->getNumOperands() > 2)
177     TransferImplicitOperands(MI);
178   LLVM_DEBUG({
179     MachineBasicBlock::iterator dMI = MI;
180     dbgs() << "replaced by: " << *(--dMI);
181   });
182   MI->eraseFromParent();
183   return true;
184 }
185 
186 /// runOnMachineFunction - Reduce subregister inserts and extracts to register
187 /// copies.
188 ///
189 bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) {
190   LLVM_DEBUG(dbgs() << "Machine Function\n"
191                     << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n"
192                     << "********** Function: " << MF.getName() << '\n');
193   TRI = MF.getSubtarget().getRegisterInfo();
194   TII = MF.getSubtarget().getInstrInfo();
195 
196   bool MadeChange = false;
197 
198   for (MachineBasicBlock &MBB : MF) {
199     for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
200       // Only expand pseudos.
201       if (!MI.isPseudo())
202         continue;
203 
204       // Give targets a chance to expand even standard pseudos.
205       if (TII->expandPostRAPseudo(MI)) {
206         MadeChange = true;
207         continue;
208       }
209 
210       // Expand standard pseudos.
211       switch (MI.getOpcode()) {
212       case TargetOpcode::SUBREG_TO_REG:
213         MadeChange |= LowerSubregToReg(&MI);
214         break;
215       case TargetOpcode::COPY:
216         MadeChange |= LowerCopy(&MI);
217         break;
218       case TargetOpcode::DBG_VALUE:
219         continue;
220       case TargetOpcode::INSERT_SUBREG:
221       case TargetOpcode::EXTRACT_SUBREG:
222         llvm_unreachable("Sub-register pseudos should have been eliminated.");
223       }
224     }
225   }
226 
227   return MadeChange;
228 }
229