Skip to content

Commit 039cfb9

Browse files
author
thk123
committed
Reworked three way merge that works when enabled and not
1 parent 0c97155 commit 039cfb9

File tree

5 files changed

+69
-91
lines changed

5 files changed

+69
-91
lines changed

src/analyses/ai.cpp

Lines changed: 5 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,6 @@ bool ai_baset::do_function_call(
416416

417417
bool new_data=false;
418418

419-
std::cout << "BEFORE MERGING" << std::endl;
420-
tmp_state->output(std::cout, *this, ns);
421-
statet &dest=get_state(l_begin);
422-
dest.output(std::cout, *this, ns);
423-
424-
std::cout << "-------------" << std::endl;
425-
426419
// merge the new stuff
427420
if(merge(*tmp_state, l_call, l_begin))
428421
new_data=true;
@@ -432,25 +425,8 @@ bool ai_baset::do_function_call(
432425
fixedpoint(goto_function.body, goto_functions, ns);
433426
}
434427

435-
#if 0
436-
{
437-
// do edge from end of function to instruction after call
438-
locationt l_begin=goto_function.body.instructions.begin();
439-
const statet &starting_state=get_state(l_begin);
440-
441-
std::unique_ptr<statet> tmp_state(make_temporary_state(starting_state));
442-
443-
/// Merge 25 into 26
444-
/// Source state is 25 (src = get_state(25)
445-
/// Destination state is 26 (i.e to = 26)
446-
447-
// src, from, to
448-
any_changes|=merge(*tmp_state, l_begin, l_return);
449-
}
450-
#endif
451428

452429
// This is the edge from function end to return site.
453-
454430
{
455431
// get location at end of the procedure we have called
456432
locationt l_end=--goto_function.body.instructions.end();
@@ -468,48 +444,13 @@ bool ai_baset::do_function_call(
468444
std::unique_ptr<statet> tmp_state(make_temporary_state(end_state));
469445
tmp_state->transform(l_end, l_return, *this, ns);
470446

471-
// We want to get a state that has only the changes from the function
472-
//const auto &symbols=get_modified_symbols(start_state, end_state);
473-
474-
475-
476-
477-
478-
// Propagate those
479-
//any_changes|=merge(get_state(l_call), l_end, l_return);
480-
481-
#if 0
482-
std::cout << "Function call " << f_it->first << " complete, modified symbols:" << std::endl;
483-
#endif
484-
//const auto &modified_symbols=get_modified_symbols(start_state, *tmp_state);
485-
486-
#if 0
487-
for(const auto &modified_symbol:modified_symbols)
488-
{
489-
std::cout << "\t" << modified_symbol.get_identifier() << "\n";
490-
}
491-
std::cout << std::endl;
492-
#endif
493-
494-
// ------------
495-
// END_FUNCTION
496-
// ------------
497-
498-
// 3 way merge normally has BASE, LOCAL and REMOTE
499-
// We take the changes applied between BASE and REMOTE and re-apply them to
500-
// local
501-
// This would look like:
502-
// BASE: function_begin
503-
// REMOTE: function_end
504-
// LOCAL: function_call
505-
447+
std::unique_ptr<statet> pre_merge_tmp_state(make_temporary_state(*tmp_state));
506448

507-
std::unique_ptr<statet> tmp_return_state(make_temporary_state(get_state(l_call)));
508-
tmp_return_state->merge_three_way_function_return(
509-
get_state(l_begin), get_state(l_end), ns);
449+
// We try to
450+
tmp_state->merge_three_way_function_return(
451+
get_state(l_call), get_state(l_begin), *pre_merge_tmp_state, ns);
510452

511-
any_changes|=merge(*tmp_return_state, l_end, l_return);
512-
//restore_domain(modified_symbols, *tmp_state, get_state(l_return), ns);
453+
any_changes|=merge(*tmp_state, l_end, l_return);
513454
}
514455

515456
return any_changes;

src/analyses/ai.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,15 @@ class ai_domain_baset
106106
exprt &condition,
107107
const namespacet &ns) const;
108108

109+
// Applies the changes between the start and end to the domain
109110
virtual void merge_three_way_function_return(
111+
const ai_domain_baset &function_call,
110112
const ai_domain_baset &function_start,
111113
const ai_domain_baset &function_end,
112114
const namespacet &ns)
113115
{
114-
// Do nothing - the result of the merge is to take
115-
// all the changes in the "remote" version
116+
// Take the state at the end of the function as a over-approximation
117+
// of applying the changes in the function
116118
}
117119

118120
};

src/analyses/variable-sensitivity/abstract_enviroment.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,7 @@ std::vector<symbol_exprt> abstract_environmentt::modified_symbols(
833833
bool all_matched=intersection.size()==a.size() &&
834834
intersection.size()==b.size();
835835

836+
#if 0
836837
std::cout << entry.first.get_identifier() << ": {";
837838
for(const auto &entry:lhs_location)
838839
{
@@ -845,6 +846,7 @@ std::vector<symbol_exprt> abstract_environmentt::modified_symbols(
845846
std::cout << entry->location_number << ", ";
846847
}
847848
std::cout << " }" << std::endl;
849+
#endif
848850

849851
if (!all_matched)
850852
{

src/analyses/variable-sensitivity/variable_sensitivity_domain.cpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,17 @@ bool variable_sensitivity_domaint::is_top() const
370370
return abstract_state.is_top();
371371
}
372372

373+
/// Get symbols that have been modified since this domain and other
374+
/// \param other: The domain that things may have been modified in
375+
/// \return A list of symbols whose write location is different
376+
std::vector<symbol_exprt>
377+
variable_sensitivity_domaint::get_modified_symbols(
378+
const variable_sensitivity_domaint &other) const
379+
{
380+
return abstract_environmentt::modified_symbols(
381+
abstract_state, other.abstract_state);
382+
}
383+
373384
/*******************************************************************\
374385
375386
Function: variable_sensitivity_domaint::transform_function_call
@@ -532,34 +543,58 @@ bool variable_sensitivity_domaint::ignore_function_call_transform(
532543
ignored_internal_function.cend();
533544
}
534545

546+
/// Perform a context aware merge of the changes that have been applied
547+
/// between function_start and the current state. Anything that has not been
548+
/// modified will be taken from the \p function_call domain.
549+
/// \param function_call: The local of the merge - values from here will be
550+
/// taken if they have not been modified
551+
/// \param function_start: THe base of the merge - changes that have been made
552+
/// between here and this will be retained.
553+
/// \param ns: The global namespace
535554
void variable_sensitivity_domaint::merge_three_way_function_return(
555+
const ai_domain_baset &function_call,
536556
const ai_domain_baset &function_start,
537557
const ai_domain_baset &function_end,
538558
const namespacet &ns)
539559
{
540-
// const variable_sensitivity_domaint &cast_function_call_site=
541-
// static_cast<const variable_sensitivity_domaint &>(function_call_site);
560+
// TODO(tkiley): flag to turn of the context aware merge
561+
if(true)
562+
{
563+
const variable_sensitivity_domaint &cast_function_call=
564+
static_cast<const variable_sensitivity_domaint &>(function_call);
542565

543-
const variable_sensitivity_domaint &cast_function_start=
544-
static_cast<const variable_sensitivity_domaint &>(function_start);
566+
const variable_sensitivity_domaint &cast_function_start=
567+
static_cast<const variable_sensitivity_domaint &>(function_start);
545568

546-
const variable_sensitivity_domaint &cast_function_end=
547-
static_cast<const variable_sensitivity_domaint &>(function_end);
569+
const variable_sensitivity_domaint &cast_function_end=
570+
static_cast<const variable_sensitivity_domaint &>(function_end);
548571

549-
const std::vector<symbol_exprt> &modified_symbols=
550-
cast_function_start.get_modified_symbols(cast_function_end);
572+
const std::vector<symbol_exprt> &modified_symbols=
573+
cast_function_start.get_modified_symbols(cast_function_end);
551574

552-
apply_domain(modified_symbols, cast_function_end, ns);
575+
abstract_state=cast_function_call.abstract_state;
576+
apply_domain(modified_symbols, cast_function_end, ns);
577+
}
578+
else
579+
{
580+
ai_domain_baset::merge_three_way_function_return(
581+
function_call, function_start, function_end, ns);
582+
}
553583
}
554584

585+
/// Given a domain and some symbols, apply those symbols values
586+
/// to the current domain
587+
/// \param modified_symbols: The symbols to write
588+
/// \param source: The domain to take the values from
589+
/// \param ns: The global namespace
555590
void variable_sensitivity_domaint::apply_domain(
556591
std::vector<symbol_exprt> modified_symbols,
557592
const variable_sensitivity_domaint &source,
558593
const namespacet &ns)
559594
{
560-
for (const auto &symbol : modified_symbols)
561-
{
562-
auto value = source.abstract_state.eval(symbol, ns);
563-
this->abstract_state.assign(symbol, value, ns);
564-
}
595+
for (const auto &symbol : modified_symbols)
596+
{
597+
abstract_object_pointert value=source.abstract_state.eval(symbol, ns);
598+
abstract_state.assign(symbol, value, ns);
599+
}
565600
}

src/analyses/variable-sensitivity/variable_sensitivity_domain.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class variable_sensitivity_domaint:public ai_domain_baset
100100
locationt to);
101101

102102
void merge_three_way_function_return(
103+
const ai_domain_baset &function_call,
103104
const ai_domain_baset &function_start,
104105
const ai_domain_baset &function_end,
105106
const namespacet &ns) override;
@@ -111,17 +112,6 @@ class variable_sensitivity_domaint:public ai_domain_baset
111112
bool is_bottom() const override;
112113
bool is_top() const override;
113114

114-
std::vector<symbol_exprt> get_modified_symbols(const variable_sensitivity_domaint &other) const
115-
{
116-
return abstract_environmentt::modified_symbols(abstract_state, other.abstract_state);
117-
}
118-
119-
120-
virtual void apply_domain(
121-
std::vector<symbol_exprt> modified_symbols,
122-
const variable_sensitivity_domaint &target,
123-
const namespacet &ns);
124-
125115
private:
126116
void transform_function_call(
127117
locationt from,
@@ -131,6 +121,14 @@ class variable_sensitivity_domaint:public ai_domain_baset
131121

132122
bool ignore_function_call_transform(const irep_idt &function_id) const;
133123

124+
std::vector<symbol_exprt> get_modified_symbols(
125+
const variable_sensitivity_domaint &other) const;
126+
127+
void apply_domain(
128+
std::vector<symbol_exprt> modified_symbols,
129+
const variable_sensitivity_domaint &target,
130+
const namespacet &ns);
131+
134132
abstract_environmentt abstract_state;
135133
};
136134

0 commit comments

Comments
 (0)