12#include "llvm/Support/ErrorHandling.h"
23 Lattice() : LiveOrigins(
nullptr) {};
28 return LiveOrigins ==
Other.LiveOrigins;
33 void dump(llvm::raw_ostream &OS,
const OriginManager &OM)
const {
34 if (LiveOrigins.isEmpty())
36 for (
const auto &Entry : LiveOrigins) {
38 const LivenessInfo &Info = Entry.second;
50 llvm_unreachable(
"liveness kind of live origins should not be dead.");
52 OS <<
" live at this point\n";
58 if (
const auto *UF = F.dyn_cast<
const UseFact *>())
59 return UF->getUseExpr()->getExprLoc();
61 if (
auto *ReturnEsc = dyn_cast<ReturnEscapeFact>(OEF))
62 return ReturnEsc->getReturnExpr()->getExprLoc();
63 if (
auto *FieldEsc = dyn_cast<FieldEscapeFact>(OEF))
64 return FieldEsc->getFieldDecl()->getLocation();
65 if (
auto *GlobalEsc = dyn_cast<GlobalEscapeFact>(OEF))
66 return GlobalEsc->getGlobal()->getLocation();
68 llvm_unreachable(
"unhandled causing fact in PointerUnion");
78 AnalysisImpl(
const CFG &
C, AnalysisDeclContext &AC, FactManager &F,
79 LivenessMap::Factory &SF)
80 : DataflowAnalysis(
C, AC, F), FactMgr(F), Factory(SF) {}
83 StringRef getAnalysisName()
const {
return "LiveOrigins"; }
85 Lattice getInitialState() {
return Lattice(Factory.getEmptyMap()); }
90 Lattice join(Lattice L1, Lattice L2)
const {
99 return GetFactLoc(A) < GetFactLoc(B) ? A : B;
110 auto CombineLivenessInfo = [&](
const LivenessInfo *L1,
111 const LivenessInfo *L2) -> LivenessInfo {
112 assert((L1 || L2) &&
"unexpectedly merging 2 empty sets");
117 return LivenessInfo(CombineCausingFact(L1->CausingFact, L2->CausingFact),
118 CombineLivenessKind(L1->Kind, L2->Kind));
121 L1.LiveOrigins, L2.LiveOrigins, Factory, CombineLivenessInfo,
130 Lattice
transfer(Lattice In,
const UseFact &UF) {
132 for (
const OriginList *Cur = UF.getUsedOrigins(); Cur;
133 Cur = Cur->peelOuterOrigin()) {
134 OriginID OID = Cur->getOuterOriginID();
136 if (UF.isWritten()) {
137 Out = Lattice(Factory.remove(
Out.LiveOrigins, OID));
141 Out = Lattice(Factory.add(
Out.LiveOrigins, OID,
150 Lattice
transfer(Lattice In,
const OriginEscapesFact &OEF) {
151 OriginID OID = OEF.getEscapedOriginID();
152 return Lattice(Factory.add(
In.LiveOrigins, OID,
157 Lattice
transfer(Lattice In,
const IssueFact &IF) {
158 return Lattice(Factory.remove(
In.LiveOrigins, IF.getOriginID()));
163 Lattice
transfer(Lattice In,
const OriginFlowFact &OF) {
164 if (!OF.getKillDest())
166 return Lattice(Factory.remove(
In.LiveOrigins, OF.getDestOriginID()));
169 Lattice
transfer(Lattice In,
const ExpireFact &F) {
170 if (
auto OID = F.getOriginID())
171 return Lattice(Factory.remove(
In.LiveOrigins, *OID));
176 return getState(P).LiveOrigins;
180 void dump(llvm::raw_ostream &OS,
181 const llvm::StringMap<ProgramPoint> &TestPoints)
const {
182 llvm::dbgs() <<
"==========================================\n";
183 llvm::dbgs() << getAnalysisName() <<
" results:\n";
184 llvm::dbgs() <<
"==========================================\n";
185 for (
const auto &Entry : TestPoints) {
186 OS <<
"TestPoint: " << Entry.getKey() <<
"\n";
187 getState(Entry.getValue()).dump(OS, FactMgr.getOriginMgr());
192 FactManager &FactMgr;
193 LivenessMap::Factory &Factory;
199 using AnalysisImpl::AnalysisImpl;
204 LivenessMap::Factory &SF)
205 : PImpl(
std::make_unique<
Impl>(
C, AC, F, SF)) {
212 return PImpl->getLiveOriginsAt(P);
216 llvm::raw_ostream &OS,
217 const llvm::StringMap<ProgramPoint> &TestPoints)
const {
218 PImpl->dump(OS, TestPoints);
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
A generic, policy-based driver for dataflow analyses.
LiveOriginsAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F, LivenessMap::Factory &SF)
void dump(llvm::raw_ostream &OS, const llvm::StringMap< ProgramPoint > &TestPoints) const
LivenessMap getLiveOriginsAt(ProgramPoint P) const
Returns the set of origins that are live at a specific program point, along with the the details of t...
Represents that an origin escapes the current scope through various means.
void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, Environment::ValueModel &Model)
Evaluates S and updates Env accordingly.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ Symmetric
A symmetric join applies the JoinValues operation to keys unique to either map, ensuring that values ...
static llvm::ImmutableSet< T > join(llvm::ImmutableSet< T > A, llvm::ImmutableSet< T > B, typename llvm::ImmutableSet< T >::Factory &F)
Computes the union of two ImmutableSets.
const Fact * ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
utils::ID< struct OriginTag > OriginID
::llvm::PointerUnion< const UseFact *, const OriginEscapesFact * > CausingFactType
llvm::ImmutableMap< OriginID, LivenessInfo > LivenessMap
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator!=(CanQual< T > x, CanQual< U > y)
@ Other
Other implicit parameter.