1 //===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements Live Variables analysis for source-level CFGs.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIVEVARIABLES_H
15 #define LLVM_CLANG_LIVEVARIABLES_H
17 #include "clang/AST/Decl.h"
18 #include "clang/Analysis/Support/BlkExprDeclBitVector.h"
19 #include "clang/Analysis/FlowSensitive/DataflowValues.h"
26 class AnalysisContext;
28 struct LiveVariables_ValueTypes {
32 // We keep dataflow state for declarations and block-level expressions;
33 typedef StmtDeclBitVector_Types::ValTy ValTy;
35 // We need to keep track of both declarations and CFGBlock-level expressions,
36 // (so that we don't explore such expressions twice). We also want
37 // to compute liveness information for block-level expressions, since these
38 // act as "temporary" values.
40 struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
46 AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {}
49 //===-----------------------------------------------------===//
50 // ObserverTy - Observer for uninitialized values queries.
51 //===-----------------------------------------------------===//
54 virtual ~ObserverTy() {}
56 /// ObserveStmt - A callback invoked right before invoking the
57 /// liveness transfer function on the given statement.
58 virtual void ObserveStmt(Stmt* S, const CFGBlock *currentBlock,
59 const AnalysisDataTy& AD,
62 virtual void ObserverKill(DeclRefExpr* DR) {}
66 class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
67 dataflow::backward_analysis_tag> {
71 typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
73 LiveVariables(AnalysisContext &AC, bool killAtAssign = true);
75 /// IsLive - Return true if a variable is live at the end of a
77 bool isLive(const CFGBlock* B, const VarDecl* D) const;
79 /// IsLive - Returns true if a variable is live at the beginning of the
80 /// the statement. This query only works if liveness information
81 /// has been recorded at the statement level (see runOnAllBlocks), and
82 /// only returns liveness information for block-level expressions.
83 bool isLive(const Stmt* S, const VarDecl* D) const;
85 /// IsLive - Returns true the block-level expression "value" is live
86 /// before the given block-level expression (see runOnAllBlocks).
87 bool isLive(const Stmt* Loc, const Stmt* StmtVal) const;
89 /// IsLive - Return true if a variable is live according to the
90 /// provided livness bitvector.
91 bool isLive(const ValTy& V, const VarDecl* D) const;
93 /// dumpLiveness - Print to stderr the liveness information encoded
94 /// by a specified bitvector.
95 void dumpLiveness(const ValTy& V, const SourceManager& M) const;
97 /// dumpBlockLiveness - Print to stderr the liveness information
98 /// associated with each basic block.
99 void dumpBlockLiveness(const SourceManager& M) const;
101 /// getNumDecls - Return the number of variables (declarations) that
102 /// whose liveness status is being tracked by the dataflow
104 unsigned getNumDecls() const { return getAnalysisData().getNumDecls(); }
106 /// IntializeValues - This routine can perform extra initialization, but
107 /// for LiveVariables this does nothing since all that logic is in
109 void InitializeValues(const CFG& cfg) {}
111 void runOnCFG(CFG& cfg);
113 /// runOnAllBlocks - Propagate the dataflow values once for each block,
114 /// starting from the current dataflow values. 'recordStmtValues' indicates
115 /// whether the method should store dataflow values per each individual
116 /// block-level expression.
117 void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
118 bool recordStmtValues=false);
121 } // end namespace clang