X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FProcessImplicitDefs.cpp;h=1ad3479afb4ca70416bd9fbf2772c983babe4844;hb=082120053fdccb7eb21681c09365175f130df210;hp=75875d2835b1cb4428663b6753f4f56eb72b409f;hpb=9cc9bfaf86510790c36198b033f241635614a8d0;p=oota-llvm.git diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index 75875d2835b..1ad3479afb4 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -26,14 +26,18 @@ using namespace llvm; char ProcessImplicitDefs::ID = 0; -static RegisterPass X("processimpdefs", - "Process Implicit Definitions."); +char &llvm::ProcessImplicitDefsID = ProcessImplicitDefs::ID; + +INITIALIZE_PASS_BEGIN(ProcessImplicitDefs, "processimpdefs", + "Process Implicit Definitions", false, false) +INITIALIZE_PASS_DEPENDENCY(LiveVariables) +INITIALIZE_PASS_END(ProcessImplicitDefs, "processimpdefs", + "Process Implicit Definitions", false, false) void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addPreserved(); AU.addPreserved(); - AU.addRequired(); AU.addPreservedID(MachineLoopInfoID); AU.addPreservedID(MachineDominatorsID); AU.addPreservedID(TwoAddressInstructionPassID); @@ -41,18 +45,32 @@ void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, - unsigned Reg, unsigned OpIdx, - const TargetInstrInfo *tii_) { - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) - return true; - - if (OpIdx == 2 && MI->isSubregToReg()) - return true; - if (OpIdx == 1 && MI->isExtractSubreg()) - return true; +bool +ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + SmallSet &ImpDefRegs) { + switch(OpIdx) { + case 1: + return MI->isCopy() && (!MI->getOperand(0).readsReg() || + ImpDefRegs.count(MI->getOperand(0).getReg())); + case 2: + return MI->isSubregToReg() && (!MI->getOperand(0).readsReg() || + ImpDefRegs.count(MI->getOperand(0).getReg())); + default: return false; + } +} + +static bool isUndefCopy(MachineInstr *MI, unsigned Reg, + SmallSet &ImpDefRegs) { + if (MI->isCopy()) { + MachineOperand &MO0 = MI->getOperand(0); + MachineOperand &MO1 = MI->getOperand(1); + if (MO1.getReg() != Reg) + return false; + if (!MO0.readsReg() || ImpDefRegs.count(MO0.getReg())) + return true; + return false; + } return false; } @@ -67,11 +85,10 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { bool Changed = false; - const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo(); - const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo(); - MachineRegisterInfo *mri_ = &fn.getRegInfo(); - - LiveVariables *lv_ = &getAnalysis(); + TII = fn.getTarget().getInstrInfo(); + TRI = fn.getTarget().getRegisterInfo(); + MRI = &fn.getRegInfo(); + LV = getAnalysisIfAvailable(); SmallSet ImpDefRegs; SmallVector ImpDefMIs; @@ -89,29 +106,35 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { MachineInstr *MI = &*I; ++I; if (MI->isImplicitDef()) { - if (MI->getOperand(0).getSubReg()) + ImpDefMIs.push_back(MI); + // Is this a sub-register read-modify-write? + if (MI->getOperand(0).readsReg()) continue; unsigned Reg = MI->getOperand(0).getReg(); ImpDefRegs.insert(Reg); if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) + for (const uint16_t *SS = TRI->getSubRegisters(Reg); *SS; ++SS) ImpDefRegs.insert(*SS); } - ImpDefMIs.push_back(MI); continue; } - if (MI->isInsertSubreg()) { - MachineOperand &MO = MI->getOperand(2); - if (ImpDefRegs.count(MO.getReg())) { - // %reg1032 = INSERT_SUBREG %reg1032, undef, 2 - // This is an identity copy, eliminate it now. - if (MO.isKill()) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); + // Eliminate %reg1032:sub = COPY undef. + if (MI->isCopy() && MI->getOperand(0).readsReg()) { + MachineOperand &MO = MI->getOperand(1); + if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) { + if (LV && MO.isKill()) { + LiveVariables::VarInfo& vi = LV->getVarInfo(MO.getReg()); vi.removeKill(MI); } + unsigned Reg = MI->getOperand(0).getReg(); MI->eraseFromParent(); Changed = true; + + // A REG_SEQUENCE may have been expanded into partial definitions. + // If this was the last one, mark Reg as implicitly defined. + if (TargetRegisterInfo::isVirtualRegister(Reg) && MRI->def_empty(Reg)) + ImpDefRegs.insert(Reg); continue; } } @@ -119,7 +142,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { bool ChangedToImpDef = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand& MO = MI->getOperand(i); - if (!MO.isReg() || !MO.isUse() || MO.isUndef()) + if (!MO.isReg() || !MO.readsReg()) continue; unsigned Reg = MO.getReg(); if (!Reg) @@ -127,15 +150,17 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { if (!ImpDefRegs.count(Reg)) continue; // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) { + if (CanTurnIntoImplicitDef(MI, Reg, i, ImpDefRegs)) { bool isKill = MO.isKill(); - MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); + MI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) MI->RemoveOperand(j); if (isKill) { ImpDefRegs.erase(Reg); - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); - vi.removeKill(MI); + if (LV) { + LiveVariables::VarInfo& vi = LV->getVarInfo(Reg); + vi.removeKill(MI); + } } ChangedToImpDef = true; Changed = true; @@ -144,11 +169,17 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { Changed = true; MO.setIsUndef(); + // This is a partial register redef of an implicit def. + // Make sure the whole register is defined by the instruction. + if (MO.isDef()) { + MI->addRegisterDefined(Reg); + continue; + } if (MO.isKill() || MI->isRegTiedToDefOperand(i)) { - // Make sure other uses of + // Make sure other reads of Reg are also marked . for (unsigned j = i+1; j != e; ++j) { MachineOperand &MOJ = MI->getOperand(j); - if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg) + if (MOJ.isReg() && MOJ.getReg() == Reg && MOJ.readsReg()) MOJ.setIsUndef(); } ImpDefRegs.erase(Reg); @@ -186,8 +217,8 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { // uses. bool Skip = false; SmallVector DeadImpDefs; - for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), - DE = mri_->def_end(); DI != DE; ++DI) { + for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(Reg), + DE = MRI->def_end(); DI != DE; ++DI) { MachineInstr *DeadImpDef = &*DI; if (!DeadImpDef->isImplicitDef()) { Skip = true; @@ -205,8 +236,8 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { Changed = true; // Process each use instruction once. - for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), - UE = mri_->use_end(); UI != UE; ++UI) { + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), + UE = MRI->use_end(); UI != UE; ++UI) { if (UI.getOperand().isUndef()) continue; MachineInstr *RMI = &*UI; @@ -218,10 +249,8 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { MachineInstr *RMI = RUses[i]; // Turn a copy use into an implicit_def. - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - Reg == SrcReg) { - RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); + if (isUndefCopy(RMI, Reg, ImpDefRegs)) { + RMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); bool isKill = false; SmallVector Ops; @@ -240,16 +269,16 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { } // Update LiveVariables varinfo if the instruction is a kill. - if (isKill) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); + if (LV && isKill) { + LiveVariables::VarInfo& vi = LV->getVarInfo(Reg); vi.removeKill(RMI); } continue; } // Replace Reg with a new vreg that's marked implicit. - const TargetRegisterClass* RC = mri_->getRegClass(Reg); - unsigned NewVReg = mri_->createVirtualRegister(RC); + const TargetRegisterClass* RC = MRI->getRegClass(Reg); + unsigned NewVReg = MRI->createVirtualRegister(RC); bool isKill = true; for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) { MachineOperand &RRMO = RMI->getOperand(j);