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.
//===----------------------------------------------------------------------===//
#include "ValueState.h"
+#include "llvm/ADT/SmallSet.h"
using namespace clang;
// for optimum performance.
llvm::SmallVector<ValueDecl*, 10> WList;
+ llvm::SmallPtrSet<ValueDecl*, 10> Marked;
+ llvm::SmallSet<SymbolID, 20> MarkedSymbols;
ValueStateImpl NewSt = *St;
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);
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();
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;
}
}
+ // 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);
}
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 {
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,
enum { BaseBits = 2,
BaseMask = 0x3 };
-private:
+protected:
void* Data;
unsigned Kind;
explicit RValue(BaseKind k)
: Data(0), Kind(k) {}
- void* getRawPtr() const {
- return reinterpret_cast<void*>(Data);
- }
-
public:
~RValue() {};
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; }
};
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) {
: 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) {
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.
: 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) {
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) {
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 {
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);
}