Index: lib/CodeGen/StackColoring.cpp =================================================================== --- lib/CodeGen/StackColoring.cpp +++ lib/CodeGen/StackColoring.cpp @@ -75,10 +75,10 @@ /// Enable enhanced dataflow scheme for lifetime analysis (treat first /// use of stack slot as start of slot lifetime, as opposed to looking /// for LIFETIME_START marker). See "Implementation notes" below for -/// more info. FIXME: set to false for the moment due to PR27903. +/// more info. static cl::opt LifetimeStartOnFirstUse("stackcoloring-lifetime-start-on-first-use", - cl::init(false), cl::Hidden, + cl::init(true), cl::Hidden, cl::desc("Treat stack lifetimes as starting on first use, not on START marker.")); @@ -289,9 +289,9 @@ /// lifetime marker (either start or end). BitVector InterestingSlots; - /// Degenerate slots -- first use appears outside of start/end - /// lifetime markers. - BitVector DegenerateSlots; + /// FI slots that need to be handled conservatively (for these + /// slots lifetime-start-on-first-use is disabled). + BitVector ConservativeSlots; /// Number of iterations taken during data flow analysis. unsigned NumIterations; @@ -331,7 +331,7 @@ bool applyFirstUse(int Slot) { if (!LifetimeStartOnFirstUse || ProtectFromEscapedAllocas) return false; - if (DegenerateSlots.test(Slot)) + if (ConservativeSlots.test(Slot)) return false; return true; } @@ -490,11 +490,12 @@ BlockBitVecMap SeenStartMap; InterestingSlots.clear(); InterestingSlots.resize(NumSlot); - DegenerateSlots.clear(); - DegenerateSlots.resize(NumSlot); + ConservativeSlots.clear(); + ConservativeSlots.resize(NumSlot); + SmallVector NumStartLifetimes(NumSlot, 0); // number of start lifetime ops for each slot // Step 1: collect markers and populate the "InterestingSlots" - // and "DegenerateSlots" sets. + // and "ConservativeSlots" sets. for (MachineBasicBlock *MBB : depth_first(MF)) { // Compute the set of slots for which we've seen a START marker but have @@ -518,10 +519,12 @@ if (Slot < 0) continue; InterestingSlots.set(Slot); - if (MI.getOpcode() == TargetOpcode::LIFETIME_START) + if (MI.getOpcode() == TargetOpcode::LIFETIME_START) { BetweenStartEnd.set(Slot); - else + NumStartLifetimes[Slot] += 1; + } else { BetweenStartEnd.reset(Slot); + } const AllocaInst *Allocation = MFI->getObjectAllocation(Slot); if (Allocation) { DEBUG(dbgs() << "Found a lifetime "); @@ -542,7 +545,7 @@ if (Slot < 0) continue; if (! BetweenStartEnd.test(Slot)) { - DegenerateSlots.set(Slot); + ConservativeSlots.set(Slot); } } } @@ -553,7 +556,13 @@ if (!MarkersFound) { return 0; } - DEBUG(dumpBV("Degenerate slots", DegenerateSlots)); + + // PR27903: slots with multiple start-lifetime ops are not safe + // to enable for "lifetime-start-on-first-use". + for (unsigned slot = 0; slot < NumSlot; ++slot) + if (NumStartLifetimes[slot] > 1) + ConservativeSlots.set(slot); + DEBUG(dumpBV("Conservative slots", ConservativeSlots)); // Step 2: compute begin/end sets for each block Index: test/CodeGen/X86/StackColoring.ll =================================================================== --- test/CodeGen/X86/StackColoring.ll +++ test/CodeGen/X86/StackColoring.ll @@ -1,5 +1,5 @@ -; RUN: llc -mcpu=corei7 -no-stack-coloring=false -stackcoloring-lifetime-start-on-first-use=true < %s | FileCheck %s --check-prefix=FIRSTUSE --check-prefix=CHECK ; RUN: llc -mcpu=corei7 -no-stack-coloring=false < %s | FileCheck %s --check-prefix=YESCOLOR --check-prefix=CHECK +; RUN: llc -mcpu=corei7 -no-stack-coloring=false -stackcoloring-lifetime-start-on-first-use=false < %s | FileCheck %s --check-prefix=NOFIRSTUSE --check-prefix=CHECK ; RUN: llc -mcpu=corei7 -no-stack-coloring=true < %s | FileCheck %s --check-prefix=NOCOLOR --check-prefix=CHECK target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -88,8 +88,8 @@ } ;CHECK-LABEL: myCall_w4: -;FIRSTUSE: subq $120, %rsp -;YESCOLOR: subq $200, %rsp +;YESCOLOR: subq $120, %rsp +;NOFIRSTUSE: subq $200, %rsp ;NOCOLOR: subq $408, %rsp define i32 @myCall_w4(i32 %in) { @@ -308,6 +308,9 @@ ;CHECK-LABEL: multi_region_bb: +;YESCOLOR: subq $272, %rsp +;NOCOLOR: subq $272, %rsp + define void @multi_region_bb() nounwind ssp { entry: %A.i1 = alloca [100 x i32], align 4 @@ -332,8 +335,6 @@ call void @llvm.lifetime.end(i64 -1, i8* %3) nounwind ret void } -;YESCOLOR: subq $272, %rsp -;NOCOLOR: subq $272, %rsp define i32 @myCall_end_before_begin(i32 %in, i1 %d) { entry: @@ -362,7 +363,7 @@ ; Regression test for PR15707. %buf1 and %buf2 should not be merged ; in this test case. ;CHECK-LABEL: myCall_pr15707: -;YESCOLOR: subq $200008, %rsp +;NOFIRSTUSE: subq $200008, %rsp ;NOCOLOR: subq $200008, %rsp define void @myCall_pr15707() { %buf1 = alloca i8, i32 100000, align 16 @@ -433,8 +434,8 @@ ; start. See llvm bug 25776. ;CHECK-LABEL: ifthen_twoslots: -;FIRSTUSE: subq $536, %rsp -;YESCOLOR: subq $1048, %rsp +;YESCOLOR: subq $536, %rsp +;NOFIRSTUSE: subq $1048, %rsp ;NOCOLOR: subq $1048, %rsp define i32 @ifthen_twoslots(i32 %x) #0 { @@ -489,8 +490,8 @@ ; markers only. ;CHECK-LABEL: while_loop: -;FIRSTUSE: subq $1032, %rsp -;YESCOLOR: subq $1544, %rsp +;YESCOLOR: subq $1032, %rsp +;NOFIRSTUSE: subq $1544, %rsp ;NOCOLOR: subq $1544, %rsp define i32 @while_loop(i32 %x) #0 { @@ -543,17 +544,12 @@ ; Test case motivated by PR27903. Same routine inlined multiple times ; into a caller results in a multi-segment lifetime, but the second -; lifetime has no explicit references to the stack slot. -; -; FIXME: the "FIRSTUSE" stack size (56) below represents buggy/incorrect -; behavior not currently exposed on trunk, due to the fact that -; the "stackcoloring-lifetime-start-on-first-use" now defaults to -; false. When a better fix for PR27903 is checked in, this result -; will change to 96. +; lifetime has no explicit references to the stack slot. Such slots +; have to be treated conservatively. ;CHECK-LABEL: twobod_b27903: -;FIRSTUSE: subq $56, %rsp ;YESCOLOR: subq $96, %rsp +;NOFIRSTUSE: subq $96, %rsp ;NOCOLOR: subq $96, %rsp define i32 @twobod_b27903(i32 %y, i32 %x) {