Home | History | Annotate | Download | only in Analyses
      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/AnalysisDeclContext.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