47 #include "config_HAVE_PRAGMA_BUILT.hpp" 73 const DesignFlowManagerConstRef _design_flow_manager)
75 behavioral_helper(function_behavior->CGetBehavioralHelper()),
76 TM(_AppM->get_tree_manager())
87 switch(relationship_type)
93 relationships.insert(std::make_pair(HDL_VAR_DECL_FIX,
SAME_FUNCTION));
97 relationships.insert(std::make_pair(VAR_DECL_FIX,
SAME_FUNCTION));
99 relationships.insert(std::make_pair(CALL_GRAPH_BUILTIN_CALL,
SAME_FUNCTION));
100 relationships.insert(std::make_pair(DETERMINE_MEMORY_ACCESSES,
CALLED_FUNCTIONS));
101 relationships.insert(std::make_pair(FIX_STRUCTS_PASSED_BY_VALUE,
SAME_FUNCTION));
102 relationships.insert(std::make_pair(FUNCTION_CALL_TYPE_CLEANUP,
SAME_FUNCTION));
103 relationships.insert(std::make_pair(IR_LOWERING,
SAME_FUNCTION));
104 relationships.insert(std::make_pair(PARM_DECL_TAKEN_ADDRESS,
SAME_FUNCTION));
105 relationships.insert(std::make_pair(PARM2SSA,
SAME_FUNCTION));
106 relationships.insert(std::make_pair(REBUILD_INITIALIZATION,
SAME_FUNCTION));
107 relationships.insert(std::make_pair(REBUILD_INITIALIZATION2,
SAME_FUNCTION));
108 relationships.insert(std::make_pair(UN_COMPARISON_LOWERING,
SAME_FUNCTION));
124 return relationships;
130 const auto fd = GetPointer<const function_decl>(tn);
143 const bool before_dereference_unknown_addr =
function_behavior->get_dereference_unknown_addr();
144 const bool before_has_undefined_function_receiving_pointers =
159 for(
const auto& formal : fd->list_of_args)
166 for(
const auto& bb :
sl->list_of_bloc)
172 for(
const auto&
phi : bb.second->CGetPhiList())
176 for(
const auto& stmt : bb.second->CGetStmtList())
184 AppM->CGetCallGraphManager()->CGetCallGraph()->WriteDot(
"call_graph_memory_analysis.dot");
197 before_dereference_unknown_addr !=
function_behavior->get_dereference_unknown_addr() ||
198 before_has_undefined_function_receiving_pointers !=
204 bool no_dynamic_address)
207 const auto node_id = tn->
index;
208 const auto tn_kind = tn->get_kind();
209 if(tn_kind != addr_expr_K && tn_kind != var_decl_K)
221 "-->Analyzing node " + tn->ToString() +
222 " - Dynamic address: " + (dynamic_address ?
" true" :
"false") +
223 " - No dynamic address: " + (no_dynamic_address ?
"true" :
"false"));
226 const auto gn = GetPointer<const gimple_node>(tn);
227 if(gn && gn->use_set)
229 for(
const auto& usv : gn->use_set->variables)
237 case gimple_assign_K:
239 const auto gm = GetPointerS<const gimple_assign>(tn);
240 if(!gm->init_assignment)
244 analyze_node(gm->op1,
false,
false, gm->temporary_address);
249 const auto op0_kind = op0->get_kind();
250 const auto op1_kind = op1->get_kind();
254 bool is_a_vector_bitfield =
false;
255 if(op1_kind == bit_field_ref_K)
257 const auto bfr = GetPointerS<const bit_field_ref>(op1);
260 is_a_vector_bitfield =
true;
264 auto load_candidate =
265 (op1_kind == bit_field_ref_K && !is_a_vector_bitfield) || op1_kind == component_ref_K ||
266 op1_kind == indirect_ref_K || op1_kind == misaligned_indirect_ref_K || op1_kind == mem_ref_K ||
267 op1_kind == array_ref_K || op1_kind == target_mem_ref_K || op1_kind == target_mem_ref461_K;
268 if(op1_kind == realpart_expr_K || op1_kind == imagpart_expr_K)
270 const auto code1 =
GET_CONST_NODE(GetPointerS<const unary_expr>(op1)->op)->get_kind();
271 if((code1 == bit_field_ref_K && !is_a_vector_bitfield) || code1 == component_ref_K ||
272 code1 == indirect_ref_K || code1 == bit_field_ref_K || code1 == misaligned_indirect_ref_K ||
273 code1 == mem_ref_K || code1 == array_ref_K || code1 == target_mem_ref_K ||
274 code1 == target_mem_ref461_K)
276 load_candidate =
true;
278 if(code1 == var_decl_K &&
281 load_candidate =
true;
284 auto store_candidate = op0_kind == bit_field_ref_K || op0_kind == component_ref_K ||
285 op0_kind == indirect_ref_K || op0_kind == misaligned_indirect_ref_K ||
286 op0_kind == mem_ref_K || op0_kind == array_ref_K || op0_kind == target_mem_ref_K ||
287 op0_kind == target_mem_ref461_K;
288 if(op0_kind == realpart_expr_K || op0_kind == imagpart_expr_K)
290 const auto code0 =
GET_CONST_NODE(GetPointerS<const unary_expr>(op0)->op)->get_kind();
291 if((code0 == bit_field_ref_K) || code0 == component_ref_K || code0 == indirect_ref_K ||
292 code0 == misaligned_indirect_ref_K || code0 == mem_ref_K || code0 == array_ref_K ||
293 code0 == target_mem_ref_K || code0 == target_mem_ref461_K)
295 store_candidate =
true;
297 if(code0 == var_decl_K &&
300 store_candidate =
true;
303 if(!gm->clobber && !gm->init_assignment && op0_type && op1_type && op1->get_kind() != insertvalue_expr_K &&
304 op1->get_kind() != extractvalue_expr_K &&
306 GET_CONST_NODE(op1_type)->get_kind() == record_type_K && op1_kind != view_convert_expr_K) ||
308 GET_CONST_NODE(op1_type)->get_kind() == union_type_K && op1_kind != view_convert_expr_K) ||
315 if(op0_kind == mem_ref_K)
317 const auto mr = GetPointerS<const mem_ref>(op0);
320 else if(op0_kind == target_mem_ref461_K)
322 const auto tmr = GetPointerS<const target_mem_ref461>(op0);
337 if(op1_kind == mem_ref_K)
339 const auto mr = GetPointerS<const mem_ref>(op1);
342 else if(op1_kind == target_mem_ref461_K)
344 const auto tmr = GetPointerS<const target_mem_ref461>(op1);
363 if(op1_kind == constructor_K && GetPointerS<const constructor>(op1) &&
364 GetPointerS<const constructor>(op1)->list_of_idx_valu.empty())
393 const auto ue = GetPointerS<const unary_expr>(tn);
395 if(GetPointer<const addr_expr>(tn))
397 if(ue_op_kind == var_decl_K)
399 const auto vd = GetPointerS<const var_decl>(
GET_CONST_NODE(ue->op));
400 bool address_externally_used =
false;
402 if((((!vd->scpe ||
GET_NODE(vd->scpe)->get_kind() == translation_unit_decl_K) && !vd->static_flag) ||
407 address_externally_used =
true;
411 if(address_externally_used)
414 "---Global variable externally accessible found: " +
423 if((!no_dynamic_address || address_externally_used))
426 "---Variable for which the dynamic address is used-1: " +
429 if(!vd->readonly_flag)
434 if(left_p && !vd->readonly_flag)
442 if(vd->init && GET_CONST_NODE(vd->init)->get_kind() != string_cst_K)
448 else if(ue_op_kind == parm_decl_K)
451 if(!no_dynamic_address)
454 "---Variable for which the dynamic address is used-2: " +
464 else if(ue_op_kind == string_cst_K)
467 if(!no_dynamic_address)
470 "---Variable for which the dynamic address is used-3: " +
476 else if(ue_op_kind == result_decl_K)
479 if(!no_dynamic_address)
482 "---Variable for which the dynamic address is used-4: " +
488 "---result_decl variable added to memory: " +
491 else if(ue_op_kind == component_ref_K || ue_op_kind == realpart_expr_K || ue_op_kind == imagpart_expr_K ||
492 ue_op_kind == array_ref_K)
494 analyze_node(ue->op,
true, !no_dynamic_address, no_dynamic_address);
496 else if(ue_op_kind == function_decl_K)
498 analyze_node(ue->op,
false, !no_dynamic_address, no_dynamic_address);
500 else if(ue_op_kind == mem_ref_K)
502 const auto mr = GetPointerS<const mem_ref>(
GET_CONST_NODE(ue->op));
503 analyze_node(mr->op0, left_p, !no_dynamic_address, no_dynamic_address);
505 else if(ue_op_kind == target_mem_ref461_K)
507 const auto tmr = GetPointerS<const target_mem_ref461>(
GET_CONST_NODE(ue->op));
510 analyze_node(tmr->base, left_p, !no_dynamic_address, no_dynamic_address);
514 analyze_node(ue->op, left_p, !no_dynamic_address, no_dynamic_address);
520 "determine_memory_accesses addressing currently not supported: " +
521 GET_NODE(ue->op)->get_kind_text() +
" @" +
STR(node_id) +
" in function " +
525 else if(tn_kind == view_convert_expr_K)
527 const auto vc = GetPointerS<const view_convert_expr>(tn);
528 analyze_node(vc->op, left_p, dynamic_address, no_dynamic_address);
530 else if(tn_kind == indirect_ref_K)
532 const auto ir = GetPointerS<const indirect_ref>(tn);
539 dynamic_address =
false;
540 no_dynamic_address =
true;
542 analyze_node(ir->op, left_p, dynamic_address, no_dynamic_address);
546 analyze_node(ue->op, left_p, dynamic_address, no_dynamic_address);
552 const auto be = GetPointerS<const binary_expr>(tn);
553 if(tn_kind == mem_ref_K)
556 const auto mr = GetPointerS<const mem_ref>(tn);
563 dynamic_address =
false;
564 no_dynamic_address =
true;
573 const bool is_variable_mem = [&]() {
577 "---Already classified as memory variable");
580 const auto vd = GetPointer<const var_decl>(
GET_CONST_NODE(ref_var));
586 if(vd->readonly_flag)
597 if(!vd->scpe or
GET_NODE(vd->scpe)->get_kind() == translation_unit_decl_K)
612 const auto type_kind =
GET_NODE(vd->type)->get_kind();
622 if(type_kind == array_type_K or type_kind == complex_type_K or type_kind == record_type_K or
623 type_kind == union_type_K)
633 AppM->add_written_object(ref_var->index);
638 analyze_node(be->op0, left_p, dynamic_address, no_dynamic_address);
639 analyze_node(be->op1, left_p, dynamic_address, no_dynamic_address);
644 const auto gc = GetPointerS<const gimple_cond>(tn);
648 case gimple_switch_K:
650 const auto se = GetPointerS<const gimple_switch>(tn);
653 analyze_node(se->op0, left_p, dynamic_address, no_dynamic_address);
657 case gimple_multi_way_if_K:
659 const auto gmwi = GetPointerS<const gimple_multi_way_if>(tn);
660 for(
const auto& cond : gmwi->list_of_cond)
664 analyze_node(cond.first, left_p, dynamic_address, no_dynamic_address);
671 const auto gp = GetPointerS<const gimple_phi>(tn);
672 for(
const auto& def_edge : gp->CGetDefEdgesList())
674 analyze_node(def_edge.first, left_p, dynamic_address, no_dynamic_address);
680 const auto te = GetPointerS<const ternary_expr>(tn);
681 if(tn_kind == component_ref_K)
687 analyze_node(te->op0, left_p, dynamic_address, no_dynamic_address);
691 analyze_node(te->op1, left_p, dynamic_address, no_dynamic_address);
695 analyze_node(te->op2, left_p, dynamic_address, no_dynamic_address);
701 const auto qe = GetPointerS<const quaternary_expr>(tn);
704 analyze_node(qe->op0, left_p, dynamic_address, no_dynamic_address);
708 analyze_node(qe->op1, left_p, dynamic_address, no_dynamic_address);
712 analyze_node(qe->op2, left_p, dynamic_address, no_dynamic_address);
716 analyze_node(qe->op3, left_p, dynamic_address, no_dynamic_address);
722 const auto le = GetPointerS<const lut_expr>(tn);
723 analyze_node(le->op0, left_p, dynamic_address, no_dynamic_address);
724 analyze_node(le->op1, left_p, dynamic_address, no_dynamic_address);
727 analyze_node(le->op2, left_p, dynamic_address, no_dynamic_address);
731 analyze_node(le->op3, left_p, dynamic_address, no_dynamic_address);
735 analyze_node(le->op4, left_p, dynamic_address, no_dynamic_address);
739 analyze_node(le->op5, left_p, dynamic_address, no_dynamic_address);
743 analyze_node(le->op6, left_p, dynamic_address, no_dynamic_address);
747 analyze_node(le->op7, left_p, dynamic_address, no_dynamic_address);
751 analyze_node(le->op8, left_p, dynamic_address, no_dynamic_address);
755 case gimple_return_K:
757 const auto re = GetPointerS<const gimple_return>(tn);
766 "structs or unions returned by copy are not yet supported: @" +
STR(node_id) +
767 " in function " + function_name);
770 AppM->add_written_object(node_id);
772 analyze_node(re->op, left_p, dynamic_address, no_dynamic_address);
777 case aggr_init_expr_K:
779 const auto ce = GetPointerS<const call_expr>(tn);
780 const auto&
args = ce->args;
781 const auto ae = GetPointerS<const addr_expr>(
GET_CONST_NODE(ce->fn));
795 const auto fd = GetPointer<function_decl>(
GET_CONST_NODE(ae->op));
796 bool is_var_args_p = GetPointer<function_type>(
GET_NODE(fd->type))->varargs_flag;
798 bool has_pointers_as_actual_parameters =
false;
799 for(
const auto&
arg : ce->args)
804 if(!fd->undefined_flag)
806 if(!(is_var_args_p || fd->list_of_args.size() == args.size()))
809 " a different number of formal and actual parameters is found when function " +
811 " - " +
STR(args.size()) +
812 "\n Check the C source code since an actual parameter is passed to a function that does " 813 "have the associated formal parameter");
815 auto formal_it = fd->list_of_args.cbegin();
816 const auto formal_it_end = fd->list_of_args.cend();
817 auto arg = ce->args.cbegin();
818 const auto arg_end = ce->args.cend();
819 for(;
arg != arg_end && formal_it != formal_it_end; ++
arg, ++formal_it)
822 const auto formal_par = *formal_it;
828 const auto FBcalled =
AppM->GetFunctionBehavior(calledFundID);
830 const auto formal_ssa_index =
AppM->getSSAFromParm(calledFundID, formal_par->index);
833 const auto formal_ssa_node =
TM->CGetTreeNode(formal_ssa_index);
834 const auto formal_ssa = GetPointerS<const ssa_name>(formal_ssa_node);
835 const auto is_singleton = formal_ssa->use_set->is_a_singleton() &&
836 actual_par->
index == formal_ssa->use_set->variables.front()->index;
840 "---Variable for which the dynamic address is used-5: " +
843 AppM->add_written_object(actual_par->
index);
848 " Analyzing node: actual parameter loaded " +
STR(actual_par));
853 else if(!formal_ssa_index)
856 "---Parameter is not used in the function body.");
860 if(FBcalled->is_variable_mem(formal_par->index))
872 " Analyzing node: formal parameter stored " +
STR(formal_par->index));
873 FBcalled->add_parm_decl_stored(formal_par->index);
874 FBcalled->add_dynamic_address(formal_par->index);
875 AppM->add_written_object(formal_par->index);
885 " Analyzing node: formal parameter stored " +
STR(formal_par->index));
886 FBcalled->add_parm_decl_stored(formal_par->index);
887 FBcalled->add_dynamic_address(formal_par->index);
888 AppM->add_written_object(formal_par->index);
889 if(actual_par->
get_kind() == string_cst_K)
892 "---Variable for which the dynamic address is used-6: " +
895 AppM->add_written_object(actual_par->
index);
899 case misaligned_indirect_ref_K:
902 case component_ref_K:
905 " Analyzing node: formal parameter copied " +
STR(formal_par->index));
906 FBcalled->add_parm_decl_copied(formal_par->index);
907 FBcalled->add_dynamic_address(formal_par->index);
908 AppM->add_written_object(formal_par->index);
921 case aggr_init_expr_K:
922 case case_label_expr_K:
924 case identifier_node_K:
925 case statement_list_K:
926 case target_mem_ref_K:
927 case target_mem_ref461_K:
936 case cleanup_point_expr_K:
940 case fix_ceil_expr_K:
941 case fix_floor_expr_K:
942 case fix_round_expr_K:
943 case fix_trunc_expr_K:
945 case imagpart_expr_K:
948 case non_lvalue_expr_K:
951 case realpart_expr_K:
952 case reference_expr_K:
953 case reinterpret_cast_expr_K:
955 case static_cast_expr_K:
957 case truth_not_expr_K:
960 case view_convert_expr_K:
961 case reduc_max_expr_K:
962 case reduc_min_expr_K:
963 case reduc_plus_expr_K:
964 case vec_unpack_hi_expr_K:
965 case vec_unpack_lo_expr_K:
966 case vec_unpack_float_hi_expr_K:
967 case vec_unpack_float_lo_expr_K:
968 case bit_field_ref_K:
970 case with_cleanup_expr_K:
974 case vec_cond_expr_K:
975 case vec_perm_expr_K:
976 case dot_prod_expr_K:
977 case ternary_plus_expr_K:
978 case ternary_pm_expr_K:
979 case ternary_mp_expr_K:
980 case ternary_mm_expr_K:
983 case bit_ior_concat_expr_K:
987 case array_range_ref_K:
991 case insertvalue_expr_K:
992 case insertelement_expr_K:
1003 "actual parameter non allocated in memory: calling @" +
STR(calledFundID) +
1004 " actual " + actual_par->
ToString());
1013 if(has_pointers_as_actual_parameters)
1023 const auto ce = GetPointerS<const gimple_call>(tn);
1024 const auto ae = GetPointerS<const addr_expr>(
GET_CONST_NODE(ce->fn));
1033 const auto fd = GetPointerS<const function_decl>(
GET_CONST_NODE(ae->op));
1037 AppM->add_written_object(node_id);
1040 bool is_var_args_p = GetPointer<function_type>(
GET_NODE(fd->type))->varargs_flag;
1042 bool has_pointers_as_actual_parameters =
false;
1043 for(
const auto&
arg : ce->args)
1048 if(!fd->undefined_flag)
1050 if(!(is_var_args_p || fd->list_of_args.size() == ce->args.size()))
1053 " a different number of formal and actual parameters is found when function " +
1055 " - " +
STR(ce->args.size()) +
1056 "\n Check the C source code since an actual parameter is passed to a function that does " 1057 "have the associated formal parameter");
1059 auto formal_it = fd->list_of_args.cbegin();
1060 const auto formal_it_end = fd->list_of_args.cend();
1061 auto arg = ce->args.cbegin();
1062 const auto arg_end = ce->args.cend();
1063 for(;
arg != arg_end && formal_it != formal_it_end; ++
arg, ++formal_it)
1066 const auto formal_par = *formal_it;
1072 const auto FBcalled =
AppM->GetFunctionBehavior(calledFundID);
1074 const auto formal_ssa_index =
AppM->getSSAFromParm(calledFundID, formal_par->index);
1077 const auto formal_ssa_node =
TM->CGetTreeNode(formal_ssa_index);
1078 const auto formal_ssa = GetPointer<const ssa_name>(formal_ssa_node);
1079 const auto is_singleton = formal_ssa->use_set->is_a_singleton() &&
1080 actual_par->
index == formal_ssa->use_set->variables.front()->index;
1084 "---Variable for which the dynamic address is used-7: " +
1087 AppM->add_written_object(actual_par->
index);
1089 if(!FBcalled->is_variable_mem(formal_par->index) &&
1093 "---actual parameter loaded " +
STR(actual_par->
index));
1098 else if(!formal_ssa_index)
1101 "---Parameter is not used in the function body.");
1104 if(FBcalled->is_variable_mem(formal_par->index))
1116 "---formal parameter stored " +
STR(formal_par->index));
1117 FBcalled->add_parm_decl_stored(formal_par->index);
1118 FBcalled->add_dynamic_address(formal_par->index);
1119 AppM->add_written_object(formal_par->index);
1129 "---formal parameter stored " +
STR(formal_par->index));
1130 FBcalled->add_parm_decl_stored(formal_par->index);
1131 FBcalled->add_dynamic_address(formal_par->index);
1132 AppM->add_written_object(formal_par->index);
1133 if(actual_par->
get_kind() == string_cst_K)
1136 AppM->add_written_object(actual_par->
index);
1140 case misaligned_indirect_ref_K:
1141 case indirect_ref_K:
1143 case component_ref_K:
1146 "---formal parameter copied " +
STR(formal_par->index));
1147 FBcalled->add_parm_decl_copied(formal_par->index);
1148 FBcalled->add_dynamic_address(formal_par->index);
1149 AppM->add_written_object(formal_par->index);
1162 case aggr_init_expr_K:
1163 case case_label_expr_K:
1165 case identifier_node_K:
1166 case statement_list_K:
1167 case target_mem_ref_K:
1168 case target_mem_ref461_K:
1172 case alignof_expr_K:
1174 case bit_not_expr_K:
1177 case cleanup_point_expr_K:
1179 case convert_expr_K:
1181 case fix_ceil_expr_K:
1182 case fix_floor_expr_K:
1183 case fix_round_expr_K:
1184 case fix_trunc_expr_K:
1186 case imagpart_expr_K:
1189 case non_lvalue_expr_K:
1192 case realpart_expr_K:
1193 case reference_expr_K:
1194 case reinterpret_cast_expr_K:
1196 case static_cast_expr_K:
1198 case truth_not_expr_K:
1201 case view_convert_expr_K:
1202 case reduc_max_expr_K:
1203 case reduc_min_expr_K:
1204 case reduc_plus_expr_K:
1205 case vec_unpack_hi_expr_K:
1206 case vec_unpack_lo_expr_K:
1207 case vec_unpack_float_hi_expr_K:
1208 case vec_unpack_float_lo_expr_K:
1209 case bit_field_ref_K:
1211 case with_cleanup_expr_K:
1212 case obj_type_ref_K:
1215 case dot_prod_expr_K:
1216 case ternary_plus_expr_K:
1217 case ternary_pm_expr_K:
1218 case ternary_mp_expr_K:
1219 case ternary_mm_expr_K:
1222 case bit_ior_concat_expr_K:
1223 case vec_cond_expr_K:
1224 case vec_perm_expr_K:
1228 case array_range_ref_K:
1232 case insertvalue_expr_K:
1233 case insertelement_expr_K:
1244 "actual parameter non allocated in memory: calling @" +
STR(calledFundID) +
1245 " actual " + actual_par->
ToString());
1254 if(has_pointers_as_actual_parameters)
1264 const auto sn = GetPointerS<const ssa_name>(tn);
1265 if(sn->use_set->is_fully_resolved())
1267 for(
const auto& var : sn->use_set->variables)
1278 case gimple_label_K:
1287 if(dynamic_address && !no_dynamic_address)
1290 "---Variable for which the dynamic address is used-8: " +
1293 AppM->add_written_object(node_id);
1297 AppM->add_written_object(node_id);
1303 const auto pd = GetPointerS<const parm_decl>(tn);
1304 if(
GET_NODE(pd->type)->get_kind() == record_type_K ||
1305 GET_NODE(pd->type)->get_kind() == union_type_K
1309 "---Variable for which the dynamic address is used-9: " +
1313 AppM->add_written_object(node_id);
1317 " Analyzing node: formal parameter copied " +
STR(node_id));
1325 const auto rd = GetPointerS<const result_decl>(tn);
1326 if(
GET_NODE(rd->type)->get_kind() == record_type_K ||
1327 GET_NODE(rd->type)->get_kind() == union_type_K
1331 " in function " + function_name);
1334 AppM->add_written_object(node_id);
1340 auto tl = GetPointerS<const tree_list>(tn);
1343 analyze_node(tl->valu, left_p, dynamic_address, no_dynamic_address);
1344 tl = tl->chan ? GetPointerS<const tree_list>(
GET_CONST_NODE(tl->chan)) :
nullptr;
1350 const auto vd = GetPointerS<const var_decl>(tn);
1355 if(!vd->scpe ||
GET_NODE(vd->scpe)->get_kind() ==
1356 translation_unit_decl_K)
1359 bool address_externally_used =
false;
1362 if(
parameters->isOption(OPT_expose_globals) &&
parameters->getOption<
bool>(OPT_expose_globals))
1364 address_externally_used =
true;
1367 if(address_externally_used)
1370 "---Global variable externally accessible found: " +
1375 if((dynamic_address && !no_dynamic_address && !vd->addr_not_taken) || address_externally_used ||
1379 "---Variable for which the dynamic address is used-10: " +
1382 if(!vd->readonly_flag)
1384 AppM->add_written_object(node_id);
1387 if(left_p && !vd->readonly_flag)
1389 AppM->add_written_object(node_id);
1391 if(vd->init && (GET_CONST_NODE(vd->init)->get_kind() != string_cst_K))
1400 "translation_unit_decl not expected a translation unit in this point @" +
STR(node_id));
1401 if(vd->static_flag ||
1403 GET_NODE(vd->type)->get_kind() == array_type_K ||
1411 GET_NODE(vd->type)->get_kind() == complex_type_K ||
1412 GET_NODE(vd->type)->get_kind() == record_type_K ||
1413 GET_NODE(vd->type)->get_kind() == union_type_K)
1416 bool address_externally_used =
false;
1419 if(
parameters->isOption(OPT_expose_globals) &&
parameters->getOption<
bool>(OPT_expose_globals))
1421 address_externally_used =
true;
1425 if(address_externally_used)
1428 "---Global variable externally accessible found: " +
1432 else if(vd->static_flag)
1437 if((dynamic_address && !no_dynamic_address && !vd->addr_not_taken) || address_externally_used ||
1441 "---Variable for which the dynamic address is used-11: " +
1444 if(!vd->readonly_flag)
1446 AppM->add_written_object(node_id);
1449 if(left_p && !vd->readonly_flag)
1451 AppM->add_written_object(node_id);
1458 if(vd->init && GET_CONST_NODE(vd->init)->get_kind() != string_cst_K)
1468 const auto con = GetPointerS<const constructor>(tn);
1469 for(
const auto&
el : con->list_of_idx_valu)
1473 analyze_node(
el.first, left_p, dynamic_address, no_dynamic_address);
1477 analyze_node(
el.second, left_p, dynamic_address, no_dynamic_address);
1484 const auto ge = GetPointerS<const gimple_goto>(tn);
1485 analyze_node(ge->op, left_p, dynamic_address, no_dynamic_address);
1490 case gimple_pragma_K:
1495 case target_mem_ref_K:
1497 const auto tmr = GetPointerS<const target_mem_ref>(tn);
1512 case target_mem_ref461_K:
1514 const auto tmr = GetPointerS<const target_mem_ref461>(tn);
1518 if(operand->get_kind() == addr_expr_K)
1521 analyze_node(GetPointerS<const addr_expr>(operand)->op, left_p,
false,
true);
1548 case function_decl_K:
1549 case template_decl_K:
1555 const auto ga = GetPointerS<const gimple_asm>(tn);
1568 case case_label_expr_K:
1574 case gimple_predict_K:
1576 case gimple_while_K:
1577 case identifier_node_K:
1578 case namespace_decl_K:
1579 case statement_list_K:
1580 case translation_unit_decl_K:
1589 std::string(tn->get_kind_text()) +
" in function " +
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
std::string ToString() const
Print this node as string in gimple format.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
Step successfully executed.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
#define BB_EXIT
constant identifying the basic block node of type exit
Definition of the class representing a generic C application.
CustomUnorderedSet< unsigned int > already_visited_ae
Already visited address expression (used to avoid infinite recursion)
const int output_level
The output level.
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
const BehavioralHelperConstRef behavioral_helper
The behavioral helper.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
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.
Determine variables to be stored in memory.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
DesignFlowStep_Status InternalExec() override
Determines the variables that require a memory access.
Base class to model interfaces for high-level synthesis.
#define BUILTIN_WAIT_CALL
constant defining the builtin wait call intrinsic function
static bool IsVolatile(const tree_nodeConstRef &tn)
return true in case the tree node corresponds to a volatile variable
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
Data structure describing a basic block at tree level.
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
~determine_memory_accesses() override
Destructor.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Target must be reexecuted.
#define BB_ENTRY
constant identifying the basic block node of type entry
determine_memory_accesses(const ParameterConstRef parameters, const application_managerRef AppM, unsigned int _function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
#define GET_CONST_NODE(t)
Classes specification of the tree_node data structures.
void analyze_node(const tree_nodeConstRef &tn, bool left_p, bool dynamic_address, bool no_dynamic_address)
Analyze the given node ID to determine which variables have to be referred in memory.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
This file collects some utility functions.
const unsigned int function_id
The index of the function to be analyzed.
static tree_nodeConstRef GetBaseVariable(const tree_nodeConstRef &mem)
Retrun the base variable of a memory access.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
CustomUnorderedSet< unsigned int > already_visited
Data structures used in operations graph.
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.
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
const tree_managerConstRef TM
The tree manager.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
int debug_level
The debug level.
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
#define GET_INDEX_CONST_NODE(t)
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...