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);
+ }
}
}
};
}
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() {
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());
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) {
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) {
}
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);
}
}
-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() &&
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.
// 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) {
// 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());
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());
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);
}
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
class Stmt;
class DeclRefExpr;
- class Decl;
+ class VarDecl;
class CFG;
class CFGBlock;
class SourceManager;
/// 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 {
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 {
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:
/// 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; }
// dumpBlockLiveness
void dumpBlockLiveness(SourceManager& M) const;
+ // dumpVarLiveness
+ void dumpVarLiveness(SourceManager& M) const;
+
// getLiveAtBlockEntryMap
BlockLivenessMap& getLiveAtBlockEntryMap() { return LiveAtBlockEntryMap; }