Mercurial > hg > CbC > CbC_gcc
comparison gcc/ddg.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* DDG - Data Dependence Graph implementation. | 1 /* DDG - Data Dependence Graph implementation. |
2 Copyright (C) 2004-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2004-2020 Free Software Foundation, Inc. |
3 Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com> | 3 Contributed by Ayal Zaks and Mustafa Hagog <zaks,mustafa@il.ibm.com> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
29 #include "sched-int.h" | 29 #include "sched-int.h" |
30 #include "ddg.h" | 30 #include "ddg.h" |
31 #include "rtl-iter.h" | 31 #include "rtl-iter.h" |
32 | 32 |
33 #ifdef INSN_SCHEDULING | 33 #ifdef INSN_SCHEDULING |
34 | |
35 /* A flag indicating that a ddg edge belongs to an SCC or not. */ | |
36 enum edge_flag {NOT_IN_SCC = 0, IN_SCC}; | |
37 | 34 |
38 /* Forward declarations. */ | 35 /* Forward declarations. */ |
39 static void add_backarc_to_ddg (ddg_ptr, ddg_edge_ptr); | 36 static void add_backarc_to_ddg (ddg_ptr, ddg_edge_ptr); |
40 static void add_backarc_to_scc (ddg_scc_ptr, ddg_edge_ptr); | 37 static void add_backarc_to_scc (ddg_scc_ptr, ddg_edge_ptr); |
41 static void add_scc_to_ddg (ddg_all_sccs_ptr, ddg_scc_ptr); | 38 static void add_scc_to_ddg (ddg_all_sccs_ptr, ddg_scc_ptr); |
82 /* Returns nonzero if INSN writes to memory. */ | 79 /* Returns nonzero if INSN writes to memory. */ |
83 static bool | 80 static bool |
84 mem_write_insn_p (rtx_insn *insn) | 81 mem_write_insn_p (rtx_insn *insn) |
85 { | 82 { |
86 mem_ref_p = false; | 83 mem_ref_p = false; |
87 note_stores (PATTERN (insn), mark_mem_store, NULL); | 84 note_stores (insn, mark_mem_store, NULL); |
88 return mem_ref_p; | 85 return mem_ref_p; |
89 } | 86 } |
90 | 87 |
91 /* Returns nonzero if X has access to memory. */ | 88 /* Returns nonzero if X has access to memory. */ |
92 static bool | 89 static bool |
213 subregs and special registers. */ | 210 subregs and special registers. */ |
214 if (set && REG_P (SET_DEST (set))) | 211 if (set && REG_P (SET_DEST (set))) |
215 { | 212 { |
216 int regno = REGNO (SET_DEST (set)); | 213 int regno = REGNO (SET_DEST (set)); |
217 df_ref first_def; | 214 df_ref first_def; |
218 struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); | 215 class df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); |
219 | 216 |
220 first_def = df_bb_regno_first_def_find (g->bb, regno); | 217 first_def = df_bb_regno_first_def_find (g->bb, regno); |
221 gcc_assert (first_def); | 218 gcc_assert (first_def); |
222 | 219 |
223 if (bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def))) | 220 if (bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def))) |
286 gcc_assert (last_def_node); | 283 gcc_assert (last_def_node); |
287 gcc_assert (first_def); | 284 gcc_assert (first_def); |
288 | 285 |
289 if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def)) | 286 if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def)) |
290 { | 287 { |
291 struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); | 288 class df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb); |
292 gcc_assert (!bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def))); | 289 gcc_assert (!bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def))); |
293 } | 290 } |
294 | 291 |
295 /* Create inter-loop true dependences and anti dependences. */ | 292 /* Create inter-loop true dependences and anti dependences. */ |
296 for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next) | 293 for (r_use = DF_REF_CHAIN (last_def); r_use != NULL; r_use = r_use->next) |
367 /* Build inter-loop dependencies, by looking at DF analysis backwards. */ | 364 /* Build inter-loop dependencies, by looking at DF analysis backwards. */ |
368 static void | 365 static void |
369 build_inter_loop_deps (ddg_ptr g) | 366 build_inter_loop_deps (ddg_ptr g) |
370 { | 367 { |
371 unsigned rd_num; | 368 unsigned rd_num; |
372 struct df_rd_bb_info *rd_bb_info; | 369 class df_rd_bb_info *rd_bb_info; |
373 bitmap_iterator bi; | 370 bitmap_iterator bi; |
374 | 371 |
375 rd_bb_info = DF_RD_BB_INFO (g->bb); | 372 rd_bb_info = DF_RD_BB_INFO (g->bb); |
376 | 373 |
377 /* Find inter-loop register output, true and anti deps. */ | 374 /* Find inter-loop register output, true and anti deps. */ |
473 static void | 470 static void |
474 build_intra_loop_deps (ddg_ptr g) | 471 build_intra_loop_deps (ddg_ptr g) |
475 { | 472 { |
476 int i; | 473 int i; |
477 /* Hold the dependency analysis state during dependency calculations. */ | 474 /* Hold the dependency analysis state during dependency calculations. */ |
478 struct deps_desc tmp_deps; | 475 class deps_desc tmp_deps; |
479 rtx_insn *head, *tail; | 476 rtx_insn *head, *tail; |
480 | 477 |
481 /* Build the dependence information, using the sched_analyze function. */ | 478 /* Build the dependence information, using the sched_analyze function. */ |
482 init_deps_global (); | 479 init_deps_global (); |
483 init_deps (&tmp_deps, false); | 480 init_deps (&tmp_deps, false); |
562 ddg_ptr | 559 ddg_ptr |
563 create_ddg (basic_block bb, int closing_branch_deps) | 560 create_ddg (basic_block bb, int closing_branch_deps) |
564 { | 561 { |
565 ddg_ptr g; | 562 ddg_ptr g; |
566 rtx_insn *insn, *first_note; | 563 rtx_insn *insn, *first_note; |
567 int i; | 564 int i, j; |
568 int num_nodes = 0; | 565 int num_nodes = 0; |
569 | 566 |
570 g = (ddg_ptr) xcalloc (1, sizeof (struct ddg)); | 567 g = (ddg_ptr) xcalloc (1, sizeof (struct ddg)); |
571 | 568 |
572 g->bb = bb; | 569 g->bb = bb; |
630 g->nodes[i].successors = sbitmap_alloc (num_nodes); | 627 g->nodes[i].successors = sbitmap_alloc (num_nodes); |
631 bitmap_clear (g->nodes[i].successors); | 628 bitmap_clear (g->nodes[i].successors); |
632 g->nodes[i].predecessors = sbitmap_alloc (num_nodes); | 629 g->nodes[i].predecessors = sbitmap_alloc (num_nodes); |
633 bitmap_clear (g->nodes[i].predecessors); | 630 bitmap_clear (g->nodes[i].predecessors); |
634 g->nodes[i].first_note = (first_note ? first_note : insn); | 631 g->nodes[i].first_note = (first_note ? first_note : insn); |
632 | |
633 g->nodes[i].aux.count = -1; | |
634 g->nodes[i].max_dist = XCNEWVEC (int, num_nodes); | |
635 for (j = 0; j < num_nodes; j++) | |
636 g->nodes[i].max_dist[j] = -1; | |
637 | |
635 g->nodes[i++].insn = insn; | 638 g->nodes[i++].insn = insn; |
636 first_note = NULL; | 639 first_note = NULL; |
637 } | 640 } |
638 | 641 |
639 /* We must have found a branch in DDG. */ | 642 /* We must have found a branch in DDG. */ |
666 free (e); | 669 free (e); |
667 e = next; | 670 e = next; |
668 } | 671 } |
669 sbitmap_free (g->nodes[i].successors); | 672 sbitmap_free (g->nodes[i].successors); |
670 sbitmap_free (g->nodes[i].predecessors); | 673 sbitmap_free (g->nodes[i].predecessors); |
674 free (g->nodes[i].max_dist); | |
671 } | 675 } |
672 if (g->num_backarcs > 0) | 676 if (g->num_backarcs > 0) |
673 free (g->backarcs); | 677 free (g->backarcs); |
674 free (g->nodes); | 678 free (g->nodes); |
675 free (g); | 679 free (g); |
790 e->type = t; | 794 e->type = t; |
791 e->data_type = dt; | 795 e->data_type = dt; |
792 e->latency = l; | 796 e->latency = l; |
793 e->distance = d; | 797 e->distance = d; |
794 e->next_in = e->next_out = NULL; | 798 e->next_in = e->next_out = NULL; |
795 e->aux.info = 0; | 799 e->in_scc = false; |
796 return e; | 800 return e; |
797 } | 801 } |
798 | 802 |
799 /* Add the given edge to the in/out linked lists of the DDG nodes. */ | 803 /* Add the given edge to the in/out linked lists of the DDG nodes. */ |
800 static void | 804 static void |
818 | 822 |
819 /* Algorithm for computing the recurrence_length of an scc. We assume at | 823 /* Algorithm for computing the recurrence_length of an scc. We assume at |
820 for now that cycles in the data dependence graph contain a single backarc. | 824 for now that cycles in the data dependence graph contain a single backarc. |
821 This simplifies the algorithm, and can be generalized later. */ | 825 This simplifies the algorithm, and can be generalized later. */ |
822 static void | 826 static void |
823 set_recurrence_length (ddg_scc_ptr scc, ddg_ptr g) | 827 set_recurrence_length (ddg_scc_ptr scc) |
824 { | 828 { |
825 int j; | 829 int j; |
826 int result = -1; | 830 int result = -1; |
827 | 831 |
828 for (j = 0; j < scc->num_backarcs; j++) | 832 for (j = 0; j < scc->num_backarcs; j++) |
829 { | 833 { |
830 ddg_edge_ptr backarc = scc->backarcs[j]; | 834 ddg_edge_ptr backarc = scc->backarcs[j]; |
831 int length; | |
832 int distance = backarc->distance; | 835 int distance = backarc->distance; |
833 ddg_node_ptr src = backarc->dest; | 836 ddg_node_ptr src = backarc->dest; |
834 ddg_node_ptr dest = backarc->src; | 837 ddg_node_ptr dest = backarc->src; |
835 | 838 int length = src->max_dist[dest->cuid]; |
836 length = longest_simple_path (g, src->cuid, dest->cuid, scc->nodes); | 839 |
837 if (length < 0 ) | 840 if (length < 0) |
838 { | 841 continue; |
839 /* fprintf (stderr, "Backarc not on simple cycle in SCC.\n"); */ | 842 |
840 continue; | |
841 } | |
842 length += backarc->latency; | 843 length += backarc->latency; |
843 result = MAX (result, (length / distance)); | 844 result = MAX (result, (length / distance)); |
844 } | 845 } |
845 scc->recurrence_length = result; | 846 scc->recurrence_length = result; |
846 } | 847 } |
847 | 848 |
848 /* Create a new SCC given the set of its nodes. Compute its recurrence_length | 849 /* Create a new SCC given the set of its nodes. Compute its recurrence_length |
849 and mark edges that belong to this scc as IN_SCC. */ | 850 and mark edges that belong to this scc. */ |
850 static ddg_scc_ptr | 851 static ddg_scc_ptr |
851 create_scc (ddg_ptr g, sbitmap nodes) | 852 create_scc (ddg_ptr g, sbitmap nodes, int id) |
852 { | 853 { |
853 ddg_scc_ptr scc; | 854 ddg_scc_ptr scc; |
854 unsigned int u = 0; | 855 unsigned int u = 0; |
855 sbitmap_iterator sbi; | 856 sbitmap_iterator sbi; |
856 | 857 |
864 EXECUTE_IF_SET_IN_BITMAP (nodes, 0, u, sbi) | 865 EXECUTE_IF_SET_IN_BITMAP (nodes, 0, u, sbi) |
865 { | 866 { |
866 ddg_edge_ptr e; | 867 ddg_edge_ptr e; |
867 ddg_node_ptr n = &g->nodes[u]; | 868 ddg_node_ptr n = &g->nodes[u]; |
868 | 869 |
870 gcc_assert (n->aux.count == -1); | |
871 n->aux.count = id; | |
872 | |
869 for (e = n->out; e; e = e->next_out) | 873 for (e = n->out; e; e = e->next_out) |
870 if (bitmap_bit_p (nodes, e->dest->cuid)) | 874 if (bitmap_bit_p (nodes, e->dest->cuid)) |
871 { | 875 { |
872 e->aux.count = IN_SCC; | 876 e->in_scc = true; |
873 if (e->distance > 0) | 877 if (e->distance > 0) |
874 add_backarc_to_scc (scc, e); | 878 add_backarc_to_scc (scc, e); |
875 } | 879 } |
876 } | 880 } |
877 | 881 |
878 set_recurrence_length (scc, g); | |
879 return scc; | 882 return scc; |
880 } | 883 } |
881 | 884 |
882 /* Cleans the memory allocation of a given SCC. */ | 885 /* Cleans the memory allocation of a given SCC. */ |
883 static void | 886 static void |
1016 /* Perform the Strongly Connected Components decomposing algorithm on the | 1019 /* Perform the Strongly Connected Components decomposing algorithm on the |
1017 DDG and return DDG_ALL_SCCS structure that contains them. */ | 1020 DDG and return DDG_ALL_SCCS structure that contains them. */ |
1018 ddg_all_sccs_ptr | 1021 ddg_all_sccs_ptr |
1019 create_ddg_all_sccs (ddg_ptr g) | 1022 create_ddg_all_sccs (ddg_ptr g) |
1020 { | 1023 { |
1021 int i; | 1024 int i, j, k, scc, way; |
1022 int num_nodes = g->num_nodes; | 1025 int num_nodes = g->num_nodes; |
1023 auto_sbitmap from (num_nodes); | 1026 auto_sbitmap from (num_nodes); |
1024 auto_sbitmap to (num_nodes); | 1027 auto_sbitmap to (num_nodes); |
1025 auto_sbitmap scc_nodes (num_nodes); | 1028 auto_sbitmap scc_nodes (num_nodes); |
1026 ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr) | 1029 ddg_all_sccs_ptr sccs = (ddg_all_sccs_ptr) |
1036 ddg_edge_ptr backarc = g->backarcs[i]; | 1039 ddg_edge_ptr backarc = g->backarcs[i]; |
1037 ddg_node_ptr src = backarc->src; | 1040 ddg_node_ptr src = backarc->src; |
1038 ddg_node_ptr dest = backarc->dest; | 1041 ddg_node_ptr dest = backarc->dest; |
1039 | 1042 |
1040 /* If the backarc already belongs to an SCC, continue. */ | 1043 /* If the backarc already belongs to an SCC, continue. */ |
1041 if (backarc->aux.count == IN_SCC) | 1044 if (backarc->in_scc) |
1042 continue; | 1045 continue; |
1043 | 1046 |
1044 bitmap_clear (scc_nodes); | 1047 bitmap_clear (scc_nodes); |
1045 bitmap_clear (from); | 1048 bitmap_clear (from); |
1046 bitmap_clear (to); | 1049 bitmap_clear (to); |
1047 bitmap_set_bit (from, dest->cuid); | 1050 bitmap_set_bit (from, dest->cuid); |
1048 bitmap_set_bit (to, src->cuid); | 1051 bitmap_set_bit (to, src->cuid); |
1049 | 1052 |
1050 if (find_nodes_on_paths (scc_nodes, g, from, to)) | 1053 if (find_nodes_on_paths (scc_nodes, g, from, to)) |
1051 { | 1054 { |
1052 scc = create_scc (g, scc_nodes); | 1055 scc = create_scc (g, scc_nodes, sccs->num_sccs); |
1053 add_scc_to_ddg (sccs, scc); | 1056 add_scc_to_ddg (sccs, scc); |
1054 } | 1057 } |
1055 } | 1058 } |
1059 | |
1060 /* Init max_dist arrays for Floyd–Warshall-like | |
1061 longest patch calculation algorithm. */ | |
1062 for (k = 0; k < num_nodes; k++) | |
1063 { | |
1064 ddg_edge_ptr e; | |
1065 ddg_node_ptr n = &g->nodes[k]; | |
1066 | |
1067 if (n->aux.count == -1) | |
1068 continue; | |
1069 | |
1070 n->max_dist[k] = 0; | |
1071 for (e = n->out; e; e = e->next_out) | |
1072 if (e->distance == 0 && g->nodes[e->dest->cuid].aux.count == n->aux.count) | |
1073 n->max_dist[e->dest->cuid] = e->latency; | |
1074 } | |
1075 | |
1076 /* Run main Floid-Warshall loop. We use only non-backarc edges | |
1077 inside each scc. */ | |
1078 for (k = 0; k < num_nodes; k++) | |
1079 { | |
1080 scc = g->nodes[k].aux.count; | |
1081 if (scc != -1) | |
1082 { | |
1083 for (i = 0; i < num_nodes; i++) | |
1084 if (g->nodes[i].aux.count == scc) | |
1085 for (j = 0; j < num_nodes; j++) | |
1086 if (g->nodes[j].aux.count == scc | |
1087 && g->nodes[i].max_dist[k] >= 0 | |
1088 && g->nodes[k].max_dist[j] >= 0) | |
1089 { | |
1090 way = g->nodes[i].max_dist[k] + g->nodes[k].max_dist[j]; | |
1091 if (g->nodes[i].max_dist[j] < way) | |
1092 g->nodes[i].max_dist[j] = way; | |
1093 } | |
1094 } | |
1095 } | |
1096 | |
1097 /* Calculate recurrence_length using max_dist info. */ | |
1098 for (i = 0; i < sccs->num_sccs; i++) | |
1099 set_recurrence_length (sccs->sccs[i]); | |
1100 | |
1056 order_sccs (sccs); | 1101 order_sccs (sccs); |
1057 | 1102 |
1058 if (flag_checking) | 1103 if (flag_checking) |
1059 check_sccs (sccs, num_nodes); | 1104 check_sccs (sccs, num_nodes); |
1060 | 1105 |
1153 } | 1198 } |
1154 | 1199 |
1155 return bitmap_and (result, reachable_from, reach_to); | 1200 return bitmap_and (result, reachable_from, reach_to); |
1156 } | 1201 } |
1157 | 1202 |
1158 | |
1159 /* Updates the counts of U_NODE's successors (that belong to NODES) to be | |
1160 at-least as large as the count of U_NODE plus the latency between them. | |
1161 Sets a bit in TMP for each successor whose count was changed (increased). | |
1162 Returns nonzero if any count was changed. */ | |
1163 static int | |
1164 update_dist_to_successors (ddg_node_ptr u_node, sbitmap nodes, sbitmap tmp) | |
1165 { | |
1166 ddg_edge_ptr e; | |
1167 int result = 0; | |
1168 | |
1169 for (e = u_node->out; e; e = e->next_out) | |
1170 { | |
1171 ddg_node_ptr v_node = e->dest; | |
1172 int v = v_node->cuid; | |
1173 | |
1174 if (bitmap_bit_p (nodes, v) | |
1175 && (e->distance == 0) | |
1176 && (v_node->aux.count < u_node->aux.count + e->latency)) | |
1177 { | |
1178 v_node->aux.count = u_node->aux.count + e->latency; | |
1179 bitmap_set_bit (tmp, v); | |
1180 result = 1; | |
1181 } | |
1182 } | |
1183 return result; | |
1184 } | |
1185 | |
1186 | |
1187 /* Find the length of a longest path from SRC to DEST in G, | |
1188 going only through NODES, and disregarding backarcs. */ | |
1189 int | |
1190 longest_simple_path (struct ddg * g, int src, int dest, sbitmap nodes) | |
1191 { | |
1192 int i; | |
1193 unsigned int u = 0; | |
1194 int change = 1; | |
1195 int num_nodes = g->num_nodes; | |
1196 auto_sbitmap workset (num_nodes); | |
1197 auto_sbitmap tmp (num_nodes); | |
1198 | |
1199 | |
1200 /* Data will hold the distance of the longest path found so far from | |
1201 src to each node. Initialize to -1 = less than minimum. */ | |
1202 for (i = 0; i < g->num_nodes; i++) | |
1203 g->nodes[i].aux.count = -1; | |
1204 g->nodes[src].aux.count = 0; | |
1205 | |
1206 bitmap_clear (tmp); | |
1207 bitmap_set_bit (tmp, src); | |
1208 | |
1209 while (change) | |
1210 { | |
1211 sbitmap_iterator sbi; | |
1212 | |
1213 change = 0; | |
1214 bitmap_copy (workset, tmp); | |
1215 bitmap_clear (tmp); | |
1216 EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi) | |
1217 { | |
1218 ddg_node_ptr u_node = &g->nodes[u]; | |
1219 | |
1220 change |= update_dist_to_successors (u_node, nodes, tmp); | |
1221 } | |
1222 } | |
1223 return g->nodes[dest].aux.count; | |
1224 } | |
1225 | |
1226 #endif /* INSN_SCHEDULING */ | 1203 #endif /* INSN_SCHEDULING */ |