+
+ while (MBB.front().getOpcode() == TargetInstrInfo::PHI)
+ LowerAtomicPHINode(MBB, AfterPHIsIt);
+
+ return true;
+}
+
+/// InstructionUsesRegister - Return true if the specified machine instr has a
+/// use of the specified register.
+static bool InstructionUsesRegister(MachineInstr *MI, unsigned SrcReg) {
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
+ if (MI->getOperand(i).isRegister() &&
+ MI->getOperand(i).getReg() == SrcReg &&
+ MI->getOperand(i).isUse())
+ return true;
+ return false;
+}
+
+/// 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) {
+ // 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();
+
+ // 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.
+ //
+ const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
+ RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC, RC);
+
+ // Update live variable information if there is any...
+ LiveVariables *LV = getAnalysisToUpdate<LiveVariables>();
+ if (LV) {
+ MachineInstr *PHICopy = prior(AfterPHIsIt);
+
+ // Increment use count of the newly created virtual register.
+ LV->getVarInfo(IncomingReg).NumUses++;
+
+ // 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);
+
+ // 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);
+
+ // If the result is dead, update LV.
+ if (LV->RegisterDefIsDead(MPhi, DestReg)) {
+ LV->addVirtualRegisterDead(DestReg, PHICopy);
+ LV->removeVirtualRegistersDead(MPhi);
+ }
+
+ // Realize that the destination register is defined by the PHI copy now, not
+ // the PHI itself.
+ LV->getVarInfo(DestReg).DefInst = PHICopy;