diff options
Diffstat (limited to 'lib/CodeGen/PHIElimination.cpp')
-rw-r--r-- | lib/CodeGen/PHIElimination.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp index b32db2e062..6f3c82c708 100644 --- a/lib/CodeGen/PHIElimination.cpp +++ b/lib/CodeGen/PHIElimination.cpp @@ -31,6 +31,7 @@ using namespace llvm; STATISTIC(NumAtomic, "Number of atomic phis lowered"); +STATISTIC(NumEH, "Number of EH try blocks skipped"); namespace { class VISIBILITY_HIDDEN PNE : public MachineFunctionPass { @@ -65,6 +66,9 @@ namespace { /// void analyzePHINodes(const MachineFunction& Fn); + void WalkPassEHTryRange(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &I, unsigned SrcReg); + typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair; typedef std::map<BBVRegPair, unsigned> VRegPHIUse; @@ -140,6 +144,39 @@ static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi, return true; } +void PNE::WalkPassEHTryRange(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &I, unsigned SrcReg) { + if (I == MBB.begin()) + return; + MachineBasicBlock::iterator PI = prior(I); + if (PI->getOpcode() != TargetInstrInfo::EH_LABEL) + return; + + // Trying to walk pass the EH try range. If we run into a use instruction, + // we want to insert the copy there. + SmallPtrSet<MachineInstr*, 4> UsesInMBB; + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg), + UE = MRI->use_end(); UI != UE; ++UI) { + MachineInstr *UseMI = &*UI; + if (UseMI->getParent() == &MBB) + UsesInMBB.insert(UseMI); + } + + while (PI != MBB.begin()) { + --PI; + if (PI->getOpcode() == TargetInstrInfo::EH_LABEL) { + ++NumEH; + I = PI; + return; + } else if (UsesInMBB.count(&*PI)) { + ++NumEH; + I = next(PI); + return; + } + } + return; +} + /// 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 @@ -238,6 +275,9 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB, // in the block (or end()). MachineBasicBlock::iterator InsertPos = opBlock.getFirstTerminator(); + // Walk pass EH try range if needed. + WalkPassEHTryRange(opBlock, InsertPos, SrcReg); + // Insert the copy. TII->copyRegToReg(opBlock, InsertPos, IncomingReg, SrcReg, RC, RC); |