зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
a3fadfcce5
Коммит
90e1481ef1
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче