Skip to content

Commit a6c5175

Browse files
authored
Merge pull request #7929 from martin-cs/refactor/tidy-up-three-way-merge
Refactor/tidy up three way merge
2 parents 3535b61 + 515f263 commit a6c5175

5 files changed

+24
-72
lines changed

src/analyses/variable-sensitivity/three_way_merge_abstract_interpreter.cpp

+10-11
Original file line numberDiff line numberDiff line change
@@ -160,22 +160,21 @@ bool ai_three_way_merget::visit_edge_function_call(
160160
*this,
161161
ns);
162162

163-
// TODO : this is probably needed to avoid three_way_merge modifying one of
164-
// its arguments as it goes. A better solution would be to refactor
165-
// merge_three_way_function_return.
166-
const std::unique_ptr<statet> ptr_s_working_copy(
167-
make_temporary_state(s_working));
163+
// The base for the three way merge is the call site
164+
const std::unique_ptr<statet> ptr_call_site_working(
165+
make_temporary_state(get_state(p_call_site)));
166+
auto tmp2 =
167+
dynamic_cast<variable_sensitivity_domaint *>(&(*ptr_call_site_working));
168+
INVARIANT(tmp2 != nullptr, "Three-way merge requires domain support");
169+
variable_sensitivity_domaint &s_call_site_working = *tmp2;
168170

169171
log.progress() << "three way merge... ";
170-
s_working.merge_three_way_function_return(
171-
get_state(p_call_site),
172-
get_state(p_callee_start),
173-
*ptr_s_working_copy,
174-
ns);
172+
s_call_site_working.merge_three_way_function_return(
173+
get_state(p_callee_start), s_working, ns);
175174

176175
log.progress() << "merging... ";
177176
if(
178-
merge(s_working, p_callee_end, p_return_site) ||
177+
merge(s_call_site_working, p_callee_end, p_return_site) ||
179178
(return_step.first == ai_history_baset::step_statust::NEW &&
180179
!s_working.is_bottom()))
181180
{

src/analyses/variable-sensitivity/variable_sensitivity_dependence_graph.cpp

+2-13
Original file line numberDiff line numberDiff line change
@@ -438,20 +438,9 @@ bool variable_sensitivity_dependence_domaint::merge(
438438
}
439439

440440
/**
441-
* Perform a context aware merge of the changes that have been applied
442-
* between function_start and the current state. Anything that has not been
443-
* modified will be taken from the \p function_call domain.
444-
*
445-
* \param function_call: The local of the merge - values from here will be
446-
* taken if they have not been modified
447-
* \param function_start: The base of the merge - changes that have been made
448-
* between here and the end will be retained.
449-
* \param function_end: The end of the merge - changes that have been made
450-
/// between the start and here will be retained.
451-
* \param ns: The global namespace
441+
* \copydoc variable_sensitivity_domaint::merge_three_way_function_return
452442
*/
453443
void variable_sensitivity_dependence_domaint::merge_three_way_function_return(
454-
const ai_domain_baset &function_call,
455444
const ai_domain_baset &function_start,
456445
const ai_domain_baset &function_end,
457446
const namespacet &ns)
@@ -462,7 +451,7 @@ void variable_sensitivity_dependence_domaint::merge_three_way_function_return(
462451
// the three way merge is that the underlying variable sensitivity domain
463452
// does its three way merge.
464453
variable_sensitivity_domaint::merge_three_way_function_return(
465-
function_call, function_start, function_end, ns);
454+
function_start, function_end, ns);
466455
}
467456

468457
/**

src/analyses/variable-sensitivity/variable_sensitivity_dependence_graph.h

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ class variable_sensitivity_dependence_domaint
132132
trace_ptrt to) override;
133133

134134
void merge_three_way_function_return(
135-
const ai_domain_baset &function_call,
136135
const ai_domain_baset &function_start,
137136
const ai_domain_baset &function_end,
138137
const namespacet &ns) override;

src/analyses/variable-sensitivity/variable_sensitivity_domain.cpp

+6-24
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,6 @@ bool variable_sensitivity_domaint::is_top() const
275275
return abstract_state.is_top();
276276
}
277277

278-
std::vector<irep_idt> variable_sensitivity_domaint::get_modified_symbols(
279-
const variable_sensitivity_domaint &other) const
280-
{
281-
return abstract_environmentt::modified_symbols(
282-
abstract_state, other.abstract_state);
283-
}
284-
285278
void variable_sensitivity_domaint::transform_function_call(
286279
locationt from,
287280
locationt to,
@@ -424,22 +417,19 @@ bool variable_sensitivity_domaint::ignore_function_call_transform(
424417
}
425418

426419
void variable_sensitivity_domaint::merge_three_way_function_return(
427-
const ai_domain_baset &function_call,
428420
const ai_domain_baset &function_start,
429421
const ai_domain_baset &function_end,
430422
const namespacet &ns)
431423
{
432-
const variable_sensitivity_domaint &cast_function_call =
433-
static_cast<const variable_sensitivity_domaint &>(function_call);
434-
435424
const variable_sensitivity_domaint &cast_function_start =
436425
static_cast<const variable_sensitivity_domaint &>(function_start);
437426

438427
const variable_sensitivity_domaint &cast_function_end =
439428
static_cast<const variable_sensitivity_domaint &>(function_end);
440429

441430
const std::vector<irep_idt> &modified_symbol_names =
442-
cast_function_start.get_modified_symbols(cast_function_end);
431+
abstract_environmentt::modified_symbols(
432+
cast_function_start.abstract_state, cast_function_end.abstract_state);
443433

444434
std::vector<symbol_exprt> modified_symbols;
445435
modified_symbols.reserve(modified_symbol_names.size());
@@ -449,22 +439,14 @@ void variable_sensitivity_domaint::merge_three_way_function_return(
449439
std::back_inserter(modified_symbols),
450440
[&ns](const irep_idt &id) { return ns.lookup(id).symbol_expr(); });
451441

452-
abstract_state = cast_function_call.abstract_state;
453-
apply_domain(modified_symbols, cast_function_end, ns);
454-
455-
return;
456-
}
457-
458-
void variable_sensitivity_domaint::apply_domain(
459-
std::vector<symbol_exprt> modified_symbols,
460-
const variable_sensitivity_domaint &source,
461-
const namespacet &ns)
462-
{
463442
for(const auto &symbol : modified_symbols)
464443
{
465-
abstract_object_pointert value = source.abstract_state.eval(symbol, ns);
444+
abstract_object_pointert value =
445+
cast_function_end.abstract_state.eval(symbol, ns);
466446
abstract_state.assign(symbol, value, ns);
467447
}
448+
449+
return;
468450
}
469451

470452
void variable_sensitivity_domaint::assume(exprt expr, namespacet ns)

src/analyses/variable-sensitivity/variable_sensitivity_domain.h

+6-23
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,17 @@ class variable_sensitivity_domaint : public ai_domain_baset
172172
virtual bool
173173
merge(const variable_sensitivity_domaint &b, trace_ptrt from, trace_ptrt to);
174174

175-
/// Perform a context aware merge of the changes that have been applied
176-
/// between function_start and the current state. Anything that has not been
177-
/// modified will be taken from the \p function_call domain.
178-
/// \param function_call: The local of the merge - values from here will be
179-
/// taken if they have not been modified
180-
/// \param function_start: The base of the merge - changes that have been made
175+
/// Merges just the things that have changes between
176+
/// "function_start" and "function_end" into "this".
177+
/// To be used correctly "this" must be derived from the function
178+
/// call site. Anything that is not modified in the function (such
179+
/// as globals) will not be changed.
180+
/// \param function_start: The base of the diff - changes that have been made
181181
/// between here and the end will be retained.
182182
/// \param function_end: The end of the merge - changes that have been made
183183
/// between the start and here will be retained.
184184
/// \param ns: The global namespace
185185
virtual void merge_three_way_function_return(
186-
const ai_domain_baset &function_call,
187186
const ai_domain_baset &function_start,
188187
const ai_domain_baset &function_end,
189188
const namespacet &ns);
@@ -241,22 +240,6 @@ class variable_sensitivity_domaint : public ai_domain_baset
241240
/// \return Returns true if the function should be ignored
242241
bool ignore_function_call_transform(const irep_idt &function_id) const;
243242

244-
/// Get symbols that have been modified since this domain and other
245-
/// \param other: The domain that things may have been modified in
246-
/// \return A list of symbols whose write location is different
247-
std::vector<irep_idt>
248-
get_modified_symbols(const variable_sensitivity_domaint &other) const;
249-
250-
/// Given a domain and some symbols, apply those symbols values
251-
/// to the current domain
252-
/// \param modified_symbols: The symbols to write
253-
/// \param target: The domain to take the values from
254-
/// \param ns: The global namespace
255-
void apply_domain(
256-
std::vector<symbol_exprt> modified_symbols,
257-
const variable_sensitivity_domaint &target,
258-
const namespacet &ns);
259-
260243
void assume(exprt expr, namespacet ns);
261244

262245
abstract_environmentt abstract_state;

0 commit comments

Comments
 (0)