Skip to content

Commit 1587143

Browse files
martinmartin
authored andcommitted
One domain per history storage in abstract interpretation
This allows more sophisticated history abstractions that have more than on distinct history per location (for example loop unwinding and calling context).
1 parent 30beeda commit 1587143

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

src/analyses/ai_storage.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,82 @@ class location_sensitive_storaget : public trace_map_storaget
212212
}
213213
};
214214

215+
// The most precise form of storage
216+
class history_sensitive_storaget : public trace_map_storaget
217+
{
218+
protected:
219+
typedef std::map<trace_ptrt, state_ptrt, ai_history_baset::compare_historyt>
220+
domain_mapt;
221+
domain_mapt domain_map;
222+
223+
public:
224+
cstate_ptrt abstract_state_before(
225+
trace_ptrt p,
226+
const ai_domain_factory_baset &fac) const override
227+
{
228+
auto it = domain_map.find(p);
229+
if(it == domain_map.end())
230+
return fac.make(p->current_location());
231+
232+
return it->second;
233+
}
234+
235+
cstate_ptrt abstract_state_before(
236+
locationt t,
237+
const ai_domain_factory_baset &fac) const override
238+
{
239+
auto traces = abstract_traces_before(t);
240+
241+
if(traces->size() == 0)
242+
{
243+
return fac.make(t);
244+
}
245+
else if(traces->size() == 1)
246+
{
247+
auto it = domain_map.find(*(traces->begin()));
248+
DATA_INVARIANT(
249+
it != domain_map.end(), "domain_map must be in sync with trace_map");
250+
return it->second;
251+
}
252+
else
253+
{
254+
// Need to merge all of the traces that reach this location
255+
auto res = fac.make(t);
256+
257+
for(auto p : *traces)
258+
{
259+
auto it = domain_map.find(p);
260+
DATA_INVARIANT(
261+
it != domain_map.end(), "domain_map must be in sync with trace_map");
262+
fac.merge(*res, *(it->second), p, p);
263+
}
264+
265+
return cstate_ptrt(res.release());
266+
}
267+
}
268+
269+
statet &get_state(trace_ptrt p, const ai_domain_factory_baset &fac) override
270+
{
271+
register_trace(p);
272+
273+
auto it = domain_map.find(p);
274+
if(it == domain_map.end())
275+
{
276+
std::shared_ptr<statet> d(fac.make(p->current_location()));
277+
auto jt = domain_map.emplace(p, d);
278+
CHECK_RETURN(jt.second);
279+
it = jt.first;
280+
}
281+
282+
return *(it->second);
283+
}
284+
285+
void clear() override
286+
{
287+
trace_map_storaget::clear();
288+
domain_map.clear();
289+
return;
290+
}
291+
};
292+
215293
#endif

0 commit comments

Comments
 (0)