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