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