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 */