aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-14 23:25:54 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-14 23:25:54 +0000
commit90e1481ef15ec75e3503e0c6e5effad5bd639f01 (patch)
tree0a460f866674b2915999a405169ba0fe71373442
parenta3fadfcce5911742801a302cac82d4fe54d5c682 (diff)
Added "symbol iterators" for RValues, allowing easy iteration over the symbols
referenced by an RValue, instead of having to query the type of the RValue. Modified ValueState::RemoveDeadBindings to also prune dead symbols. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47142 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Analysis/RValues.cpp26
-rw-r--r--Analysis/ValueState.cpp32
-rw-r--r--Analysis/ValueState.h8
-rw-r--r--include/clang/Analysis/PathSensitive/RValues.h26
4 files changed, 73 insertions, 19 deletions
diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp
index 8d16f12d32..8eb607c9e5 100644
--- a/Analysis/RValues.cpp
+++ b/Analysis/RValues.cpp
@@ -123,8 +123,32 @@ ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
return *C;
}
+//===----------------------------------------------------------------------===//
+// Symbol Iteration.
+//===----------------------------------------------------------------------===//
+
+RValue::symbol_iterator RValue::symbol_begin() const {
+ if (isa<LValue>(this)) {
+ if (isa<lval::SymbolVal>(this))
+ return (symbol_iterator) (&Data);
+ }
+ else {
+ if (isa<nonlval::SymbolVal>(this))
+ return (symbol_iterator) (&Data);
+ else if (isa<nonlval::SymIntConstraintVal>(this)) {
+ const SymIntConstraint& C =
+ cast<nonlval::SymIntConstraintVal>(this)->getConstraint();
+ return (symbol_iterator) &C.getSymbol();
+ }
+ }
+
+ return NULL;
+}
-
+RValue::symbol_iterator RValue::symbol_end() const {
+ symbol_iterator X = symbol_begin();
+ return X ? X+1 : NULL;
+}
//===----------------------------------------------------------------------===//
// Transfer function dispatch for Non-LValues.
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp
index c74c876b51..27818efa34 100644
--- a/Analysis/ValueState.cpp
+++ b/Analysis/ValueState.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ValueState.h"
+#include "llvm/ADT/SmallSet.h"
using namespace clang;
@@ -43,6 +44,8 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
// for optimum performance.
llvm::SmallVector<ValueDecl*, 10> WList;
+ llvm::SmallPtrSet<ValueDecl*, 10> Marked;
+ llvm::SmallSet<SymbolID, 20> MarkedSymbols;
ValueStateImpl NewSt = *St;
@@ -55,10 +58,16 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
Expr* BlkExpr = I.getKey();
if (Liveness.isLive(Loc, BlkExpr)) {
- if (isa<lval::DeclVal>(I.getData())) {
- lval::DeclVal LV = cast<lval::DeclVal>(I.getData());
+ RValue X = I.getData();
+
+ if (isa<lval::DeclVal>(X)) {
+ lval::DeclVal LV = cast<lval::DeclVal>(X);
WList.push_back(LV.getDecl());
}
+
+ for (RValue::symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end();
+ SI != SE; ++SI)
+ MarkedSymbols.insert(*SI);
}
else
NewSt.BlockExprBindings = Remove(NewSt, BlkExpr);
@@ -70,8 +79,7 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
if (Liveness.isLive(Loc, I.getKey()))
WList.push_back(I.getKey());
-
- llvm::SmallPtrSet<ValueDecl*, 10> Marked;
+
while (!WList.empty()) {
ValueDecl* V = WList.back();
@@ -83,7 +91,11 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
Marked.insert(V);
if (V->getType()->isPointerType()) {
- const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
+ const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
+
+ for (RValue::symbol_iterator SI=LV.symbol_begin(), SE=LV.symbol_end();
+ SI != SE; ++SI)
+ MarkedSymbols.insert(*SI);
if (!isa<lval::DeclVal>(LV))
continue;
@@ -93,10 +105,20 @@ ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
}
}
+ // Remove dead variable bindings.
for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
if (!Marked.count(I.getKey()))
NewSt.VarBindings = Remove(NewSt, I.getKey());
+ // Remove dead symbols.
+ for (ValueState::ce_iterator I = St.ce_begin(), E=St.ce_end(); I!=E; ++I)
+ if (!MarkedSymbols.count(I.getKey()))
+ NewSt.ConstantEq = CEFactory.Remove(NewSt.ConstantEq, I.getKey());
+
+ for (ValueState::cne_iterator I = St.cne_begin(), E=St.cne_end(); I!=E; ++I)
+ if (!MarkedSymbols.count(I.getKey()))
+ NewSt.ConstantNotEq = CNEFactory.Remove(NewSt.ConstantNotEq, I.getKey());
+
return getPersistentState(NewSt);
}
diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h
index c0bc81deda..38c34cb84a 100644
--- a/Analysis/ValueState.h
+++ b/Analysis/ValueState.h
@@ -153,6 +153,14 @@ public:
beb_iterator beb_begin() const { return Data->BlockExprBindings.begin(); }
beb_iterator beb_end() const { return Data->BlockExprBindings.end(); }
+ typedef ConstantNotEqTy::iterator cne_iterator;
+ cne_iterator cne_begin() const { return Data->ConstantNotEq.begin(); }
+ cne_iterator cne_end() const { return Data->ConstantNotEq.end(); }
+
+ typedef ConstantEqTy::iterator ce_iterator;
+ ce_iterator ce_begin() const { return Data->ConstantEq.begin(); }
+ ce_iterator ce_end() const { return Data->ConstantEq.end(); }
+
// Profiling and equality testing.
bool operator==(const ValueState& RHS) const {
diff --git a/include/clang/Analysis/PathSensitive/RValues.h b/include/clang/Analysis/PathSensitive/RValues.h
index 3eb08ff37e..acf841170d 100644
--- a/include/clang/Analysis/PathSensitive/RValues.h
+++ b/include/clang/Analysis/PathSensitive/RValues.h
@@ -137,7 +137,7 @@ public:
Op(op), Val(V) {}
BinaryOperator::Opcode getOpcode() const { return Op; }
- SymbolID getSymbol() const { return Symbol; }
+ const SymbolID& getSymbol() const { return Symbol; }
const llvm::APSInt& getInt() const { return Val; }
static inline void Profile(llvm::FoldingSetNodeID& ID,
@@ -249,7 +249,7 @@ public:
enum { BaseBits = 2,
BaseMask = 0x3 };
-private:
+protected:
void* Data;
unsigned Kind;
@@ -261,10 +261,6 @@ protected:
explicit RValue(BaseKind k)
: Data(0), Kind(k) {}
- void* getRawPtr() const {
- return reinterpret_cast<void*>(Data);
- }
-
public:
~RValue() {};
@@ -293,6 +289,10 @@ public:
void print(std::ostream& OS) const;
void print() const;
+ typedef const SymbolID* symbol_iterator;
+ symbol_iterator symbol_begin() const;
+ symbol_iterator symbol_end() const;
+
// Implement isa<T> support.
static inline bool classof(const RValue*) { return true; }
};
@@ -374,7 +374,7 @@ namespace nonlval {
reinterpret_cast<void*>((uintptr_t) SymID)) {}
SymbolID getSymbol() const {
- return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+ return (SymbolID) reinterpret_cast<uintptr_t>(Data);
}
static inline bool classof(const RValue* V) {
@@ -388,7 +388,7 @@ namespace nonlval {
: NonLValue(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {}
const SymIntConstraint& getConstraint() const {
- return *reinterpret_cast<SymIntConstraint*>(getRawPtr());
+ return *reinterpret_cast<SymIntConstraint*>(Data);
}
static inline bool classof(const RValue* V) {
@@ -401,7 +401,7 @@ namespace nonlval {
ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(getRawPtr());
+ return *static_cast<llvm::APSInt*>(Data);
}
// Transfer functions for binary/unary operations on ConcreteInts.
@@ -442,7 +442,7 @@ namespace lval {
: LValue(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
SymbolID getSymbol() const {
- return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+ return (SymbolID) reinterpret_cast<uintptr_t>(Data);
}
static inline bool classof(const RValue* V) {
@@ -459,7 +459,7 @@ namespace lval {
GotoLabel(LabelStmt* Label) : LValue(GotoLabelKind, Label) {}
LabelStmt* getLabel() const {
- return static_cast<LabelStmt*>(getRawPtr());
+ return static_cast<LabelStmt*>(Data);
}
static inline bool classof(const RValue* V) {
@@ -477,7 +477,7 @@ namespace lval {
DeclVal(const ValueDecl* vd) : LValue(DeclValKind,vd) {}
ValueDecl* getDecl() const {
- return static_cast<ValueDecl*>(getRawPtr());
+ return static_cast<ValueDecl*>(Data);
}
inline bool operator==(const DeclVal& R) const {
@@ -503,7 +503,7 @@ namespace lval {
ConcreteInt(const llvm::APSInt& V) : LValue(ConcreteIntKind, &V) {}
const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(getRawPtr());
+ return *static_cast<llvm::APSInt*>(Data);
}