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
// 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
// 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) {
// 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");
-; RUN: llc < %s -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -verify-machineinstrs -no-phi-elim-live-out-early-exit | FileCheck %s
target triple = "x86_64-apple-macosx10.8.0"
; The critical edge from for.cond to if.end2 should be split to avoid injecting
%add = add nsw i32 %r.0, %b
ret i32 %add
}
+
+; CHECK: split_live_out
+; CHECK: %while.body
+; CHECK: cmp
+; CHECK-NEXT: ja
+define i8* @split_live_out(i32 %value, i8* %target) nounwind uwtable readonly ssp {
+entry:
+ %cmp10 = icmp ugt i32 %value, 127
+ br i1 %cmp10, label %while.body.preheader, label %while.end
+
+while.body.preheader: ; preds = %entry
+ br label %while.body
+
+while.body: ; preds = %while.body.preheader, %while.body
+ %target.addr.012 = phi i8* [ %incdec.ptr, %while.body ], [ %target, %while.body.preheader ]
+ %value.addr.011 = phi i32 [ %shr, %while.body ], [ %value, %while.body.preheader ]
+ %or = or i32 %value.addr.011, 128
+ %conv = trunc i32 %or to i8
+ store i8 %conv, i8* %target.addr.012, align 1
+ %shr = lshr i32 %value.addr.011, 7
+ %incdec.ptr = getelementptr inbounds i8, i8* %target.addr.012, i64 1
+ %cmp = icmp ugt i32 %value.addr.011, 16383
+ br i1 %cmp, label %while.body, label %while.end.loopexit
+
+while.end.loopexit: ; preds = %while.body
+ %incdec.ptr.lcssa = phi i8* [ %incdec.ptr, %while.body ]
+ %shr.lcssa = phi i32 [ %shr, %while.body ]
+ br label %while.end
+
+while.end: ; preds = %while.end.loopexit, %entry
+ %target.addr.0.lcssa = phi i8* [ %target, %entry ], [ %incdec.ptr.lcssa, %while.end.loopexit ]
+ %value.addr.0.lcssa = phi i32 [ %value, %entry ], [ %shr.lcssa, %while.end.loopexit ]
+ %conv1 = trunc i32 %value.addr.0.lcssa to i8
+ store i8 %conv1, i8* %target.addr.0.lcssa, align 1
+ %incdec.ptr3 = getelementptr inbounds i8, i8* %target.addr.0.lcssa, i64 1
+ ret i8* %incdec.ptr3
+}