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