15#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_DATAFLOW_H
16#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_DATAFLOW_H
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/TimeProfiler.h"
56template <
typename Derived,
typename LatticeType, Direction Dir>
67 llvm::DenseMap<const CFGBlock *, Lattice> InStates;
69 llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
86 Derived &D =
static_cast<Derived &
>(*this);
87 llvm::TimeTraceScope Time(D.getAnalysisName());
89 PointToState.resize(
FactMgr.getNumFacts());
96 const CFGBlock *Start = isForward() ? &Cfg.getEntry() : &Cfg.getExit();
97 InStates[Start] = D.getInitialState();
98 W.enqueueBlock(Start);
100 while (
const CFGBlock *B = W.dequeue()) {
102 Lattice StateOut = transferBlock(B, StateIn);
103 OutStates[B] = StateOut;
104 for (
const CFGBlock *AdjacentB : isForward() ? B->
succs() : B->preds()) {
107 std::optional<Lattice> OldInState =
getInState(AdjacentB);
109 !OldInState ? StateOut : D.join(*OldInState, StateOut);
112 if (!OldInState || NewInState != *OldInState) {
113 InStates[AdjacentB] = NewInState;
114 W.enqueueBlock(AdjacentB);
126 auto It = InStates.find(B);
127 if (It == InStates.end())
135 const Derived *D =
static_cast<const Derived *
>(
this);
136 llvm::dbgs() <<
"==========================================\n";
137 llvm::dbgs() << D->getAnalysisName() <<
" results:\n";
138 llvm::dbgs() <<
"==========================================\n";
139 const CFGBlock &B = isForward() ? Cfg.getExit() : Cfg.getEntry();
146 Lattice transferBlock(
const CFGBlock *
Block, Lattice State) {
148 if constexpr (isForward()) {
149 for (
const Fact *F : Facts) {
150 State = transferFact(State, F);
151 PointToState[F->getID().Value] = State;
154 for (
const Fact *F : llvm::reverse(Facts)) {
156 PointToState[F->getID().Value] = State;
157 State = transferFact(State, F);
165 Derived *D =
static_cast<Derived *
>(
this);
166 switch (F->getKind()) {
168 return D->transfer(In, *F->getAs<IssueFact>());
170 return D->transfer(In, *F->getAs<ExpireFact>());
172 return D->transfer(In, *F->getAs<OriginFlowFact>());
174 return D->transfer(In, *F->getAs<OriginEscapesFact>());
176 return D->transfer(In, *F->getAs<UseFact>());
178 return D->transfer(In, *F->getAs<TestPointFact>());
180 llvm_unreachable(
"Unknown fact kind");
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a single basic block in a source-level CFG.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
DataflowAnalysis(const CFG &Cfg, AnalysisDeclContext &AC, FactManager &FactMgr)
std::optional< Lattice > getInState(const CFGBlock *B) const
Lattice transfer(Lattice In, const OriginFlowFact &)
Lattice transfer(Lattice In, const TestPointFact &)
Lattice getOutState(const CFGBlock *B) const
Lattice transfer(Lattice In, const UseFact &)
Lattice transfer(Lattice In, const IssueFact &)
Lattice transfer(Lattice In, const OriginEscapesFact &)
Lattice transfer(Lattice In, const ExpireFact &)
DataflowAnalysis< Derived, Lattice, Dir > Base
Lattice getState(ProgramPoint P) const
llvm::ArrayRef< const Fact * > getFacts(const CFGBlock *B) const
An abstract base class for a single, atomic lifetime-relevant event.
@ TestPoint
A marker for a specific point in the code, for testing.
@ Expire
A loan expires as its underlying storage is freed (e.g., variable goes out of scope).
@ Issue
A new loan is issued from a borrow expression (e.g., &x).
@ OriginFlow
An origin is propagated from a source to a destination (e.g., p = q).
@ Use
An origin is used (eg. appears as l-value expression like DeclRefExpr).
@ OriginEscapes
An origin that escapes the function scope (e.g., via return).
A dummy-fact used to mark a specific point in the code for testing.
const Fact * ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
A worklist implementation for backward dataflow analysis.
A worklist implementation for forward dataflow analysis.