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/ExpandPostRAPseudos.h" 15 #include "llvm/CodeGen/MachineDominators.h" 16 #include "llvm/CodeGen/MachineFunctionPass.h" 17 #include "llvm/CodeGen/MachineInstr.h" 18 #include "llvm/CodeGen/MachineLoopInfo.h" 19 #include "llvm/CodeGen/Passes.h" 20 #include "llvm/CodeGen/TargetInstrInfo.h" 21 #include "llvm/CodeGen/TargetRegisterInfo.h" 22 #include "llvm/CodeGen/TargetSubtargetInfo.h" 23 #include "llvm/InitializePasses.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 using namespace llvm; 28 29 #define DEBUG_TYPE "postrapseudos" 30 31 namespace { 32 struct ExpandPostRA { 33 bool run(MachineFunction &); 34 35 private: 36 const TargetRegisterInfo *TRI = nullptr; 37 const TargetInstrInfo *TII = nullptr; 38 39 bool LowerSubregToReg(MachineInstr *MI); 40 }; 41 42 struct ExpandPostRALegacy : public MachineFunctionPass { 43 static char ID; 44 ExpandPostRALegacy() : MachineFunctionPass(ID) { 45 initializeExpandPostRALegacyPass(*PassRegistry::getPassRegistry()); 46 } 47 48 void getAnalysisUsage(AnalysisUsage &AU) const override { 49 AU.setPreservesCFG(); 50 AU.addPreservedID(MachineLoopInfoID); 51 AU.addPreservedID(MachineDominatorsID); 52 MachineFunctionPass::getAnalysisUsage(AU); 53 } 54 55 /// runOnMachineFunction - pass entry point 56 bool runOnMachineFunction(MachineFunction &) override; 57 }; 58 } // end anonymous namespace 59 60 PreservedAnalyses 61 ExpandPostRAPseudosPass::run(MachineFunction &MF, 62 MachineFunctionAnalysisManager &MFAM) { 63 if (!ExpandPostRA().run(MF)) 64 return PreservedAnalyses::all(); 65 66 return getMachineFunctionPassPreservedAnalyses() 67 .preserveSet<CFGAnalyses>() 68 .preserve<MachineLoopAnalysis>() 69 .preserve<MachineDominatorTreeAnalysis>(); 70 } 71 72 char ExpandPostRALegacy::ID = 0; 73 char &llvm::ExpandPostRAPseudosID = ExpandPostRALegacy::ID; 74 75 INITIALIZE_PASS(ExpandPostRALegacy, DEBUG_TYPE, 76 "Post-RA pseudo instruction expansion pass", false, false) 77 78 bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { 79 MachineBasicBlock *MBB = MI->getParent(); 80 assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && 81 MI->getOperand(1).isImm() && 82 (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && 83 MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); 84 85 Register DstReg = MI->getOperand(0).getReg(); 86 Register InsReg = MI->getOperand(2).getReg(); 87 assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); 88 unsigned SubIdx = MI->getOperand(3).getImm(); 89 90 assert(SubIdx != 0 && "Invalid index for insert_subreg"); 91 Register DstSubReg = TRI->getSubReg(DstReg, SubIdx); 92 93 assert(DstReg.isPhysical() && 94 "Insert destination must be in a physical register"); 95 assert(InsReg.isPhysical() && 96 "Inserted value must be in a physical register"); 97 98 LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); 99 100 if (MI->allDefsAreDead()) { 101 MI->setDesc(TII->get(TargetOpcode::KILL)); 102 MI->removeOperand(3); // SubIdx 103 MI->removeOperand(1); // Imm 104 LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI); 105 return true; 106 } 107 108 if (DstSubReg == InsReg) { 109 // No need to insert an identity copy instruction. 110 // Watch out for case like this: 111 // %rax = SUBREG_TO_REG 0, killed %eax, 3 112 // We must leave %rax live. 113 if (DstReg != InsReg) { 114 MI->setDesc(TII->get(TargetOpcode::KILL)); 115 MI->removeOperand(3); // SubIdx 116 MI->removeOperand(1); // Imm 117 LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI); 118 return true; 119 } 120 LLVM_DEBUG(dbgs() << "subreg: eliminated!"); 121 } else { 122 TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, 123 MI->getOperand(2).isKill()); 124 125 // Implicitly define DstReg for subsequent uses. 126 MachineBasicBlock::iterator CopyMI = MI; 127 --CopyMI; 128 CopyMI->addRegisterDefined(DstReg); 129 LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); 130 } 131 132 LLVM_DEBUG(dbgs() << '\n'); 133 MBB->erase(MI); 134 return true; 135 } 136 137 bool ExpandPostRALegacy::runOnMachineFunction(MachineFunction &MF) { 138 return ExpandPostRA().run(MF); 139 } 140 141 /// runOnMachineFunction - Reduce subregister inserts and extracts to register 142 /// copies. 143 /// 144 bool ExpandPostRA::run(MachineFunction &MF) { 145 LLVM_DEBUG(dbgs() << "Machine Function\n" 146 << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" 147 << "********** Function: " << MF.getName() << '\n'); 148 TRI = MF.getSubtarget().getRegisterInfo(); 149 TII = MF.getSubtarget().getInstrInfo(); 150 151 bool MadeChange = false; 152 153 for (MachineBasicBlock &MBB : MF) { 154 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) { 155 // Only expand pseudos. 156 if (!MI.isPseudo()) 157 continue; 158 159 // Give targets a chance to expand even standard pseudos. 160 if (TII->expandPostRAPseudo(MI)) { 161 MadeChange = true; 162 continue; 163 } 164 165 // Expand standard pseudos. 166 switch (MI.getOpcode()) { 167 case TargetOpcode::SUBREG_TO_REG: 168 MadeChange |= LowerSubregToReg(&MI); 169 break; 170 case TargetOpcode::COPY: 171 TII->lowerCopy(&MI, TRI); 172 MadeChange = true; 173 break; 174 case TargetOpcode::DBG_VALUE: 175 continue; 176 case TargetOpcode::INSERT_SUBREG: 177 case TargetOpcode::EXTRACT_SUBREG: 178 llvm_unreachable("Sub-register pseudos should have been eliminated."); 179 } 180 } 181 } 182 183 return MadeChange; 184 } 185