1f22ef01cSRoman Divacky //===---------------------- ProcessImplicitDefs.cpp -----------------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky 10f22ef01cSRoman Divacky #define DEBUG_TYPE "processimplicitdefs" 11f22ef01cSRoman Divacky 12f22ef01cSRoman Divacky #include "llvm/CodeGen/ProcessImplicitDefs.h" 13f22ef01cSRoman Divacky 14f22ef01cSRoman Divacky #include "llvm/ADT/DepthFirstIterator.h" 15f22ef01cSRoman Divacky #include "llvm/ADT/SmallSet.h" 16f22ef01cSRoman Divacky #include "llvm/Analysis/AliasAnalysis.h" 17f22ef01cSRoman Divacky #include "llvm/CodeGen/LiveVariables.h" 18f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstr.h" 19f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 20f22ef01cSRoman Divacky #include "llvm/CodeGen/Passes.h" 21f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 22f22ef01cSRoman Divacky #include "llvm/Target/TargetInstrInfo.h" 23f22ef01cSRoman Divacky #include "llvm/Target/TargetRegisterInfo.h" 24f22ef01cSRoman Divacky 25f22ef01cSRoman Divacky 26f22ef01cSRoman Divacky using namespace llvm; 27f22ef01cSRoman Divacky 28f22ef01cSRoman Divacky char ProcessImplicitDefs::ID = 0; 29f22ef01cSRoman Divacky static RegisterPass<ProcessImplicitDefs> X("processimpdefs", 30f22ef01cSRoman Divacky "Process Implicit Definitions."); 31f22ef01cSRoman Divacky 32f22ef01cSRoman Divacky void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { 33f22ef01cSRoman Divacky AU.setPreservesCFG(); 34f22ef01cSRoman Divacky AU.addPreserved<AliasAnalysis>(); 35f22ef01cSRoman Divacky AU.addPreserved<LiveVariables>(); 36f22ef01cSRoman Divacky AU.addRequired<LiveVariables>(); 37f22ef01cSRoman Divacky AU.addPreservedID(MachineLoopInfoID); 38f22ef01cSRoman Divacky AU.addPreservedID(MachineDominatorsID); 39f22ef01cSRoman Divacky AU.addPreservedID(TwoAddressInstructionPassID); 40f22ef01cSRoman Divacky AU.addPreservedID(PHIEliminationID); 41f22ef01cSRoman Divacky MachineFunctionPass::getAnalysisUsage(AU); 42f22ef01cSRoman Divacky } 43f22ef01cSRoman Divacky 44ffd1746dSEd Schouten bool 45ffd1746dSEd Schouten ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, 46f22ef01cSRoman Divacky unsigned Reg, unsigned OpIdx, 47ffd1746dSEd Schouten const TargetInstrInfo *tii_, 48ffd1746dSEd Schouten SmallSet<unsigned, 8> &ImpDefRegs) { 49f22ef01cSRoman Divacky unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; 50f22ef01cSRoman Divacky if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && 51ffd1746dSEd Schouten Reg == SrcReg && 52ffd1746dSEd Schouten (DstSubReg == 0 || ImpDefRegs.count(DstReg))) 53f22ef01cSRoman Divacky return true; 54f22ef01cSRoman Divacky 55ffd1746dSEd Schouten switch(OpIdx) { 56ffd1746dSEd Schouten case 1: 57ffd1746dSEd Schouten return MI->isCopy() && (MI->getOperand(0).getSubReg() == 0 || 58ffd1746dSEd Schouten ImpDefRegs.count(MI->getOperand(0).getReg())); 59ffd1746dSEd Schouten case 2: 60ffd1746dSEd Schouten return MI->isSubregToReg() && (MI->getOperand(0).getSubReg() == 0 || 61ffd1746dSEd Schouten ImpDefRegs.count(MI->getOperand(0).getReg())); 62ffd1746dSEd Schouten default: return false; 63ffd1746dSEd Schouten } 64ffd1746dSEd Schouten } 65ffd1746dSEd Schouten 66ffd1746dSEd Schouten static bool isUndefCopy(MachineInstr *MI, unsigned Reg, 67ffd1746dSEd Schouten const TargetInstrInfo *tii_, 68ffd1746dSEd Schouten SmallSet<unsigned, 8> &ImpDefRegs) { 69ffd1746dSEd Schouten if (MI->isCopy()) { 70ffd1746dSEd Schouten MachineOperand &MO0 = MI->getOperand(0); 71ffd1746dSEd Schouten MachineOperand &MO1 = MI->getOperand(1); 72ffd1746dSEd Schouten if (MO1.getReg() != Reg) 73ffd1746dSEd Schouten return false; 74ffd1746dSEd Schouten if (!MO0.getSubReg() || ImpDefRegs.count(MO0.getReg())) 75f22ef01cSRoman Divacky return true; 76ffd1746dSEd Schouten return false; 77ffd1746dSEd Schouten } 78ffd1746dSEd Schouten 79ffd1746dSEd Schouten unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; 80ffd1746dSEd Schouten if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) { 81ffd1746dSEd Schouten if (Reg != SrcReg) 82ffd1746dSEd Schouten return false; 83ffd1746dSEd Schouten if (DstSubReg == 0 || ImpDefRegs.count(DstReg)) 84f22ef01cSRoman Divacky return true; 85ffd1746dSEd Schouten } 86f22ef01cSRoman Divacky return false; 87f22ef01cSRoman Divacky } 88f22ef01cSRoman Divacky 89f22ef01cSRoman Divacky /// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure 90f22ef01cSRoman Divacky /// there is one implicit_def for each use. Add isUndef marker to 91f22ef01cSRoman Divacky /// implicit_def defs and their uses. 92f22ef01cSRoman Divacky bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { 93f22ef01cSRoman Divacky 94f22ef01cSRoman Divacky DEBUG(dbgs() << "********** PROCESS IMPLICIT DEFS **********\n" 95f22ef01cSRoman Divacky << "********** Function: " 96f22ef01cSRoman Divacky << ((Value*)fn.getFunction())->getName() << '\n'); 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky bool Changed = false; 99f22ef01cSRoman Divacky 100f22ef01cSRoman Divacky const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo(); 101f22ef01cSRoman Divacky const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo(); 102f22ef01cSRoman Divacky MachineRegisterInfo *mri_ = &fn.getRegInfo(); 103f22ef01cSRoman Divacky 104f22ef01cSRoman Divacky LiveVariables *lv_ = &getAnalysis<LiveVariables>(); 105f22ef01cSRoman Divacky 106f22ef01cSRoman Divacky SmallSet<unsigned, 8> ImpDefRegs; 107f22ef01cSRoman Divacky SmallVector<MachineInstr*, 8> ImpDefMIs; 108f22ef01cSRoman Divacky SmallVector<MachineInstr*, 4> RUses; 109f22ef01cSRoman Divacky SmallPtrSet<MachineBasicBlock*,16> Visited; 110f22ef01cSRoman Divacky SmallPtrSet<MachineInstr*, 8> ModInsts; 111f22ef01cSRoman Divacky 112f22ef01cSRoman Divacky MachineBasicBlock *Entry = fn.begin(); 113f22ef01cSRoman Divacky for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> > 114f22ef01cSRoman Divacky DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); 115f22ef01cSRoman Divacky DFI != E; ++DFI) { 116f22ef01cSRoman Divacky MachineBasicBlock *MBB = *DFI; 117f22ef01cSRoman Divacky for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); 118f22ef01cSRoman Divacky I != E; ) { 119f22ef01cSRoman Divacky MachineInstr *MI = &*I; 120f22ef01cSRoman Divacky ++I; 121f22ef01cSRoman Divacky if (MI->isImplicitDef()) { 122f22ef01cSRoman Divacky if (MI->getOperand(0).getSubReg()) 123f22ef01cSRoman Divacky continue; 124f22ef01cSRoman Divacky unsigned Reg = MI->getOperand(0).getReg(); 125f22ef01cSRoman Divacky ImpDefRegs.insert(Reg); 126f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 127f22ef01cSRoman Divacky for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) 128f22ef01cSRoman Divacky ImpDefRegs.insert(*SS); 129f22ef01cSRoman Divacky } 130f22ef01cSRoman Divacky ImpDefMIs.push_back(MI); 131f22ef01cSRoman Divacky continue; 132f22ef01cSRoman Divacky } 133f22ef01cSRoman Divacky 134ffd1746dSEd Schouten // Eliminate %reg1032:sub<def> = COPY undef. 135ffd1746dSEd Schouten if (MI->isCopy() && MI->getOperand(0).getSubReg()) { 136ffd1746dSEd Schouten MachineOperand &MO = MI->getOperand(1); 137ffd1746dSEd Schouten if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) { 138f22ef01cSRoman Divacky if (MO.isKill()) { 139f22ef01cSRoman Divacky LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); 140f22ef01cSRoman Divacky vi.removeKill(MI); 141f22ef01cSRoman Divacky } 142f22ef01cSRoman Divacky MI->eraseFromParent(); 143f22ef01cSRoman Divacky Changed = true; 144f22ef01cSRoman Divacky continue; 145f22ef01cSRoman Divacky } 146f22ef01cSRoman Divacky } 147f22ef01cSRoman Divacky 148f22ef01cSRoman Divacky bool ChangedToImpDef = false; 149f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 150f22ef01cSRoman Divacky MachineOperand& MO = MI->getOperand(i); 151ffd1746dSEd Schouten if (!MO.isReg() || (MO.isDef() && !MO.getSubReg()) || MO.isUndef()) 152f22ef01cSRoman Divacky continue; 153f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 154f22ef01cSRoman Divacky if (!Reg) 155f22ef01cSRoman Divacky continue; 156f22ef01cSRoman Divacky if (!ImpDefRegs.count(Reg)) 157f22ef01cSRoman Divacky continue; 158f22ef01cSRoman Divacky // Use is a copy, just turn it into an implicit_def. 159ffd1746dSEd Schouten if (CanTurnIntoImplicitDef(MI, Reg, i, tii_, ImpDefRegs)) { 160f22ef01cSRoman Divacky bool isKill = MO.isKill(); 161f22ef01cSRoman Divacky MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); 162f22ef01cSRoman Divacky for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) 163f22ef01cSRoman Divacky MI->RemoveOperand(j); 164f22ef01cSRoman Divacky if (isKill) { 165f22ef01cSRoman Divacky ImpDefRegs.erase(Reg); 166f22ef01cSRoman Divacky LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); 167f22ef01cSRoman Divacky vi.removeKill(MI); 168f22ef01cSRoman Divacky } 169f22ef01cSRoman Divacky ChangedToImpDef = true; 170f22ef01cSRoman Divacky Changed = true; 171f22ef01cSRoman Divacky break; 172f22ef01cSRoman Divacky } 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky Changed = true; 175f22ef01cSRoman Divacky MO.setIsUndef(); 176ffd1746dSEd Schouten // This is a partial register redef of an implicit def. 177ffd1746dSEd Schouten // Make sure the whole register is defined by the instruction. 178ffd1746dSEd Schouten if (MO.isDef()) { 179ffd1746dSEd Schouten MI->addRegisterDefined(Reg); 180ffd1746dSEd Schouten continue; 181ffd1746dSEd Schouten } 182f22ef01cSRoman Divacky if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { 183f22ef01cSRoman Divacky // Make sure other uses of 184f22ef01cSRoman Divacky for (unsigned j = i+1; j != e; ++j) { 185f22ef01cSRoman Divacky MachineOperand &MOJ = MI->getOperand(j); 186f22ef01cSRoman Divacky if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) 187f22ef01cSRoman Divacky MOJ.setIsUndef(); 188f22ef01cSRoman Divacky } 189f22ef01cSRoman Divacky ImpDefRegs.erase(Reg); 190f22ef01cSRoman Divacky } 191f22ef01cSRoman Divacky } 192f22ef01cSRoman Divacky 193f22ef01cSRoman Divacky if (ChangedToImpDef) { 194f22ef01cSRoman Divacky // Backtrack to process this new implicit_def. 195f22ef01cSRoman Divacky --I; 196f22ef01cSRoman Divacky } else { 197f22ef01cSRoman Divacky for (unsigned i = 0; i != MI->getNumOperands(); ++i) { 198f22ef01cSRoman Divacky MachineOperand& MO = MI->getOperand(i); 199f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 200f22ef01cSRoman Divacky continue; 201f22ef01cSRoman Divacky ImpDefRegs.erase(MO.getReg()); 202f22ef01cSRoman Divacky } 203f22ef01cSRoman Divacky } 204f22ef01cSRoman Divacky } 205f22ef01cSRoman Divacky 206f22ef01cSRoman Divacky // Any outstanding liveout implicit_def's? 207f22ef01cSRoman Divacky for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) { 208f22ef01cSRoman Divacky MachineInstr *MI = ImpDefMIs[i]; 209f22ef01cSRoman Divacky unsigned Reg = MI->getOperand(0).getReg(); 210f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(Reg) || 211f22ef01cSRoman Divacky !ImpDefRegs.count(Reg)) { 212f22ef01cSRoman Divacky // Delete all "local" implicit_def's. That include those which define 213f22ef01cSRoman Divacky // physical registers since they cannot be liveout. 214f22ef01cSRoman Divacky MI->eraseFromParent(); 215f22ef01cSRoman Divacky Changed = true; 216f22ef01cSRoman Divacky continue; 217f22ef01cSRoman Divacky } 218f22ef01cSRoman Divacky 219f22ef01cSRoman Divacky // If there are multiple defs of the same register and at least one 220f22ef01cSRoman Divacky // is not an implicit_def, do not insert implicit_def's before the 221f22ef01cSRoman Divacky // uses. 222f22ef01cSRoman Divacky bool Skip = false; 223f22ef01cSRoman Divacky SmallVector<MachineInstr*, 4> DeadImpDefs; 224f22ef01cSRoman Divacky for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), 225f22ef01cSRoman Divacky DE = mri_->def_end(); DI != DE; ++DI) { 226f22ef01cSRoman Divacky MachineInstr *DeadImpDef = &*DI; 227f22ef01cSRoman Divacky if (!DeadImpDef->isImplicitDef()) { 228f22ef01cSRoman Divacky Skip = true; 229f22ef01cSRoman Divacky break; 230f22ef01cSRoman Divacky } 231f22ef01cSRoman Divacky DeadImpDefs.push_back(DeadImpDef); 232f22ef01cSRoman Divacky } 233f22ef01cSRoman Divacky if (Skip) 234f22ef01cSRoman Divacky continue; 235f22ef01cSRoman Divacky 236f22ef01cSRoman Divacky // The only implicit_def which we want to keep are those that are live 237f22ef01cSRoman Divacky // out of its block. 238f22ef01cSRoman Divacky for (unsigned j = 0, ee = DeadImpDefs.size(); j != ee; ++j) 239f22ef01cSRoman Divacky DeadImpDefs[j]->eraseFromParent(); 240f22ef01cSRoman Divacky Changed = true; 241f22ef01cSRoman Divacky 242f22ef01cSRoman Divacky // Process each use instruction once. 243f22ef01cSRoman Divacky for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), 244f22ef01cSRoman Divacky UE = mri_->use_end(); UI != UE; ++UI) { 245f22ef01cSRoman Divacky if (UI.getOperand().isUndef()) 246f22ef01cSRoman Divacky continue; 247f22ef01cSRoman Divacky MachineInstr *RMI = &*UI; 248f22ef01cSRoman Divacky if (ModInsts.insert(RMI)) 249f22ef01cSRoman Divacky RUses.push_back(RMI); 250f22ef01cSRoman Divacky } 251f22ef01cSRoman Divacky 252f22ef01cSRoman Divacky for (unsigned i = 0, e = RUses.size(); i != e; ++i) { 253f22ef01cSRoman Divacky MachineInstr *RMI = RUses[i]; 254f22ef01cSRoman Divacky 255f22ef01cSRoman Divacky // Turn a copy use into an implicit_def. 256ffd1746dSEd Schouten if (isUndefCopy(RMI, Reg, tii_, ImpDefRegs)) { 257f22ef01cSRoman Divacky RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); 258f22ef01cSRoman Divacky 259f22ef01cSRoman Divacky bool isKill = false; 260f22ef01cSRoman Divacky SmallVector<unsigned, 4> Ops; 261f22ef01cSRoman Divacky for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) { 262f22ef01cSRoman Divacky MachineOperand &RRMO = RMI->getOperand(j); 263f22ef01cSRoman Divacky if (RRMO.isReg() && RRMO.getReg() == Reg) { 264f22ef01cSRoman Divacky Ops.push_back(j); 265f22ef01cSRoman Divacky if (RRMO.isKill()) 266f22ef01cSRoman Divacky isKill = true; 267f22ef01cSRoman Divacky } 268f22ef01cSRoman Divacky } 269f22ef01cSRoman Divacky // Leave the other operands along. 270f22ef01cSRoman Divacky for (unsigned j = 0, ee = Ops.size(); j != ee; ++j) { 271f22ef01cSRoman Divacky unsigned OpIdx = Ops[j]; 272f22ef01cSRoman Divacky RMI->RemoveOperand(OpIdx-j); 273f22ef01cSRoman Divacky } 274f22ef01cSRoman Divacky 275f22ef01cSRoman Divacky // Update LiveVariables varinfo if the instruction is a kill. 276f22ef01cSRoman Divacky if (isKill) { 277f22ef01cSRoman Divacky LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); 278f22ef01cSRoman Divacky vi.removeKill(RMI); 279f22ef01cSRoman Divacky } 280f22ef01cSRoman Divacky continue; 281f22ef01cSRoman Divacky } 282f22ef01cSRoman Divacky 283f22ef01cSRoman Divacky // Replace Reg with a new vreg that's marked implicit. 284f22ef01cSRoman Divacky const TargetRegisterClass* RC = mri_->getRegClass(Reg); 285f22ef01cSRoman Divacky unsigned NewVReg = mri_->createVirtualRegister(RC); 286f22ef01cSRoman Divacky bool isKill = true; 287f22ef01cSRoman Divacky for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) { 288f22ef01cSRoman Divacky MachineOperand &RRMO = RMI->getOperand(j); 289f22ef01cSRoman Divacky if (RRMO.isReg() && RRMO.getReg() == Reg) { 290f22ef01cSRoman Divacky RRMO.setReg(NewVReg); 291f22ef01cSRoman Divacky RRMO.setIsUndef(); 292f22ef01cSRoman Divacky if (isKill) { 293f22ef01cSRoman Divacky // Only the first operand of NewVReg is marked kill. 294f22ef01cSRoman Divacky RRMO.setIsKill(); 295f22ef01cSRoman Divacky isKill = false; 296f22ef01cSRoman Divacky } 297f22ef01cSRoman Divacky } 298f22ef01cSRoman Divacky } 299f22ef01cSRoman Divacky } 300f22ef01cSRoman Divacky RUses.clear(); 301f22ef01cSRoman Divacky ModInsts.clear(); 302f22ef01cSRoman Divacky } 303f22ef01cSRoman Divacky ImpDefRegs.clear(); 304f22ef01cSRoman Divacky ImpDefMIs.clear(); 305f22ef01cSRoman Divacky } 306f22ef01cSRoman Divacky 307f22ef01cSRoman Divacky return Changed; 308f22ef01cSRoman Divacky } 309f22ef01cSRoman Divacky 310