80 unsigned int _function_id,
81 const DesignFlowManagerConstRef _design_flow_manager)
83 restart_if_opt(
false),
84 restart_mwi_opt(
false),
96 switch(relationship_type)
100 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
102 relationships.insert(std::make_pair(BITVALUE_RANGE,
SAME_FUNCTION));
104 relationships.insert(std::make_pair(COMPUTE_IMPLICIT_CALLS,
SAME_FUNCTION));
105 relationships.insert(std::make_pair(DEAD_CODE_ELIMINATION,
CALLED_FUNCTIONS));
106 relationships.insert(std::make_pair(FIX_STRUCTS_PASSED_BY_VALUE,
SAME_FUNCTION));
108 relationships.insert(std::make_pair(PARM_DECL_TAKEN_ADDRESS,
SAME_FUNCTION));
111 relationships.insert(std::make_pair(SOFT_FLOAT_CG_EXT,
SAME_FUNCTION));
113 relationships.insert(std::make_pair(USE_COUNTING,
SAME_FUNCTION));
114 relationships.insert(std::make_pair(USE_COUNTING, CALLING_FUNCTIONS));
115 relationships.insert(std::make_pair(UN_COMPARISON_LOWERING,
SAME_FUNCTION));
116 relationships.insert(std::make_pair(PHI_OPT,
SAME_FUNCTION));
117 relationships.insert(std::make_pair(MULTI_WAY_IF,
SAME_FUNCTION));
118 relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF,
SAME_FUNCTION));
119 relationships.insert(std::make_pair(DETERMINE_MEMORY_ACCESSES,
SAME_FUNCTION));
132 relationships.insert(std::make_pair(DETERMINE_MEMORY_ACCESSES,
SAME_FUNCTION));
136 relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF,
SAME_FUNCTION));
137 relationships.insert(std::make_pair(PHI_OPT,
SAME_FUNCTION));
141 relationships.insert(std::make_pair(MULTI_WAY_IF,
SAME_FUNCTION));
142 relationships.insert(std::make_pair(PHI_OPT,
SAME_FUNCTION));
144 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
146 relationships.insert(std::make_pair(BIT_VALUE,
SAME_FUNCTION));
156 return relationships;
165 std::map<unsigned int, bool> cur_writing_memory;
166 std::map<unsigned int, bool> cur_reading_memory;
167 const auto TM =
AppM->get_tree_manager();
168 for(
const auto i :
AppM->CGetCallGraphManager()->get_called_by(
function_id))
170 const auto curr_tn = TM->GetTreeNode(i);
171 const auto fdCalled = GetPointerS<const function_decl>(curr_tn);
172 cur_writing_memory[i] = fdCalled->writing_memory;
173 cur_reading_memory[i] = fdCalled->reading_memory;
181 const auto design_flow_graph = design_flow_manager->CGetDesignFlowGraph();
184 if(sdc_scheduling_step)
186 const auto sdc_scheduling =
187 GetPointer<SDCScheduling>(design_flow_graph->CGetDesignFlowStepInfo(sdc_scheduling_step)->design_flow_step);
189 sdc_scheduling->movements_list.remove_if(
190 [&](
const std::vector<unsigned int>& mv) {
return mv[0] == removed_index; });
203 const auto ssa = GetPointerS<ssa_name>(
GET_NODE(op0));
204 THROW_ASSERT(ssa->CGetDefStmts().size() == 1,
"unexpected condition");
206 if(ssa->CGetNumberUses() != 0)
217 const auto utype = tree_man->GetUnsignedIntegerType();
219 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ne_schema;
232 for(
const auto& use : StmtUses)
235 "---replace constant usage before: " + use.first->ToString());
238 "---replace constant usage after: " + use.first->ToString());
240 THROW_ASSERT(ssa->CGetNumberUses() == 0,
"unexpected condition");
246 const auto v_ssa = GetPointerS<ssa_name>(
GET_NODE(vdef));
250 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_nop_schema;
256 GetPointerS<gimple_node>(
GET_NODE(nop_stmt))->vdef = vdef;
257 v_ssa->SetDefStmt(nop_stmt);
264 const auto gn = GetPointer<gimple_node>(
GET_NODE(cur_stmt));
268 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_nop_IR_schema;
270 gn->include_name +
":" +
STR(gn->line_number) +
":" +
STR(gn->column_number);
275 const auto new_gn = GetPointerS<gimple_node>(
GET_NODE(nop_stmt));
278 new_gn->vdef = gn->vdef;
283 new_gn->vuses = gn->vuses;
285 if(gn->vovers.size())
287 new_gn->vovers = gn->vovers;
289 bb->PushBefore(nop_stmt, cur_stmt,
AppM);
295 const unsigned int cand_bb_dest,
const unsigned int bb_dest_number)
const 297 const auto& bb_succ = sl->
list_of_bloc.at(cand_bb_dest);
298 const auto& bb_dest = sl->
list_of_bloc.at(bb_dest_number);
301 const auto bb_new = blocRef(
new bloc(new_bbi));
303 "---Created BB" +
STR(bb_new->number) +
" as new successor of BB" +
STR(bb_pred->number));
306 bb_new->loop_id = bb_pred->loop_id;
307 bb_new->SetSSAUsesComputed();
308 bb_new->schedule = bb_pred->schedule;
310 bb_new->list_of_pred.push_back(bb_pred->number);
311 bb_new->list_of_succ.push_back(bb_dest->number);
312 bb_dest->list_of_pred.push_back(bb_new->number);
313 bb_pred->list_of_succ.erase(std::find(bb_pred->list_of_succ.begin(), bb_pred->list_of_succ.end(), bb_succ->number));
314 bb_pred->list_of_succ.push_back(bb_new->number);
316 bb_succ->list_of_pred.erase(std::find(bb_succ->list_of_pred.begin(), bb_succ->list_of_pred.end(), bb_pred->number));
318 for(
const auto&
phi : bb_succ->CGetPhiList())
320 const auto gp = GetPointerS<gimple_phi>(
GET_NODE(
phi));
321 for(
const auto& def_edge : gp->CGetDefEdgesList())
323 if(def_edge.second == bb_pred->number)
326 "---Removing <" + def_edge.first->ToString() +
", BB" +
STR(def_edge.second) +
">");
327 gp->RemoveDefEdge(TM, def_edge);
332 for(
const auto&
phi : bb_dest->CGetPhiList())
334 const auto gp = GetPointerS<gimple_phi>(
GET_NODE(
phi));
336 for(
const auto& def_edge : gp->CGetDefEdgesList())
338 if(def_edge.second == bb_pred->number)
343 for(
const auto& def_edge : new_defedges)
346 "---Adding from predecessor <" + def_edge.first->ToString() +
", BB" +
STR(def_edge.second) +
348 gp->AddDefEdge(TM, def_edge);
360 if(
parameters->IsParameter(
"disable-dce") &&
parameters->GetParameter<
unsigned int>(
"disable-dce") == 1)
364 const auto TM =
AppM->get_tree_manager();
365 auto fd = GetPointerS<function_decl>(TM->GetTreeNode(
function_id));
366 auto sl = GetPointerS<statement_list>(
GET_NODE(fd->body));
368 const auto& blocks = sl->list_of_bloc;
370 bool modified =
false;
371 bool restart_analysis =
false;
378 restart_analysis =
false;
379 bool do_reachability =
false;
380 std::list<blocRef> new_bbs;
381 const auto get_new_bbi = [&]() ->
unsigned int {
382 return sl->list_of_bloc.rbegin()->first + 1
U +
static_cast<unsigned int>(new_bbs.size());
386 for(
const auto&
block : blocks)
388 const auto& stmt_list =
block.second->CGetStmtList();
389 for(
const auto& stmt : stmt_list)
391 const auto gn = GetPointerS<gimple_node>(
GET_NODE(stmt));
392 THROW_ASSERT(gn->vovers.empty() || gn->vdef,
"unexpected condition");
393 for(
const auto& vo : gn->vovers)
400 for(
const auto&
block : blocks)
402 const auto& bb =
block.second;
404 const auto& stmt_list = bb->CGetStmtList();
405 std::list<tree_nodeRef> new_vssa_nop;
406 std::list<tree_nodeRef> stmts_to_be_removed;
407 for(
auto stmt = stmt_list.rbegin(); stmt != stmt_list.rend(); stmt++)
409 if(!
AppM->ApplyNewTransformation())
415 if(
GET_NODE(*stmt)->get_kind() == gimple_assign_K)
417 const auto ga = GetPointerS<gimple_assign>(
GET_NODE(*stmt));
419 if(ga->predicate &&
GET_NODE(ga->predicate)->get_kind() == integer_cst_K &&
425 new_vssa_nop.push_back(
kill_vdef(TM, ga->vdef));
429 else if(
GET_NODE(ga->op0)->get_kind() == ssa_name_K)
431 if(ga->vdef || ga->vuses.size() || ga->vovers.size())
442 stmts_to_be_removed.push_back(*stmt);
450 if(op0->get_kind() == ssa_name_K)
452 const auto ssa = GetPointerS<ssa_name>(op0);
454 if(ssa->CGetNumberUses() == 0 and ssa->CGetDefStmts().size() == 1)
456 bool is_a_writing_memory_call =
false;
457 bool is_a_reading_memory_call =
false;
458 if(
GET_NODE(ga->op1)->get_kind() == call_expr_K ||
459 GET_NODE(ga->op1)->get_kind() == aggr_init_expr_K)
461 const auto ce = GetPointerS<call_expr>(
GET_NODE(ga->op1));
462 if(
GET_NODE(ce->fn)->get_kind() == addr_expr_K)
464 const auto addr_node =
GET_NODE(ce->fn);
465 const auto ae = GetPointerS<const addr_expr>(addr_node);
467 THROW_ASSERT(fu_decl_node->get_kind() == function_decl_K,
468 "node " +
STR(fu_decl_node) +
" is not function_decl but " +
469 fu_decl_node->get_kind_text());
470 const auto fdCalled = GetPointerS<const function_decl>(fu_decl_node);
471 if(fdCalled->writing_memory || !fdCalled->body)
473 is_a_writing_memory_call =
true;
475 if(fdCalled->reading_memory)
477 is_a_reading_memory_call =
true;
482 is_a_writing_memory_call =
true;
485 if(!is_a_writing_memory_call)
492 if(is_a_reading_memory_call || ga->vdef || ga->vuses.size() || ga->vovers.size() ||
493 GET_NODE(ga->op1)->get_kind() == addr_expr_K ||
494 GET_NODE(ga->op1)->get_kind() == mem_ref_K)
498 stmts_to_be_removed.push_back(*stmt);
506 "---LHS ssa used: " +
STR(ssa->CGetNumberUses()) +
"-" +
507 STR(ssa->CGetDefStmts().size()));
512 const auto mr = GetPointerS<mem_ref>(op0);
518 if(
GET_NODE(mr->op0)->get_kind() == integer_cst_K)
525 "unexpected condition" + ga->ToString());
526 auto derefVar = GetPointerS<ssa_name>(
GET_NODE(mr->op0));
527 auto& defStmts = derefVar->CGetDefStmts();
528 if(defStmts.size() == 1)
530 auto defStmt = *defStmts.begin();
531 if(
GET_NODE(defStmt)->get_kind() == gimple_assign_K)
533 const auto derefGA = GetPointerS<gimple_assign>(
GET_NODE(defStmt));
534 if(
GET_NODE(derefGA->op1)->get_kind() == addr_expr_K)
536 const auto addressedVar = GetPointerS<addr_expr>(
GET_NODE(derefGA->op1))->op;
537 if(
GET_NODE(addressedVar)->get_kind() == var_decl_K)
539 const auto varDecl = GetPointerS<var_decl>(
GET_NODE(addressedVar));
541 !varDecl->static_flag)
546 ssaDef = GetPointerS<ssa_name>(
GET_NODE(ga->vdef));
548 "---VDEF: " +
STR(ga->vdef));
559 vdefvover_map.find(ssaDef->
index) == vdefvover_map.end())
562 "---Dead Store found");
567 stmts_to_be_removed.push_back(*stmt);
574 "---check if the associated load are dead");
576 for(
const auto& use : StmtUses)
578 const auto gn_used = GetPointerS<gimple_node>(
GET_NODE(use.first));
579 if(!gn_used->vdef && gn_used->bb_index == ga->bb_index &&
580 gn_used->get_kind() == gimple_assign_K)
583 GetPointerS<gimple_assign>(
GET_NODE(use.first));
584 if(
GET_NODE(ga_used->op0)->get_kind() == ssa_name_K &&
585 GET_NODE(ga_used->op1)->get_kind() == mem_ref_K &&
586 !(ga_used->predicate &&
587 GET_NODE(ga_used->predicate)->get_kind() == integer_cst_K &&
591 GetPointerS<mem_ref>(
GET_NODE(ga_used->op1));
599 "---read_bw: " +
STR(read_bw) +
600 " written_bw: " +
STR(written_bw));
603 written_bw == read_bw &&
612 "---found a candidate " +
615 auto curr_stmt = stmt;
616 bool found_load =
false;
617 if(curr_stmt != stmt_list.rbegin())
629 GetPointerS<gimple_node>(
GET_NODE(*curr_stmt));
630 if(!found_load && gn_curr->vdef &&
631 (ga_used->vuses.find(gn_curr->vdef) !=
632 ga_used->vuses.end() ||
633 (vdefvover_map.find(ssaDef->
index) !=
634 vdefvover_map.end() &&
635 vdefvover_map.find(ssaDef->
index)
638 vdefvover_map.find(ssaDef->
index)
643 if(curr_stmt == stmt_list.rbegin())
656 "---found a Dead Load " +
658 const auto ssa_used_op0 =
659 GetPointerS<ssa_name>(
GET_NODE(ga_used->op0));
661 ssa_used_op0->CGetUseStmts();
662 for(
const auto& useop0 : StmtUsesOp0)
666 "---replace var usage before: " +
667 useop0.first->ToString());
668 TM->ReplaceTreeNode(useop0.first, ga_used->op0,
672 "---replace var usage after: " +
673 useop0.first->ToString());
676 "unexpected condition");
677 stmts_to_be_removed.push_back(*curr_stmt);
678 AppM->RegisterTransformation(
GetName(), *curr_stmt);
691 "---local variable later used");
697 "---non local variable");
732 else if(
GET_NODE(*stmt)->get_kind() == gimple_cond_K)
734 const auto gc = GetPointerS<gimple_cond>(
GET_NODE(*stmt));
735 if(
GET_NODE(gc->op0)->get_kind() == integer_cst_K)
738 do_reachability =
true;
742 const auto new_bb =
move2emptyBB(TM, get_new_bbi(), sl, bb, bb->false_edge, bb->true_edge);
743 new_bbs.push_back(new_bb);
744 bb->false_edge = new_bb->number;
748 const auto new_bb =
move2emptyBB(TM, get_new_bbi(), sl, bb, bb->true_edge, bb->false_edge);
749 new_bbs.push_back(new_bb);
750 bb->true_edge = new_bb->number;
754 else if(
GET_NODE(*stmt)->get_kind() == gimple_multi_way_if_K)
756 const auto gm = GetPointerS<gimple_multi_way_if>(
GET_NODE(*stmt));
758 bool one_is_const =
false;
759 bool all_false =
true;
760 unsigned int bb_dest = 0;
761 for(
const auto& cond : gm->list_of_cond)
768 bb_dest = cond.second;
771 else if(
GET_NODE(cond.first)->get_kind() == integer_cst_K)
778 bb_dest = cond.second;
786 if(all_false || one_is_const)
789 "---gimple_multi_way_if with constant conditions");
791 for(
auto& cond : gm->list_of_cond)
793 if(cond.second != bb_dest)
795 do_reachability =
true;
796 const auto new_bb =
move2emptyBB(TM, get_new_bbi(), sl, bb, cond.second, bb_dest);
797 new_bbs.push_back(new_bb);
798 cond.second = new_bb->number;
805 std::map<unsigned int, unsigned int> condIndex2BBdest;
806 auto do0ConstantCondRemoval =
false;
807 for(
auto& cond : gm->list_of_cond)
811 if(
GET_NODE(cond.first)->get_kind() == integer_cst_K)
813 if(!blocks.at(cond.second)->CGetStmtList().empty())
815 do0ConstantCondRemoval =
true;
818 else if(condIndex2BBdest.find(
GET_INDEX_NODE(cond.first)) == condIndex2BBdest.end())
822 else if(!blocks.at(cond.second)->CGetStmtList().empty())
824 do_reachability =
true;
826 "---gimple_multi_way_if duplicated condition from BB" +
STR(bb->number) +
827 " to BB" +
STR(cond.second));
828 const auto new_bb =
move2emptyBB(TM, get_new_bbi(), sl, bb, cond.second,
830 new_bbs.push_back(new_bb);
831 cond.second = new_bb->number;
835 if(do0ConstantCondRemoval)
838 "---gimple_multi_way_if do zero condition removal");
839 const auto bb0_dest = condIndex2BBdest.begin()->second;
840 for(
auto& cond : gm->list_of_cond)
844 if(
GET_NODE(cond.first)->get_kind() == integer_cst_K)
847 do_reachability =
true;
849 "---gimple_multi_way_if duplicated condition from BB" +
STR(bb->number) +
850 " to BB" +
STR(cond.second));
851 const auto new_bb =
move2emptyBB(TM, get_new_bbi(), sl, bb, cond.second, bb0_dest);
852 new_bbs.push_back(new_bb);
853 cond.second = new_bb->number;
860 else if(
GET_NODE(*stmt)->get_kind() == gimple_call_K)
862 const auto gc = GetPointerS<gimple_call>(
GET_NODE(*stmt));
866 if(temp_node->get_kind() == addr_expr_K)
868 const auto ue = GetPointerS<unary_expr>(temp_node);
870 fdCalled = GetPointer<function_decl>(
GET_NODE(temp_node));
872 else if(temp_node->get_kind() == obj_type_ref_K)
875 fdCalled = GetPointer<function_decl>(
GET_NODE(temp_node));
879 bool is_a_writing_memory_call =
false;
882 is_a_writing_memory_call =
true;
886 if(gc->vdef || gc->vuses.size() || gc->vovers.size())
891 stmts_to_be_removed.push_back(*stmt);
903 if(!stmts_to_be_removed.empty())
907 restart_analysis =
true;
909 "-->Removing " +
STR(stmts_to_be_removed.size()) +
" dead statements");
910 for(
const auto& curr_el : stmts_to_be_removed)
912 bb->RemoveStmt(curr_el,
AppM);
917 for(
const auto& vssa_nop : new_vssa_nop)
919 bb->PushFront(vssa_nop,
AppM);
921 if(bb->CGetStmtList().empty() && bb->CGetPhiList().empty())
931 const auto& phi_list = bb->CGetPhiList();
932 std::list<tree_nodeRef> phis_to_be_removed;
934 for(
auto phi = phi_list.rbegin();
phi != phi_list.rend();
phi++)
936 if(!
AppM->ApplyNewTransformation())
943 GET_NODE(*phi)->ToString() +
" is of kind " +
945 const auto gphi = GetPointerS<gimple_phi>(
GET_NODE(*
phi));
946 const auto res =
GET_NODE(gphi->res);
949 const auto ssa = GetPointerS<ssa_name>(res);
951 if(ssa->CGetNumberUses() == 0 && ssa->CGetDefStmts().size() == 1)
954 phis_to_be_removed.push_back(*
phi);
960 if(!phis_to_be_removed.empty())
963 restart_analysis =
true;
965 "-->Removing " +
STR(phis_to_be_removed.size()) +
" dead phis");
966 for(
const auto& curr_phi : phis_to_be_removed)
968 bb->RemovePhi(curr_phi);
975 for(
const auto& bb : new_bbs)
977 sl->list_of_bloc[bb->number] = bb;
980 while(do_reachability)
983 do_reachability =
false;
987 std::queue<unsigned> to_be_processed;
989 while(!to_be_processed.empty())
991 auto curr = to_be_processed.front();
992 to_be_processed.pop();
994 for(
auto bb : blocks.at(curr)->list_of_succ)
996 if(BB_reached.insert(bb).second)
998 to_be_processed.push(bb);
1003 for(
const auto& bb_pair : blocks)
1005 if(BB_reached.find(bb_pair.first) == BB_reached.end())
1007 bb_to_remove.insert(bb_pair.first);
1010 if(!bb_to_remove.empty())
1013 "-->Removing " +
STR(bb_to_remove.size()) +
" unreachable BBs");
1014 for(
auto bbi : bb_to_remove)
1017 do_reachability =
true;
1018 const auto& bb = blocks.at(bbi);
1019 const auto phi_list = bb->CGetPhiList();
1020 std::list<tree_nodeRef> phis_to_be_removed;
1022 for(
auto phi = phi_list.rbegin();
phi != phi_list.rend();
phi++)
1026 GET_NODE(*phi)->ToString() +
" is of kind " +
GET_NODE(*phi)->get_kind_text());
1027 const auto gphi = GetPointerS<gimple_phi>(
GET_NODE(*
phi));
1028 const auto res =
GET_NODE(gphi->res);
1029 THROW_ASSERT(res->get_kind() == ssa_name_K, res->ToString() +
" is of kind " + res->get_kind_text());
1030 const auto ssa = GetPointerS<const ssa_name>(res);
1031 if(ssa->virtual_flag)
1039 bb->RemovePhi(*
phi);
1043 const auto stmt_list = bb->CGetStmtList();
1044 for(
auto stmt = stmt_list.rbegin(); stmt != stmt_list.rend(); stmt++)
1047 const auto node_stmt =
GET_NODE(*stmt);
1048 const auto gn = GetPointerS<gimple_node>(node_stmt);
1054 else if(node_stmt->get_kind() == gimple_assign_K)
1056 const auto ga = GetPointerS<gimple_assign>(node_stmt);
1057 if(
GET_NODE(ga->op0)->get_kind() == ssa_name_K)
1062 bb->RemoveStmt(*stmt,
AppM);
1066 if(bb->CGetStmtList().empty() && bb->CGetPhiList().empty())
1071 for(
const auto sblock : bb->list_of_succ)
1077 THROW_ASSERT(blocks.find(sblock) != blocks.end(),
"Already removed BB" +
STR(sblock));
1078 const auto& succ_block = blocks.at(sblock);
1079 succ_block->list_of_pred.erase(
1080 std::find(succ_block->list_of_pred.begin(), succ_block->list_of_pred.end(), bb->number));
1082 for(
const auto&
phi : succ_block->CGetPhiList())
1084 const auto gp = GetPointerS<gimple_phi>(
GET_NODE(
phi));
1085 for(
const auto& def_edge : gp->CGetDefEdgesList())
1087 if(def_edge.second == bb->number)
1090 "---Removing <" + def_edge.first->ToString() +
", BB" +
STR(def_edge.second) +
1092 gp->RemoveDefEdge(TM, def_edge);
1098 bb->list_of_succ.clear();
1101 for(
const auto bbi : bb_to_remove)
1103 sl->list_of_bloc.erase(bbi);
1108 }
while(restart_analysis);
1111 for(
const auto&
block : blocks)
1113 const auto& bb =
block.second;
1115 const auto& stmt_list = bb->CGetStmtList();
1116 std::list<tree_nodeRef> new_vssa_nop;
1117 for(
auto stmt = stmt_list.rbegin(); stmt != stmt_list.rend(); stmt++)
1120 const auto stmt_kind =
GET_NODE(*stmt)->get_kind();
1122 if(stmt_kind == gimple_assign_K)
1124 const auto ga = GetPointerS<const gimple_assign>(
GET_CONST_NODE(*stmt));
1126 if(rhs_kind == call_expr_K || rhs_kind == aggr_init_expr_K)
1128 const auto ce = GetPointerS<const call_expr>(
GET_CONST_NODE(ga->op1));
1132 const auto ae = GetPointerS<const addr_expr>(addr_node);
1134 THROW_ASSERT(fu_decl_node->get_kind() == function_decl_K,
"node " +
STR(fu_decl_node) +
1135 " is not function_decl but " +
1136 fu_decl_node->get_kind_text());
1137 fdCalled = GetPointer<const function_decl>(fu_decl_node);
1141 else if(stmt_kind == gimple_call_K)
1143 const auto gc = GetPointerS<const gimple_call>(
GET_CONST_NODE(*stmt));
1145 if(op_kind == addr_expr_K)
1147 const auto ue = GetPointerS<const unary_expr>(
GET_CONST_NODE(gc->fn));
1148 fdCalled = GetPointer<const function_decl>(
GET_CONST_NODE(ue->op));
1150 else if(op_kind == obj_type_ref_K)
1153 fdCalled = GetPointer<const function_decl>(
GET_CONST_NODE(obj_ref));
1158 const auto gn = GetPointerS<gimple_node>(
GET_NODE(*stmt));
1166 for(
const auto& vo : gn->vovers)
1173 GetPointerS<ssa_name>(
GET_NODE(vo))->AddUseStmt(*stmt);
1179 new_vssa_nop.push_back(
kill_vdef(TM, gn->vdef));
1181 for(
const auto& vo : gn->vovers)
1184 GetPointerS<ssa_name>(
GET_NODE(vo))->RemoveUse(*stmt);
1189 "---Nothing is written by this function: Fixed VDEF/VOVER ");
1195 for(
const auto& vssa_nop : new_vssa_nop)
1197 bb->PushFront(vssa_nop,
AppM);
1204 fd->writing_memory =
false;
1205 fd->reading_memory =
false;
1206 for(
const auto&
block : blocks)
1208 const auto& bb =
block.second;
1210 const auto& stmt_list = bb->CGetStmtList();
1211 for(
auto stmt = stmt_list.rbegin(); stmt != stmt_list.rend(); stmt++)
1214 const auto gn = GetPointerS<const gimple_node>(
GET_CONST_NODE(*stmt));
1216 if(!gn->vuses.empty() &&
GET_CONST_NODE(*stmt)->get_kind() != gimple_return_K)
1218 fd->reading_memory =
true;
1223 fd->writing_memory =
true;
1226 else if(
const auto ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(*stmt)))
1231 const auto ce = GetPointerS<const call_expr>(
GET_CONST_NODE(ga->op1));
1235 const auto ae = GetPointerS<const addr_expr>(addr_node);
1237 THROW_ASSERT(fu_decl_node->get_kind() == function_decl_K,
"node " +
STR(fu_decl_node) +
1238 " is not function_decl but " +
1239 fu_decl_node->get_kind_text());
1240 const auto fdCalled = GetPointerS<const function_decl>(fu_decl_node);
1241 if(fdCalled->writing_memory || !fdCalled->body || fdCalled->undefined_flag)
1243 fd->writing_memory =
true;
1246 if(fdCalled->reading_memory || !fdCalled->body || fdCalled->undefined_flag)
1248 fd->reading_memory =
true;
1254 fd->writing_memory =
true;
1255 fd->reading_memory =
true;
1260 else if(
const auto gc = GetPointer<const gimple_call>(
GET_CONST_NODE(*stmt)))
1265 const auto ue = GetPointerS<const unary_expr>(
GET_CONST_NODE(gc->fn));
1266 fdCalled = GetPointer<const function_decl>(
GET_CONST_NODE(ue->op));
1271 fdCalled = GetPointerS<const function_decl>(
GET_CONST_NODE(gc->fn));
1282 fd->reading_memory =
true;
1288 fd->writing_memory =
true;
1289 fd->reading_memory =
true;
1295 fd->writing_memory =
true;
1296 fd->reading_memory =
true;
1304 "---write flag " + (fd->writing_memory ? std::string(
"T") : std::string(
"F")));
1306 "---read flag " + (fd->reading_memory ? std::string(
"T") : std::string(
"F")));
1308 const auto calledSet =
AppM->CGetCallGraphManager()->get_called_by(
function_id);
1309 for(
const auto i : calledSet)
1311 const auto fdCalled = GetPointerS<const function_decl>(
AppM->get_tree_manager()->CGetTreeNode(i));
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static bool IsSameType(const tree_nodeConstRef &tn0, const tree_nodeConstRef &tn1)
Given two nodes tells if they have same base type (const is not considered: const double == double) ...
const TreeNodeSet CGetDefStmts() const
Return the set of definition statements.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
const TreeNodeMap< size_t > & CGetUseStmts() const
Return the use stmts.
static bool is_a_nop_function_decl(const function_decl *fd)
Data structure representing the entire HLS information.
This struct specifies the field bloc (basic block).
#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 DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
Step successfully executed.
bool writing_memory
True if function write in memory somehow.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void ReplaceTreeNode(const tree_nodeRef &stmt, const tree_nodeRef &old_node, const tree_nodeRef &new_node)
Replace the occurrences of tree node old_node with new_node in statement identified by tn...
This struct specifies the statement_list node.
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.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
struct definition of the function_decl tree node.
Source must be executed to satisfy target.
mathematical utility function not provided by standard libraries
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
tree_nodeRef add_gimple_nop(const tree_managerRef &TM, const tree_nodeRef &cur_stmt, const blocRef &bb)
std::list< DefEdge > DefEdgeList
The type of the def edge list.
bool undefined_flag
undefined_flag means external reference: do not allocate storage, and refer to a definition elsewhere...
void fix_sdc_motion(tree_nodeRef removedStmt) const
A simple interface to token object of the raw files.
std::map< unsigned int, blocRef > list_of_bloc
list_of_bloc field is the list of basic block. If this field is null then the list_of_stmt field is n...
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
blocRef move2emptyBB(const tree_managerRef &TM, const unsigned int new_bbi, const statement_list *sl, const blocRef &bb_pred, const unsigned int cand_bb_dest, const unsigned int bb_dest) const
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
~dead_code_elimination() override
Destructor.
Data structure describing a basic block at tree level.
static std::string ComputeSignature(const HLSFlowStep_Type hls_flow_step_type, const HLSFlowStepSpecializationConstRef hls_flow_step_specialization, const unsigned int function_id)
Compute the signature of a hls flow step.
dead_code_elimination(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
redefinition of map to manage ordered/unordered structures
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
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.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
size_t CGetNumberUses() const
Return the number of uses.
void kill_uses(const tree_managerRef &TM, const tree_nodeRef &op0) const
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
tree_nodeRef CreateUniqueRealCst(long double value, const tree_nodeConstRef &type)
memoization of integer constants
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...
void create_tree_node(const unsigned int node_id, enum kind tree_node_type, std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
Factory method.
Classes to describe design flow graph.
tree_nodeRef body
body field is the saved representation of the body of the entire function.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
Target must be reexecuted.
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
redefinition of set to manage ordered/unordered structures
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
Class definition of the sdc scheduling.
bool reading_memory
True if function read from memory somehow.
#define GET_CONST_NODE(t)
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#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
static tree_nodeRef kill_vdef(const tree_managerRef &TM, const tree_nodeRef &vdef)
Replace virtual ssa definition with gimple nop.
This struct specifies the block node.
This file collects some utility functions.
static tree_nodeRef find_obj_type_ref_function(const tree_nodeConstRef &tn)
Given the tree_node of an obj_type_ref return the tree_node of the called function.
refcount< T > lock() const
const unsigned int function_id
The index of the function to be analyzed.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
std::map< unsigned int, bool > last_writing_memory
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.
std::map< unsigned int, bool > last_reading_memory
Classes specification of the tree_node data structures not present in the gcc.
This struct specifies the ssa_name node.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
#define GET_INDEX_CONST_NODE(t)
Data structure definition for high-level synthesis flow.
DesignFlowStep_Status InternalExec() override
Performs dead code elimination.
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...