diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-12-07 23:11:03 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-12-07 23:11:03 +0000 |
commit | 3a41ddb1b98ba6f8ea8b2b65e9d9d0e53d3d4419 (patch) | |
tree | f4d40736b0ef8629c7ddc9b70cafd8898a444734 /lib/CodeGen/MachineSSAUpdater.cpp | |
parent | d8f079c25e8bcaf4d10bfa9c3f6a38cd5ac84329 (diff) |
Watch out for duplicated PHI instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90816 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineSSAUpdater.cpp')
-rw-r--r-- | lib/CodeGen/MachineSSAUpdater.cpp | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/CodeGen/MachineSSAUpdater.cpp b/lib/CodeGen/MachineSSAUpdater.cpp index f41109e80c..292096f00d 100644 --- a/lib/CodeGen/MachineSSAUpdater.cpp +++ b/lib/CodeGen/MachineSSAUpdater.cpp @@ -85,6 +85,36 @@ unsigned MachineSSAUpdater::GetValueAtEndOfBlock(MachineBasicBlock *BB) { return GetValueAtEndOfBlockInternal(BB); } +static +unsigned LookForIdenticalPHI(MachineBasicBlock *BB, + SmallVector<std::pair<MachineBasicBlock*, unsigned>, 8> &PredValues) { + if (BB->empty()) + return 0; + + MachineBasicBlock::iterator I = BB->front(); + if (I->getOpcode() != TargetInstrInfo::PHI) + return 0; + + AvailableValsTy AVals; + for (unsigned i = 0, e = PredValues.size(); i != e; ++i) + AVals[PredValues[i].first] = PredValues[i].second; + while (I != BB->end() && I->getOpcode() == TargetInstrInfo::PHI) { + bool Same = true; + for (unsigned i = 1, e = I->getNumOperands(); i != e; i += 2) { + unsigned SrcReg = I->getOperand(i).getReg(); + MachineBasicBlock *SrcBB = I->getOperand(i+1).getMBB(); + if (AVals[SrcBB] != SrcReg) { + Same = false; + break; + } + } + if (Same) + return I->getOperand(0).getReg(); + ++I; + } + return 0; +} + /// InsertNewDef - Insert an empty PHI or IMPLICIT_DEF instruction which define /// a value of the given register class at the start of the specified basic /// block. It returns the virtual register defined by the instruction. @@ -97,7 +127,6 @@ MachineInstr *InsertNewDef(unsigned Opcode, return BuildMI(*BB, I, DebugLoc::getUnknownLoc(), TII->get(Opcode), NewVR); } - /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that /// is live in the middle of the specified block. /// @@ -121,7 +150,7 @@ unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) { // If there is no definition of the renamed variable in this block, just use // GetValueAtEndOfBlock to do our work. if (!getAvailableVals(AV).count(BB)) - return GetValueAtEndOfBlock(BB); + return GetValueAtEndOfBlockInternal(BB); // If there are no predecessors, just return undef. if (BB->pred_empty()) { @@ -156,6 +185,11 @@ unsigned MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB) { if (SingularValue != 0) return SingularValue; + // If an identical PHI is already in BB, just reuse it. + unsigned DupPHI = LookForIdenticalPHI(BB, PredValues); + if (DupPHI) + return DupPHI; + // Otherwise, we do need a PHI: insert one now. MachineBasicBlock::iterator Loc = BB->empty() ? BB->end() : BB->front(); MachineInstr *InsertedPHI = InsertNewDef(TargetInstrInfo::PHI, BB, @@ -199,7 +233,7 @@ void MachineSSAUpdater::RewriteUse(MachineOperand &U) { unsigned NewVR = 0; if (UseMI->getOpcode() == TargetInstrInfo::PHI) { MachineBasicBlock *SourceBB = findCorrespondingPred(UseMI, &U); - NewVR = GetValueAtEndOfBlock(SourceBB); + NewVR = GetValueAtEndOfBlockInternal(SourceBB); } else { NewVR = GetValueInMiddleOfBlock(UseMI->getParent()); } |