36 std::unordered_map<irep_idt, unsigned, irep_id_hash>
map_unique;
53 unsigned &stack_scope)
55 message.
debug() <<
"I resolve " << symb <<
" with " 57 if(pointer_to_fun.find(symb)==pointer_to_fun.end())
61 goto_function=pointer_to_fun[symb];
62 stack_scope=pointer_to_stack[symb];
74 return add(symb, goto_function, callsite_stack.size());
81 pointer_to_fun[symb]=goto_function;
82 pointer_to_stack[symb]=scope;
85 if(fun_id_to_invok.find(function_symb.
base_name)==fun_id_to_invok.end())
86 fun_id_to_invok[function_symb.
base_name]=scope;
93 assert(pointer_to_fun.find(symb)!=pointer_to_fun.end());
94 pointer_to_fun.erase(symb);
100 return pointer_to_fun.find(symb)!=pointer_to_fun.end();
105 return pointer_to_fun[symb];
114 unsigned stack_scope);
127 goto_programt::instructionst::iterator it);
134 :symbol_table(_symbol_table), goto_functions(_goto_functions),
135 ns(_symbol_table), message(_message)
152 unsigned stack_scope)
160 goto_programt::const_targetst::const_iterator
163 std::string last_suffix=
"";
166 current_call>=stack_scope;
169 message.
debug() <<
"current_call=" << current_call <<
" stack_scope=" 170 << stack_scope <<
" callsite_stack.size()=" <<
callsite_stack.size()
176 const irep_idt function_id=(*callsite)->function;
181 std::string suffix=
"$";
183 if(current_call>stack_scope)
188 suffix+=std::to_string(
map_unique[function_id]);
194 suffix+=std::to_string(
map_unique[function_id]);
199 message.
debug() <<
"duplicate function: " << function_id
206 pfunction_dup=&function_dup;
209 it!=function_dup.
body.instructions.end(); ++it)
210 it->function=function_new_id;
216 for(code_typet::parameterst::iterator it=args.begin();
217 it!=args.end(); ++it)
227 dup_fun_symb=fun_symb;
234 message.
debug() <<
"new function " << function_new_id <<
" created." 243 message.
debug() <<
"we then modify the previous callers" 248 pfunction_dup->
body.instructions;
253 it->source_location!=(*callsite)->source_location &&
254 it!=new_instructions.end();
259 assert(it->source_location==(*callsite)->source_location);
261 assert(function_called.
id()==ID_symbol);
263 symbol_fun_called.set_identifier(
264 id2string(symbol_fun_called.get_identifier())+last_suffix);
269 for(code_function_callt::argumentst::iterator arg_it=args.begin();
270 arg_it!=args.end(); ++arg_it)
272 if(arg_it->id()==ID_symbol)
281 else if(arg_it->id()==ID_address_of)
291 new_callsite_stack.push_back(it);
300 pfunction_dup->
body.instructions;
305 it->source_location!=(*callsite)->source_location &&
306 it!=new_instructions.end();
314 assert(it->source_location==(*callsite)->source_location);
318 new_callsite_stack.push_back(it);
328 for(goto_programt::const_targetst::const_iterator it=callsite;
330 new_callsite_stack.push_back(*it);
340 goto_programt::instructionst::iterator it)
355 code_typet::parameterst::const_iterator cor_arg_it=
356 cor_function.type.parameters().begin();
358 for(code_function_callt::argumentst::const_iterator arg_it=arg.begin();
360 ++arg_it, ++cor_arg_it)
362 assert(cor_arg_it!=cor_function.type.parameters().end());
364 if(arg_it->id()!=ID_symbol && arg_it->id()!=ID_address_of)
367 if(arg_it->id()==ID_address_of)
373 assert(arg_expr.
id()==ID_symbol);
380 for(std::unordered_map<irep_idt, unsigned, irep_id_hash>::const_iterator
387 cfpp.
add(cor_arg_it->get_base_name(), arg_symbol_expr);
388 insert(cor_arg_it->get_base_name());
407 insert(cor_arg_it->get_base_name());
418 for(const_iterator arg_it=begin(); arg_it!=end(); ++arg_it)
450 if(rhs.
id()!=ID_address_of)
454 if(addr_rhs.
object().
id()!=ID_symbol
460 if(lhs.
id()!=ID_symbol || lhs.
type().
id()!=ID_pointer)
468 else if(it->is_function_call())
475 if(fun.
id()==ID_dereference)
478 if(fun_pointer.
id()!=ID_symbol)
488 unsigned stack_scope=0;
502 arg_stack.
add_args(const_function, it);
516 else if(fun.
id()==ID_symbol)
526 arg_stack.
add_args(fun_symbol_expr, it);
535 else if(it->is_end_function())
552 goto_functions, message);
irep_idt name
The unique identifier.
virtual bool lookup(const irep_idt &name, const symbolt *&symbol) const
symbolt & lookup(const irep_idt &identifier)
Find a symbol in the symbol table.
std::set< irep_idt > functions_met
const std::string & id2string(const irep_idt &d)
std::list< instructiont > instructionst
goto_functionst & goto_functions
std::unordered_map< irep_idt, unsigned, irep_id_hash > fun_id_to_invok
const irep_idt & get_identifier() const
Goto Programs with Functions.
bool resolve(const irep_idt &symb, symbol_exprt &goto_function, unsigned &stack_scope)
std::vector< parametert > parameterst
std::unordered_map< irep_idt, unsigned, irep_id_hash > map_unique
void add_args(const symbol_exprt &const_function, goto_programt::instructionst::iterator it)
adds const pointers (instantiated here or propagated) passed as arguments in the map ...
irep_idt pretty_name
Language-specific display name.
exprt::operandst argumentst
goto_programt::const_targetst callsite_stack
Symbol table entry.This is a symbol in the symbol table, stored in an object of type symbol_tablet...
static mstreamt & eom(mstreamt &m)
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast a generic exprt to a dereference_exprt.
const_function_pointer_propagationt & cfpp
bool add(const irep_idt &symb, const symbol_exprt &goto_function, unsigned scope)
Constant Function Pointer Propagation.
const code_assignt & to_code_assign(const codet &code)
const irep_idt & id() const
symbol_exprt get(const irep_idt &symb)
void copy_from(const goto_function_templatet &other)
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast a generic exprt to an address_of_exprt.
arg_stackt(const_function_pointer_propagationt &_cfpp)
std::unordered_map< irep_idt, unsigned, irep_id_hash > pointer_to_stack
source_locationt source_location
void dup_caller_and_inline_callee(const symbol_exprt &function, unsigned stack_scope)
static irep_idt entry_point()
bool has(const irep_idt &symb) const
API to expression classes.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
Operator to return the address of an object.
function_mapt function_map
const_function_pointer_propagationt(symbol_tablet &_symbol_table, goto_functionst &_goto_functions, messaget &_message)
void propagate_const_function_pointers(symbol_tablet &symbol_table, goto_functionst &goto_functions, message_handlert &message_handler)
Base class for all expressions.
const parameterst & parameters() const
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast a generic exprt to a symbol_exprt.
irep_idt base_name
Base (non-scoped) name.
std::unordered_map< irep_idt, symbol_exprt, irep_id_hash > pointer_to_fun
void propagate(const irep_idt &function)
symbol_tablet & symbol_table
#define Forall_goto_program_instructions(it, program)
Expression to hold a symbol (variable)
bool add(const irep_idt &symb, const symbol_exprt &goto_function)
std::list< const_targett > const_targetst
bool remove(const irep_idt &symb)
const code_function_callt & to_code_function_call(const codet &code)
instructionst::iterator targett