1226584Sdim//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===// 2226584Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6226584Sdim// 7226584Sdim//===----------------------------------------------------------------------===// 8226584Sdim// 9226584Sdim// This file defines a pass that expands COPY and SUBREG_TO_REG pseudo 10226584Sdim// instructions after register allocation. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14226584Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 15226584Sdim#include "llvm/CodeGen/MachineInstr.h" 16226584Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 17226584Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 18321369Sdim#include "llvm/CodeGen/Passes.h" 19327952Sdim#include "llvm/CodeGen/TargetInstrInfo.h" 20327952Sdim#include "llvm/CodeGen/TargetRegisterInfo.h" 21327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 22360784Sdim#include "llvm/InitializePasses.h" 23249423Sdim#include "llvm/Support/Debug.h" 24249423Sdim#include "llvm/Support/raw_ostream.h" 25280031Sdim 26226584Sdimusing namespace llvm; 27226584Sdim 28276479Sdim#define DEBUG_TYPE "postrapseudos" 29276479Sdim 30226584Sdimnamespace { 31226584Sdimstruct ExpandPostRA : public MachineFunctionPass { 32226584Sdimprivate: 33226584Sdim const TargetRegisterInfo *TRI; 34226584Sdim const TargetInstrInfo *TII; 35226584Sdim 36226584Sdimpublic: 37226584Sdim static char ID; // Pass identification, replacement for typeid 38226584Sdim ExpandPostRA() : MachineFunctionPass(ID) {} 39226584Sdim 40276479Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 41226584Sdim AU.setPreservesCFG(); 42226584Sdim AU.addPreservedID(MachineLoopInfoID); 43226584Sdim AU.addPreservedID(MachineDominatorsID); 44226584Sdim MachineFunctionPass::getAnalysisUsage(AU); 45226584Sdim } 46226584Sdim 47226584Sdim /// runOnMachineFunction - pass entry point 48276479Sdim bool runOnMachineFunction(MachineFunction&) override; 49226584Sdim 50226584Sdimprivate: 51226584Sdim bool LowerSubregToReg(MachineInstr *MI); 52226584Sdim bool LowerCopy(MachineInstr *MI); 53226584Sdim 54309124Sdim void TransferImplicitOperands(MachineInstr *MI); 55226584Sdim}; 56226584Sdim} // end anonymous namespace 57226584Sdim 58226584Sdimchar ExpandPostRA::ID = 0; 59234353Sdimchar &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID; 60226584Sdim 61321369SdimINITIALIZE_PASS(ExpandPostRA, DEBUG_TYPE, 62234353Sdim "Post-RA pseudo instruction expansion pass", false, false) 63226584Sdim 64309124Sdim/// TransferImplicitOperands - MI is a pseudo-instruction, and the lowered 65309124Sdim/// replacement instructions immediately precede it. Copy any implicit 66226584Sdim/// operands from MI to the replacement instruction. 67309124Sdimvoid ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) { 68226584Sdim MachineBasicBlock::iterator CopyMI = MI; 69226584Sdim --CopyMI; 70226584Sdim 71309124Sdim for (const MachineOperand &MO : MI->implicit_operands()) 72309124Sdim if (MO.isReg()) 73309124Sdim CopyMI->addOperand(MO); 74226584Sdim} 75226584Sdim 76226584Sdimbool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { 77226584Sdim MachineBasicBlock *MBB = MI->getParent(); 78226584Sdim assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && 79226584Sdim MI->getOperand(1).isImm() && 80226584Sdim (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && 81226584Sdim MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); 82226584Sdim 83360784Sdim Register DstReg = MI->getOperand(0).getReg(); 84360784Sdim Register InsReg = MI->getOperand(2).getReg(); 85226584Sdim assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); 86226584Sdim unsigned SubIdx = MI->getOperand(3).getImm(); 87226584Sdim 88226584Sdim assert(SubIdx != 0 && "Invalid index for insert_subreg"); 89360784Sdim Register DstSubReg = TRI->getSubReg(DstReg, SubIdx); 90226584Sdim 91360784Sdim assert(Register::isPhysicalRegister(DstReg) && 92226584Sdim "Insert destination must be in a physical register"); 93360784Sdim assert(Register::isPhysicalRegister(InsReg) && 94226584Sdim "Inserted value must be in a physical register"); 95226584Sdim 96341825Sdim LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); 97226584Sdim 98249423Sdim if (MI->allDefsAreDead()) { 99249423Sdim MI->setDesc(TII->get(TargetOpcode::KILL)); 100344779Sdim MI->RemoveOperand(3); // SubIdx 101344779Sdim MI->RemoveOperand(1); // Imm 102341825Sdim LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI); 103249423Sdim return true; 104249423Sdim } 105249423Sdim 106226584Sdim if (DstSubReg == InsReg) { 107261991Sdim // No need to insert an identity copy instruction. 108226584Sdim // Watch out for case like this: 109327952Sdim // %rax = SUBREG_TO_REG 0, killed %eax, 3 110327952Sdim // We must leave %rax live. 111226584Sdim if (DstReg != InsReg) { 112226584Sdim MI->setDesc(TII->get(TargetOpcode::KILL)); 113226584Sdim MI->RemoveOperand(3); // SubIdx 114226584Sdim MI->RemoveOperand(1); // Imm 115341825Sdim LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI); 116226584Sdim return true; 117226584Sdim } 118341825Sdim LLVM_DEBUG(dbgs() << "subreg: eliminated!"); 119226584Sdim } else { 120226584Sdim TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, 121226584Sdim MI->getOperand(2).isKill()); 122239462Sdim 123239462Sdim // Implicitly define DstReg for subsequent uses. 124239462Sdim MachineBasicBlock::iterator CopyMI = MI; 125239462Sdim --CopyMI; 126239462Sdim CopyMI->addRegisterDefined(DstReg); 127341825Sdim LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI); 128226584Sdim } 129226584Sdim 130341825Sdim LLVM_DEBUG(dbgs() << '\n'); 131226584Sdim MBB->erase(MI); 132226584Sdim return true; 133226584Sdim} 134226584Sdim 135226584Sdimbool ExpandPostRA::LowerCopy(MachineInstr *MI) { 136249423Sdim 137249423Sdim if (MI->allDefsAreDead()) { 138341825Sdim LLVM_DEBUG(dbgs() << "dead copy: " << *MI); 139249423Sdim MI->setDesc(TII->get(TargetOpcode::KILL)); 140341825Sdim LLVM_DEBUG(dbgs() << "replaced by: " << *MI); 141249423Sdim return true; 142249423Sdim } 143249423Sdim 144226584Sdim MachineOperand &DstMO = MI->getOperand(0); 145226584Sdim MachineOperand &SrcMO = MI->getOperand(1); 146226584Sdim 147321369Sdim bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg()); 148321369Sdim if (IdentityCopy || SrcMO.isUndef()) { 149341825Sdim LLVM_DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy: ") 150341825Sdim << *MI); 151226584Sdim // No need to insert an identity copy instruction, but replace with a KILL 152226584Sdim // if liveness is changed. 153249423Sdim if (SrcMO.isUndef() || MI->getNumOperands() > 2) { 154226584Sdim // We must make sure the super-register gets killed. Replace the 155226584Sdim // instruction with KILL. 156226584Sdim MI->setDesc(TII->get(TargetOpcode::KILL)); 157341825Sdim LLVM_DEBUG(dbgs() << "replaced by: " << *MI); 158226584Sdim return true; 159226584Sdim } 160226584Sdim // Vanilla identity copy. 161226584Sdim MI->eraseFromParent(); 162226584Sdim return true; 163226584Sdim } 164226584Sdim 165341825Sdim LLVM_DEBUG(dbgs() << "real copy: " << *MI); 166226584Sdim TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), 167226584Sdim DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill()); 168226584Sdim 169226584Sdim if (MI->getNumOperands() > 2) 170309124Sdim TransferImplicitOperands(MI); 171341825Sdim LLVM_DEBUG({ 172226584Sdim MachineBasicBlock::iterator dMI = MI; 173226584Sdim dbgs() << "replaced by: " << *(--dMI); 174226584Sdim }); 175226584Sdim MI->eraseFromParent(); 176226584Sdim return true; 177226584Sdim} 178226584Sdim 179226584Sdim/// runOnMachineFunction - Reduce subregister inserts and extracts to register 180226584Sdim/// copies. 181226584Sdim/// 182226584Sdimbool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { 183341825Sdim LLVM_DEBUG(dbgs() << "Machine Function\n" 184341825Sdim << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" 185341825Sdim << "********** Function: " << MF.getName() << '\n'); 186280031Sdim TRI = MF.getSubtarget().getRegisterInfo(); 187280031Sdim TII = MF.getSubtarget().getInstrInfo(); 188226584Sdim 189226584Sdim bool MadeChange = false; 190226584Sdim 191226584Sdim for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); 192226584Sdim mbbi != mbbe; ++mbbi) { 193226584Sdim for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); 194226584Sdim mi != me;) { 195309124Sdim MachineInstr &MI = *mi; 196226584Sdim // Advance iterator here because MI may be erased. 197226584Sdim ++mi; 198226584Sdim 199226584Sdim // Only expand pseudos. 200309124Sdim if (!MI.isPseudo()) 201226584Sdim continue; 202226584Sdim 203226584Sdim // Give targets a chance to expand even standard pseudos. 204226584Sdim if (TII->expandPostRAPseudo(MI)) { 205226584Sdim MadeChange = true; 206226584Sdim continue; 207226584Sdim } 208226584Sdim 209226584Sdim // Expand standard pseudos. 210309124Sdim switch (MI.getOpcode()) { 211226584Sdim case TargetOpcode::SUBREG_TO_REG: 212309124Sdim MadeChange |= LowerSubregToReg(&MI); 213226584Sdim break; 214226584Sdim case TargetOpcode::COPY: 215309124Sdim MadeChange |= LowerCopy(&MI); 216226584Sdim break; 217226584Sdim case TargetOpcode::DBG_VALUE: 218226584Sdim continue; 219226584Sdim case TargetOpcode::INSERT_SUBREG: 220226584Sdim case TargetOpcode::EXTRACT_SUBREG: 221226584Sdim llvm_unreachable("Sub-register pseudos should have been eliminated."); 222226584Sdim } 223226584Sdim } 224226584Sdim } 225226584Sdim 226226584Sdim return MadeChange; 227226584Sdim} 228