From 53a79aaae988d9dc9d12af8970f8b8fe58cc478d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 3 Oct 2005 04:47:08 +0000 Subject: [PATCH] Break the body of the loop out into a new method git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23606 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/PHIElimination.cpp | 287 +++++++++++++++++---------------- 1 file changed, 149 insertions(+), 138 deletions(-) diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp index 7b66bcfaa24..80c884dc9ae 100644 --- a/lib/CodeGen/PHIElimination.cpp +++ b/lib/CodeGen/PHIElimination.cpp @@ -22,6 +22,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" +#include using namespace llvm; namespace { @@ -46,6 +47,10 @@ namespace { /// in predecessor basic blocks. /// bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB); + void LowerAtomicPHINode(MachineBasicBlock &MBB, + MachineBasicBlock::iterator AfterPHIsIt, + DenseMap &VUC, + unsigned BBIsSuccOfPreds); }; RegisterPass X("phi-node-elimination", @@ -60,11 +65,7 @@ const PassInfo *llvm::PHIEliminationID = X.getPassInfo(); /// bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) { if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) - return false; // Quick exit for normal case... - - LiveVariables *LV = getAnalysisToUpdate(); - const TargetInstrInfo &MII = *MF.getTarget().getInstrInfo(); - const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + return false; // Quick exit for basic blocks without PHIs. // VRegPHIUseCount - Keep track of the number of times each virtual register // is used by PHI nodes in successors of this block. @@ -84,169 +85,179 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) { } // Get an iterator to the first instruction after the last PHI node (this may - // also be the end of the basic block). While we are scanning the PHIs, - // populate the VRegPHIUseCount map. + // also be the end of the basic block). MachineBasicBlock::iterator AfterPHIsIt = MBB.begin(); while (AfterPHIsIt != MBB.end() && AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI) ++AfterPHIsIt; // Skip over all of the PHI nodes... while (MBB.front().getOpcode() == TargetInstrInfo::PHI) { - // Unlink the PHI node from the basic block, but don't delete the PHI yet. - MachineInstr *MPhi = MBB.remove(MBB.begin()); + LowerAtomicPHINode(MBB, AfterPHIsIt, VRegPHIUseCount, BBIsSuccOfPreds); + } + return true; +} - assert(MRegisterInfo::isVirtualRegister(MPhi->getOperand(0).getReg()) && - "PHI node doesn't write virt reg?"); +/// LowerAtomicPHINode - Lower the PHI node at the top of the specified block, +/// under the assuption that it needs to be lowered in a way that supports +/// atomic execution of PHIs. This lowering method is always correct all of the +/// time. +void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB, + MachineBasicBlock::iterator AfterPHIsIt, + DenseMap &VRegPHIUseCount, + unsigned BBIsSuccOfPreds) { + // Unlink the PHI node from the basic block, but don't delete the PHI yet. + MachineInstr *MPhi = MBB.remove(MBB.begin()); - unsigned DestReg = MPhi->getOperand(0).getReg(); + unsigned DestReg = MPhi->getOperand(0).getReg(); - // Create a new register for the incoming PHI arguments - const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg); - unsigned IncomingReg = MF.getSSARegMap()->createVirtualRegister(RC); + // Create a new register for the incoming PHI arguments/ + MachineFunction &MF = *MBB.getParent(); + const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg); + unsigned IncomingReg = MF.getSSARegMap()->createVirtualRegister(RC); - // Insert a register to register copy in the top of the current block (but - // after any remaining phi nodes) which copies the new incoming register - // into the phi node destination. + // Insert a register to register copy in the top of the current block (but + // after any remaining phi nodes) which copies the new incoming register + // into the phi node destination. + // + const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC); + + // Update live variable information if there is any... + LiveVariables *LV = getAnalysisToUpdate(); + if (LV) { + MachineInstr *PHICopy = prior(AfterPHIsIt); + + // Add information to LiveVariables to know that the incoming value is + // killed. Note that because the value is defined in several places (once + // each for each incoming block), the "def" block and instruction fields + // for the VarInfo is not filled in. // - RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC); + LV->addVirtualRegisterKilled(IncomingReg, PHICopy); - // Update live variable information if there is any... - if (LV) { - MachineInstr *PHICopy = prior(AfterPHIsIt); + // Since we are going to be deleting the PHI node, if it is the last use + // of any registers, or if the value itself is dead, we need to move this + // information over to the new copy we just inserted. + // + LV->removeVirtualRegistersKilled(MPhi); - // Add information to LiveVariables to know that the incoming value is - // killed. Note that because the value is defined in several places (once - // each for each incoming block), the "def" block and instruction fields - // for the VarInfo is not filled in. - // - LV->addVirtualRegisterKilled(IncomingReg, PHICopy); + std::pair + RKs = LV->dead_range(MPhi); + if (RKs.first != RKs.second) { + for (LiveVariables::killed_iterator I = RKs.first; I != RKs.second; ++I) + LV->addVirtualRegisterDead(*I, PHICopy); + LV->removeVirtualRegistersDead(MPhi); + } + } - // Since we are going to be deleting the PHI node, if it is the last use - // of any registers, or if the value itself is dead, we need to move this - // information over to the new copy we just inserted. - // - LV->removeVirtualRegistersKilled(MPhi); + // Adjust the VRegPHIUseCount map to account for the removal of this PHI + // node. + for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) + VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= BBIsSuccOfPreds; - std::pair - RKs = LV->dead_range(MPhi); - if (RKs.first != RKs.second) { - for (LiveVariables::killed_iterator I = RKs.first; I != RKs.second; ++I) - LV->addVirtualRegisterDead(*I, PHICopy); - LV->removeVirtualRegistersDead(MPhi); + // Now loop over all of the incoming arguments, changing them to copy into + // the IncomingReg register in the corresponding predecessor basic block. + // + for (int i = MPhi->getNumOperands() - 1; i >= 2; i-=2) { + MachineOperand &opVal = MPhi->getOperand(i-1); + + // Get the MachineBasicBlock equivalent of the BasicBlock that is the + // source path the PHI. + MachineBasicBlock &opBlock = *MPhi->getOperand(i).getMachineBasicBlock(); + + MachineBasicBlock::iterator I = opBlock.getFirstTerminator(); + + // Check to make sure we haven't already emitted the copy for this block. + // This can happen because PHI nodes may have multiple entries for the + // same basic block. It doesn't matter which entry we use though, because + // all incoming values are guaranteed to be the same for a particular bb. + // + // If we emitted a copy for this basic block already, it will be right + // where we want to insert one now. Just check for a definition of the + // register we are interested in! + // + bool HaveNotEmitted = true; + + if (I != opBlock.begin()) { + MachineBasicBlock::iterator PrevInst = prior(I); + for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) { + MachineOperand &MO = PrevInst->getOperand(i); + if (MO.isRegister() && MO.getReg() == IncomingReg) + if (MO.isDef()) { + HaveNotEmitted = false; + break; + } } } - // Adjust the VRegPHIUseCount map to account for the removal of this PHI - // node. - for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) - VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= BBIsSuccOfPreds; + if (HaveNotEmitted) { // If the copy has not already been emitted, do it. + assert(MRegisterInfo::isVirtualRegister(opVal.getReg()) && + "Machine PHI Operands must all be virtual registers!"); + unsigned SrcReg = opVal.getReg(); + RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC); - // Now loop over all of the incoming arguments, changing them to copy into - // the IncomingReg register in the corresponding predecessor basic block. - // - for (int i = MPhi->getNumOperands() - 1; i >= 2; i-=2) { - MachineOperand &opVal = MPhi->getOperand(i-1); + // Now update live variable information if we have it. + if (LV) { + // We want to be able to insert a kill of the register if this PHI + // (aka, the copy we just inserted) is the last use of the source + // value. Live variable analysis conservatively handles this by + // saying that the value is live until the end of the block the PHI + // entry lives in. If the value really is dead at the PHI copy, there + // will be no successor blocks which have the value live-in. + // + // Check to see if the copy is the last use, and if so, update the + // live variables information so that it knows the copy source + // instruction kills the incoming value. + // + LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); - // Get the MachineBasicBlock equivalent of the BasicBlock that is the - // source path the PHI. - MachineBasicBlock &opBlock = *MPhi->getOperand(i).getMachineBasicBlock(); + // Loop over all of the successors of the basic block, checking to see + // if the value is either live in the block, or if it is killed in the + // block. Also check to see if this register is in use by another PHI + // node which has not yet been eliminated. If so, it will be killed + // at an appropriate point later. + // + bool ValueIsLive = false; + for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), + E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { + MachineBasicBlock *SuccMBB = *SI; - MachineBasicBlock::iterator I = opBlock.getFirstTerminator(); + // Is it alive in this successor? + unsigned SuccIdx = SuccMBB->getNumber(); + if (SuccIdx < InRegVI.AliveBlocks.size() && + InRegVI.AliveBlocks[SuccIdx]) { + ValueIsLive = true; + break; + } - // Check to make sure we haven't already emitted the copy for this block. - // This can happen because PHI nodes may have multiple entries for the - // same basic block. It doesn't matter which entry we use though, because - // all incoming values are guaranteed to be the same for a particular bb. - // - // If we emitted a copy for this basic block already, it will be right - // where we want to insert one now. Just check for a definition of the - // register we are interested in! - // - bool HaveNotEmitted = true; - - if (I != opBlock.begin()) { - MachineBasicBlock::iterator PrevInst = prior(I); - for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) { - MachineOperand &MO = PrevInst->getOperand(i); - if (MO.isRegister() && MO.getReg() == IncomingReg) - if (MO.isDef()) { - HaveNotEmitted = false; - break; - } - } - } - - if (HaveNotEmitted) { // If the copy has not already been emitted, do it. - assert(MRegisterInfo::isVirtualRegister(opVal.getReg()) && - "Machine PHI Operands must all be virtual registers!"); - unsigned SrcReg = opVal.getReg(); - RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC); - - // Now update live variable information if we have it. - if (LV) { - // We want to be able to insert a kill of the register if this PHI - // (aka, the copy we just inserted) is the last use of the source - // value. Live variable analysis conservatively handles this by - // saying that the value is live until the end of the block the PHI - // entry lives in. If the value really is dead at the PHI copy, there - // will be no successor blocks which have the value live-in. - // - // Check to see if the copy is the last use, and if so, update the - // live variables information so that it knows the copy source - // instruction kills the incoming value. - // - LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); - - // Loop over all of the successors of the basic block, checking to see - // if the value is either live in the block, or if it is killed in the - // block. Also check to see if this register is in use by another PHI - // node which has not yet been eliminated. If so, it will be killed - // at an appropriate point later. - // - bool ValueIsLive = false; - for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), - E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { - MachineBasicBlock *SuccMBB = *SI; - - // Is it alive in this successor? - unsigned SuccIdx = SuccMBB->getNumber(); - if (SuccIdx < InRegVI.AliveBlocks.size() && - InRegVI.AliveBlocks[SuccIdx]) { + // Is it killed in this successor? + for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) + if (InRegVI.Kills[i]->getParent() == SuccMBB) { ValueIsLive = true; break; } - // Is it killed in this successor? - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == SuccMBB) { - ValueIsLive = true; - break; - } + // Is it used by any PHI instructions in this block? + if (!ValueIsLive) + ValueIsLive = VRegPHIUseCount[SrcReg] != 0; + } - // Is it used by any PHI instructions in this block? - if (!ValueIsLive) - ValueIsLive = VRegPHIUseCount[SrcReg] != 0; - } + // Okay, if we now know that the value is not live out of the block, + // we can add a kill marker to the copy we inserted saying that it + // kills the incoming value! + // + if (!ValueIsLive) { + MachineBasicBlock::iterator Prev = prior(I); + LV->addVirtualRegisterKilled(SrcReg, Prev); - // Okay, if we now know that the value is not live out of the block, - // we can add a kill marker to the copy we inserted saying that it - // kills the incoming value! - // - if (!ValueIsLive) { - MachineBasicBlock::iterator Prev = prior(I); - LV->addVirtualRegisterKilled(SrcReg, Prev); - - // This vreg no longer lives all of the way through opBlock. - unsigned opBlockNum = opBlock.getNumber(); - if (opBlockNum < InRegVI.AliveBlocks.size()) - InRegVI.AliveBlocks[opBlockNum] = false; - } + // This vreg no longer lives all of the way through opBlock. + unsigned opBlockNum = opBlock.getNumber(); + if (opBlockNum < InRegVI.AliveBlocks.size()) + InRegVI.AliveBlocks[opBlockNum] = false; } } } - - // Really delete the PHI instruction now! - delete MPhi; } - return true; + + // Really delete the PHI instruction now! + delete MPhi; }