ExpandPostRAPseudos.cpp revision 74e2d6ea66a9289fc3c00583f3c2b2abd84e1866
1//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines a pass that expands COPY and SUBREG_TO_REG pseudo 11// instructions after register allocation. 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "postrapseudos" 16#include "llvm/CodeGen/Passes.h" 17#include "llvm/Function.h" 18#include "llvm/CodeGen/MachineFunctionPass.h" 19#include "llvm/CodeGen/MachineInstr.h" 20#include "llvm/CodeGen/MachineInstrBuilder.h" 21#include "llvm/CodeGen/MachineRegisterInfo.h" 22#include "llvm/Target/TargetRegisterInfo.h" 23#include "llvm/Target/TargetInstrInfo.h" 24#include "llvm/Target/TargetMachine.h" 25#include "llvm/Support/Debug.h" 26#include "llvm/Support/raw_ostream.h" 27using namespace llvm; 28 29namespace { 30struct ExpandPostRA : public MachineFunctionPass { 31private: 32 const TargetRegisterInfo *TRI; 33 const TargetInstrInfo *TII; 34 35public: 36 static char ID; // Pass identification, replacement for typeid 37 ExpandPostRA() : MachineFunctionPass(ID) {} 38 39 const char *getPassName() const { 40 return "Post-RA pseudo instruction expansion pass"; 41 } 42 43 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 44 AU.setPreservesCFG(); 45 AU.addPreservedID(MachineLoopInfoID); 46 AU.addPreservedID(MachineDominatorsID); 47 MachineFunctionPass::getAnalysisUsage(AU); 48 } 49 50 /// runOnMachineFunction - pass entry point 51 bool runOnMachineFunction(MachineFunction&); 52 53private: 54 bool LowerSubregToReg(MachineInstr *MI); 55 bool LowerCopy(MachineInstr *MI); 56 57 void TransferDeadFlag(MachineInstr *MI, unsigned DstReg, 58 const TargetRegisterInfo *TRI); 59 void TransferImplicitDefs(MachineInstr *MI); 60}; 61} // end anonymous namespace 62 63char ExpandPostRA::ID = 0; 64 65FunctionPass *llvm::createExpandPostRAPseudosPass() { 66 return new ExpandPostRA(); 67} 68 69/// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, 70/// and the lowered replacement instructions immediately precede it. 71/// Mark the replacement instructions with the dead flag. 72void 73ExpandPostRA::TransferDeadFlag(MachineInstr *MI, unsigned DstReg, 74 const TargetRegisterInfo *TRI) { 75 for (MachineBasicBlock::iterator MII = 76 prior(MachineBasicBlock::iterator(MI)); ; --MII) { 77 if (MII->addRegisterDead(DstReg, TRI)) 78 break; 79 assert(MII != MI->getParent()->begin() && 80 "copyPhysReg output doesn't reference destination register!"); 81 } 82} 83 84/// TransferImplicitDefs - MI is a pseudo-instruction, and the lowered 85/// replacement instructions immediately precede it. Copy any implicit-def 86/// operands from MI to the replacement instruction. 87void 88ExpandPostRA::TransferImplicitDefs(MachineInstr *MI) { 89 MachineBasicBlock::iterator CopyMI = MI; 90 --CopyMI; 91 92 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 93 MachineOperand &MO = MI->getOperand(i); 94 if (!MO.isReg() || !MO.isImplicit() || MO.isUse()) 95 continue; 96 CopyMI->addOperand(MachineOperand::CreateReg(MO.getReg(), true, true)); 97 } 98} 99 100bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { 101 MachineBasicBlock *MBB = MI->getParent(); 102 assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && 103 MI->getOperand(1).isImm() && 104 (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) && 105 MI->getOperand(3).isImm() && "Invalid subreg_to_reg"); 106 107 unsigned DstReg = MI->getOperand(0).getReg(); 108 unsigned InsReg = MI->getOperand(2).getReg(); 109 assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?"); 110 unsigned SubIdx = MI->getOperand(3).getImm(); 111 112 assert(SubIdx != 0 && "Invalid index for insert_subreg"); 113 unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx); 114 115 assert(TargetRegisterInfo::isPhysicalRegister(DstReg) && 116 "Insert destination must be in a physical register"); 117 assert(TargetRegisterInfo::isPhysicalRegister(InsReg) && 118 "Inserted value must be in a physical register"); 119 120 DEBUG(dbgs() << "subreg: CONVERTING: " << *MI); 121 122 if (DstSubReg == InsReg) { 123 // No need to insert an identify copy instruction. 124 // Watch out for case like this: 125 // %RAX<def> = SUBREG_TO_REG 0, %EAX<kill>, 3 126 // We must leave %RAX live. 127 if (DstReg != InsReg) { 128 MI->setDesc(TII->get(TargetOpcode::KILL)); 129 MI->RemoveOperand(3); // SubIdx 130 MI->RemoveOperand(1); // Imm 131 DEBUG(dbgs() << "subreg: replace by: " << *MI); 132 return true; 133 } 134 DEBUG(dbgs() << "subreg: eliminated!"); 135 } else { 136 TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg, 137 MI->getOperand(2).isKill()); 138 // Transfer the kill/dead flags, if needed. 139 if (MI->getOperand(0).isDead()) 140 TransferDeadFlag(MI, DstSubReg, TRI); 141 DEBUG({ 142 MachineBasicBlock::iterator dMI = MI; 143 dbgs() << "subreg: " << *(--dMI); 144 }); 145 } 146 147 DEBUG(dbgs() << '\n'); 148 MBB->erase(MI); 149 return true; 150} 151 152bool ExpandPostRA::LowerCopy(MachineInstr *MI) { 153 MachineOperand &DstMO = MI->getOperand(0); 154 MachineOperand &SrcMO = MI->getOperand(1); 155 156 if (SrcMO.getReg() == DstMO.getReg()) { 157 DEBUG(dbgs() << "identity copy: " << *MI); 158 // No need to insert an identity copy instruction, but replace with a KILL 159 // if liveness is changed. 160 if (DstMO.isDead() || 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 DEBUG(dbgs() << "replaced by: " << *MI); 165 return true; 166 } 167 // Vanilla identity copy. 168 MI->eraseFromParent(); 169 return true; 170 } 171 172 DEBUG(dbgs() << "real copy: " << *MI); 173 TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), 174 DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill()); 175 176 if (DstMO.isDead()) 177 TransferDeadFlag(MI, DstMO.getReg(), TRI); 178 if (MI->getNumOperands() > 2) 179 TransferImplicitDefs(MI); 180 DEBUG({ 181 MachineBasicBlock::iterator dMI = MI; 182 dbgs() << "replaced by: " << *(--dMI); 183 }); 184 MI->eraseFromParent(); 185 return true; 186} 187 188/// runOnMachineFunction - Reduce subregister inserts and extracts to register 189/// copies. 190/// 191bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { 192 DEBUG(dbgs() << "Machine Function\n" 193 << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" 194 << "********** Function: " 195 << MF.getFunction()->getName() << '\n'); 196 TRI = MF.getTarget().getRegisterInfo(); 197 TII = MF.getTarget().getInstrInfo(); 198 199 bool MadeChange = false; 200 201 for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); 202 mbbi != mbbe; ++mbbi) { 203 for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); 204 mi != me;) { 205 MachineBasicBlock::iterator nmi = llvm::next(mi); 206 MachineInstr *MI = mi; 207 assert(!MI->isInsertSubreg() && "INSERT_SUBREG should no longer appear"); 208 assert(MI->getOpcode() != TargetOpcode::EXTRACT_SUBREG && 209 "EXTRACT_SUBREG should no longer appear"); 210 if (MI->isSubregToReg()) { 211 MadeChange |= LowerSubregToReg(MI); 212 } else if (MI->isCopy()) { 213 MadeChange |= LowerCopy(MI); 214 } 215 mi = nmi; 216 } 217 } 218 219 return MadeChange; 220} 221