diff options
author | Justin Bogner <mail@justinbogner.com> | 2016-04-04 21:41:54 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2016-04-04 21:41:54 +0000 |
commit | 35c6903f220d4065aa0051df9785a9b2b6f94bf2 (patch) | |
tree | c0c8eaac95f39004bee7b0a8bc19a4365776b3cf /llvm/lib/CodeGen/TailDuplication.cpp | |
parent | 7511abd5c1c6a8adcd7609cca53446613310a6d9 (diff) | |
download | llvm-35c6903f220d4065aa0051df9785a9b2b6f94bf2.zip llvm-35c6903f220d4065aa0051df9785a9b2b6f94bf2.tar.gz llvm-35c6903f220d4065aa0051df9785a9b2b6f94bf2.tar.bz2 |
Revert "CodeGen: Remove dead code in TailDuplicate"
It seems this is reachable after all. It hit on 7zip-benchmark in lnt
on ppc64:
http://lab.llvm.org:8011/builders/clang-ppc64be-linux-lnt/builds/2317
This reverts r265347.
llvm-svn: 265352
Diffstat (limited to 'llvm/lib/CodeGen/TailDuplication.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TailDuplication.cpp | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/TailDuplication.cpp b/llvm/lib/CodeGen/TailDuplication.cpp index 7f135be..2a8431c 100644 --- a/llvm/lib/CodeGen/TailDuplication.cpp +++ b/llvm/lib/CodeGen/TailDuplication.cpp @@ -92,7 +92,8 @@ namespace { MachineBasicBlock *PredBB, DenseMap<unsigned, unsigned> &LocalVRMap, SmallVectorImpl<std::pair<unsigned,unsigned> > &Copies, - const DenseSet<unsigned> &UsedByPhi); + const DenseSet<unsigned> &UsedByPhi, + bool Remove); void DuplicateInstruction(MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, @@ -394,7 +395,7 @@ void TailDuplicatePass::ProcessPHI( MachineInstr *MI, MachineBasicBlock *TailBB, MachineBasicBlock *PredBB, DenseMap<unsigned, unsigned> &LocalVRMap, SmallVectorImpl<std::pair<unsigned, unsigned> > &Copies, - const DenseSet<unsigned> &RegsUsedByPhi) { + const DenseSet<unsigned> &RegsUsedByPhi, bool Remove) { unsigned DefReg = MI->getOperand(0).getReg(); unsigned SrcOpIdx = getPHISrcRegOpIdx(MI, PredBB); assert(SrcOpIdx && "Unable to find matching PHI source?"); @@ -409,6 +410,9 @@ void TailDuplicatePass::ProcessPHI( if (isDefLiveOut(DefReg, TailBB, MRI) || RegsUsedByPhi.count(DefReg)) AddSSAUpdateEntry(DefReg, NewDef, PredBB); + if (!Remove) + return; + // Remove PredBB from the PHI node. MI->RemoveOperand(SrcOpIdx+1); MI->RemoveOperand(SrcOpIdx); @@ -836,7 +840,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, if (MI->isPHI()) { // Replace the uses of the def of the PHI with the register coming // from PredBB. - ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi); + ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi, true); } else { // Replace def of virtual registers with new registers, and update // uses with PHI source register or the new registers. @@ -890,7 +894,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, // Replace the uses of the def of the PHI with the register coming // from PredBB. MachineInstr *MI = &*I++; - ProcessPHI(MI, TailBB, PrevBB, LocalVRMap, CopyInfos, UsedByPhi); + ProcessPHI(MI, TailBB, PrevBB, LocalVRMap, CopyInfos, UsedByPhi, true); if (MI->getParent()) MI->eraseFromParent(); } @@ -922,16 +926,56 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, Changed = true; } - // TODO: We shouldn't need this assert. It's here to be defensive about - // removing the logic from r132816, which handled an unreachable case. - assert((!PreRegAlloc || !Changed || - std::all_of(Preds.begin(), Preds.end(), - [&TDBBs](MachineBasicBlock *PredBB) { - return (std::find(TDBBs.begin(), TDBBs.end(), PredBB) != - TDBBs.end()) || - PredBB->succ_size() != 1; - })) && - "loop block duplicated into some but not all predecessors"); + // If this is after register allocation, there are no phis to fix. + if (!PreRegAlloc) + return Changed; + + // If we made no changes so far, we are safe. + if (!Changed) + return Changed; + + + // Handle the nasty case in that we duplicated a block that is part of a loop + // into some but not all of its predecessors. For example: + // 1 -> 2 <-> 3 | + // \ | + // \---> rest | + // if we duplicate 2 into 1 but not into 3, we end up with + // 12 -> 3 <-> 2 -> rest | + // \ / | + // \----->-----/ | + // If there was a "var = phi(1, 3)" in 2, it has to be ultimately replaced + // with a phi in 3 (which now dominates 2). + // What we do here is introduce a copy in 3 of the register defined by the + // phi, just like when we are duplicating 2 into 3, but we don't copy any + // real instructions or remove the 3 -> 2 edge from the phi in 2. + for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(), + PE = Preds.end(); PI != PE; ++PI) { + MachineBasicBlock *PredBB = *PI; + if (std::find(TDBBs.begin(), TDBBs.end(), PredBB) != TDBBs.end()) + continue; + + // EH edges + if (PredBB->succ_size() != 1) + continue; + + DenseMap<unsigned, unsigned> LocalVRMap; + SmallVector<std::pair<unsigned,unsigned>, 4> CopyInfos; + MachineBasicBlock::iterator I = TailBB->begin(); + // Process PHI instructions first. + while (I != TailBB->end() && I->isPHI()) { + // Replace the uses of the def of the PHI with the register coming + // from PredBB. + MachineInstr *MI = &*I++; + ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi, false); + } + MachineBasicBlock::iterator Loc = PredBB->getFirstTerminator(); + for (unsigned i = 0, e = CopyInfos.size(); i != e; ++i) { + Copies.push_back(BuildMI(*PredBB, Loc, DebugLoc(), + TII->get(TargetOpcode::COPY), + CopyInfos[i].first).addReg(CopyInfos[i].second)); + } + } return Changed; } |