[llvm] 01f3e2d - [StackLifetime] More efficient loop for LivenessType::Must

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 28 16:29:01 PDT 2022


Author: Vitaly Buka
Date: 2022-09-28T16:28:45-07:00
New Revision: 01f3e2d6197829486622a440acca83786d52fc85

URL: https://github.com/llvm/llvm-project/commit/01f3e2d6197829486622a440acca83786d52fc85
DIFF: https://github.com/llvm/llvm-project/commit/01f3e2d6197829486622a440acca83786d52fc85.diff

LOG: [StackLifetime] More efficient loop for LivenessType::Must

CFG with cycles may requires additional passes of "while (Changed)"
iteration if to propagate data back from latter blocks to earlier blocks,
ordered according to depth_fist.

OR logic, used for ::May, converge to stable state faster then AND logic
use for ::Must.

Though the better solution is to switch to some some form of queue, but
having that this one is good enough, I will consider to do that later.

We can switch ::Must to OR logic if we calculate "may be dead" instead
of direct "must be alive" and then convert values to match existing
interface.

Additionally it fixes correctness in "@cycle" test.

Reviewed By: kstoimenov, fmayer

Differential Revision: https://reviews.llvm.org/D134796

Added: 
    

Modified: 
    llvm/lib/Analysis/StackLifetime.cpp
    llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index d6c3fc80e1793..72a1ac7b4eff5 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -174,32 +174,32 @@ void StackLifetime::collectMarkers() {
 
 void StackLifetime::calculateLocalLiveness() {
   bool Changed = true;
+
+  // LiveIn, LiveOut and BitsIn have a 
diff erent meaning deppends on type.
+  // ::Maybe true bits represent "may be alive" allocas, ::Must true bits
+  // represent "may be dead". After the loop we will convert ::Must bits from
+  // "may be dead" to "must be alive".
   while (Changed) {
+    // TODO: Consider switching to worklist instead of traversing entire graph.
     Changed = false;
 
     for (const BasicBlock *BB : depth_first(&F)) {
       BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
 
-      // Compute LiveIn by unioning together the LiveOut sets of all preds.
+      // Compute BitsIn by unioning together the LiveOut sets of all preds.
       BitVector BitsIn;
       for (const auto *PredBB : predecessors(BB)) {
         LivenessMap::const_iterator I = BlockLiveness.find(PredBB);
         // If a predecessor is unreachable, ignore it.
         if (I == BlockLiveness.end())
           continue;
-        switch (Type) {
-        case LivenessType::May:
-          BitsIn |= I->second.LiveOut;
-          break;
-        case LivenessType::Must:
-          if (BitsIn.empty())
-            BitsIn = I->second.LiveOut;
-          else
-            BitsIn &= I->second.LiveOut;
-          break;
-        }
+        BitsIn |= I->second.LiveOut;
       }
 
+      // Everything is "may be dead" for entry without predecessors.
+      if (Type == LivenessType::Must && BitsIn.empty())
+        BitsIn.resize(NumAllocas, true);
+
       // Update block LiveIn set, noting whether it has changed.
       if (BitsIn.test(BlockInfo.LiveIn)) {
         BlockInfo.LiveIn |= BitsIn;
@@ -212,8 +212,18 @@ void StackLifetime::calculateLocalLiveness() {
       // because we already handle the case where the BEGIN comes
       // before the END when collecting the markers (and building the
       // BEGIN/END vectors).
-      BitsIn.reset(BlockInfo.End);
-      BitsIn |= BlockInfo.Begin;
+      switch (Type) {
+      case LivenessType::May:
+        BitsIn.reset(BlockInfo.End);
+        // "may be alive" is set by lifetime start.
+        BitsIn |= BlockInfo.Begin;
+        break;
+      case LivenessType::Must:
+        BitsIn.reset(BlockInfo.Begin);
+        // "may be dead" is set by lifetime end.
+        BitsIn |= BlockInfo.End;
+        break;
+      }
 
       // Update block LiveOut set, noting whether it has changed.
       if (BitsIn.test(BlockInfo.LiveOut)) {
@@ -222,6 +232,14 @@ void StackLifetime::calculateLocalLiveness() {
       }
     }
   } // while changed.
+
+  if (Type == LivenessType::Must) {
+    // Convert from "may be dead" to "must be alive".
+    for (auto &[BB, BlockInfo] : BlockLiveness) {
+      BlockInfo.LiveIn.flip();
+      BlockInfo.LiveOut.flip();
+    }
+  }
 }
 
 void StackLifetime::calculateLiveIntervals() {

diff  --git a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
index ed257753cad34..6d5789b91f90e 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/lifetime.ll
@@ -1070,22 +1070,19 @@ entry:
 if.then:
 ; CHECK: if.then:
 ; MAY-NEXT: Alive: <x y>
-; MUST-NEXT: Alive: <>
+; MUST-NEXT: Alive: <x>
   call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
 ; CHECK: call void @llvm.lifetime.start.p0i8(i64 1, i8* %y)
-; MAY-NEXT: Alive: <x y>
-; MUST-NEXT: Alive: <y>
-; FIXME: Alive: <x y> is expected above.
+; CHECK-NEXT: Alive: <x y>
 
   br i1 %a, label %if.then, label %if.end
 ; CHECK: br i1 %a, label %if.then, label %if.end
-; MAY-NEXT: Alive: <x y>
-; MUST-NEXT: Alive: <y>
+; CHECK-NEXT: Alive: <x y>
 
 if.end:
 ; CHECK: if.end:
 ; MAY-NEXT: Alive: <x y>
-; MUST-NEXT: Alive: <>
+; MUST-NEXT: Alive: <x>
 
   ret void
 }


        


More information about the llvm-commits mailing list