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(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 }; 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(0).getReg(); 67 Register InsReg = MI->getOperand(2).getReg(); 68 assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); 69 unsigned SubIdx = MI->getOperand(3).getImm(); 70 71 assert(SubIdx != 0 && "Invalid index for insert_subreg"); 72 Register DstSubReg = TRI->getSubReg(DstReg, 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(TargetOpcode::KILL)); 83 MI->removeOperand(3); // SubIdx 84 MI->removeOperand(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(TargetOpcode::KILL)); 96 MI->removeOperand(3); // SubIdx 97 MI->removeOperand(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, MI, MI->getDebugLoc(), DstSubReg, InsReg, 104 MI->getOperand(2).isKill()); 105 106 // Implicitly define DstReg for subsequent uses. 107 MachineBasicBlock::iterator CopyMI = MI; 108 --CopyMI; 109 CopyMI->addRegisterDefined(DstReg); 110 LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); 111 } 112 113 LLVM_DEBUG(dbgs() << '\n'); 114 MBB->erase(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(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); 146 break; 147 case TargetOpcode::COPY: 148 TII->lowerCopy(&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