aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h5
-rw-r--r--include/clang/Analysis/AnalysisContext.h4
-rw-r--r--lib/Analysis/AnalysisContext.cpp14
-rw-r--r--lib/Analysis/LiveVariables.cpp14
4 files changed, 28 insertions, 9 deletions
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 44ab080acb..237fe14aed 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -41,8 +41,9 @@ struct LiveVariables_ValueTypes {
ObserverTy* Observer;
ValTy AlwaysLive;
AnalysisContext *AC;
+ bool killAtAssign;
- AnalysisDataTy() : Observer(NULL), AC(NULL) {}
+ AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {}
};
//===-----------------------------------------------------===//
@@ -68,7 +69,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
public:
typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
- LiveVariables(AnalysisContext &AC);
+ LiveVariables(AnalysisContext &AC, bool killAtAssign = true);
/// IsLive - Return true if a variable is live at the end of a
/// specified block.
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 6091db4be9..7d4d25f8b0 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -49,6 +49,7 @@ class AnalysisContext {
CFG *cfg, *completeCFG;
bool builtCFG, builtCompleteCFG;
LiveVariables *liveness;
+ LiveVariables *relaxedLiveness;
ParentMap *PM;
PseudoConstantAnalysis *PCA;
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
@@ -61,7 +62,7 @@ public:
bool addehedges = false)
: D(d), TU(tu), cfg(0), completeCFG(0),
builtCFG(false), builtCompleteCFG(false),
- liveness(0), PM(0), PCA(0),
+ liveness(0), relaxedLiveness(0), PM(0), PCA(0),
ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
AddEHEdges(addehedges) {}
@@ -89,6 +90,7 @@ public:
ParentMap &getParentMap();
PseudoConstantAnalysis *getPseudoConstantAnalysis();
LiveVariables *getLiveVariables();
+ LiveVariables *getRelaxedLiveVariables();
typedef const VarDecl * const * referenced_decls_iterator;
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index 2c337f07c3..884cbc65f4 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -104,6 +104,20 @@ LiveVariables *AnalysisContext::getLiveVariables() {
return liveness;
}
+LiveVariables *AnalysisContext::getRelaxedLiveVariables() {
+ if (!relaxedLiveness) {
+ CFG *c = getCFG();
+ if (!c)
+ return 0;
+
+ relaxedLiveness = new LiveVariables(*this, false);
+ relaxedLiveness->runOnCFG(*c);
+ relaxedLiveness->runOnAllBlocks(*c, 0, true);
+ }
+
+ return relaxedLiveness;
+}
+
AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
idx::TranslationUnit *TU) {
AnalysisContext *&AC = Contexts[D];
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 3011fd0dee..47b2e3d604 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -77,12 +77,13 @@ public:
};
} // end anonymous namespace
-LiveVariables::LiveVariables(AnalysisContext &AC) {
+LiveVariables::LiveVariables(AnalysisContext &AC, bool killAtAssign) {
// Register all referenced VarDecls.
CFG &cfg = *AC.getCFG();
getAnalysisData().setCFG(cfg);
getAnalysisData().setContext(AC.getASTContext());
getAnalysisData().AC = &AC;
+ getAnalysisData().killAtAssign = killAtAssign;
RegisterDecls R(getAnalysisData());
cfg.VisitBlockStmts(R);
@@ -260,12 +261,13 @@ void TransferFuncs::VisitAssign(BinaryOperator* B) {
if (DR->getDecl()->getType()->isReferenceType()) {
VisitDeclRefExpr(DR);
} else {
- // Update liveness inforamtion.
- unsigned bit = AD.getIdx(DR->getDecl());
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+ if (AD.killAtAssign) {
+ // Update liveness inforamtion.
+ unsigned bit = AD.getIdx(DR->getDecl());
+ LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
+ if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+ }
// Handle things like +=, etc., which also generate "uses"
// of a variable. Do this just by visiting the subexpression.
if (B->getOpcode() != BO_Assign)