94 switch(relationship_type)
98 relationships.insert(std::make_pair(BIT_VALUE,
ALL_FUNCTIONS));
99 relationships.insert(std::make_pair(CALL_GRAPH_BUILTIN_CALL,
ALL_FUNCTIONS));
100 relationships.insert(std::make_pair(COMPUTE_IMPLICIT_CALLS,
ALL_FUNCTIONS));
102 relationships.insert(std::make_pair(IR_LOWERING,
ALL_FUNCTIONS));
103 relationships.insert(std::make_pair(PARM2SSA,
ALL_FUNCTIONS));
106 relationships.insert(std::make_pair(SOFT_FLOAT_CG_EXT,
ALL_FUNCTIONS));
108 relationships.insert(std::make_pair(USE_COUNTING,
ALL_FUNCTIONS));
109 relationships.insert(std::make_pair(UN_COMPARISON_LOWERING,
ALL_FUNCTIONS));
125 return relationships;
139 const auto design_flow_step = design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step;
140 relationships.insert(design_flow_step);
142 fun_id_to_restart.clear();
149 const auto design_flow_step = design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step;
150 relationships.insert(design_flow_step);
152 fun_id_to_restart_caller.clear();
159 std::map<unsigned int, unsigned int> cur_bitvalue_ver;
160 std::map<unsigned int, unsigned int> cur_bb_ver;
161 const auto CGMan =
AppM->CGetCallGraphManager();
162 for(
const auto i : CGMan->GetReachedBodyFunctions())
164 const auto FB =
AppM->CGetFunctionBehavior(i);
165 cur_bitvalue_ver[i] = FB->GetBitValueVersion();
166 cur_bb_ver[i] = FB->GetBBVersion();
174 "Bit value IPA should not be executed");
175 if(!
AppM->ApplyNewTransformation())
184 const auto CGMan =
AppM->CGetCallGraphManager();
185 const auto cg = CGMan->CGetCallGraph();
186 const auto reached_body_fun_ids = CGMan->GetReachedBodyFunctions();
187 auto root_fun_ids = CGMan->GetRootFunctions();
188 const auto addressed_functions = CGMan->GetAddressedFunctions();
189 root_fun_ids.insert(addressed_functions.begin(), addressed_functions.end());
193 for(
const auto& cvertex : reached_body_fun_ids)
195 vertex_subset.insert(CGMan->GetVertex(cvertex));
197 const auto subgraph = CGMan->CGetCallSubGraph(vertex_subset);
199 for(boost::tie(e_it, e_it_end) =
boost::edges(*subgraph); e_it != e_it_end; ++e_it)
201 const auto* info = Cget_edge_info<FunctionEdgeInfo, const CallGraph>(*e_it, *subgraph);
202 if(info->indirect_call_points.size())
210 for(
const auto& fu_id : reached_body_fun_ids)
212 const auto fu_name =
AppM->CGetFunctionBehavior(fu_id)->CGetBehavioralHelper()->get_function_name();
214 "-->Analyzing function \"" + fu_name +
"\": id = " +
STR(fu_id));
215 const auto fu_node =
TM->CGetTreeReindex(fu_id);
216 const auto fd = GetPointer<function_decl>(
GET_CONST_NODE(fu_node));
217 THROW_ASSERT(fd && fd->body,
"Node is not a function or it hasn't a body");
222 const auto ft = GetPointer<const function_type>(
GET_CONST_NODE(fu_type));
224 "is_root = " +
STR(root_fun_ids.find(fu_id) != root_fun_ids.end()));
228 for(
const auto& parm_decl_node : fd->list_of_args)
231 const auto parmssa =
TM->GetTreeNode(p_decl_id);
232 THROW_ASSERT(parmssa->get_kind() == ssa_name_K,
"expected an ssa variable");
234 "parm_decl ssa id: " +
STR(p_decl_id) +
" " + parmssa->ToString());
235 const auto p = GetPointerS<ssa_name>(parmssa);
242 "unexpected condition " + parmssa->ToString() +
" for function " + fu_name);
257 "<--function return type is not considered: " +
STR(ft->retn));
275 for(
const auto& fu_id : reached_body_fun_ids)
277 const auto fu_name =
AppM->CGetFunctionBehavior(fu_id)->CGetBehavioralHelper()->get_function_name();
279 "-->Analyzing function \"" + fu_name +
"\": id = " +
STR(fu_id));
281 const auto fu_node =
TM->CGetTreeReindex(fu_id);
282 const auto fd = GetPointer<const function_decl>(
GET_CONST_NODE(fu_node));
283 THROW_ASSERT(fd && fd->body,
"Node is not a function or it hasn't a body");
288 const auto ft = GetPointer<const function_type>(
GET_CONST_NODE(fu_type));
291 if(root_fun_ids.find(fu_id) == root_fun_ids.end())
297 "-->Propagating bitvalue of the return value of function " + fu_name);
307 if(!
AppM->ApplyNewTransformation())
317 current.insert(std::make_pair(fu_id,
best.at(fu_id)));
321 const auto fu_cgv = CGMan->GetVertex(fu_id);
323 boost::tie(ie_it, ie_end) = boost::in_edges(fu_cgv, *cg);
324 for(; ie_it != ie_end; ie_it++)
326 const auto caller_id = CGMan->get_function(boost::source(*ie_it, *cg));
327 if(reached_body_fun_ids.find(caller_id) == reached_body_fun_ids.cend())
332 "-->examining caller \"" +
333 AppM->CGetFunctionBehavior(caller_id)->CGetBehavioralHelper()->get_function_name() +
334 "\": id = " +
STR(caller_id));
335 const auto call_edge_info = cg->CGetFunctionEdgeInfo(*ie_it);
336 for(
const auto& i : call_edge_info->direct_call_points)
339 const auto call_node =
TM->CGetTreeNode(i);
341 "-->examining direct call point " + call_node->ToString());
342 if(call_node->get_kind() == gimple_assign_K)
345 const auto ga = GetPointer<const gimple_assign>(call_node);
354 const auto s = GetPointerS<const ssa_name>(
GET_CONST_NODE(ga->op0));
359 AppM->CGetFunctionBehavior(caller_id)->CGetBehavioralHelper()->get_function_name() +
360 " calls function " + fu_name +
362 " and assigns the return value to ssa " +
STR(s) +
364 THROW_ASSERT(!s->bit_values.empty(),
"unexpected assignment of return value to ssa " +
STR(s) +
365 " with id " +
STR(s->index) +
" and empty bit_values");
368 "res_fanout from ssa " +
STR(s) +
" id: " +
STR(s->index) +
370 THROW_ASSERT(res_fanout.size(),
"unexpected condition");
371 res =
inf(res, res_fanout, fu_node);
374 auto res_sup =
sup(
best.at(fu_id), res_fanout, fu_node);
380 " is better than: " + s->bit_values);
390 else if(call_node->get_kind() == gimple_call_K)
396 THROW_ERROR(
"unexpected condition " + call_node->ToString());
401 "<--examined caller \"" +
402 AppM->CGetFunctionBehavior(caller_id)->CGetBehavioralHelper()->get_function_name() +
403 "\": id = " +
STR(caller_id));
410 "---After backward id: " +
STR(fu_id) +
416 "---After mix id: " +
STR(fu_id) +
422 "<--Propagated bitvalue of the return value of function " + fu_name);
427 "Return value function " + fu_name +
" not handled bitvalue");
432 for(
const auto& pd : fd->list_of_args)
434 if(!
AppM->ApplyNewTransformation())
439 const auto parmssa =
TM->CGetTreeNode(pd_id);
440 THROW_ASSERT(parmssa->get_kind() == ssa_name_K,
"expected an ssa variable");
442 "parm_decl ssa id: " +
STR(pd_id) +
" " + parmssa->ToString());
448 "param \"" +
STR(pd) +
"\" id: " +
STR(pd_id) +
" not handled by bitvalue");
450 "-->Propagating bitvalue through parameter " +
STR(
GET_NODE(pd)) +
" of function " +
451 fu_name +
" parm id: " +
STR(pd_id));
464 current.insert(std::make_pair(pd_id,
best.at(pd_id)));
468 const auto fu_cgv = CGMan->GetVertex(fu_id);
470 boost::tie(ie_it, ie_end) = boost::in_edges(fu_cgv, *cg);
471 for(; ie_it != ie_end; ie_it++)
473 const auto caller_id = CGMan->get_function(boost::source(*ie_it, *cg));
474 if(reached_body_fun_ids.find(caller_id) == reached_body_fun_ids.cend())
478 const auto caller_name =
479 AppM->CGetFunctionBehavior(caller_id)->CGetBehavioralHelper()->get_function_name();
481 "-->examining caller \"" + caller_name +
"\": id = " +
STR(caller_id));
482 const auto call_edge_info = cg->CGetFunctionEdgeInfo(*ie_it);
483 for(
const auto& i : call_edge_info->direct_call_points)
486 std::deque<bit_lattice> res_tmp;
488 const auto call_node =
TM->CGetTreeNode(i);
489 if(call_node->get_kind() == gimple_assign_K)
491 const auto ga = GetPointer<const gimple_assign>(call_node);
494 "unexpected pattern");
496 const auto ce = GetPointer<const call_expr>(
GET_CONST_NODE(ga->op1));
497 const auto actual_parms = ce->args;
498 THROW_ASSERT(ce->args.size() == fd->list_of_args.size(),
499 "actual parameters: " +
STR(ce->args.size()) +
500 " formal parameters: " +
STR(fd->list_of_args.size()));
501 const auto ap = std::next(ce->args.cbegin(), args_n - 1);
503 const auto& ap_node = *ap;
507 "function " + caller_name +
" calls function " + fu_name +
"\nformal param " +
510 "\ndifferent signedness!");
511 if(ap_kind == ssa_name_K)
513 const auto ssa = GetPointerS<const ssa_name>(
GET_CONST_NODE(ap_node));
514 res_tmp = ssa->bit_values.empty() ?
518 "actual parameter " +
STR(ssa) +
" id: " +
STR(ssa->index) +
521 else if(ap_kind == integer_cst_K)
527 "actual parameter " +
STR(ap_node) +
537 else if(call_node->get_kind() == gimple_call_K)
539 const auto gc = GetPointer<const gimple_call>(call_node);
540 const auto actual_parms = gc->args;
541 THROW_ASSERT(gc->args.size() == fd->list_of_args.size(),
542 "actual parameters: " +
STR(gc->args.size()) +
543 " formal parameters: " +
STR(fd->list_of_args.size()));
544 const auto ap = std::next(gc->args.cbegin(), args_n - 1);
546 const auto& ap_node = *ap;
550 "function " + caller_name +
" calls function " + fu_name +
"\nformal param " +
553 "\ndifferent signedness!");
554 if(ap_kind == ssa_name_K)
556 const auto ssa = GetPointerS<const ssa_name>(
GET_CONST_NODE(ap_node));
557 res_tmp = ssa->bit_values.empty() ?
561 "actual parameter " +
STR(ssa) +
" id: " +
STR(ssa->index) +
564 else if(ap_kind == integer_cst_K)
570 "actual parameter " +
STR(ap_node) +
583 "this call point is not in the form (ssa_name = call_expr)\n" 584 "no way to retrieve the actual parameters of the call");
586 caller_name +
" in operation " +
STR(call_node));
588 res =
inf(res, res_tmp, parmssa);
594 "<--examined caller \"" + caller_name +
"\": id = " +
STR(caller_id));
601 "---After forward id: " +
STR(pd_id) +
608 "---After mix id: " +
STR(pd_id) +
612 "<--Propagated bitvalue through parameter " +
STR(
GET_CONST_NODE(pd)) +
" of function " +
613 fu_name +
" parm id: " +
STR(pd_id));
619 " not handled by bitvalue");
629 for(
const auto& b :
best)
631 const auto& tn_id = b.first;
634 "---updating node id: " +
STR(tn_id) +
" bitstring: " + new_bitvalue);
635 const auto tn =
TM->CGetTreeReindex(tn_id);
638 std::string null_string =
"";
639 std::string* old_bitvalue = &null_string;
640 unsigned long long size = 0u;
641 auto restart_fun_id = 0u;
642 if(
kind == function_decl_K)
644 auto fd = GetPointerS<function_decl>(
GET_NODE(tn));
646 "---is a function_decl: " +
647 AppM->CGetFunctionBehavior(fd->index)->CGetBehavioralHelper()->get_function_name() +
648 " id: " +
STR(fd->index));
650 old_bitvalue = &fd->bit_values;
655 const auto ft = GetPointer<const function_type>(
GET_CONST_NODE(fu_type));
658 restart_fun_id = fd->index;
660 else if(
kind == ssa_name_K)
662 auto pd = GetPointerS<ssa_name>(
GET_NODE(tn));
664 old_bitvalue = &pd->bit_values;
667 const auto pdecl = GetPointerS<const parm_decl>(
GET_CONST_NODE(pd->var));
676 if(old_bitvalue->empty())
689 "---old bitstring: " + *old_bitvalue +
" new bitstring: " + new_bitvalue +
690 " restart = " + (restart ?
"YES" :
"NO") +
" " +
691 AppM->CGetFunctionBehavior(restart_fun_id)->CGetBehavioralHelper()->get_function_name());
692 *old_bitvalue = new_bitvalue;
694 "---updated best id: " +
STR(tn_id) +
" bitstring: " + *old_bitvalue);
699 "restart function " +
700 AppM->CGetFunctionBehavior(restart_fun_id)->CGetBehavioralHelper()->get_function_name());
702 const auto fu_cgv = CGMan->GetVertex(restart_fun_id);
704 boost::tie(ie_it, ie_end) = boost::in_edges(fu_cgv, *cg);
705 for(; ie_it != ie_end; ie_it++)
707 const auto caller_id = CGMan->get_function(boost::source(*ie_it, *cg));
708 if(reached_body_fun_ids.find(caller_id) == reached_body_fun_ids.cend())
712 const auto call_edge_info = cg->CGetFunctionEdgeInfo(*ie_it);
713 if(!call_edge_info->direct_call_points.empty())
717 AppM->CGetFunctionBehavior(caller_id)->CGetBehavioralHelper()->get_function_name());
731 const auto FB =
AppM->GetFunctionBehavior(i);
732 FB->UpdateBitValueVersion();
736 const auto FB =
AppM->GetFunctionBehavior(i);
737 FB->UpdateBitValueVersion();
740 for(
const auto& i : CGMan->GetReachedBodyFunctions())
742 const auto FB =
AppM->CGetFunctionBehavior(i);
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
BitValueIPA(const application_managerRef AM, const DesignFlowManagerConstRef dfm, const ParameterConstRef parameters)
STD include.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
std::deque< bit_lattice > create_bitstring_from_constant(integer_cst_t value, unsigned long long len, bool signed_value)
Creates a bitstring from a constant input.
File containing functions and utilities to support the printing of debug messagges.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
Step successfully executed.
std::deque< bit_lattice > create_x_bitstring(size_t lenght)
Create a bitstring containing bits initialized at <X>
CustomOrderedSet< unsigned int > fun_id_to_restart_caller
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
static bool isBetter(const std::string &a_string, const std::string &b_string)
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
bool IsHandledByBitvalue(const tree_nodeConstRef &tn) const
Returns true if the type identified by type_id is handled by bitvalue analysis.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
This class contains the base representation for a generic frontend flow step which works on a single ...
Data structure describing a basic block at tree level.
redefinition of map to manage ordered/unordered structures
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static bool IsScalarType(const tree_nodeConstRef &type)
Return true if the treenode is an int, an unsigned, a real or a Boolean data type.
boost::graph_traits< graph >::edge_iterator EdgeIterator
edge_iterator definition.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
CustomSet< unsigned int > signed_var
Set storing the signed ssa.
std::string bitstring_to_string(const std::deque< bit_lattice > &bitstring)
Translates a bitstring ( expressed as an std::deque of bit_lattice ) into a string of characters...
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
std::deque< bit_lattice > inf(const std::deque< bit_lattice > &a, const std::deque< bit_lattice > &b, const unsigned int output_uid) const
Computes the inf between two bitstrings.
DesignFlowStep_Status Exec() override
Execute the step.
std::deque< bit_lattice > create_u_bitstring(size_t lenght)
Creates a bitstring containing bits initialized at <U>
CustomMap< unsigned int, std::deque< bit_lattice > > current
Map of the current bit-values of each variable.
bool update_current(std::deque< bit_lattice > &res, const tree_nodeConstRef &tn)
Given a bitstring res, and the id of a tree node ouput_uid, this functions checks if it is necessary ...
Classes to describe design flow graph.
Target must be reexecuted.
redefinition of set to manage ordered/unordered structures
static unsigned long long size(const tree_managerConstRef tm, unsigned int index)
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
void ComputeRelationships(DesignFlowStepSet &relationships, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
#define GET_CONST_NODE(t)
static unsigned long long Size(const tree_nodeConstRef &t)
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
const tree_managerConstRef TM
std::map< unsigned int, unsigned int > last_bitvalue_ver
This file collects some utility functions.
bool mix()
Mixes the content of current and best using the sup operation, storing the result in the best map...
std::deque< bit_lattice > string_to_bitstring(const std::string &s)
inverse of bitstring_to_string
std::deque< bit_lattice > sup(const std::deque< bit_lattice > &a, const std::deque< bit_lattice > &b, const unsigned int output_uid) const
Computes the sup between two bitstrings.
refcount< T > lock() const
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
Created on: June 27, 2016.
CustomMap< unsigned int, std::deque< bit_lattice > > best
Map of the best bit-values of each variable.
void clear()
Clean up the internal data structures.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
this class is used to manage the command-line or XML options.
std::string GetName() const override
Return the name of this design step.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
std::map< unsigned int, unsigned int > last_bb_ver
#define GET_INDEX_CONST_NODE(t)
CustomOrderedSet< unsigned int > fun_id_to_restart
stores the function ids of the functions whose Bit_Value intra procedural steps have to be invalidate...
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function.
#define NULL_VERTEX
null vertex definition
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
static const std::string ComputeSignature(const FrontendFlowStepType frontend_flow_step_type, const unsigned int function_id)
Compute the signature of a function frontend flow step.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...