summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-03-13 22:59:14 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-03-13 22:59:14 +0000
commit94419d6fddae3fce2ab11865188810fc34ce34e1 (patch)
tree15a943cff54a9c3fffa6dfa96ec930d78e3d075f /llvm/lib/CodeGen
parent9750429e61dffb55035abe1514a028ccb8d1b295 (diff)
downloadbcm5719-llvm-94419d6fddae3fce2ab11865188810fc34ce34e1.tar.gz
bcm5719-llvm-94419d6fddae3fce2ab11865188810fc34ce34e1.zip
Fix PR3784: If the source of a phi comes from a bb ended with an invoke, make sure the copy is inserted before the try range (unless it's used as an input to the invoke, then insert it after the last use), not at the end of the bb.
Also re-apply r66140 which was disabled as a workaround. llvm-svn: 66976
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/PHIElimination.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
index b32db2e062f..6f3c82c7081 100644
--- a/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/llvm/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);
OpenPOWER on IntegriCloud