ExpandPostRAPseudos.cpp revision 360784
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 26using namespace llvm; 27 28#define DEBUG_TYPE "postrapseudos" 29 30namespace { 31struct ExpandPostRA : public MachineFunctionPass { 32private: 33 const TargetRegisterInfo *TRI; 34 const TargetInstrInfo *TII; 35 36public: 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 50private: 51 bool LowerSubregToReg(MachineInstr *MI); 52 bool LowerCopy(MachineInstr *MI); 53 54 void TransferImplicitOperands(MachineInstr *MI); 55}; 56} // end anonymous namespace 57 58char ExpandPostRA::ID = 0; 59char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID; 60 61INITIALIZE_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. 67void ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) { 68 MachineBasicBlock::iterator CopyMI = MI; 69 --CopyMI; 70 71 for (const MachineOperand &MO : MI->implicit_operands()) 72 if (MO.isReg()) 73 CopyMI->addOperand(MO); 74} 75 76bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { 77 MachineBasicBlock *MBB = MI->getParent(); 78 assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && 79 MI->getOperand(1).isImm() && 80 (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && 81 MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); 82 83 Register DstReg = MI->getOperand(0).getReg(); 84 Register InsReg = MI->getOperand(2).getReg(); 85 assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); 86 unsigned SubIdx = MI->getOperand(3).getImm(); 87 88 assert(SubIdx != 0 && "Invalid index for insert_subreg"); 89 Register DstSubReg = TRI->getSubReg(DstReg, SubIdx); 90 91 assert(Register::isPhysicalRegister(DstReg) && 92 "Insert destination must be in a physical register"); 93 assert(Register::isPhysicalRegister(InsReg) && 94 "Inserted value must be in a physical register"); 95 96 LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); 97 98 if (MI->allDefsAreDead()) { 99 MI->setDesc(TII->get(TargetOpcode::KILL)); 100 MI->RemoveOperand(3); // SubIdx 101 MI->RemoveOperand(1); // Imm 102 LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI); 103 return true; 104 } 105 106 if (DstSubReg == InsReg) { 107 // No need to insert an identity copy instruction. 108 // Watch out for case like this: 109 // %rax = SUBREG_TO_REG 0, killed %eax, 3 110 // We must leave %rax live. 111 if (DstReg != InsReg) { 112 MI->setDesc(TII->get(TargetOpcode::KILL)); 113 MI->RemoveOperand(3); // SubIdx 114 MI->RemoveOperand(1); // Imm 115 LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI); 116 return true; 117 } 118 LLVM_DEBUG(dbgs() << "subreg: eliminated!"); 119 } else { 120 TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, 121 MI->getOperand(2).isKill()); 122 123 // Implicitly define DstReg for subsequent uses. 124 MachineBasicBlock::iterator CopyMI = MI; 125 --CopyMI; 126 CopyMI->addRegisterDefined(DstReg); 127 LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); 128 } 129 130 LLVM_DEBUG(dbgs() << '\n'); 131 MBB->erase(MI); 132 return true; 133} 134 135bool ExpandPostRA::LowerCopy(MachineInstr *MI) { 136 137 if (MI->allDefsAreDead()) { 138 LLVM_DEBUG(dbgs() << "dead copy: " << *MI); 139 MI->setDesc(TII->get(TargetOpcode::KILL)); 140 LLVM_DEBUG(dbgs() << "replaced by: " << *MI); 141 return true; 142 } 143 144 MachineOperand &DstMO = MI->getOperand(0); 145 MachineOperand &SrcMO = MI->getOperand(1); 146 147 bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg()); 148 if (IdentityCopy || SrcMO.isUndef()) { 149 LLVM_DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy: ") 150 << *MI); 151 // No need to insert an identity copy instruction, but replace with a KILL 152 // if liveness is changed. 153 if (SrcMO.isUndef() || MI->getNumOperands() > 2) { 154 // We must make sure the super-register gets killed. Replace the 155 // instruction with KILL. 156 MI->setDesc(TII->get(TargetOpcode::KILL)); 157 LLVM_DEBUG(dbgs() << "replaced by: " << *MI); 158 return true; 159 } 160 // Vanilla identity copy. 161 MI->eraseFromParent(); 162 return true; 163 } 164 165 LLVM_DEBUG(dbgs() << "real copy: " << *MI); 166 TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), 167 DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill()); 168 169 if (MI->getNumOperands() > 2) 170 TransferImplicitOperands(MI); 171 LLVM_DEBUG({ 172 MachineBasicBlock::iterator dMI = MI; 173 dbgs() << "replaced by: " << *(--dMI); 174 }); 175 MI->eraseFromParent(); 176 return true; 177} 178 179/// runOnMachineFunction - Reduce subregister inserts and extracts to register 180/// copies. 181/// 182bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { 183 LLVM_DEBUG(dbgs() << "Machine Function\n" 184 << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" 185 << "********** Function: " << MF.getName() << '\n'); 186 TRI = MF.getSubtarget().getRegisterInfo(); 187 TII = MF.getSubtarget().getInstrInfo(); 188 189 bool MadeChange = false; 190 191 for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); 192 mbbi != mbbe; ++mbbi) { 193 for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); 194 mi != me;) { 195 MachineInstr &MI = *mi; 196 // Advance iterator here because MI may be erased. 197 ++mi; 198 199 // Only expand pseudos. 200 if (!MI.isPseudo()) 201 continue; 202 203 // Give targets a chance to expand even standard pseudos. 204 if (TII->expandPostRAPseudo(MI)) { 205 MadeChange = true; 206 continue; 207 } 208 209 // Expand standard pseudos. 210 switch (MI.getOpcode()) { 211 case TargetOpcode::SUBREG_TO_REG: 212 MadeChange |= LowerSubregToReg(&MI); 213 break; 214 case TargetOpcode::COPY: 215 MadeChange |= LowerCopy(&MI); 216 break; 217 case TargetOpcode::DBG_VALUE: 218 continue; 219 case TargetOpcode::INSERT_SUBREG: 220 case TargetOpcode::EXTRACT_SUBREG: 221 llvm_unreachable("Sub-register pseudos should have been eliminated."); 222 } 223 } 224 } 225 226 return MadeChange; 227} 228