[llvm] f224f3d - [StackSafety] Add StackLifetime::isAliveAfter

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 19 02:32:35 PDT 2020


Author: Vitaly Buka
Date: 2020-06-19T02:32:17-07:00
New Revision: f224f3d0f2b8a66ee13a26b7075e1b93bcb97dc0

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

LOG: [StackSafety] Add StackLifetime::isAliveAfter

This function is going to be added into StackSafety checks.
This patch uses function in ::print implementation to make sure
that it works as expected.

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/StackLifetime.h
    llvm/lib/Analysis/StackLifetime.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/StackLifetime.h b/llvm/include/llvm/Analysis/StackLifetime.h
index ad0e3d69cedb..cead60020b19 100644
--- a/llvm/include/llvm/Analysis/StackLifetime.h
+++ b/llvm/include/llvm/Analysis/StackLifetime.h
@@ -150,13 +150,19 @@ class StackLifetime {
   /// that is large enough for LiveRange::Overlaps to be correct.
   const LiveRange &getLiveRange(const AllocaInst *AI) const;
 
+  /// Returns true if instruction is reachable from entry.
+  bool isReachable(const Instruction *I) const;
+
+  /// Returns true if the alloca is alive after the instruction.
+  bool isAliveAfter(const AllocaInst *AI, const Instruction *I) const;
+
   /// Returns a live range that represents an alloca that is live throughout the
   /// entire function.
   LiveRange getFullLiveRange() const {
     return LiveRange(Instructions.size(), true);
   }
 
-  void print(raw_ostream &O, bool AllInstructions = false);
+  void print(raw_ostream &O);
 };
 
 static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) {

diff  --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index d3358219e9f4..9c8347f9837f 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -42,6 +42,27 @@ StackLifetime::getLiveRange(const AllocaInst *AI) const {
   return LiveRanges[IT->second];
 }
 
+bool StackLifetime::isReachable(const Instruction *I) const {
+  return BlockInstRange.find(I->getParent()) != BlockInstRange.end();
+}
+
+bool StackLifetime::isAliveAfter(const AllocaInst *AI,
+                                 const Instruction *I) const {
+  const BasicBlock *BB = I->getParent();
+  auto ItBB = BlockInstRange.find(BB);
+  assert(ItBB != BlockInstRange.end() && "Unreachable is not expected");
+
+  // Find the first instruction after the V.
+  auto It = std::upper_bound(Instructions.begin() + ItBB->getSecond().first + 1,
+                             Instructions.begin() + ItBB->getSecond().second, I,
+                             [](const Instruction *L, const Instruction *R) {
+                               return L->comesBefore(R);
+                             });
+  --It;
+  unsigned InstNum = It - Instructions.begin();
+  return getLiveRange(AI).test(InstNum);
+}
+
 static bool readMarker(const Instruction *I, bool *IsStart) {
   if (!I->isLifetimeStartOrEnd())
     return false;
@@ -298,7 +319,6 @@ void StackLifetime::run() {
 class StackLifetime::LifetimeAnnotationWriter
     : public AssemblyAnnotationWriter {
   const StackLifetime &SL;
-  bool AllInstructions;
 
   void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) {
     SmallVector<StringRef, 16> Names;
@@ -320,32 +340,24 @@ class StackLifetime::LifetimeAnnotationWriter
 
   void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
     const Instruction *Instr = dyn_cast<Instruction>(&V);
-    if (!Instr)
-      return;
-    auto ItBB = SL.BlockInstRange.find(Instr->getParent());
-    if (ItBB == SL.BlockInstRange.end())
-      return; // Unreachable.
-    // Find the first instruction after the V.
-    auto It =
-        std::upper_bound(SL.Instructions.begin() + ItBB->getSecond().first + 1,
-                         SL.Instructions.begin() + ItBB->getSecond().second,
-                         Instr, [](const Instruction *L, const Instruction *R) {
-                           return L->comesBefore(R);
-                         });
-    --It;
-    if (!AllInstructions && *It != Instr)
+    if (!Instr || !SL.isReachable(Instr))
       return;
-    OS << "\n";
-    printInstrAlive(It - SL.Instructions.begin(), OS);
+
+    SmallVector<StringRef, 16> Names;
+    for (const auto &KV : SL.AllocaNumbering) {
+      if (SL.isAliveAfter(KV.getFirst(), Instr))
+        Names.push_back(KV.getFirst()->getName());
+    }
+    llvm::sort(Names);
+    OS << "\n  ; Alive: <" << llvm::join(Names, " ") << ">\n";
   }
 
 public:
-  LifetimeAnnotationWriter(const StackLifetime &SL, bool AllInstructions)
-      : SL(SL), AllInstructions(AllInstructions) {}
+  LifetimeAnnotationWriter(const StackLifetime &SL) : SL(SL) {}
 };
 
-void StackLifetime::print(raw_ostream &OS, bool AllInstructions) {
-  LifetimeAnnotationWriter AAW(*this, AllInstructions);
+void StackLifetime::print(raw_ostream &OS) {
+  LifetimeAnnotationWriter AAW(*this);
   F.print(OS, &AAW);
 }
 
@@ -357,6 +369,6 @@ PreservedAnalyses StackLifetimePrinterPass::run(Function &F,
       Allocas.push_back(AI);
   StackLifetime SL(F, Allocas, Type);
   SL.run();
-  SL.print(OS, true);
+  SL.print(OS);
   return PreservedAnalyses::all();
 }


        


More information about the llvm-commits mailing list