blob: 6a9023af649c459daa5c3867054ca0bdc6652f2b [file] [log] [blame]
Ted Kremenek9153f732008-02-05 07:17:49 +00001//= ValueState.cpp - Path-Sens. "State" for tracking valuues -----*- C++ -*--=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenekd70b62e2008-02-08 20:29:23 +000010// This files defines SymbolID, ExprBindKey, and ValueState.
Ted Kremenek9153f732008-02-05 07:17:49 +000011//
12//===----------------------------------------------------------------------===//
13
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +000014#include "ValueState.h"
15
16using namespace clang;
17
Ted Kremenek862d5bb2008-02-06 00:54:14 +000018bool ValueState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
19 // First, retrieve the NE-set associated with the given symbol.
20 ConstantNotEqTy::TreeTy* T = Data->ConstantNotEq.SlimFind(sym);
21
22 if (!T)
23 return false;
24
25 // Second, see if V is present in the NE-set.
26 return T->getValue().second.contains(&V);
27}
28
29const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const {
30 ConstantEqTy::TreeTy* T = Data->ConstantEq.SlimFind(sym);
31 return T ? T->getValue().second : NULL;
32}
33
Ted Kremenekb87d9092008-02-08 19:17:19 +000034ValueState
35ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
36 const LiveVariables& Liveness) {
37
38 // This code essentially performs a "mark-and-sweep" of the VariableBindings.
39 // The roots are any Block-level exprs and Decls that our liveness algorithm
40 // tells us are live. We then see what Decls they may reference, and keep
41 // those around. This code more than likely can be made faster, and the
42 // frequency of which this method is called should be experimented with
43 // for optimum performance.
44
45 llvm::SmallVector<ValueDecl*, 10> WList;
Ted Kremenek016f52f2008-02-08 21:10:02 +000046
47 for (StateTy::eb_iterator I = St.eb_begin(), E = St.eb_end(); I!=E ; ++I) {
48
49 ExprBindKey K = I.getKey();
Ted Kremenekb87d9092008-02-08 19:17:19 +000050
51 // Remove old bindings for subexpressions.
Ted Kremenek016f52f2008-02-08 21:10:02 +000052 if (K.isSubExpr()) {
53 St = Remove(St, K);
Ted Kremenekb87d9092008-02-08 19:17:19 +000054 continue;
55 }
56
Ted Kremenek016f52f2008-02-08 21:10:02 +000057 assert (I.getKey().isBlkExpr());
58
59 if (Liveness.isLive(Loc, K.getExpr())) {
60 if (isa<lval::DeclVal>(I.getData())) {
61 lval::DeclVal LV = cast<lval::DeclVal>(I.getData());
62 WList.push_back(LV.getDecl());
Ted Kremenekb87d9092008-02-08 19:17:19 +000063 }
Ted Kremenekb87d9092008-02-08 19:17:19 +000064 }
Ted Kremenek016f52f2008-02-08 21:10:02 +000065 else
66 St = Remove(St, K);
Ted Kremenekb87d9092008-02-08 19:17:19 +000067
Ted Kremenek016f52f2008-02-08 21:10:02 +000068 continue;
Ted Kremenekb87d9092008-02-08 19:17:19 +000069 }
Ted Kremenek016f52f2008-02-08 21:10:02 +000070
71 for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
72 if (Liveness.isLive(Loc, I.getKey()))
73 WList.push_back(I.getKey());
Ted Kremenekb87d9092008-02-08 19:17:19 +000074
75 llvm::SmallPtrSet<ValueDecl*, 10> Marked;
76
77 while (!WList.empty()) {
78 ValueDecl* V = WList.back();
79 WList.pop_back();
80
81 if (Marked.count(V))
82 continue;
83
84 Marked.insert(V);
85
86 if (V->getType()->isPointerType()) {
87 const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
88
89 if (!isa<lval::DeclVal>(LV))
90 continue;
91
92 const lval::DeclVal& LVD = cast<lval::DeclVal>(LV);
93 WList.push_back(LVD.getDecl());
94 }
95 }
96
Ted Kremenek016f52f2008-02-08 21:10:02 +000097 for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
98 if (!Marked.count(I.getKey()))
99 St = Remove(St, I.getKey());
Ted Kremenekb87d9092008-02-08 19:17:19 +0000100
101 return St;
102}
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000103
104
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000105RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV,
106 QualType* T) {
Ted Kremenek22031182008-02-08 02:57:34 +0000107 if (isa<UnknownVal>(LV))
108 return UnknownVal();
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000109
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000110 switch (LV.getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000111 case lval::DeclValKind: {
Ted Kremenek53c641a2008-02-08 03:02:48 +0000112 StateTy::VarBindingsTy::TreeTy* T =
Ted Kremenek016f52f2008-02-08 21:10:02 +0000113 // FIXME: We should make lval::DeclVal only contain VarDecl
114 St.getImpl()->VarBindings.SlimFind(
115 cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()));
Ted Kremenek9153f732008-02-05 07:17:49 +0000116
Ted Kremenek22031182008-02-08 02:57:34 +0000117 return T ? T->getValue().second : UnknownVal();
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000118 }
Ted Kremenekd131c4f2008-02-07 05:48:01 +0000119
120 // FIXME: We should bind how far a "ContentsOf" will go...
121
122 case lval::SymbolValKind: {
123 const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
124 assert (T);
125
126 if (T->getTypePtr()->isPointerType())
127 return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
128 else
129 return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
130 }
131
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000132 default:
133 assert (false && "Invalid LValue.");
134 break;
135 }
136
Ted Kremenek22031182008-02-08 02:57:34 +0000137 return UnknownVal();
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000138}
139
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000140ValueStateManager::StateTy
141ValueStateManager::AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V) {
142 // First, retrieve the NE-set associated with the given symbol.
143 ValueState::ConstantNotEqTy::TreeTy* T =
144 St.getImpl()->ConstantNotEq.SlimFind(sym);
145
146 ValueState::IntSetTy S = T ? T->getValue().second : ISetFactory.GetEmptySet();
147
148 // Now add V to the NE set.
149 S = ISetFactory.Add(S, &V);
150
151 // Create a new state with the old binding replaced.
152 ValueStateImpl NewStateImpl = *St.getImpl();
153 NewStateImpl.ConstantNotEq = CNEFactory.Add(NewStateImpl.ConstantNotEq,
154 sym, S);
155
156 // Get the persistent copy.
157 return getPersistentState(NewStateImpl);
158}
159
160ValueStateManager::StateTy
161ValueStateManager::AddEQ(StateTy St, SymbolID sym, const llvm::APSInt& V) {
162 // Create a new state with the old binding replaced.
163 ValueStateImpl NewStateImpl = *St.getImpl();
164 NewStateImpl.ConstantEq = CEFactory.Add(NewStateImpl.ConstantEq, sym, &V);
165
166 // Get the persistent copy.
167 return getPersistentState(NewStateImpl);
168}
169
Ted Kremenekd70b62e2008-02-08 20:29:23 +0000170RValue ValueStateManager::GetValue(const StateTy& St, Expr* S, bool* hasVal) {
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000171 for (;;) {
172 switch (S->getStmtClass()) {
173
174 // ParenExprs are no-ops.
175
176 case Stmt::ParenExprClass:
177 S = cast<ParenExpr>(S)->getSubExpr();
178 continue;
179
180 // DeclRefExprs can either evaluate to an LValue or a Non-LValue
181 // (assuming an implicit "load") depending on the context. In this
182 // context we assume that we are retrieving the value contained
183 // within the referenced variables.
184
185 case Stmt::DeclRefExprClass:
Ted Kremenek329f8542008-02-05 21:52:21 +0000186 return GetValue(St, lval::DeclVal(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000187
188 // Integer literals evaluate to an RValue. Simply retrieve the
189 // RValue for the literal.
190
191 case Stmt::IntegerLiteralClass:
192 return NonLValue::GetValue(ValMgr, cast<IntegerLiteral>(S));
193
194 // Casts where the source and target type are the same
195 // are no-ops. We blast through these to get the descendant
196 // subexpression that has a value.
197
198 case Stmt::ImplicitCastExprClass: {
199 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
200 if (C->getType() == C->getSubExpr()->getType()) {
201 S = C->getSubExpr();
202 continue;
203 }
204 break;
205 }
206
207 case Stmt::CastExprClass: {
208 CastExpr* C = cast<CastExpr>(S);
209 if (C->getType() == C->getSubExpr()->getType()) {
210 S = C->getSubExpr();
211 continue;
212 }
213 break;
214 }
215
216 // Handle all other Stmt* using a lookup.
217
218 default:
219 break;
220 };
221
222 break;
223 }
224
Ted Kremenek016f52f2008-02-08 21:10:02 +0000225 StateTy::ExprBindingsTy::TreeTy* T =
226 St.getImpl()->ExprBindings.SlimFind(S);
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000227
Ted Kremenekf233d482008-02-05 00:26:40 +0000228 if (T) {
229 if (hasVal) *hasVal = true;
230 return T->getValue().second;
231 }
232 else {
233 if (hasVal) *hasVal = false;
Ted Kremenek22031182008-02-08 02:57:34 +0000234 return UnknownVal();
Ted Kremenekf233d482008-02-05 00:26:40 +0000235 }
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000236}
237
Ted Kremenek016f52f2008-02-08 21:10:02 +0000238LValue ValueStateManager::GetLValue(const StateTy& St, Expr* E) {
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000239
Ted Kremenek016f52f2008-02-08 21:10:02 +0000240 while (ParenExpr* P = dyn_cast<ParenExpr>(E))
241 E = P->getSubExpr();
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000242
Ted Kremenek016f52f2008-02-08 21:10:02 +0000243 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
Ted Kremenek329f8542008-02-05 21:52:21 +0000244 return lval::DeclVal(DR->getDecl());
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000245
Ted Kremenek016f52f2008-02-08 21:10:02 +0000246 if (UnaryOperator* U = dyn_cast<UnaryOperator>(E))
Ted Kremenek5b6dc2d2008-02-07 01:08:27 +0000247 if (U->getOpcode() == UnaryOperator::Deref)
248 return cast<LValue>(GetValue(St, U->getSubExpr()));
249
Ted Kremenek016f52f2008-02-08 21:10:02 +0000250 return cast<LValue>(GetValue(St, E));
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000251}
252
253
254ValueStateManager::StateTy
Ted Kremenek016f52f2008-02-08 21:10:02 +0000255ValueStateManager::SetValue(StateTy St, Expr* E, bool isBlkExpr,
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000256 const RValue& V) {
257
Ted Kremenek016f52f2008-02-08 21:10:02 +0000258 assert (E);
259 return V.isKnown() ? Add(St, ExprBindKey(E, isBlkExpr), V) : St;
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000260}
261
262ValueStateManager::StateTy
263ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) {
264
265 switch (LV.getSubKind()) {
Ted Kremenek329f8542008-02-05 21:52:21 +0000266 case lval::DeclValKind:
Ted Kremenek016f52f2008-02-08 21:10:02 +0000267 return V.isKnown() // FIXME: Have DeclVal only contain VarDecl
268 ? Add(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()), V)
269 : Remove(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()));
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000270
271 default:
272 assert ("SetValue for given LValue type not yet implemented.");
273 return St;
274 }
275}
276
Ted Kremenek9153f732008-02-05 07:17:49 +0000277ValueStateManager::StateTy
Ted Kremenek016f52f2008-02-08 21:10:02 +0000278ValueStateManager::Add(StateTy St, ExprBindKey K, const RValue& V) {
279
Ted Kremenek9153f732008-02-05 07:17:49 +0000280 // Create a new state with the old binding removed.
281 ValueStateImpl NewStateImpl = *St.getImpl();
Ted Kremenek016f52f2008-02-08 21:10:02 +0000282 NewStateImpl.ExprBindings =
283 EXFactory.Add(NewStateImpl.ExprBindings, K, V);
284
Ted Kremenek9153f732008-02-05 07:17:49 +0000285 // Get the persistent copy.
286 return getPersistentState(NewStateImpl);
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000287}
Ted Kremenek9153f732008-02-05 07:17:49 +0000288
289ValueStateManager::StateTy
Ted Kremenek016f52f2008-02-08 21:10:02 +0000290ValueStateManager::Remove(StateTy St, ExprBindKey K) {
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000291
Ted Kremenek9153f732008-02-05 07:17:49 +0000292 // Create a new state with the old binding removed.
293 ValueStateImpl NewStateImpl = *St.getImpl();
Ted Kremenek016f52f2008-02-08 21:10:02 +0000294 NewStateImpl.ExprBindings =
295 EXFactory.Remove(NewStateImpl.ExprBindings, K);
Ted Kremenek9153f732008-02-05 07:17:49 +0000296
297 // Get the persistent copy.
298 return getPersistentState(NewStateImpl);
299}
300
Ted Kremenek016f52f2008-02-08 21:10:02 +0000301ValueStateManager::StateTy
302ValueStateManager::Add(StateTy St, VarDecl* D, const RValue& V) {
303
304 // Create a new state with the old binding removed.
305 ValueStateImpl NewStateImpl = *St.getImpl();
306 NewStateImpl.VarBindings =
307 VBFactory.Add(NewStateImpl.VarBindings, D, V);
308
309 // Get the persistent copy.
310 return getPersistentState(NewStateImpl);
311}
312
313ValueStateManager::StateTy
314ValueStateManager::Remove(StateTy St, VarDecl* D) {
315
316 // Create a new state with the old binding removed.
317 ValueStateImpl NewStateImpl = *St.getImpl();
318 NewStateImpl.VarBindings =
319 VBFactory.Remove(NewStateImpl.VarBindings, D);
320
321 // Get the persistent copy.
322 return getPersistentState(NewStateImpl);
323}
Ted Kremenek9153f732008-02-05 07:17:49 +0000324
325ValueStateManager::StateTy
326ValueStateManager::getInitialState() {
327
328 // Create a state with empty variable bindings.
Ted Kremenek016f52f2008-02-08 21:10:02 +0000329 ValueStateImpl StateImpl(EXFactory.GetEmptyMap(),
330 VBFactory.GetEmptyMap(),
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000331 CNEFactory.GetEmptyMap(),
332 CEFactory.GetEmptyMap());
Ted Kremenek9153f732008-02-05 07:17:49 +0000333
334 return getPersistentState(StateImpl);
335}
336
337ValueStateManager::StateTy
338ValueStateManager::getPersistentState(const ValueStateImpl &State) {
339
340 llvm::FoldingSetNodeID ID;
341 State.Profile(ID);
342 void* InsertPos;
343
344 if (ValueStateImpl* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
345 return I;
346
Ted Kremenek41652a92008-02-06 02:45:20 +0000347 ValueStateImpl* I = (ValueStateImpl*) Alloc.Allocate<ValueStateImpl>();
Ted Kremenek9153f732008-02-05 07:17:49 +0000348 new (I) ValueStateImpl(State);
349 StateSet.InsertNode(I, InsertPos);
350 return I;
351}