aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/LiveVariables.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/Analysis/LiveVariables.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
downloadsrc-b60736ec1405bb0a8dd40989f67ef4c93da068ab.tar.gz
src-b60736ec1405bb0a8dd40989f67ef4c93da068ab.zip
Vendor import of llvm-project main 8e464dd76bef, the last commit beforevendor/llvm-project/llvmorg-12-init-17869-g8e464dd76bef
the upstream release/12.x branch was created.
Diffstat (limited to 'clang/lib/Analysis/LiveVariables.cpp')
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp102
1 files changed, 52 insertions, 50 deletions
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
index d24c40b457b4..8cdc4cc5bd61 100644
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ b/clang/lib/Analysis/LiveVariables.cpp
@@ -27,7 +27,7 @@ namespace {
class LiveVariablesImpl {
public:
AnalysisDeclContext &analysisContext;
- llvm::ImmutableSet<const Stmt *>::Factory SSetFact;
+ llvm::ImmutableSet<const Expr *>::Factory ESetFact;
llvm::ImmutableSet<const VarDecl *>::Factory DSetFact;
llvm::ImmutableSet<const BindingDecl *>::Factory BSetFact;
llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness;
@@ -45,16 +45,15 @@ public:
LiveVariables::Observer *obs = nullptr);
void dumpBlockLiveness(const SourceManager& M);
- void dumpStmtLiveness(const SourceManager& M);
+ void dumpExprLiveness(const SourceManager& M);
LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign)
- : analysisContext(ac),
- SSetFact(false), // Do not canonicalize ImmutableSets by default.
- DSetFact(false), // This is a *major* performance win.
- BSetFact(false),
- killAtAssign(KillAtAssign) {}
+ : analysisContext(ac),
+ ESetFact(false), // Do not canonicalize ImmutableSets by default.
+ DSetFact(false), // This is a *major* performance win.
+ BSetFact(false), killAtAssign(KillAtAssign) {}
};
-}
+} // namespace
static LiveVariablesImpl &getImpl(void *x) {
return *((LiveVariablesImpl *) x);
@@ -64,8 +63,8 @@ static LiveVariablesImpl &getImpl(void *x) {
// Operations and queries on LivenessValues.
//===----------------------------------------------------------------------===//
-bool LiveVariables::LivenessValues::isLive(const Stmt *S) const {
- return liveStmts.contains(S);
+bool LiveVariables::LivenessValues::isLive(const Expr *E) const {
+ return liveExprs.contains(E);
}
bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const {
@@ -97,10 +96,10 @@ LiveVariables::LivenessValues
LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
LiveVariables::LivenessValues valsB) {
- llvm::ImmutableSetRef<const Stmt *>
- SSetRefA(valsA.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()),
- SSetRefB(valsB.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory());
-
+ llvm::ImmutableSetRef<const Expr *> SSetRefA(
+ valsA.liveExprs.getRootWithoutRetain(), ESetFact.getTreeFactory()),
+ SSetRefB(valsB.liveExprs.getRootWithoutRetain(),
+ ESetFact.getTreeFactory());
llvm::ImmutableSetRef<const VarDecl *>
DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()),
@@ -122,7 +121,7 @@ LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
}
bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const {
- return liveStmts == V.liveStmts && liveDecls == V.liveDecls;
+ return liveExprs == V.liveExprs && liveDecls == V.liveDecls;
}
//===----------------------------------------------------------------------===//
@@ -141,8 +140,8 @@ bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) {
return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D);
}
-bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) {
- return getImpl(impl).stmtsToLiveness[Loc].isLive(S);
+bool LiveVariables::isLive(const Stmt *Loc, const Expr *Val) {
+ return getImpl(impl).stmtsToLiveness[Loc].isLive(Val);
}
//===----------------------------------------------------------------------===//
@@ -186,27 +185,27 @@ static const VariableArrayType *FindVA(QualType Ty) {
return nullptr;
}
-static const Stmt *LookThroughStmt(const Stmt *S) {
- while (S) {
- if (const Expr *Ex = dyn_cast<Expr>(S))
- S = Ex->IgnoreParens();
- if (const FullExpr *FE = dyn_cast<FullExpr>(S)) {
- S = FE->getSubExpr();
+static const Expr *LookThroughExpr(const Expr *E) {
+ while (E) {
+ if (const Expr *Ex = dyn_cast<Expr>(E))
+ E = Ex->IgnoreParens();
+ if (const FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ E = FE->getSubExpr();
continue;
}
- if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) {
- S = OVE->getSourceExpr();
+ if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+ E = OVE->getSourceExpr();
continue;
}
break;
}
- return S;
+ return E;
}
-static void AddLiveStmt(llvm::ImmutableSet<const Stmt *> &Set,
- llvm::ImmutableSet<const Stmt *>::Factory &F,
- const Stmt *S) {
- Set = F.add(Set, LookThroughStmt(S));
+static void AddLiveExpr(llvm::ImmutableSet<const Expr *> &Set,
+ llvm::ImmutableSet<const Expr *>::Factory &F,
+ const Expr *E) {
+ Set = F.add(Set, LookThroughExpr(E));
}
void TransferFunctions::Visit(Stmt *S) {
@@ -215,8 +214,8 @@ void TransferFunctions::Visit(Stmt *S) {
StmtVisitor<TransferFunctions>::Visit(S);
- if (isa<Expr>(S)) {
- val.liveStmts = LV.SSetFact.remove(val.liveStmts, S);
+ if (const auto *E = dyn_cast<Expr>(S)) {
+ val.liveExprs = LV.ESetFact.remove(val.liveExprs, E);
}
// Mark all children expressions live.
@@ -233,7 +232,7 @@ void TransferFunctions::Visit(Stmt *S) {
// Include the implicit "this" pointer as being live.
CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S);
if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) {
- AddLiveStmt(val.liveStmts, LV.SSetFact, ImplicitObj);
+ AddLiveExpr(val.liveExprs, LV.ESetFact, ImplicitObj);
}
break;
}
@@ -250,7 +249,7 @@ void TransferFunctions::Visit(Stmt *S) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
for (const VariableArrayType* VA = FindVA(VD->getType());
VA != nullptr; VA = FindVA(VA->getElementType())) {
- AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr());
+ AddLiveExpr(val.liveExprs, LV.ESetFact, VA->getSizeExpr());
}
}
break;
@@ -263,7 +262,7 @@ void TransferFunctions::Visit(Stmt *S) {
if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child))
child = OV->getSourceExpr();
child = child->IgnoreParens();
- val.liveStmts = LV.SSetFact.add(val.liveStmts, child);
+ val.liveExprs = LV.ESetFact.add(val.liveExprs, child);
return;
}
@@ -284,36 +283,39 @@ void TransferFunctions::Visit(Stmt *S) {
// If one of the branches is an expression rather than a compound
// statement, it will be bad if we mark it as live at the terminator
// of the if-statement (i.e., immediately after the condition expression).
- AddLiveStmt(val.liveStmts, LV.SSetFact, cast<IfStmt>(S)->getCond());
+ AddLiveExpr(val.liveExprs, LV.ESetFact, cast<IfStmt>(S)->getCond());
return;
}
case Stmt::WhileStmtClass: {
// If the loop body is an expression rather than a compound statement,
// it will be bad if we mark it as live at the terminator of the loop
// (i.e., immediately after the condition expression).
- AddLiveStmt(val.liveStmts, LV.SSetFact, cast<WhileStmt>(S)->getCond());
+ AddLiveExpr(val.liveExprs, LV.ESetFact, cast<WhileStmt>(S)->getCond());
return;
}
case Stmt::DoStmtClass: {
// If the loop body is an expression rather than a compound statement,
// it will be bad if we mark it as live at the terminator of the loop
// (i.e., immediately after the condition expression).
- AddLiveStmt(val.liveStmts, LV.SSetFact, cast<DoStmt>(S)->getCond());
+ AddLiveExpr(val.liveExprs, LV.ESetFact, cast<DoStmt>(S)->getCond());
return;
}
case Stmt::ForStmtClass: {
// If the loop body is an expression rather than a compound statement,
// it will be bad if we mark it as live at the terminator of the loop
// (i.e., immediately after the condition expression).
- AddLiveStmt(val.liveStmts, LV.SSetFact, cast<ForStmt>(S)->getCond());
+ AddLiveExpr(val.liveExprs, LV.ESetFact, cast<ForStmt>(S)->getCond());
return;
}
}
+ // HACK + FIXME: What is this? One could only guess that this is an attempt to
+ // fish for live values, for example, arguments from a call expression.
+ // Maybe we could take inspiration from UninitializedVariable analysis?
for (Stmt *Child : S->children()) {
- if (Child)
- AddLiveStmt(val.liveStmts, LV.SSetFact, Child);
+ if (const auto *E = dyn_cast_or_null<Expr>(Child))
+ AddLiveExpr(val.liveExprs, LV.ESetFact, E);
}
}
@@ -416,7 +418,7 @@ VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE)
const Expr *subEx = UE->getArgumentExpr();
if (subEx->getType()->isVariableArrayType()) {
assert(subEx->isLValue());
- val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens());
+ val.liveExprs = LV.ESetFact.add(val.liveExprs, subEx->IgnoreParens());
}
}
@@ -613,19 +615,19 @@ void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) {
llvm::errs() << "\n";
}
-void LiveVariables::dumpStmtLiveness(const SourceManager &M) {
- getImpl(impl).dumpStmtLiveness(M);
+void LiveVariables::dumpExprLiveness(const SourceManager &M) {
+ getImpl(impl).dumpExprLiveness(M);
}
-void LiveVariablesImpl::dumpStmtLiveness(const SourceManager &M) {
+void LiveVariablesImpl::dumpExprLiveness(const SourceManager &M) {
// Don't iterate over blockEndsToLiveness directly because it's not sorted.
- for (auto I : *analysisContext.getCFG()) {
+ for (const CFGBlock *B : *analysisContext.getCFG()) {
- llvm::errs() << "\n[ B" << I->getBlockID()
- << " (live statements at block exit) ]\n";
- for (auto S : blocksEndToLiveness[I].liveStmts) {
+ llvm::errs() << "\n[ B" << B->getBlockID()
+ << " (live expressions at block exit) ]\n";
+ for (const Expr *E : blocksEndToLiveness[B].liveExprs) {
llvm::errs() << "\n";
- S->dump();
+ E->dump();
}
llvm::errs() << "\n";
}