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