1 //===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements Live Variables analysis for source-level CFGs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H 15 #define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H 16 17 #include "clang/AST/Decl.h" 18 #include "clang/Analysis/AnalysisContext.h" 19 #include "llvm/ADT/ImmutableSet.h" 20 21 namespace clang { 22 23 class CFG; 24 class CFGBlock; 25 class Stmt; 26 class DeclRefExpr; 27 class SourceManager; 28 29 class LiveVariables : public ManagedAnalysis { 30 public: 31 class LivenessValues { 32 public: 33 34 llvm::ImmutableSet<const Stmt *> liveStmts; 35 llvm::ImmutableSet<const VarDecl *> liveDecls; 36 37 bool equals(const LivenessValues &V) const; 38 39 LivenessValues() 40 : liveStmts(nullptr), liveDecls(nullptr) {} 41 42 LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts, 43 llvm::ImmutableSet<const VarDecl *> LiveDecls) 44 : liveStmts(LiveStmts), liveDecls(LiveDecls) {} 45 46 bool isLive(const Stmt *S) const; 47 bool isLive(const VarDecl *D) const; 48 49 friend class LiveVariables; 50 }; 51 52 class Observer { 53 virtual void anchor(); 54 public: 55 virtual ~Observer() {} 56 57 /// A callback invoked right before invoking the 58 /// liveness transfer function on the given statement. 59 virtual void observeStmt(const Stmt *S, 60 const CFGBlock *currentBlock, 61 const LivenessValues& V) {} 62 63 /// Called when the live variables analysis registers 64 /// that a variable is killed. 65 virtual void observerKill(const DeclRefExpr *DR) {} 66 }; 67 68 ~LiveVariables() override; 69 70 /// Compute the liveness information for a given CFG. 71 static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext, 72 bool killAtAssign); 73 74 /// Return true if a variable is live at the end of a 75 /// specified block. 76 bool isLive(const CFGBlock *B, const VarDecl *D); 77 78 /// Returns true if a variable is live at the beginning of the 79 /// the statement. This query only works if liveness information 80 /// has been recorded at the statement level (see runOnAllBlocks), and 81 /// only returns liveness information for block-level expressions. 82 bool isLive(const Stmt *S, const VarDecl *D); 83 84 /// Returns true the block-level expression "value" is live 85 /// before the given block-level expression (see runOnAllBlocks). 86 bool isLive(const Stmt *Loc, const Stmt *StmtVal); 87 88 /// Print to stderr the liveness information associated with 89 /// each basic block. 90 void dumpBlockLiveness(const SourceManager& M); 91 92 void runOnAllBlocks(Observer &obs); 93 94 static LiveVariables *create(AnalysisDeclContext &analysisContext) { 95 return computeLiveness(analysisContext, true); 96 } 97 98 static const void *getTag(); 99 100 private: 101 LiveVariables(void *impl); 102 void *impl; 103 }; 104 105 class RelaxedLiveVariables : public LiveVariables { 106 public: 107 static LiveVariables *create(AnalysisDeclContext &analysisContext) { 108 return computeLiveness(analysisContext, false); 109 } 110 111 static const void *getTag(); 112 }; 113 114 } // end namespace clang 115 116 #endif 117