-
Notifications
You must be signed in to change notification settings - Fork 276
cfgt: index entry-map by instruction location number, not the instruction itself #5049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
aba7e75
313416a
79be445
33ceb0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,9 @@ Author: Daniel Kroening, [email protected] | |
#ifndef CPROVER_GOTO_PROGRAMS_CFG_H | ||
#define CPROVER_GOTO_PROGRAMS_CFG_H | ||
|
||
#include <util/std_expr.h> | ||
#include <util/dense_integer_map.h> | ||
#include <util/graph.h> | ||
#include <util/std_expr.h> | ||
|
||
#include "goto_functions.h" | ||
|
||
|
@@ -31,6 +32,29 @@ struct cfg_base_nodet:public graph_nodet<empty_edget>, public T | |
I PC; | ||
}; | ||
|
||
/// Functor to convert cfg nodes into dense integers, used by \ref cfg_baset. | ||
/// Default implementation: the identity function. | ||
template <class T> | ||
class cfg_instruction_to_dense_integert | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could do with some unit tests. |
||
{ | ||
public: | ||
std::size_t operator()(T &&t) const | ||
{ | ||
return std::forward<T>(identity_functort{}(t)); | ||
} | ||
}; | ||
|
||
/// GOTO-instruction to location number functor. | ||
template <> | ||
class cfg_instruction_to_dense_integert<goto_programt::const_targett> | ||
{ | ||
public: | ||
std::size_t operator()(const goto_programt::const_targett &t) const | ||
{ | ||
return t->location_number; | ||
} | ||
}; | ||
|
||
/// A multi-procedural control flow graph (CFG) whose nodes store references to | ||
/// instructions in a GOTO program. | ||
/// | ||
|
@@ -69,7 +93,11 @@ class cfg_baset:public grapht< cfg_base_nodet<T, I> > | |
|
||
class entry_mapt final | ||
{ | ||
typedef std::map<goto_programt::const_targett, entryt> data_typet; | ||
typedef dense_integer_mapt< | ||
goto_programt::const_targett, | ||
entryt, | ||
cfg_instruction_to_dense_integert<goto_programt::const_targett>> | ||
data_typet; | ||
data_typet data; | ||
|
||
public: | ||
|
@@ -114,6 +142,12 @@ class cfg_baset:public grapht< cfg_base_nodet<T, I> > | |
{ | ||
return data.at(t); | ||
} | ||
|
||
template <class Iter> | ||
void setup_for_keys(Iter begin, Iter end) | ||
{ | ||
data.setup_for_keys(begin, end); | ||
} | ||
}; | ||
entry_mapt entry_map; | ||
|
||
|
@@ -173,12 +207,30 @@ class cfg_baset:public grapht< cfg_base_nodet<T, I> > | |
void operator()( | ||
const goto_functionst &goto_functions) | ||
{ | ||
std::vector<goto_programt::const_targett> possible_keys; | ||
for(const auto &id_and_function : goto_functions.function_map) | ||
{ | ||
const auto &instructions = id_and_function.second.body.instructions; | ||
possible_keys.reserve( | ||
possible_keys.size() + | ||
std::distance(instructions.begin(), instructions.end())); | ||
for(auto it = instructions.begin(); it != instructions.end(); ++it) | ||
possible_keys.push_back(it); | ||
} | ||
entry_map.setup_for_keys(possible_keys.begin(), possible_keys.end()); | ||
compute_edges(goto_functions); | ||
} | ||
|
||
void operator()(P &goto_program) | ||
{ | ||
goto_functionst goto_functions; | ||
std::vector<goto_programt::const_targett> possible_keys; | ||
const auto &instructions = goto_program.instructions; | ||
possible_keys.reserve( | ||
std::distance(instructions.begin(), instructions.end())); | ||
for(auto it = instructions.begin(); it != instructions.end(); ++it) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why |
||
possible_keys.push_back(it); | ||
entry_map.setup_for_keys(possible_keys.begin(), possible_keys.end()); | ||
compute_edges(goto_functions, goto_program); | ||
} | ||
|
||
|
@@ -187,19 +239,19 @@ class cfg_baset:public grapht< cfg_base_nodet<T, I> > | |
/// in that particular case you should just use `cfg.get_node(i)`). Storing | ||
/// node indices saves a map lookup, so it can be worthwhile when you expect | ||
/// to repeatedly look up the same program point. | ||
entryt get_node_index(const I &program_point) const | ||
entryt get_node_index(const goto_programt::const_targett &program_point) const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could use pass-by-value 🍐 |
||
{ | ||
return entry_map.at(program_point); | ||
} | ||
|
||
/// Get the CFG graph node relating to \p program_point. | ||
nodet &get_node(const I &program_point) | ||
nodet &get_node(const goto_programt::const_targett &program_point) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍐 |
||
{ | ||
return (*this)[get_node_index(program_point)]; | ||
} | ||
|
||
/// Get the CFG graph node relating to \p program_point. | ||
const nodet &get_node(const I &program_point) const | ||
const nodet &get_node(const goto_programt::const_targett &program_point) const | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍐 |
||
{ | ||
return (*this)[get_node_index(program_point)]; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it might fix an obscure bug or two...