aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/PHIElimination.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2015-03-03 10:23:11 +0000
committerDaniel Jasper <djasper@google.com>2015-03-03 10:23:11 +0000
commit8f239f83b033b50294f21bbca7e79ae4b1ccb1ca (patch)
treeb2208f05f71103a2c71f40d96e8be8b8560acd9b /llvm/lib/CodeGen/PHIElimination.cpp
parent34d761d893e0126c415d7b17f7474a3bef2beaa2 (diff)
downloadllvm-8f239f83b033b50294f21bbca7e79ae4b1ccb1ca.zip
llvm-8f239f83b033b50294f21bbca7e79ae4b1ccb1ca.tar.gz
llvm-8f239f83b033b50294f21bbca7e79ae4b1ccb1ca.tar.bz2
During PHI elimination, split critical edges that move copies out of loops.
This prevents the behavior observed in llvm.org/PR22369. I am not sure whether I am reading the code correctly, but the early exit based on isLiveOutPastPHIs() seems to make the wrong assumption that RegisterCoalescer won't be able to coalesce those copies later. This change hides the new behavior behind -no-phi-elim-live-out-early-exit as it currently breaks four tests: * Assertion in: CodeGen/Hexagon/hwloop-cleanup.ll * Worse code in: CodeGen/X86/coalescer-commute4.ll CodeGen/X86/phys_subreg_coalesce-2.ll CodeGen/X86/zlib-longest-match.ll The root cause here seems to be that the heuristic that determines the visitation order in RegisterCoalescer gets less lucky. llvm-svn: 231064
Diffstat (limited to 'llvm/lib/CodeGen/PHIElimination.cpp')
-rw-r--r--llvm/lib/CodeGen/PHIElimination.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
index def2e3d..7098057 100644
--- a/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/llvm/lib/CodeGen/PHIElimination.cpp
@@ -46,6 +46,10 @@ SplitAllCriticalEdges("phi-elim-split-all-critical-edges", cl::init(false),
cl::Hidden, cl::desc("Split all critical edges during "
"PHI elimination"));
+static cl::opt<bool> NoPhiElimLiveOutEarlyExit(
+ "no-phi-elim-live-out-early-exit", cl::init(false), cl::Hidden,
+ cl::desc("Do not use an early exit if isLiveOutPastPHIs returns true."));
+
namespace {
class PHIElimination : public MachineFunctionPass {
MachineRegisterInfo *MRI; // Machine register information
@@ -573,12 +577,14 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
// there is a risk it may not be coalesced away.
//
// If the copy would be a kill, there is no need to split the edge.
- if (!isLiveOutPastPHIs(Reg, PreMBB) && !SplitAllCriticalEdges)
+ bool ShouldSplit = isLiveOutPastPHIs(Reg, PreMBB);
+ if (!ShouldSplit && !NoPhiElimLiveOutEarlyExit)
continue;
-
- DEBUG(dbgs() << PrintReg(Reg) << " live-out before critical edge BB#"
- << PreMBB->getNumber() << " -> BB#" << MBB.getNumber()
- << ": " << *BBI);
+ if (ShouldSplit) {
+ DEBUG(dbgs() << PrintReg(Reg) << " live-out before critical edge BB#"
+ << PreMBB->getNumber() << " -> BB#" << MBB.getNumber()
+ << ": " << *BBI);
+ }
// If Reg is not live-in to MBB, it means it must be live-in to some
// other PreMBB successor, and we can avoid the interference by splitting
@@ -588,7 +594,7 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
// is likely to be left after coalescing. If we are looking at a loop
// exiting edge, split it so we won't insert code in the loop, otherwise
// don't bother.
- bool ShouldSplit = !isLiveIn(Reg, &MBB) || SplitAllCriticalEdges;
+ ShouldSplit = ShouldSplit && !isLiveIn(Reg, &MBB);
// Check for a loop exiting edge.
if (!ShouldSplit && CurLoop != PreLoop) {
@@ -603,7 +609,7 @@ bool PHIElimination::SplitPHIEdges(MachineFunction &MF,
// Split unless this edge is entering CurLoop from an outer loop.
ShouldSplit = PreLoop && !PreLoop->contains(CurLoop);
}
- if (!ShouldSplit)
+ if (!ShouldSplit && !SplitAllCriticalEdges)
continue;
if (!PreMBB->SplitCriticalEdge(&MBB, this)) {
DEBUG(dbgs() << "Failed to split critical edge.\n");