37 exprt::operandst::const_iterator it1=arguments.begin();
40 for(
const auto &identifier : parameter_identifiers)
44 source_location.
as_string() +
": no identifier for function parameter");
49 const typet ¶meter_type = symbol.
type;
59 if(it1==arguments.end())
62 log.
warning() <<
"call to '" << function_name <<
"': "
63 <<
"not enough arguments, "
79 if(parameter_type != actual.
type())
81 const typet &f_partype = parameter_type;
86 (f_partype.
id() == ID_pointer && f_acttype.
id() == ID_pointer) ||
87 (f_partype.
id() == ID_pointer && f_acttype.
id() == ID_array &&
93 else if((f_partype.
id()==ID_signedbv ||
94 f_partype.
id()==ID_unsignedbv ||
95 f_partype.
id()==ID_bool) &&
96 (f_acttype.
id()==ID_signedbv ||
97 f_acttype.
id()==ID_unsignedbv ||
98 f_acttype.
id()==ID_bool))
115 if(it1!=arguments.end())
119 if(it1!=arguments.end())
135 for(
const auto &identifier : parameter_identifiers)
139 source_location.
as_string() +
": no identifier for function parameter");
146 dead->code_nonconst().add_source_location() = source_location;
155 for(goto_programt::instructionst::iterator
160 if(it->is_set_return_value())
196 if(!property_class.
empty())
199 if(!property_id.
empty())
226 const irep_idt identifier=
function.get_identifier();
235 "final instruction of a function must be an END_FUNCTION");
261 unsigned begin_location_number=t_it->location_number;
264 t_it->is_end_function(),
265 "final instruction of a function must be an END_FUNCTION");
266 unsigned end_location_number=t_it->location_number;
268 unsigned call_location_number=target->location_number;
272 begin_location_number,
274 call_location_number,
282 instruction.source_location_nonconst(), target->source_location());
285 if(instruction.has_condition())
288 instruction.condition_nonconst(), target->source_location());
305 const bool transitive,
306 const bool force_full,
314 std::cout <<
"Expanding call:\n";
315 target->output(std::cout);
322 get_call(target, lhs, function_expr, arguments);
324 if(function_expr.
id()!=ID_symbol)
329 const irep_idt identifier=
function.get_identifier();
340 log.
warning() <<
"recursion is ignored on call to '" << identifier <<
"'"
344 target->turn_into_skip();
349 goto_functionst::function_mapt::iterator f_it=
355 log.
warning() <<
"missing function '" << identifier <<
"' is ignored"
359 target->turn_into_skip();
386 log.
progress() <<
"Inserting " << identifier <<
" into caller"
393 log.
progress() <<
"Removing " << identifier <<
" from cache"
399 cache.erase(identifier);
426 log.
warning() <<
"no body for function '" << identifier <<
"'"
440 lhs = it->call_lhs();
441 function = it->call_function();
442 arguments = it->call_arguments();
452 const bool force_full)
458 const irep_idt identifier = gf_entry.first;
465 goto_inline(identifier, goto_function, inline_map, force_full);
480 const bool force_full)
494 const bool force_full)
497 for(
const auto &call : call_list)
502 goto_program, inline_map, call.second, force_full, call.first);
510 const bool force_full)
514 finished_sett::const_iterator f_it=
finished_set.find(identifier);
523 const inline_mapt::const_iterator im_it=inline_map.find(identifier);
525 if(im_it==inline_map.end())
530 if(call_list.empty())
535 for(
const auto &call : call_list)
537 const bool transitive=call.second;
561 const bool force_full)
565 cachet::const_iterator c_it=
cache.find(identifier);
567 if(c_it!=
cache.end())
572 "body of cached functions must be available");
578 cached.
body.
empty(),
"body of new function in cache must be empty");
593 if(i_it->is_function_call())
594 call_list.push_back(i_it);
597 if(call_list.empty())
602 for(
const auto &call : call_list)
631 goto_functionst::function_mapt::const_iterator f_it=
636 inline_mapt::const_iterator im_it=inline_map.find(identifier);
638 if(im_it==inline_map.end())
643 if(call_list.empty())
648 for(
const auto &call : call_list)
654 if(target->function!=identifier)
661 target->location_number <= ln)
666 if(!target->is_function_call())
669 ln=target->location_number;
692 for(
const auto &it : inline_map)
697 out <<
"Function: " <<
id <<
"\n";
699 goto_functionst::function_mapt::const_iterator f_it=
708 "cannot inline function with empty body");
710 for(
const auto &call : call_list)
713 bool transitive=call.second;
717 out <<
" Transitive: " << transitive <<
"\n";
729 for(
auto it=
cache.begin(); it!=
cache.end(); it++)
731 if(it!=
cache.begin())
734 out << it->first <<
"\n";
749 for(
const auto &it : function_map)
756 cleanup(goto_function.
body);
762 const unsigned begin_location_number,
763 const unsigned end_location_number,
764 const unsigned call_location_number,
769 PRECONDITION(end_location_number >= begin_location_number);
773 log_map.find(start) == log_map.end(),
774 "inline function should be registered once in map of inline functions");
802 "'to' target function is not allowed to be empty");
804 it1->location_number == it2->location_number,
805 "both functions' instruction should point to the same source");
807 log_mapt::const_iterator l_it=log_map.find(it1);
808 if(l_it!=log_map.end())
812 log_map.find(it2) == log_map.end(),
813 "'to' target is not expected to be in the log_map");
840 for(
const auto &it : log_map)
846 PRECONDITION(start->location_number <= end->location_number);
857 {
"originalSegment", std::move(json_orig)},
858 {
"inlinedSegment", std::move(json_new)}};
860 json_inlined.
push_back(std::move(
object));
863 return std::move(json_result);
A goto_instruction_codet representing an assignment in the program.
A goto_instruction_codet representing the declaration of a local variable.
codet representation of an expression statement.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
const char * c_str() const
Base class for all expressions.
std::vector< exprt > operandst
source_locationt & add_source_location()
const source_locationt & source_location() const
typet & type()
Return the type of the expression.
std::map< irep_idt, goto_functiont > function_mapt
function_mapt function_map
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
std::vector< irep_idt > parameter_identifierst
parameter_identifierst parameter_identifiers
The identifiers of the parameters of this function.
void copy_from(const goto_functiont &other)
bool body_available() const
goto_programt::const_targett end
unsigned end_location_number
unsigned begin_location_number
unsigned call_location_number
void copy_from(const goto_programt &from, const goto_programt &to)
jsont output_inline_log_json() const
void cleanup(const goto_programt &goto_program)
void add_segment(const goto_programt &goto_program, const unsigned begin_location_number, const unsigned end_location_number, const unsigned call_location_number, const irep_idt function)
bool is_ignored(const irep_idt id) const
void goto_inline_nontransitive(const irep_idt identifier, goto_functiont &goto_function, const inline_mapt &inline_map, const bool force_full)
std::list< callt > call_listt
goto_functionst & goto_functions
static void get_call(goto_programt::const_targett target, exprt &lhs, exprt &function, exprt::operandst &arguments)
const goto_functiont & goto_inline_transitive(const irep_idt identifier, const goto_functiont &goto_function, const bool force_full)
void goto_inline(const irep_idt identifier, goto_functiont &goto_function, const inline_mapt &inline_map, const bool force_full=false)
Inline all of the chosen calls in a given function.
recursion_sett recursion_set
void insert_function_body(const goto_functiont &f, goto_programt &dest, goto_programt::targett target, const exprt &lhs, const symbol_exprt &function, const exprt::operandst &arguments)
bool check_inline_map(const inline_mapt &inline_map) const
void parameter_destruction(const goto_programt::targett target, const goto_functiont::parameter_identifierst ¶meter_identifiers, goto_programt &dest)
const bool adjust_function
goto_inline_logt inline_log
void output_inline_map(std::ostream &out, const inline_mapt &inline_map)
goto_functionst::goto_functiont goto_functiont
void parameter_assignments(const goto_programt::targett target, const irep_idt &function_name, const goto_functiont::parameter_identifierst ¶meter_identifiers, const exprt::operandst &arguments, goto_programt &dest)
std::map< irep_idt, call_listt > inline_mapt
void replace_return(goto_programt &body, const exprt &lhs)
finished_sett finished_set
void expand_function_call(goto_programt &dest, const inline_mapt &inline_map, const bool transitive, const bool force_full, goto_programt::targett target)
Inlines a single function call Calls out to goto_inline_transitive or goto_inline_nontransitive.
void output_cache(std::ostream &out) const
This class represents an instruction in the GOTO intermediate representation.
bool is_end_function() const
static const unsigned nil_target
Uniquely identify an invalid target or location.
const source_locationt & source_location() const
A generic container class for the GOTO intermediate representation of one function.
instructionst instructions
The list of instructions in the goto program.
void copy_from(const goto_programt &src)
Copy a full goto program, preserving targets.
static instructiont make_dead(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
void destructive_insert(const_targett target, goto_programt &p)
Inserts the given program p before target.
instructionst::iterator targett
instructionst::const_iterator const_targett
void destructive_append(goto_programt &p)
Appends the given program p to *this. p is destroyed.
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
static instructiont make_other(const goto_instruction_codet &_code, const source_locationt &l=source_locationt::nil())
static instructiont make_location(const source_locationt &l)
targett add(instructiont &&instruction)
Adds a given instruction at the end.
bool empty() const
Is the program empty?
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
std::list< targett > targetst
const irept & find(const irep_idt &name) const
const irep_idt & id() const
jsont & push_back(const jsont &json)
json_arrayt & make_array()
source_locationt source_location
mstreamt & warning() const
mstreamt & progress() const
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
A side_effect_exprt that returns a non-deterministically chosen value.
void set_comment(const irep_idt &comment)
void set_property_id(const irep_idt &property_id)
const irep_idt & get_property_id() const
const irep_idt & get_comment() const
void set_property_class(const irep_idt &property_class)
const irep_idt & get_property_class() const
std::string as_string() const
Expression to hold a symbol (variable)
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
#define Forall_operands(it, expr)
void replace_location(source_locationt &dest, const source_locationt &new_location)
Function Inlining This is a class that encapsulates the state and functionality needed to do inline m...
#define forall_goto_program_instructions(it, program)
#define Forall_goto_program_instructions(it, program)
static std::string comment(const rw_set_baset::entryt &entry, bool write)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
const type_with_subtypet & to_type_with_subtype(const typet &type)