summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2007-09-10 17:36:42 +0000
committerTed Kremenek <kremenek@apple.com>2007-09-10 17:36:42 +0000
commitbd9cc5ca890d6d18eaaca1b78a0465b668e9a7dd (patch)
tree343dc5c78284495b1a3f2565cd4a60b24cc73363
parent5f64ca8ec59dcd0320bc56481562fdb8f0363b7a (diff)
downloadbcm5719-llvm-bd9cc5ca890d6d18eaaca1b78a0465b668e9a7dd.tar.gz
bcm5719-llvm-bd9cc5ca890d6d18eaaca1b78a0465b668e9a7dd.zip
Fixed LiveVariables to no longer track the liveness of function pointers
that refer to direct function calls. Modified interface of LiveVariables to only track liveness of VarDecls. This cleans up a bunch of edge cases, and removed the bug just mentioned. llvm-svn: 41797
-rw-r--r--clang/Analysis/DeadStores.cpp23
-rw-r--r--clang/Analysis/LiveVariables.cpp74
-rw-r--r--clang/Driver/ASTStreamers.cpp3
-rw-r--r--clang/include/clang/Analysis/LiveVariables.h24
4 files changed, 87 insertions, 37 deletions
diff --git a/clang/Analysis/DeadStores.cpp b/clang/Analysis/DeadStores.cpp
index 4073eccf60b..e0922eede94 100644
--- a/clang/Analysis/DeadStores.cpp
+++ b/clang/Analysis/DeadStores.cpp
@@ -36,29 +36,28 @@ public:
return;
// Is this an assignment to a variable?
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS())) {
+ if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS()))
// Is the variable live?
- if (!L.isLive(Live,DR->getDecl())) {
+ if (!L.isLive(Live,cast<VarDecl>(DR->getDecl()))) {
SourceRange R = B->getRHS()->getSourceRange();
PP.getDiagnostics().Report(DR->getSourceRange().Begin(),
diag::warn_dead_store, 0, 0,
&R,1);
}
- }
}
else if(DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
// Iterate through the decls. Warn if any of them (which have
// initializers) are not live.
- for (Decl* D = DS->getDecl() ; D != NULL ; D = D->getNextDeclarator())
- if (VarDecl* V = dyn_cast<VarDecl>(D))
- if (Expr* E = V->getInit())
- if (!L.isLive(Live,D)) {
- SourceRange R = E->getSourceRange();
- PP.getDiagnostics().Report(D->getLocation(),
- diag::warn_dead_store, 0, 0,
- &R,1);
- }
+ for (VarDecl* V = cast<VarDecl>(DS->getDecl()); V != NULL ;
+ V = cast<VarDecl>(V->getNextDeclarator()))
+ if (Expr* E = V->getInit())
+ if (!L.isLive(Live,V)) {
+ SourceRange R = E->getSourceRange();
+ PP.getDiagnostics().Report(V->getLocation(),
+ diag::warn_dead_store, 0, 0,
+ &R,1);
+ }
}
}
};
diff --git a/clang/Analysis/LiveVariables.cpp b/clang/Analysis/LiveVariables.cpp
index 1d06c26af84..4324b3ec567 100644
--- a/clang/Analysis/LiveVariables.cpp
+++ b/clang/Analysis/LiveVariables.cpp
@@ -65,10 +65,12 @@ void RegisterDecls::RegisterDeclChain(Decl* D) {
}
void RegisterDecls::Register(Decl* D) {
- LiveVariables::VPair& VP = L.getVarInfoMap()[const_cast<const Decl*>(D)];
+ if (VarDecl* V = dyn_cast<VarDecl>(D)) {
+ LiveVariables::VPair& VP = L.getVarInfoMap()[V];
- VP.V.AliveBlocks.reserve(cfg.getNumBlockIDs());
- VP.Idx = L.getNumDecls()++;
+ VP.V.AliveBlocks.resize(cfg.getNumBlockIDs());
+ VP.Idx = L.getNumDecls()++;
+ }
}
void RegisterDecls::RegisterUsedDecls() {
@@ -135,7 +137,7 @@ public:
void VisitDeclStmt(DeclStmt* DS);
void VisitUnaryOperator(UnaryOperator* U);
- unsigned getIdx(const Decl* D) {
+ unsigned getIdx(const VarDecl* D) {
LiveVariables::VarInfoMap& V = L.getVarInfoMap();
LiveVariables::VarInfoMap::iterator I = V.find(D);
assert (I != V.end());
@@ -144,7 +146,7 @@ public:
bool ProcessBlock(const CFGBlock* B);
llvm::BitVector* getBlockEntryLiveness(const CFGBlock* B);
- LiveVariables::VarInfo& KillVar(Decl* D);
+ LiveVariables::VarInfo& KillVar(VarDecl* D);
};
void LivenessTFuncs::VisitStmt(Stmt* S) {
@@ -163,7 +165,8 @@ void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
Observer->ObserveStmt(DR,L,Live);
// Register a use of the variable.
- Live.set(getIdx(DR->getDecl()));
+ if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
+ Live.set(getIdx(V));
}
void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) {
@@ -205,7 +208,8 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) {
}
else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
// Treat the --/++/& operator as a kill.
- LiveVariables::VarInfo& V = KillVar(DR->getDecl());
+ LiveVariables::VarInfo& V =
+ KillVar(cast<VarDecl>(DR->getDecl()));
if (!blockPreviouslyProcessed)
V.AddKill(CurrentStmt,DR);
@@ -225,7 +229,7 @@ void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) {
}
}
-LiveVariables::VarInfo& LivenessTFuncs::KillVar(Decl* D) {
+LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) {
LiveVariables::VarInfoMap::iterator I = L.getVarInfoMap().find(D);
assert (I != L.getVarInfoMap().end() &&
@@ -247,7 +251,7 @@ void LivenessTFuncs::VisitAssign(BinaryOperator* B) {
Stmt* LHS = B->getLHS();
if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
- LiveVariables::VarInfo& V = KillVar(DR->getDecl());
+ LiveVariables::VarInfo& V = KillVar(cast<VarDecl>(DR->getDecl()));
// We only need to register kills once, so we check if this block
// has been previously processed.
@@ -272,7 +276,7 @@ void LivenessTFuncs::VisitDeclStmt(DeclStmt* DS) {
// in the sense that the value is obliterated, so we do not register
// DeclStmts as a "kill site" for a variable.
for (Decl* D = DS->getDecl(); D != NULL ; D = D->getNextDeclarator())
- KillVar(D);
+ KillVar(cast<VarDecl>(D));
}
llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) {
@@ -385,7 +389,7 @@ void LiveVariables::runOnBlock(const CFGBlock* B,
// liveness queries
//
-bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const {
+bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B);
assert (I != LiveAtBlockEntryMap.end());
@@ -395,13 +399,13 @@ bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const {
return I->second[VI->second.Idx];
}
-bool LiveVariables::isLive(llvm::BitVector& Live, const Decl* D) const {
+bool LiveVariables::isLive(llvm::BitVector& Live, const VarDecl* D) const {
VarInfoMap::const_iterator VI = VarInfos.find(D);
assert (VI != VarInfos.end());
return Live[VI->second.Idx];
}
-bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const {
+bool LiveVariables::KillsVar(const Stmt* S, const VarDecl* D) const {
VarInfoMap::const_iterator VI = VarInfos.find(D);
assert (VI != VarInfos.end());
@@ -413,13 +417,13 @@ bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const {
return false;
}
-LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) {
+LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) {
VarInfoMap::iterator VI = VarInfos.find(D);
assert (VI != VarInfos.end());
return VI->second.V;
}
-const LiveVariables::VarInfo& LiveVariables::getVarInfo(const Decl* D) const {
+const LiveVariables::VarInfo& LiveVariables::getVarInfo(const VarDecl* D) const{
return const_cast<LiveVariables*>(this)->getVarInfo(D);
}
@@ -465,4 +469,44 @@ void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
dumpLiveness(I->second,M);
}
+
+ fprintf(stderr,"\n");
+}
+
+void LiveVariables::dumpVarLiveness(SourceManager& SM) const {
+
+ for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
+ SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
+
+ fprintf(stderr, "[ %s <%s:%u:%u> ]\n",
+ I->first->getIdentifier()->getName(),
+ SM.getSourceName(PhysLoc),
+ SM.getLineNumber(PhysLoc),
+ SM.getColumnNumber(PhysLoc));
+
+ I->second.V.Dump(SM);
+ }
+}
+
+void LiveVariables::VarInfo::Dump(SourceManager& SM) const {
+ fprintf(stderr," Blocks Alive:");
+ for (unsigned i = 0; i < AliveBlocks.size(); ++i) {
+ if (i % 5 == 0)
+ fprintf(stderr,"\n ");
+
+ fprintf(stderr," B%d", i);
+ }
+
+ fprintf(stderr,"\n Kill Sites:\n");
+ for (KillsSet::const_iterator I = Kills.begin(), E = Kills.end(); I!=E; ++I) {
+ SourceLocation PhysLoc =
+ SM.getPhysicalLoc(I->second->getSourceRange().Begin());
+
+ fprintf(stderr, " <%s:%u:%u>\n",
+ SM.getSourceName(PhysLoc),
+ SM.getLineNumber(PhysLoc),
+ SM.getColumnNumber(PhysLoc));
+ }
+
+ fprintf(stderr,"\n");
} \ No newline at end of file
diff --git a/clang/Driver/ASTStreamers.cpp b/clang/Driver/ASTStreamers.cpp
index 59be1b36e7a..d4c55ad681a 100644
--- a/clang/Driver/ASTStreamers.cpp
+++ b/clang/Driver/ASTStreamers.cpp
@@ -240,7 +240,8 @@ namespace {
virtual void VisitCFG(CFG& C) {
LiveVariables L;
L.runOnCFG(C);
- L.dumpBlockLiveness(PP.getSourceManager());
+ L.dumpBlockLiveness(PP.getSourceManager());
+ L.dumpVarLiveness(PP.getSourceManager());
}
};
} // end anonymous namespace
diff --git a/clang/include/clang/Analysis/LiveVariables.h b/clang/include/clang/Analysis/LiveVariables.h
index 18b6b18683a..7d1d0210a06 100644
--- a/clang/include/clang/Analysis/LiveVariables.h
+++ b/clang/include/clang/Analysis/LiveVariables.h
@@ -22,7 +22,7 @@ namespace clang {
class Stmt;
class DeclRefExpr;
- class Decl;
+ class VarDecl;
class CFG;
class CFGBlock;
class SourceManager;
@@ -45,7 +45,7 @@ public:
/// then V contains the liveness information after the execution of
/// the given block.
virtual void ObserveBlockExit(const CFGBlock* B, LiveVariables& L,
- llvm::BitVector& V);
+ llvm::BitVector& V);
};
class LiveVariables {
@@ -70,7 +70,10 @@ public:
void AddKill(Stmt* S, DeclRefExpr* DR) {
Kills.push_back(std::make_pair(const_cast<const Stmt*>(S),
const_cast<const DeclRefExpr*>(DR)));
- }
+ }
+
+ // Dump - prints VarInfo data to stderr.
+ void Dump(SourceManager& M) const;
};
struct VPair {
@@ -78,7 +81,7 @@ public:
unsigned Idx;
};
- typedef llvm::DenseMap<const Decl*, VPair > VarInfoMap;
+ typedef llvm::DenseMap<const VarDecl*, VPair > VarInfoMap;
typedef llvm::DenseMap<const CFGBlock*, llvm::BitVector > BlockLivenessMap;
public:
@@ -96,22 +99,22 @@ public:
/// KillsVar - Return true if the specified statement kills the
/// specified variable.
- bool KillsVar(const Stmt* S, const Decl* D) const;
+ bool KillsVar(const Stmt* S, const VarDecl* D) const;
/// IsLive - Return true if a variable is live at beginning of a specified
// block.
- bool isLive(const CFGBlock* B, const Decl* D) const;
+ bool isLive(const CFGBlock* B, const VarDecl* D) const;
/// IsLive - Return true if a variable is live according to the provided
/// livness bitvector. This is typically used by classes that subclass
/// LiveVariablesObserver.
- bool isLive(llvm::BitVector& V, const Decl* D) const;
+ bool isLive(llvm::BitVector& V, const VarDecl* D) const;
/// getVarInfo - Return the liveness information associated with a given
/// variable.
- VarInfo& getVarInfo(const Decl* D);
+ VarInfo& getVarInfo(const VarDecl* D);
- const VarInfo& getVarInfo(const Decl* D) const;
+ const VarInfo& getVarInfo(const VarDecl* D) const;
/// getVarInfoMap
VarInfoMap& getVarInfoMap() { return VarInfos; }
@@ -124,6 +127,9 @@ public:
// dumpBlockLiveness
void dumpBlockLiveness(SourceManager& M) const;
+ // dumpVarLiveness
+ void dumpVarLiveness(SourceManager& M) const;
+
// getLiveAtBlockEntryMap
BlockLivenessMap& getLiveAtBlockEntryMap() { return LiveAtBlockEntryMap; }
OpenPOWER on IntegriCloud