X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FTwoAddressInstructionPass.cpp;h=52a54eb5bd86876a418700207816dfb11edfa874;hb=253174bf50c932abaa680f465e2888c0e5272267;hp=d2e5288d34b6cfb5f8b2ea28f04d1d47861445fe;hpb=f660c171c838793b87b7e58e91609cecf256378d;p=oota-llvm.git diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index d2e5288d34b..52a54eb5bd8 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -37,6 +37,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/BitVector.h" @@ -64,20 +65,22 @@ namespace { unsigned Reg, MachineBasicBlock::iterator OldPos); - bool isSafeToReMat(unsigned DstReg, MachineInstr *MI); bool isProfitableToReMat(unsigned Reg, const TargetRegisterClass *RC, MachineInstr *MI, MachineInstr *DefMI, MachineBasicBlock *MBB, unsigned Loc, DenseMap &DistanceMap); public: static char ID; // Pass identification, replacement for typeid - TwoAddressInstructionPass() : MachineFunctionPass((intptr_t)&ID) {} + TwoAddressInstructionPass() : MachineFunctionPass(&ID) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved(); AU.addPreservedID(MachineLoopInfoID); AU.addPreservedID(MachineDominatorsID); - AU.addPreservedID(PHIEliminationID); + if (StrongPHIElim) + AU.addPreservedID(StrongPHIEliminationID); + else + AU.addPreservedID(PHIEliminationID); MachineFunctionPass::getAnalysisUsage(AU); } @@ -109,7 +112,7 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isRegister()) + if (!MO.isReg()) continue; unsigned MOReg = MO.getReg(); if (!MOReg) @@ -159,7 +162,7 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, ++NumVisited; for (unsigned i = 0, e = OtherMI->getNumOperands(); i != e; ++i) { MachineOperand &MO = OtherMI->getOperand(i); - if (!MO.isRegister()) + if (!MO.isReg()) continue; unsigned MOReg = MO.getReg(); if (!MOReg) @@ -184,11 +187,8 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI); KillMO->setIsKill(true); - if (LV) { - LiveVariables::VarInfo& VarInfo = LV->getVarInfo(SavedReg); - VarInfo.removeKill(KillMI); - VarInfo.Kills.push_back(MI); - } + if (LV) + LV->replaceKillInstruction(SavedReg, KillMI, MI); // Move instruction to its destination. MBB->remove(MI); @@ -198,40 +198,13 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, return true; } -/// isSafeToReMat - Return true if it's safe to rematerialize the specified -/// instruction which defined the specified register instead of copying it. -bool -TwoAddressInstructionPass::isSafeToReMat(unsigned DstReg, MachineInstr *MI) { - const TargetInstrDesc &TID = MI->getDesc(); - if (!TID.isAsCheapAsAMove()) - return false; - bool SawStore = false; - if (!MI->isSafeToMove(TII, SawStore)) - return false; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (!MO.isRegister()) - continue; - // FIXME: For now, do not remat any instruction with register operands. - // Later on, we can loosen the restriction is the register operands have - // not been modified between the def and use. Note, this is different from - // MachineSink because the code in no longer in two-address form (at least - // partially). - if (MO.isUse()) - return false; - else if (!MO.isDead() && MO.getReg() != DstReg) - return false; - } - return true; -} - /// isTwoAddrUse - Return true if the specified MI is using the specified /// register as a two-address operand. static bool isTwoAddrUse(MachineInstr *UseMI, unsigned Reg) { const TargetInstrDesc &TID = UseMI->getDesc(); for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { MachineOperand &MO = UseMI->getOperand(i); - if (MO.isRegister() && MO.getReg() == Reg && + if (MO.isReg() && MO.getReg() == Reg && (MO.isDef() || TID.getOperandConstraint(i, TOI::TIED_TO) != -1)) // Earlier use is a two-address one. return true; @@ -323,7 +296,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { FirstTied = false; - assert(mi->getOperand(si).isRegister() && mi->getOperand(si).getReg() && + assert(mi->getOperand(si).isReg() && mi->getOperand(si).getReg() && mi->getOperand(si).isUse() && "two address instruction invalid"); // If the two operands are the same we just remove the use @@ -347,7 +320,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // should never occur because we are in SSA form. for (unsigned i = 0; i != mi->getNumOperands(); ++i) assert((int)i == ti || - !mi->getOperand(i).isRegister() || + !mi->getOperand(i).isReg() || mi->getOperand(i).getReg() != regA); #endif @@ -361,7 +334,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // and C joinable. // FIXME: This code also works for A := B op C instructions. if (TID.isCommutable() && mi->getNumOperands() >= 3) { - assert(mi->getOperand(3-si).isRegister() && + assert(mi->getOperand(3-si).isReg() && "Not a proper commutative instruction!"); unsigned regC = mi->getOperand(3-si).getReg(); @@ -375,10 +348,9 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { DOUT << "2addr: COMMUTED TO: " << *NewMI; // If the instruction changed to commute it, update livevar. if (NewMI != mi) { - if (LV) { + if (LV) // Update live variables - LV->instructionChanged(mi, NewMI); - } + LV->replaceKillInstruction(regC, mi, NewMI); mbbi->insert(mi, NewMI); // Insert the new inst mbbi->erase(mi); // Nuke the old inst. @@ -435,7 +407,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // If it's safe and profitable, remat the definition instead of // copying it. if (DefMI && - isSafeToReMat(regB, DefMI) && + DefMI->getDesc().isAsCheapAsAMove() && + DefMI->isSafeToReMat(TII, regB) && isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist,DistanceMap)){ DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n"); TII->reMaterialize(*mbbi, mi, regA, DefMI); @@ -446,7 +419,6 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { } MachineBasicBlock::iterator prevMi = prior(mi); - DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM)); // Update live variables for regB. if (LV) { @@ -455,16 +427,18 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { // regB is used in this BB. varInfoB.UsedBlocks[mbbi->getNumber()] = true; - if (LV->removeVirtualRegisterKilled(regB, mbbi, mi)) + if (LV->removeVirtualRegisterKilled(regB, mi)) LV->addVirtualRegisterKilled(regB, prevMi); - if (LV->removeVirtualRegisterDead(regB, mbbi, mi)) + if (LV->removeVirtualRegisterDead(regB, mi)) LV->addVirtualRegisterDead(regB, prevMi); } + + DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM)); // Replace all occurences of regB with regA. for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) { - if (mi->getOperand(i).isRegister() && + if (mi->getOperand(i).isReg() && mi->getOperand(i).getReg() == regB) mi->getOperand(i).setReg(regA); }