diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/CodeGen/PHIElimination.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'llvm/lib/CodeGen/PHIElimination.cpp')
-rw-r--r-- | llvm/lib/CodeGen/PHIElimination.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp index 4dd4c4b1084e5..311b87fa9e3b0 100644 --- a/llvm/lib/CodeGen/PHIElimination.cpp +++ b/llvm/lib/CodeGen/PHIElimination.cpp @@ -96,7 +96,8 @@ namespace { /// Split critical edges where necessary for good coalescer performance. bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, - MachineLoopInfo *MLI); + MachineLoopInfo *MLI, + std::vector<SparseBitVector<>> *LiveInSets); // These functions are temporary abstractions around LiveVariables and // LiveIntervals, so they can go away when LiveVariables does. @@ -151,16 +152,45 @@ bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; - // This pass takes the function out of SSA form. - MRI->leaveSSA(); - // Split critical edges to help the coalescer. if (!DisableEdgeSplitting && (LV || LIS)) { + // A set of live-in regs for each MBB which is used to update LV + // efficiently also with large functions. + std::vector<SparseBitVector<>> LiveInSets; + if (LV) { + LiveInSets.resize(MF.size()); + for (unsigned Index = 0, e = MRI->getNumVirtRegs(); Index != e; ++Index) { + // Set the bit for this register for each MBB where it is + // live-through or live-in (killed). + unsigned VirtReg = Register::index2VirtReg(Index); + MachineInstr *DefMI = MRI->getVRegDef(VirtReg); + if (!DefMI) + continue; + LiveVariables::VarInfo &VI = LV->getVarInfo(VirtReg); + SparseBitVector<>::iterator AliveBlockItr = VI.AliveBlocks.begin(); + SparseBitVector<>::iterator EndItr = VI.AliveBlocks.end(); + while (AliveBlockItr != EndItr) { + unsigned BlockNum = *(AliveBlockItr++); + LiveInSets[BlockNum].set(Index); + } + // The register is live into an MBB in which it is killed but not + // defined. See comment for VarInfo in LiveVariables.h. + MachineBasicBlock *DefMBB = DefMI->getParent(); + if (VI.Kills.size() > 1 || + (!VI.Kills.empty() && VI.Kills.front()->getParent() != DefMBB)) + for (auto *MI : VI.Kills) + LiveInSets[MI->getParent()->getNumber()].set(Index); + } + } + MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); for (auto &MBB : MF) - Changed |= SplitPHIEdges(MF, MBB, MLI); + Changed |= SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr)); } + // This pass takes the function out of SSA form. + MRI->leaveSSA(); + // Populate VRegPHIUseCount analyzePHINodes(MF); @@ -561,7 +591,8 @@ void PHIElimination::analyzePHINodes(const MachineFunction& MF) { bool PHIElimination::SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, - MachineLoopInfo *MLI) { + MachineLoopInfo *MLI, + std::vector<SparseBitVector<>> *LiveInSets) { if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad()) return false; // Quick exit for basic blocks without PHIs. @@ -628,7 +659,7 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF, } if (!ShouldSplit && !SplitAllCriticalEdges) continue; - if (!PreMBB->SplitCriticalEdge(&MBB, *this)) { + if (!PreMBB->SplitCriticalEdge(&MBB, *this, LiveInSets)) { LLVM_DEBUG(dbgs() << "Failed to split critical edge.\n"); continue; } |