Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-data-ref.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
75 */ | 75 */ |
76 | 76 |
77 #include "config.h" | 77 #include "config.h" |
78 #include "system.h" | 78 #include "system.h" |
79 #include "coretypes.h" | 79 #include "coretypes.h" |
80 #include "tm.h" | |
81 #include "ggc.h" | |
82 #include "flags.h" | |
83 #include "tree.h" | |
84 | |
85 /* These RTL headers are needed for basic-block.h. */ | |
86 #include "basic-block.h" | |
87 #include "diagnostic.h" | |
88 #include "tree-pretty-print.h" | |
89 #include "gimple-pretty-print.h" | 80 #include "gimple-pretty-print.h" |
90 #include "tree-flow.h" | 81 #include "tree-flow.h" |
91 #include "tree-dump.h" | |
92 #include "timevar.h" | |
93 #include "cfgloop.h" | 82 #include "cfgloop.h" |
94 #include "tree-data-ref.h" | 83 #include "tree-data-ref.h" |
95 #include "tree-scalar-evolution.h" | 84 #include "tree-scalar-evolution.h" |
96 #include "tree-pass.h" | 85 #include "tree-pass.h" |
97 #include "langhooks.h" | 86 #include "langhooks.h" |
153 dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs) | 142 dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs) |
154 { | 143 { |
155 unsigned int i; | 144 unsigned int i; |
156 struct data_reference *dr; | 145 struct data_reference *dr; |
157 | 146 |
158 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) | 147 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr) |
159 dump_data_reference (file, dr); | 148 dump_data_reference (file, dr); |
160 } | 149 } |
161 | 150 |
162 /* Dump into STDERR all the data references from DATAREFS. */ | 151 /* Dump into STDERR all the data references from DATAREFS. */ |
163 | 152 |
164 void | 153 DEBUG_FUNCTION void |
165 debug_data_references (VEC (data_reference_p, heap) *datarefs) | 154 debug_data_references (VEC (data_reference_p, heap) *datarefs) |
166 { | 155 { |
167 dump_data_references (stderr, datarefs); | 156 dump_data_references (stderr, datarefs); |
168 } | 157 } |
169 | 158 |
170 /* Dump to STDERR all the dependence relations from DDRS. */ | 159 /* Dump to STDERR all the dependence relations from DDRS. */ |
171 | 160 |
172 void | 161 DEBUG_FUNCTION void |
173 debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs) | 162 debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs) |
174 { | 163 { |
175 dump_data_dependence_relations (stderr, ddrs); | 164 dump_data_dependence_relations (stderr, ddrs); |
176 } | 165 } |
177 | 166 |
182 VEC (ddr_p, heap) *ddrs) | 171 VEC (ddr_p, heap) *ddrs) |
183 { | 172 { |
184 unsigned int i; | 173 unsigned int i; |
185 struct data_dependence_relation *ddr; | 174 struct data_dependence_relation *ddr; |
186 | 175 |
187 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++) | 176 FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) |
188 dump_data_dependence_relation (file, ddr); | 177 dump_data_dependence_relation (file, ddr); |
189 } | 178 } |
190 | 179 |
191 /* Print to STDERR the data_reference DR. */ | 180 /* Print to STDERR the data_reference DR. */ |
192 | 181 |
193 void | 182 DEBUG_FUNCTION void |
194 debug_data_reference (struct data_reference *dr) | 183 debug_data_reference (struct data_reference *dr) |
195 { | 184 { |
196 dump_data_reference (stderr, dr); | 185 dump_data_reference (stderr, dr); |
197 } | 186 } |
198 | 187 |
202 dump_data_reference (FILE *outf, | 191 dump_data_reference (FILE *outf, |
203 struct data_reference *dr) | 192 struct data_reference *dr) |
204 { | 193 { |
205 unsigned int i; | 194 unsigned int i; |
206 | 195 |
207 fprintf (outf, "#(Data Ref: \n# stmt: "); | 196 fprintf (outf, "#(Data Ref: \n"); |
197 fprintf (outf, "# bb: %d \n", gimple_bb (DR_STMT (dr))->index); | |
198 fprintf (outf, "# stmt: "); | |
208 print_gimple_stmt (outf, DR_STMT (dr), 0, 0); | 199 print_gimple_stmt (outf, DR_STMT (dr), 0, 0); |
209 fprintf (outf, "# ref: "); | 200 fprintf (outf, "# ref: "); |
210 print_generic_stmt (outf, DR_REF (dr), 0); | 201 print_generic_stmt (outf, DR_REF (dr), 0); |
211 fprintf (outf, "# base_object: "); | 202 fprintf (outf, "# base_object: "); |
212 print_generic_stmt (outf, DR_BASE_OBJECT (dr), 0); | 203 print_generic_stmt (outf, DR_BASE_OBJECT (dr), 0); |
343 int length) | 334 int length) |
344 { | 335 { |
345 unsigned j; | 336 unsigned j; |
346 lambda_vector v; | 337 lambda_vector v; |
347 | 338 |
348 for (j = 0; VEC_iterate (lambda_vector, dir_vects, j, v); j++) | 339 FOR_EACH_VEC_ELT (lambda_vector, dir_vects, j, v) |
349 print_direction_vector (outf, v, length); | 340 print_direction_vector (outf, v, length); |
341 } | |
342 | |
343 /* Print out a vector VEC of length N to OUTFILE. */ | |
344 | |
345 static inline void | |
346 print_lambda_vector (FILE * outfile, lambda_vector vector, int n) | |
347 { | |
348 int i; | |
349 | |
350 for (i = 0; i < n; i++) | |
351 fprintf (outfile, "%3d ", vector[i]); | |
352 fprintf (outfile, "\n"); | |
350 } | 353 } |
351 | 354 |
352 /* Print a vector of distance vectors. */ | 355 /* Print a vector of distance vectors. */ |
353 | 356 |
354 void | 357 void |
356 int length) | 359 int length) |
357 { | 360 { |
358 unsigned j; | 361 unsigned j; |
359 lambda_vector v; | 362 lambda_vector v; |
360 | 363 |
361 for (j = 0; VEC_iterate (lambda_vector, dist_vects, j, v); j++) | 364 FOR_EACH_VEC_ELT (lambda_vector, dist_vects, j, v) |
362 print_lambda_vector (outf, v, length); | 365 print_lambda_vector (outf, v, length); |
363 } | 366 } |
364 | 367 |
365 /* Debug version. */ | 368 /* Debug version. */ |
366 | 369 |
367 void | 370 DEBUG_FUNCTION void |
368 debug_data_dependence_relation (struct data_dependence_relation *ddr) | 371 debug_data_dependence_relation (struct data_dependence_relation *ddr) |
369 { | 372 { |
370 dump_data_dependence_relation (stderr, ddr); | 373 dump_data_dependence_relation (stderr, ddr); |
371 } | 374 } |
372 | 375 |
421 dump_subscript (outf, DDR_SUBSCRIPT (ddr, i)); | 424 dump_subscript (outf, DDR_SUBSCRIPT (ddr, i)); |
422 } | 425 } |
423 | 426 |
424 fprintf (outf, " inner loop index: %d\n", DDR_INNER_LOOP (ddr)); | 427 fprintf (outf, " inner loop index: %d\n", DDR_INNER_LOOP (ddr)); |
425 fprintf (outf, " loop nest: ("); | 428 fprintf (outf, " loop nest: ("); |
426 for (i = 0; VEC_iterate (loop_p, DDR_LOOP_NEST (ddr), i, loopi); i++) | 429 FOR_EACH_VEC_ELT (loop_p, DDR_LOOP_NEST (ddr), i, loopi) |
427 fprintf (outf, "%d ", loopi->num); | 430 fprintf (outf, "%d ", loopi->num); |
428 fprintf (outf, ")\n"); | 431 fprintf (outf, ")\n"); |
429 | 432 |
430 for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++) | 433 for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++) |
431 { | 434 { |
496 { | 499 { |
497 unsigned int i, j; | 500 unsigned int i, j; |
498 struct data_dependence_relation *ddr; | 501 struct data_dependence_relation *ddr; |
499 lambda_vector v; | 502 lambda_vector v; |
500 | 503 |
501 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++) | 504 FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) |
502 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE && DDR_AFFINE_P (ddr)) | 505 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE && DDR_AFFINE_P (ddr)) |
503 { | 506 { |
504 for (j = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), j, v); j++) | 507 FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), j, v) |
505 { | 508 { |
506 fprintf (file, "DISTANCE_V ("); | 509 fprintf (file, "DISTANCE_V ("); |
507 print_lambda_vector (file, v, DDR_NB_LOOPS (ddr)); | 510 print_lambda_vector (file, v, DDR_NB_LOOPS (ddr)); |
508 fprintf (file, ")\n"); | 511 fprintf (file, ")\n"); |
509 } | 512 } |
510 | 513 |
511 for (j = 0; VEC_iterate (lambda_vector, DDR_DIR_VECTS (ddr), j, v); j++) | 514 FOR_EACH_VEC_ELT (lambda_vector, DDR_DIR_VECTS (ddr), j, v) |
512 { | 515 { |
513 fprintf (file, "DIRECTION_V ("); | 516 fprintf (file, "DIRECTION_V ("); |
514 print_direction_vector (file, v, DDR_NB_LOOPS (ddr)); | 517 print_direction_vector (file, v, DDR_NB_LOOPS (ddr)); |
515 fprintf (file, ")\n"); | 518 fprintf (file, ")\n"); |
516 } | 519 } |
525 dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs) | 528 dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs) |
526 { | 529 { |
527 unsigned int i; | 530 unsigned int i; |
528 struct data_dependence_relation *ddr; | 531 struct data_dependence_relation *ddr; |
529 | 532 |
530 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++) | 533 FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) |
531 dump_data_dependence_relation (file, ddr); | 534 dump_data_dependence_relation (file, ddr); |
532 | 535 |
533 fprintf (file, "\n\n"); | 536 fprintf (file, "\n\n"); |
534 } | 537 } |
535 | 538 |
747 if (dump_file && (dump_flags & TDF_DETAILS)) | 750 if (dump_file && (dump_flags & TDF_DETAILS)) |
748 fprintf (dump_file, "failed: bit offset alignment.\n"); | 751 fprintf (dump_file, "failed: bit offset alignment.\n"); |
749 return false; | 752 return false; |
750 } | 753 } |
751 | 754 |
752 base = build_fold_addr_expr (base); | 755 if (TREE_CODE (base) == MEM_REF) |
756 { | |
757 if (!integer_zerop (TREE_OPERAND (base, 1))) | |
758 { | |
759 if (!poffset) | |
760 { | |
761 double_int moff = mem_ref_offset (base); | |
762 poffset = double_int_to_tree (sizetype, moff); | |
763 } | |
764 else | |
765 poffset = size_binop (PLUS_EXPR, poffset, TREE_OPERAND (base, 1)); | |
766 } | |
767 base = TREE_OPERAND (base, 0); | |
768 } | |
769 else | |
770 base = build_fold_addr_expr (base); | |
753 if (in_loop) | 771 if (in_loop) |
754 { | 772 { |
755 if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, | 773 if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, |
756 false)) | 774 false)) |
757 { | 775 { |
812 | 830 |
813 return true; | 831 return true; |
814 } | 832 } |
815 | 833 |
816 /* Determines the base object and the list of indices of memory reference | 834 /* Determines the base object and the list of indices of memory reference |
817 DR, analyzed in loop nest NEST. */ | 835 DR, analyzed in LOOP and instantiated in loop nest NEST. */ |
818 | 836 |
819 static void | 837 static void |
820 dr_analyze_indices (struct data_reference *dr, struct loop *nest) | 838 dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) |
821 { | 839 { |
822 gimple stmt = DR_STMT (dr); | |
823 struct loop *loop = loop_containing_stmt (stmt); | |
824 VEC (tree, heap) *access_fns = NULL; | 840 VEC (tree, heap) *access_fns = NULL; |
825 tree ref = unshare_expr (DR_REF (dr)), aref = ref, op; | 841 tree ref = unshare_expr (DR_REF (dr)), aref = ref, op; |
826 tree base, off, access_fn = NULL_TREE; | 842 tree base, off, access_fn = NULL_TREE; |
827 basic_block before_loop = NULL; | 843 basic_block before_loop = NULL; |
828 | 844 |
845 } | 861 } |
846 | 862 |
847 aref = TREE_OPERAND (aref, 0); | 863 aref = TREE_OPERAND (aref, 0); |
848 } | 864 } |
849 | 865 |
850 if (nest && INDIRECT_REF_P (aref)) | 866 if (nest |
867 && (INDIRECT_REF_P (aref) | |
868 || TREE_CODE (aref) == MEM_REF)) | |
851 { | 869 { |
852 op = TREE_OPERAND (aref, 0); | 870 op = TREE_OPERAND (aref, 0); |
853 access_fn = analyze_scalar_evolution (loop, op); | 871 access_fn = analyze_scalar_evolution (loop, op); |
854 access_fn = instantiate_scev (before_loop, loop, access_fn); | 872 access_fn = instantiate_scev (before_loop, loop, access_fn); |
855 base = initial_condition (access_fn); | 873 base = initial_condition (access_fn); |
856 split_constant_offset (base, &base, &off); | 874 split_constant_offset (base, &base, &off); |
875 if (TREE_CODE (aref) == MEM_REF) | |
876 off = size_binop (PLUS_EXPR, off, | |
877 fold_convert (ssizetype, TREE_OPERAND (aref, 1))); | |
857 access_fn = chrec_replace_initial_condition (access_fn, | 878 access_fn = chrec_replace_initial_condition (access_fn, |
858 fold_convert (TREE_TYPE (base), off)); | 879 fold_convert (TREE_TYPE (base), off)); |
859 | 880 |
860 TREE_OPERAND (aref, 0) = base; | 881 TREE_OPERAND (aref, 0) = base; |
861 VEC_safe_push (tree, heap, access_fns, access_fn); | 882 VEC_safe_push (tree, heap, access_fns, access_fn); |
862 } | 883 } |
863 | 884 |
885 if (TREE_CODE (aref) == MEM_REF) | |
886 TREE_OPERAND (aref, 1) | |
887 = build_int_cst (TREE_TYPE (TREE_OPERAND (aref, 1)), 0); | |
888 | |
889 if (TREE_CODE (ref) == MEM_REF | |
890 && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR | |
891 && integer_zerop (TREE_OPERAND (ref, 1))) | |
892 ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); | |
893 | |
894 /* For canonicalization purposes we'd like to strip all outermost | |
895 zero-offset component-refs. | |
896 ??? For now simply handle zero-index array-refs. */ | |
897 while (TREE_CODE (ref) == ARRAY_REF | |
898 && integer_zerop (TREE_OPERAND (ref, 1))) | |
899 ref = TREE_OPERAND (ref, 0); | |
900 | |
864 DR_BASE_OBJECT (dr) = ref; | 901 DR_BASE_OBJECT (dr) = ref; |
865 DR_ACCESS_FNS (dr) = access_fns; | 902 DR_ACCESS_FNS (dr) = access_fns; |
866 } | 903 } |
867 | 904 |
868 /* Extracts the alias analysis information from the memory reference DR. */ | 905 /* Extracts the alias analysis information from the memory reference DR. */ |
871 dr_analyze_alias (struct data_reference *dr) | 908 dr_analyze_alias (struct data_reference *dr) |
872 { | 909 { |
873 tree ref = DR_REF (dr); | 910 tree ref = DR_REF (dr); |
874 tree base = get_base_address (ref), addr; | 911 tree base = get_base_address (ref), addr; |
875 | 912 |
876 if (INDIRECT_REF_P (base)) | 913 if (INDIRECT_REF_P (base) |
914 || TREE_CODE (base) == MEM_REF) | |
877 { | 915 { |
878 addr = TREE_OPERAND (base, 0); | 916 addr = TREE_OPERAND (base, 0); |
879 if (TREE_CODE (addr) == SSA_NAME) | 917 if (TREE_CODE (addr) == SSA_NAME) |
880 DR_PTR_INFO (dr) = SSA_NAME_PTR_INFO (addr); | 918 DR_PTR_INFO (dr) = SSA_NAME_PTR_INFO (addr); |
881 } | 919 } |
887 dr_address_invariant_p (struct data_reference *dr) | 925 dr_address_invariant_p (struct data_reference *dr) |
888 { | 926 { |
889 unsigned i; | 927 unsigned i; |
890 tree idx; | 928 tree idx; |
891 | 929 |
892 for (i = 0; VEC_iterate (tree, DR_ACCESS_FNS (dr), i, idx); i++) | 930 FOR_EACH_VEC_ELT (tree, DR_ACCESS_FNS (dr), i, idx) |
893 if (tree_contains_chrecs (idx, NULL)) | 931 if (tree_contains_chrecs (idx, NULL)) |
894 return false; | 932 return false; |
895 | 933 |
896 return true; | 934 return true; |
897 } | 935 } |
905 free (dr); | 943 free (dr); |
906 } | 944 } |
907 | 945 |
908 /* Analyzes memory reference MEMREF accessed in STMT. The reference | 946 /* Analyzes memory reference MEMREF accessed in STMT. The reference |
909 is read if IS_READ is true, write otherwise. Returns the | 947 is read if IS_READ is true, write otherwise. Returns the |
910 data_reference description of MEMREF. NEST is the outermost loop of the | 948 data_reference description of MEMREF. NEST is the outermost loop |
911 loop nest in that the reference should be analyzed. */ | 949 in which the reference should be instantiated, LOOP is the loop in |
950 which the data reference should be analyzed. */ | |
912 | 951 |
913 struct data_reference * | 952 struct data_reference * |
914 create_data_ref (struct loop *nest, tree memref, gimple stmt, bool is_read) | 953 create_data_ref (loop_p nest, loop_p loop, tree memref, gimple stmt, |
954 bool is_read) | |
915 { | 955 { |
916 struct data_reference *dr; | 956 struct data_reference *dr; |
917 | 957 |
918 if (dump_file && (dump_flags & TDF_DETAILS)) | 958 if (dump_file && (dump_flags & TDF_DETAILS)) |
919 { | 959 { |
926 DR_STMT (dr) = stmt; | 966 DR_STMT (dr) = stmt; |
927 DR_REF (dr) = memref; | 967 DR_REF (dr) = memref; |
928 DR_IS_READ (dr) = is_read; | 968 DR_IS_READ (dr) = is_read; |
929 | 969 |
930 dr_analyze_innermost (dr); | 970 dr_analyze_innermost (dr); |
931 dr_analyze_indices (dr, nest); | 971 dr_analyze_indices (dr, nest, loop); |
932 dr_analyze_alias (dr); | 972 dr_analyze_alias (dr); |
933 | 973 |
934 if (dump_file && (dump_flags & TDF_DETAILS)) | 974 if (dump_file && (dump_flags & TDF_DETAILS)) |
935 { | 975 { |
936 fprintf (dump_file, "\tbase_address: "); | 976 fprintf (dump_file, "\tbase_address: "); |
1189 return false; | 1229 return false; |
1190 } | 1230 } |
1191 obj = TREE_OPERAND (obj, 0); | 1231 obj = TREE_OPERAND (obj, 0); |
1192 } | 1232 } |
1193 | 1233 |
1194 if (!INDIRECT_REF_P (obj)) | 1234 if (!INDIRECT_REF_P (obj) |
1235 && TREE_CODE (obj) != MEM_REF) | |
1195 return true; | 1236 return true; |
1196 | 1237 |
1197 return !chrec_contains_symbols_defined_in_loop (TREE_OPERAND (obj, 0), | 1238 return !chrec_contains_symbols_defined_in_loop (TREE_OPERAND (obj, 0), |
1198 loop->num); | 1239 loop->num); |
1199 } | 1240 } |
1200 | 1241 |
1201 /* Returns true if A and B are accesses to different objects, or to different | |
1202 fields of the same object. */ | |
1203 | |
1204 static bool | |
1205 disjoint_objects_p (tree a, tree b) | |
1206 { | |
1207 tree base_a, base_b; | |
1208 VEC (tree, heap) *comp_a = NULL, *comp_b = NULL; | |
1209 bool ret; | |
1210 | |
1211 base_a = get_base_address (a); | |
1212 base_b = get_base_address (b); | |
1213 | |
1214 if (DECL_P (base_a) | |
1215 && DECL_P (base_b) | |
1216 && base_a != base_b) | |
1217 return true; | |
1218 | |
1219 if (!operand_equal_p (base_a, base_b, 0)) | |
1220 return false; | |
1221 | |
1222 /* Compare the component references of A and B. We must start from the inner | |
1223 ones, so record them to the vector first. */ | |
1224 while (handled_component_p (a)) | |
1225 { | |
1226 VEC_safe_push (tree, heap, comp_a, a); | |
1227 a = TREE_OPERAND (a, 0); | |
1228 } | |
1229 while (handled_component_p (b)) | |
1230 { | |
1231 VEC_safe_push (tree, heap, comp_b, b); | |
1232 b = TREE_OPERAND (b, 0); | |
1233 } | |
1234 | |
1235 ret = false; | |
1236 while (1) | |
1237 { | |
1238 if (VEC_length (tree, comp_a) == 0 | |
1239 || VEC_length (tree, comp_b) == 0) | |
1240 break; | |
1241 | |
1242 a = VEC_pop (tree, comp_a); | |
1243 b = VEC_pop (tree, comp_b); | |
1244 | |
1245 /* Real and imaginary part of a variable do not alias. */ | |
1246 if ((TREE_CODE (a) == REALPART_EXPR | |
1247 && TREE_CODE (b) == IMAGPART_EXPR) | |
1248 || (TREE_CODE (a) == IMAGPART_EXPR | |
1249 && TREE_CODE (b) == REALPART_EXPR)) | |
1250 { | |
1251 ret = true; | |
1252 break; | |
1253 } | |
1254 | |
1255 if (TREE_CODE (a) != TREE_CODE (b)) | |
1256 break; | |
1257 | |
1258 /* Nothing to do for ARRAY_REFs, as the indices of array_refs in | |
1259 DR_BASE_OBJECT are always zero. */ | |
1260 if (TREE_CODE (a) == ARRAY_REF) | |
1261 continue; | |
1262 else if (TREE_CODE (a) == COMPONENT_REF) | |
1263 { | |
1264 if (operand_equal_p (TREE_OPERAND (a, 1), TREE_OPERAND (b, 1), 0)) | |
1265 continue; | |
1266 | |
1267 /* Different fields of unions may overlap. */ | |
1268 base_a = TREE_OPERAND (a, 0); | |
1269 if (TREE_CODE (TREE_TYPE (base_a)) == UNION_TYPE) | |
1270 break; | |
1271 | |
1272 /* Different fields of structures cannot. */ | |
1273 ret = true; | |
1274 break; | |
1275 } | |
1276 else | |
1277 break; | |
1278 } | |
1279 | |
1280 VEC_free (tree, heap, comp_a); | |
1281 VEC_free (tree, heap, comp_b); | |
1282 | |
1283 return ret; | |
1284 } | |
1285 | |
1286 /* Returns false if we can prove that data references A and B do not alias, | 1242 /* Returns false if we can prove that data references A and B do not alias, |
1287 true otherwise. */ | 1243 true otherwise. */ |
1288 | 1244 |
1289 bool | 1245 bool |
1290 dr_may_alias_p (const struct data_reference *a, const struct data_reference *b) | 1246 dr_may_alias_p (const struct data_reference *a, const struct data_reference *b) |
1291 { | 1247 { |
1292 const_tree addr_a = DR_BASE_ADDRESS (a); | 1248 tree addr_a = DR_BASE_OBJECT (a); |
1293 const_tree addr_b = DR_BASE_ADDRESS (b); | 1249 tree addr_b = DR_BASE_OBJECT (b); |
1294 const_tree type_a, type_b; | 1250 |
1295 const_tree decl_a = NULL_TREE, decl_b = NULL_TREE; | 1251 if (DR_IS_WRITE (a) && DR_IS_WRITE (b)) |
1296 | 1252 return refs_output_dependent_p (addr_a, addr_b); |
1297 /* If the accessed objects are disjoint, the memory references do not | 1253 else if (DR_IS_READ (a) && DR_IS_WRITE (b)) |
1298 alias. */ | 1254 return refs_anti_dependent_p (addr_a, addr_b); |
1299 if (disjoint_objects_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b))) | 1255 return refs_may_alias_p (addr_a, addr_b); |
1300 return false; | |
1301 | |
1302 /* Query the alias oracle. */ | |
1303 if (!DR_IS_READ (a) && !DR_IS_READ (b)) | |
1304 { | |
1305 if (!refs_output_dependent_p (DR_REF (a), DR_REF (b))) | |
1306 return false; | |
1307 } | |
1308 else if (DR_IS_READ (a) && !DR_IS_READ (b)) | |
1309 { | |
1310 if (!refs_anti_dependent_p (DR_REF (a), DR_REF (b))) | |
1311 return false; | |
1312 } | |
1313 else if (!refs_may_alias_p (DR_REF (a), DR_REF (b))) | |
1314 return false; | |
1315 | |
1316 if (!addr_a || !addr_b) | |
1317 return true; | |
1318 | |
1319 /* If the references are based on different static objects, they cannot | |
1320 alias (PTA should be able to disambiguate such accesses, but often | |
1321 it fails to). */ | |
1322 if (TREE_CODE (addr_a) == ADDR_EXPR | |
1323 && TREE_CODE (addr_b) == ADDR_EXPR) | |
1324 return TREE_OPERAND (addr_a, 0) == TREE_OPERAND (addr_b, 0); | |
1325 | |
1326 /* An instruction writing through a restricted pointer is "independent" of any | |
1327 instruction reading or writing through a different restricted pointer, | |
1328 in the same block/scope. */ | |
1329 | |
1330 type_a = TREE_TYPE (addr_a); | |
1331 type_b = TREE_TYPE (addr_b); | |
1332 gcc_assert (POINTER_TYPE_P (type_a) && POINTER_TYPE_P (type_b)); | |
1333 | |
1334 if (TREE_CODE (addr_a) == SSA_NAME) | |
1335 decl_a = SSA_NAME_VAR (addr_a); | |
1336 if (TREE_CODE (addr_b) == SSA_NAME) | |
1337 decl_b = SSA_NAME_VAR (addr_b); | |
1338 | |
1339 if (TYPE_RESTRICT (type_a) && TYPE_RESTRICT (type_b) | |
1340 && (!DR_IS_READ (a) || !DR_IS_READ (b)) | |
1341 && decl_a && DECL_P (decl_a) | |
1342 && decl_b && DECL_P (decl_b) | |
1343 && decl_a != decl_b | |
1344 && TREE_CODE (DECL_CONTEXT (decl_a)) == FUNCTION_DECL | |
1345 && DECL_CONTEXT (decl_a) == DECL_CONTEXT (decl_b)) | |
1346 return false; | |
1347 | |
1348 return true; | |
1349 } | 1256 } |
1350 | 1257 |
1351 static void compute_self_dependence (struct data_dependence_relation *); | 1258 static void compute_self_dependence (struct data_dependence_relation *); |
1352 | 1259 |
1353 /* Initialize a data dependence relation between data accesses A and | 1260 /* Initialize a data dependence relation between data accesses A and |
1415 { | 1322 { |
1416 DDR_ARE_DEPENDENT (res) = chrec_dont_know; | 1323 DDR_ARE_DEPENDENT (res) = chrec_dont_know; |
1417 return res; | 1324 return res; |
1418 } | 1325 } |
1419 | 1326 |
1420 gcc_assert (DR_NUM_DIMENSIONS (a) == DR_NUM_DIMENSIONS (b)); | 1327 /* If the number of dimensions of the access to not agree we can have |
1328 a pointer access to a component of the array element type and an | |
1329 array access while the base-objects are still the same. Punt. */ | |
1330 if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)) | |
1331 { | |
1332 DDR_ARE_DEPENDENT (res) = chrec_dont_know; | |
1333 return res; | |
1334 } | |
1421 | 1335 |
1422 DDR_AFFINE_P (res) = true; | 1336 DDR_AFFINE_P (res) = true; |
1423 DDR_ARE_DEPENDENT (res) = NULL_TREE; | 1337 DDR_ARE_DEPENDENT (res) = NULL_TREE; |
1424 DDR_SUBSCRIPTS (res) = VEC_alloc (subscript_p, heap, DR_NUM_DIMENSIONS (a)); | 1338 DDR_SUBSCRIPTS (res) = VEC_alloc (subscript_p, heap, DR_NUM_DIMENSIONS (a)); |
1425 DDR_LOOP_NEST (res) = loop_nest; | 1339 DDR_LOOP_NEST (res) = loop_nest; |
1462 free_subscripts (VEC (subscript_p, heap) *subscripts) | 1376 free_subscripts (VEC (subscript_p, heap) *subscripts) |
1463 { | 1377 { |
1464 unsigned i; | 1378 unsigned i; |
1465 subscript_p s; | 1379 subscript_p s; |
1466 | 1380 |
1467 for (i = 0; VEC_iterate (subscript_p, subscripts, i, s); i++) | 1381 FOR_EACH_VEC_ELT (subscript_p, subscripts, i, s) |
1468 { | 1382 { |
1469 free_conflict_function (s->conflicting_iterations_in_a); | 1383 free_conflict_function (s->conflicting_iterations_in_a); |
1470 free_conflict_function (s->conflicting_iterations_in_b); | 1384 free_conflict_function (s->conflicting_iterations_in_b); |
1471 free (s); | 1385 free (s); |
1472 } | 1386 } |
1672 | 1586 |
1673 bool | 1587 bool |
1674 estimated_loop_iterations (struct loop *loop, bool conservative, | 1588 estimated_loop_iterations (struct loop *loop, bool conservative, |
1675 double_int *nit) | 1589 double_int *nit) |
1676 { | 1590 { |
1677 estimate_numbers_of_iterations_loop (loop); | 1591 estimate_numbers_of_iterations_loop (loop, true); |
1678 if (conservative) | 1592 if (conservative) |
1679 { | 1593 { |
1680 if (!loop->any_upper_bound) | 1594 if (!loop->any_upper_bound) |
1681 return false; | 1595 return false; |
1682 | 1596 |
2158 affine_fn_free (overlaps_b_xz); | 2072 affine_fn_free (overlaps_b_xz); |
2159 affine_fn_free (overlaps_a_yz); | 2073 affine_fn_free (overlaps_a_yz); |
2160 affine_fn_free (overlaps_b_yz); | 2074 affine_fn_free (overlaps_b_yz); |
2161 affine_fn_free (overlaps_a_xyz); | 2075 affine_fn_free (overlaps_a_xyz); |
2162 affine_fn_free (overlaps_b_xyz); | 2076 affine_fn_free (overlaps_b_xyz); |
2077 } | |
2078 | |
2079 /* Copy the elements of vector VEC1 with length SIZE to VEC2. */ | |
2080 | |
2081 static void | |
2082 lambda_vector_copy (lambda_vector vec1, lambda_vector vec2, | |
2083 int size) | |
2084 { | |
2085 memcpy (vec2, vec1, size * sizeof (*vec1)); | |
2086 } | |
2087 | |
2088 /* Copy the elements of M x N matrix MAT1 to MAT2. */ | |
2089 | |
2090 static void | |
2091 lambda_matrix_copy (lambda_matrix mat1, lambda_matrix mat2, | |
2092 int m, int n) | |
2093 { | |
2094 int i; | |
2095 | |
2096 for (i = 0; i < m; i++) | |
2097 lambda_vector_copy (mat1[i], mat2[i], n); | |
2098 } | |
2099 | |
2100 /* Store the N x N identity matrix in MAT. */ | |
2101 | |
2102 static void | |
2103 lambda_matrix_id (lambda_matrix mat, int size) | |
2104 { | |
2105 int i, j; | |
2106 | |
2107 for (i = 0; i < size; i++) | |
2108 for (j = 0; j < size; j++) | |
2109 mat[i][j] = (i == j) ? 1 : 0; | |
2110 } | |
2111 | |
2112 /* Return the first nonzero element of vector VEC1 between START and N. | |
2113 We must have START <= N. Returns N if VEC1 is the zero vector. */ | |
2114 | |
2115 static int | |
2116 lambda_vector_first_nz (lambda_vector vec1, int n, int start) | |
2117 { | |
2118 int j = start; | |
2119 while (j < n && vec1[j] == 0) | |
2120 j++; | |
2121 return j; | |
2122 } | |
2123 | |
2124 /* Add a multiple of row R1 of matrix MAT with N columns to row R2: | |
2125 R2 = R2 + CONST1 * R1. */ | |
2126 | |
2127 static void | |
2128 lambda_matrix_row_add (lambda_matrix mat, int n, int r1, int r2, int const1) | |
2129 { | |
2130 int i; | |
2131 | |
2132 if (const1 == 0) | |
2133 return; | |
2134 | |
2135 for (i = 0; i < n; i++) | |
2136 mat[r2][i] += const1 * mat[r1][i]; | |
2137 } | |
2138 | |
2139 /* Swap rows R1 and R2 in matrix MAT. */ | |
2140 | |
2141 static void | |
2142 lambda_matrix_row_exchange (lambda_matrix mat, int r1, int r2) | |
2143 { | |
2144 lambda_vector row; | |
2145 | |
2146 row = mat[r1]; | |
2147 mat[r1] = mat[r2]; | |
2148 mat[r2] = row; | |
2149 } | |
2150 | |
2151 /* Multiply vector VEC1 of length SIZE by a constant CONST1, | |
2152 and store the result in VEC2. */ | |
2153 | |
2154 static void | |
2155 lambda_vector_mult_const (lambda_vector vec1, lambda_vector vec2, | |
2156 int size, int const1) | |
2157 { | |
2158 int i; | |
2159 | |
2160 if (const1 == 0) | |
2161 lambda_vector_clear (vec2, size); | |
2162 else | |
2163 for (i = 0; i < size; i++) | |
2164 vec2[i] = const1 * vec1[i]; | |
2165 } | |
2166 | |
2167 /* Negate vector VEC1 with length SIZE and store it in VEC2. */ | |
2168 | |
2169 static void | |
2170 lambda_vector_negate (lambda_vector vec1, lambda_vector vec2, | |
2171 int size) | |
2172 { | |
2173 lambda_vector_mult_const (vec1, vec2, size, -1); | |
2174 } | |
2175 | |
2176 /* Negate row R1 of matrix MAT which has N columns. */ | |
2177 | |
2178 static void | |
2179 lambda_matrix_row_negate (lambda_matrix mat, int n, int r1) | |
2180 { | |
2181 lambda_vector_negate (mat[r1], mat[r1], n); | |
2182 } | |
2183 | |
2184 /* Return true if two vectors are equal. */ | |
2185 | |
2186 static bool | |
2187 lambda_vector_equal (lambda_vector vec1, lambda_vector vec2, int size) | |
2188 { | |
2189 int i; | |
2190 for (i = 0; i < size; i++) | |
2191 if (vec1[i] != vec2[i]) | |
2192 return false; | |
2193 return true; | |
2194 } | |
2195 | |
2196 /* Given an M x N integer matrix A, this function determines an M x | |
2197 M unimodular matrix U, and an M x N echelon matrix S such that | |
2198 "U.A = S". This decomposition is also known as "right Hermite". | |
2199 | |
2200 Ref: Algorithm 2.1 page 33 in "Loop Transformations for | |
2201 Restructuring Compilers" Utpal Banerjee. */ | |
2202 | |
2203 static void | |
2204 lambda_matrix_right_hermite (lambda_matrix A, int m, int n, | |
2205 lambda_matrix S, lambda_matrix U) | |
2206 { | |
2207 int i, j, i0 = 0; | |
2208 | |
2209 lambda_matrix_copy (A, S, m, n); | |
2210 lambda_matrix_id (U, m); | |
2211 | |
2212 for (j = 0; j < n; j++) | |
2213 { | |
2214 if (lambda_vector_first_nz (S[j], m, i0) < m) | |
2215 { | |
2216 ++i0; | |
2217 for (i = m - 1; i >= i0; i--) | |
2218 { | |
2219 while (S[i][j] != 0) | |
2220 { | |
2221 int sigma, factor, a, b; | |
2222 | |
2223 a = S[i-1][j]; | |
2224 b = S[i][j]; | |
2225 sigma = (a * b < 0) ? -1: 1; | |
2226 a = abs (a); | |
2227 b = abs (b); | |
2228 factor = sigma * (a / b); | |
2229 | |
2230 lambda_matrix_row_add (S, n, i, i-1, -factor); | |
2231 lambda_matrix_row_exchange (S, i, i-1); | |
2232 | |
2233 lambda_matrix_row_add (U, m, i, i-1, -factor); | |
2234 lambda_matrix_row_exchange (U, i, i-1); | |
2235 } | |
2236 } | |
2237 } | |
2238 } | |
2163 } | 2239 } |
2164 | 2240 |
2165 /* Determines the overlapping elements due to accesses CHREC_A and | 2241 /* Determines the overlapping elements due to accesses CHREC_A and |
2166 CHREC_B, that are affine functions. This function cannot handle | 2242 CHREC_B, that are affine functions. This function cannot handle |
2167 symbolic evolution functions, ie. when initial conditions are | 2243 symbolic evolution functions, ie. when initial conditions are |
2603 conflict_function **overlaps_a, | 2679 conflict_function **overlaps_a, |
2604 conflict_function **overlaps_b, | 2680 conflict_function **overlaps_b, |
2605 tree *last_conflicts, | 2681 tree *last_conflicts, |
2606 struct loop *loop_nest) | 2682 struct loop *loop_nest) |
2607 { | 2683 { |
2608 /* FIXME: This is a MIV subscript, not yet handled. | |
2609 Example: (A[{1, +, 1}_1] vs. A[{1, +, 1}_2]) that comes from | |
2610 (A[i] vs. A[j]). | |
2611 | |
2612 In the SIV test we had to solve a Diophantine equation with two | |
2613 variables. In the MIV case we have to solve a Diophantine | |
2614 equation with 2*n variables (if the subscript uses n IVs). | |
2615 */ | |
2616 tree type, difference; | 2684 tree type, difference; |
2617 | 2685 |
2618 dependence_stats.num_miv++; | 2686 dependence_stats.num_miv++; |
2619 if (dump_file && (dump_flags & TDF_DETAILS)) | 2687 if (dump_file && (dump_flags & TDF_DETAILS)) |
2620 fprintf (dump_file, "(analyze_miv_subscript \n"); | 2688 fprintf (dump_file, "(analyze_miv_subscript \n"); |
2743 } | 2811 } |
2744 | 2812 |
2745 /* If they are the same chrec, and are affine, they overlap | 2813 /* If they are the same chrec, and are affine, they overlap |
2746 on every iteration. */ | 2814 on every iteration. */ |
2747 else if (eq_evolutions_p (chrec_a, chrec_b) | 2815 else if (eq_evolutions_p (chrec_a, chrec_b) |
2748 && evolution_function_is_affine_multivariate_p (chrec_a, lnn)) | 2816 && (evolution_function_is_affine_multivariate_p (chrec_a, lnn) |
2817 || operand_equal_p (chrec_a, chrec_b, 0))) | |
2749 { | 2818 { |
2750 dependence_stats.num_same_subscript_function++; | 2819 dependence_stats.num_same_subscript_function++; |
2751 *overlap_iterations_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); | 2820 *overlap_iterations_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); |
2752 *overlap_iterations_b = conflict_fn (1, affine_fn_cst (integer_zero_node)); | 2821 *overlap_iterations_b = conflict_fn (1, affine_fn_cst (integer_zero_node)); |
2753 *last_conflicts = chrec_dont_know; | 2822 *last_conflicts = chrec_dont_know; |
2754 } | 2823 } |
2755 | 2824 |
2756 /* If they aren't the same, and aren't affine, we can't do anything | 2825 /* If they aren't the same, and aren't affine, we can't do anything |
2757 yet. */ | 2826 yet. */ |
2758 else if ((chrec_contains_symbols (chrec_a) | 2827 else if ((chrec_contains_symbols (chrec_a) |
2759 || chrec_contains_symbols (chrec_b)) | 2828 || chrec_contains_symbols (chrec_b)) |
2760 && (!evolution_function_is_affine_multivariate_p (chrec_a, lnn) | 2829 && (!evolution_function_is_affine_multivariate_p (chrec_a, lnn) |
2761 || !evolution_function_is_affine_multivariate_p (chrec_b, lnn))) | 2830 || !evolution_function_is_affine_multivariate_p (chrec_b, lnn))) |
2762 { | 2831 { |
2797 save_dist_v (struct data_dependence_relation *ddr, lambda_vector dist_v) | 2866 save_dist_v (struct data_dependence_relation *ddr, lambda_vector dist_v) |
2798 { | 2867 { |
2799 unsigned i; | 2868 unsigned i; |
2800 lambda_vector v; | 2869 lambda_vector v; |
2801 | 2870 |
2802 for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, v); i++) | 2871 FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), i, v) |
2803 if (lambda_vector_equal (v, dist_v, DDR_NB_LOOPS (ddr))) | 2872 if (lambda_vector_equal (v, dist_v, DDR_NB_LOOPS (ddr))) |
2804 return; | 2873 return; |
2805 | 2874 |
2806 VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), dist_v); | 2875 VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), dist_v); |
2807 } | 2876 } |
2812 save_dir_v (struct data_dependence_relation *ddr, lambda_vector dir_v) | 2881 save_dir_v (struct data_dependence_relation *ddr, lambda_vector dir_v) |
2813 { | 2882 { |
2814 unsigned i; | 2883 unsigned i; |
2815 lambda_vector v; | 2884 lambda_vector v; |
2816 | 2885 |
2817 for (i = 0; VEC_iterate (lambda_vector, DDR_DIR_VECTS (ddr), i, v); i++) | 2886 FOR_EACH_VEC_ELT (lambda_vector, DDR_DIR_VECTS (ddr), i, v) |
2818 if (lambda_vector_equal (v, dir_v, DDR_NB_LOOPS (ddr))) | 2887 if (lambda_vector_equal (v, dir_v, DDR_NB_LOOPS (ddr))) |
2819 return; | 2888 return; |
2820 | 2889 |
2821 VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), dir_v); | 2890 VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), dir_v); |
2822 } | 2891 } |
2881 | 2950 |
2882 if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC | 2951 if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC |
2883 && TREE_CODE (access_fn_b) == POLYNOMIAL_CHREC) | 2952 && TREE_CODE (access_fn_b) == POLYNOMIAL_CHREC) |
2884 { | 2953 { |
2885 int dist, index; | 2954 int dist, index; |
2886 int index_a = index_in_loop_nest (CHREC_VARIABLE (access_fn_a), | 2955 int var_a = CHREC_VARIABLE (access_fn_a); |
2887 DDR_LOOP_NEST (ddr)); | 2956 int var_b = CHREC_VARIABLE (access_fn_b); |
2888 int index_b = index_in_loop_nest (CHREC_VARIABLE (access_fn_b), | 2957 |
2889 DDR_LOOP_NEST (ddr)); | 2958 if (var_a != var_b |
2890 | 2959 || chrec_contains_undetermined (SUB_DISTANCE (subscript))) |
2891 /* The dependence is carried by the outermost loop. Example: | |
2892 | loop_1 | |
2893 | A[{4, +, 1}_1] | |
2894 | loop_2 | |
2895 | A[{5, +, 1}_2] | |
2896 | endloop_2 | |
2897 | endloop_1 | |
2898 In this case, the dependence is carried by loop_1. */ | |
2899 index = index_a < index_b ? index_a : index_b; | |
2900 *index_carry = MIN (index, *index_carry); | |
2901 | |
2902 if (chrec_contains_undetermined (SUB_DISTANCE (subscript))) | |
2903 { | 2960 { |
2904 non_affine_dependence_relation (ddr); | 2961 non_affine_dependence_relation (ddr); |
2905 return false; | 2962 return false; |
2906 } | 2963 } |
2907 | 2964 |
2908 dist = int_cst_value (SUB_DISTANCE (subscript)); | 2965 dist = int_cst_value (SUB_DISTANCE (subscript)); |
2966 index = index_in_loop_nest (var_a, DDR_LOOP_NEST (ddr)); | |
2967 *index_carry = MIN (index, *index_carry); | |
2909 | 2968 |
2910 /* This is the subscript coupling test. If we have already | 2969 /* This is the subscript coupling test. If we have already |
2911 recorded a distance for this loop (a distance coming from | 2970 recorded a distance for this loop (a distance coming from |
2912 another subscript), it should be the same. For example, | 2971 another subscript), it should be the same. For example, |
2913 in the following code, there is no dependence: | 2972 in the following code, there is no dependence: |
3275 build_classic_dir_vector (struct data_dependence_relation *ddr) | 3334 build_classic_dir_vector (struct data_dependence_relation *ddr) |
3276 { | 3335 { |
3277 unsigned i, j; | 3336 unsigned i, j; |
3278 lambda_vector dist_v; | 3337 lambda_vector dist_v; |
3279 | 3338 |
3280 for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++) | 3339 FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v) |
3281 { | 3340 { |
3282 lambda_vector dir_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); | 3341 lambda_vector dir_v = lambda_vector_new (DDR_NB_LOOPS (ddr)); |
3283 | 3342 |
3284 for (j = 0; j < DDR_NB_LOOPS (ddr); j++) | 3343 for (j = 0; j < DDR_NB_LOOPS (ddr); j++) |
3285 dir_v[j] = dir_from_dist (dist_v[j]); | 3344 dir_v[j] = dir_from_dist (dist_v[j]); |
3377 { | 3436 { |
3378 unsigned int i; | 3437 unsigned int i; |
3379 VEC(tree,heap) *fns = DR_ACCESS_FNS (a); | 3438 VEC(tree,heap) *fns = DR_ACCESS_FNS (a); |
3380 tree t; | 3439 tree t; |
3381 | 3440 |
3382 for (i = 0; VEC_iterate (tree, fns, i, t); i++) | 3441 FOR_EACH_VEC_ELT (tree, fns, i, t) |
3383 if (!evolution_function_is_invariant_p (t, loop_nest->num) | 3442 if (!evolution_function_is_invariant_p (t, loop_nest->num) |
3384 && !evolution_function_is_affine_multivariate_p (t, loop_nest->num)) | 3443 && !evolution_function_is_affine_multivariate_p (t, loop_nest->num)) |
3385 return false; | 3444 return false; |
3386 | 3445 |
3387 return true; | 3446 return true; |
3572 tree type = signed_type_for_types (TREE_TYPE (access_fun_a), | 3631 tree type = signed_type_for_types (TREE_TYPE (access_fun_a), |
3573 TREE_TYPE (access_fun_b)); | 3632 TREE_TYPE (access_fun_b)); |
3574 tree fun_a = chrec_convert (type, access_fun_a, NULL); | 3633 tree fun_a = chrec_convert (type, access_fun_a, NULL); |
3575 tree fun_b = chrec_convert (type, access_fun_b, NULL); | 3634 tree fun_b = chrec_convert (type, access_fun_b, NULL); |
3576 tree difference = chrec_fold_minus (type, fun_a, fun_b); | 3635 tree difference = chrec_fold_minus (type, fun_a, fun_b); |
3636 tree minus_one; | |
3577 | 3637 |
3578 /* When the fun_a - fun_b is not constant, the dependence is not | 3638 /* When the fun_a - fun_b is not constant, the dependence is not |
3579 captured by the classic distance vector representation. */ | 3639 captured by the classic distance vector representation. */ |
3580 if (TREE_CODE (difference) != INTEGER_CST) | 3640 if (TREE_CODE (difference) != INTEGER_CST) |
3581 return false; | 3641 return false; |
3586 /* There is no dependence. */ | 3646 /* There is no dependence. */ |
3587 *maybe_dependent = false; | 3647 *maybe_dependent = false; |
3588 return true; | 3648 return true; |
3589 } | 3649 } |
3590 | 3650 |
3591 fun_b = chrec_fold_multiply (type, fun_b, integer_minus_one_node); | 3651 minus_one = build_int_cst (type, -1); |
3652 fun_b = chrec_fold_multiply (type, fun_b, minus_one); | |
3592 | 3653 |
3593 eq = omega_add_zero_eq (pb, omega_black); | 3654 eq = omega_add_zero_eq (pb, omega_black); |
3594 if (!init_omega_eq_with_af (pb, eq, DDR_NB_LOOPS (ddr), fun_a, ddr) | 3655 if (!init_omega_eq_with_af (pb, eq, DDR_NB_LOOPS (ddr), fun_a, ddr) |
3595 || !init_omega_eq_with_af (pb, eq, 0, fun_b, ddr)) | 3656 || !init_omega_eq_with_af (pb, eq, 0, fun_b, ddr)) |
3596 /* There is probably a dependence, but the system of | 3657 /* There is probably a dependence, but the system of |
3839 fprintf (file, "\n(Number of distance vectors differ: Banerjee has %d, Omega has %d.\n", | 3900 fprintf (file, "\n(Number of distance vectors differ: Banerjee has %d, Omega has %d.\n", |
3840 VEC_length (lambda_vector, dist_vects), | 3901 VEC_length (lambda_vector, dist_vects), |
3841 DDR_NUM_DIST_VECTS (ddr)); | 3902 DDR_NUM_DIST_VECTS (ddr)); |
3842 | 3903 |
3843 fprintf (file, "Banerjee dist vectors:\n"); | 3904 fprintf (file, "Banerjee dist vectors:\n"); |
3844 for (i = 0; VEC_iterate (lambda_vector, dist_vects, i, b_dist_v); i++) | 3905 FOR_EACH_VEC_ELT (lambda_vector, dist_vects, i, b_dist_v) |
3845 print_lambda_vector (file, b_dist_v, DDR_NB_LOOPS (ddr)); | 3906 print_lambda_vector (file, b_dist_v, DDR_NB_LOOPS (ddr)); |
3846 | 3907 |
3847 fprintf (file, "Omega dist vectors:\n"); | 3908 fprintf (file, "Omega dist vectors:\n"); |
3848 for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++) | 3909 for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++) |
3849 print_lambda_vector (file, DDR_DIST_VECT (ddr, i), DDR_NB_LOOPS (ddr)); | 3910 print_lambda_vector (file, DDR_DIST_VECT (ddr, i), DDR_NB_LOOPS (ddr)); |
3868 lambda_vector a_dist_v; | 3929 lambda_vector a_dist_v; |
3869 lambda_vector b_dist_v = DDR_DIST_VECT (ddr, i); | 3930 lambda_vector b_dist_v = DDR_DIST_VECT (ddr, i); |
3870 | 3931 |
3871 /* Distance vectors are not ordered in the same way in the DDR | 3932 /* Distance vectors are not ordered in the same way in the DDR |
3872 and in the DIST_VECTS: search for a matching vector. */ | 3933 and in the DIST_VECTS: search for a matching vector. */ |
3873 for (j = 0; VEC_iterate (lambda_vector, dist_vects, j, a_dist_v); j++) | 3934 FOR_EACH_VEC_ELT (lambda_vector, dist_vects, j, a_dist_v) |
3874 if (lambda_vector_equal (a_dist_v, b_dist_v, DDR_NB_LOOPS (ddr))) | 3935 if (lambda_vector_equal (a_dist_v, b_dist_v, DDR_NB_LOOPS (ddr))) |
3875 break; | 3936 break; |
3876 | 3937 |
3877 if (j == VEC_length (lambda_vector, dist_vects)) | 3938 if (j == VEC_length (lambda_vector, dist_vects)) |
3878 { | 3939 { |
3891 lambda_vector a_dir_v; | 3952 lambda_vector a_dir_v; |
3892 lambda_vector b_dir_v = DDR_DIR_VECT (ddr, i); | 3953 lambda_vector b_dir_v = DDR_DIR_VECT (ddr, i); |
3893 | 3954 |
3894 /* Direction vectors are not ordered in the same way in the DDR | 3955 /* Direction vectors are not ordered in the same way in the DDR |
3895 and in the DIR_VECTS: search for a matching vector. */ | 3956 and in the DIR_VECTS: search for a matching vector. */ |
3896 for (j = 0; VEC_iterate (lambda_vector, dir_vects, j, a_dir_v); j++) | 3957 FOR_EACH_VEC_ELT (lambda_vector, dir_vects, j, a_dir_v) |
3897 if (lambda_vector_equal (a_dir_v, b_dir_v, DDR_NB_LOOPS (ddr))) | 3958 if (lambda_vector_equal (a_dir_v, b_dir_v, DDR_NB_LOOPS (ddr))) |
3898 break; | 3959 break; |
3899 | 3960 |
3900 if (j == VEC_length (lambda_vector, dist_vects)) | 3961 if (j == VEC_length (lambda_vector, dist_vects)) |
3901 { | 3962 { |
4061 { | 4122 { |
4062 struct data_dependence_relation *ddr; | 4123 struct data_dependence_relation *ddr; |
4063 struct data_reference *a, *b; | 4124 struct data_reference *a, *b; |
4064 unsigned int i, j; | 4125 unsigned int i, j; |
4065 | 4126 |
4066 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, a); i++) | 4127 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, a) |
4067 for (j = i + 1; VEC_iterate (data_reference_p, datarefs, j, b); j++) | 4128 for (j = i + 1; VEC_iterate (data_reference_p, datarefs, j, b); j++) |
4068 if (!DR_IS_READ (a) || !DR_IS_READ (b) || compute_self_and_rr) | 4129 if (DR_IS_WRITE (a) || DR_IS_WRITE (b) || compute_self_and_rr) |
4069 { | 4130 { |
4070 ddr = initialize_data_dependence_relation (a, b, loop_nest); | 4131 ddr = initialize_data_dependence_relation (a, b, loop_nest); |
4071 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); | 4132 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); |
4072 if (loop_nest) | 4133 if (loop_nest) |
4073 compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0)); | 4134 compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0)); |
4074 } | 4135 } |
4075 | 4136 |
4076 if (compute_self_and_rr) | 4137 if (compute_self_and_rr) |
4077 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, a); i++) | 4138 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, a) |
4078 { | 4139 { |
4079 ddr = initialize_data_dependence_relation (a, a, loop_nest); | 4140 ddr = initialize_data_dependence_relation (a, a, loop_nest); |
4080 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); | 4141 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); |
4081 compute_self_dependence (ddr); | 4142 compute_self_dependence (ddr); |
4082 } | 4143 } |
4170 { | 4231 { |
4171 VEC_free (data_ref_loc, heap, references); | 4232 VEC_free (data_ref_loc, heap, references); |
4172 return false; | 4233 return false; |
4173 } | 4234 } |
4174 | 4235 |
4175 for (i = 0; VEC_iterate (data_ref_loc, references, i, ref); i++) | 4236 FOR_EACH_VEC_ELT (data_ref_loc, references, i, ref) |
4176 { | 4237 { |
4177 dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read); | 4238 dr = create_data_ref (nest, loop_containing_stmt (stmt), |
4239 *ref->pos, stmt, ref->is_read); | |
4178 gcc_assert (dr != NULL); | 4240 gcc_assert (dr != NULL); |
4179 | 4241 |
4180 /* FIXME -- data dependence analysis does not work correctly for objects | 4242 /* FIXME -- data dependence analysis does not work correctly for objects |
4181 with invariant addresses in loop nests. Let us fail here until the | 4243 with invariant addresses in loop nests. Let us fail here until the |
4182 problem is fixed. */ | 4244 problem is fixed. */ |
4193 } | 4255 } |
4194 VEC_free (data_ref_loc, heap, references); | 4256 VEC_free (data_ref_loc, heap, references); |
4195 return ret; | 4257 return ret; |
4196 } | 4258 } |
4197 | 4259 |
4198 /* Stores the data references in STMT to DATAREFS. If there is an unanalyzable | 4260 /* Stores the data references in STMT to DATAREFS. If there is an |
4199 reference, returns false, otherwise returns true. NEST is the outermost | 4261 unanalyzable reference, returns false, otherwise returns true. |
4200 loop of the loop nest in which the references should be analyzed. */ | 4262 NEST is the outermost loop of the loop nest in which the references |
4263 should be instantiated, LOOP is the loop in which the references | |
4264 should be analyzed. */ | |
4201 | 4265 |
4202 bool | 4266 bool |
4203 graphite_find_data_references_in_stmt (struct loop *nest, gimple stmt, | 4267 graphite_find_data_references_in_stmt (loop_p nest, loop_p loop, gimple stmt, |
4204 VEC (data_reference_p, heap) **datarefs) | 4268 VEC (data_reference_p, heap) **datarefs) |
4205 { | 4269 { |
4206 unsigned i; | 4270 unsigned i; |
4207 VEC (data_ref_loc, heap) *references; | 4271 VEC (data_ref_loc, heap) *references; |
4208 data_ref_loc *ref; | 4272 data_ref_loc *ref; |
4213 { | 4277 { |
4214 VEC_free (data_ref_loc, heap, references); | 4278 VEC_free (data_ref_loc, heap, references); |
4215 return false; | 4279 return false; |
4216 } | 4280 } |
4217 | 4281 |
4218 for (i = 0; VEC_iterate (data_ref_loc, references, i, ref); i++) | 4282 FOR_EACH_VEC_ELT (data_ref_loc, references, i, ref) |
4219 { | 4283 { |
4220 dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read); | 4284 dr = create_data_ref (nest, loop, *ref->pos, stmt, ref->is_read); |
4221 gcc_assert (dr != NULL); | 4285 gcc_assert (dr != NULL); |
4222 VEC_safe_push (data_reference_p, heap, *datarefs, dr); | 4286 VEC_safe_push (data_reference_p, heap, *datarefs, dr); |
4223 } | 4287 } |
4224 | 4288 |
4225 VEC_free (data_ref_loc, heap, references); | 4289 VEC_free (data_ref_loc, heap, references); |
4334 COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */ | 4398 COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */ |
4335 | 4399 |
4336 bool | 4400 bool |
4337 compute_data_dependences_for_loop (struct loop *loop, | 4401 compute_data_dependences_for_loop (struct loop *loop, |
4338 bool compute_self_and_read_read_dependences, | 4402 bool compute_self_and_read_read_dependences, |
4403 VEC (loop_p, heap) **loop_nest, | |
4339 VEC (data_reference_p, heap) **datarefs, | 4404 VEC (data_reference_p, heap) **datarefs, |
4340 VEC (ddr_p, heap) **dependence_relations) | 4405 VEC (ddr_p, heap) **dependence_relations) |
4341 { | 4406 { |
4342 bool res = true; | 4407 bool res = true; |
4343 VEC (loop_p, heap) *vloops = VEC_alloc (loop_p, heap, 3); | |
4344 | 4408 |
4345 memset (&dependence_stats, 0, sizeof (dependence_stats)); | 4409 memset (&dependence_stats, 0, sizeof (dependence_stats)); |
4346 | 4410 |
4347 /* If the loop nest is not well formed, or one of the data references | 4411 /* If the loop nest is not well formed, or one of the data references |
4348 is not computable, give up without spending time to compute other | 4412 is not computable, give up without spending time to compute other |
4349 dependences. */ | 4413 dependences. */ |
4350 if (!loop | 4414 if (!loop |
4351 || !find_loop_nest (loop, &vloops) | 4415 || !find_loop_nest (loop, loop_nest) |
4352 || find_data_references_in_loop (loop, datarefs) == chrec_dont_know) | 4416 || find_data_references_in_loop (loop, datarefs) == chrec_dont_know) |
4353 { | 4417 { |
4354 struct data_dependence_relation *ddr; | 4418 struct data_dependence_relation *ddr; |
4355 | 4419 |
4356 /* Insert a single relation into dependence_relations: | 4420 /* Insert a single relation into dependence_relations: |
4357 chrec_dont_know. */ | 4421 chrec_dont_know. */ |
4358 ddr = initialize_data_dependence_relation (NULL, NULL, vloops); | 4422 ddr = initialize_data_dependence_relation (NULL, NULL, *loop_nest); |
4359 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); | 4423 VEC_safe_push (ddr_p, heap, *dependence_relations, ddr); |
4360 res = false; | 4424 res = false; |
4361 } | 4425 } |
4362 else | 4426 else |
4363 compute_all_dependences (*datarefs, dependence_relations, vloops, | 4427 compute_all_dependences (*datarefs, dependence_relations, *loop_nest, |
4364 compute_self_and_read_read_dependences); | 4428 compute_self_and_read_read_dependences); |
4365 | 4429 |
4366 if (dump_file && (dump_flags & TDF_STATS)) | 4430 if (dump_file && (dump_flags & TDF_STATS)) |
4367 { | 4431 { |
4368 fprintf (dump_file, "Dependence tester statistics:\n"); | 4432 fprintf (dump_file, "Dependence tester statistics:\n"); |
4462 int nb_data_refs = 10; | 4526 int nb_data_refs = 10; |
4463 VEC (data_reference_p, heap) *datarefs = | 4527 VEC (data_reference_p, heap) *datarefs = |
4464 VEC_alloc (data_reference_p, heap, nb_data_refs); | 4528 VEC_alloc (data_reference_p, heap, nb_data_refs); |
4465 VEC (ddr_p, heap) *dependence_relations = | 4529 VEC (ddr_p, heap) *dependence_relations = |
4466 VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs); | 4530 VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs); |
4531 VEC (loop_p, heap) *loop_nest = VEC_alloc (loop_p, heap, 3); | |
4467 | 4532 |
4468 /* Compute DDs on the whole function. */ | 4533 /* Compute DDs on the whole function. */ |
4469 compute_data_dependences_for_loop (loop, false, &datarefs, | 4534 compute_data_dependences_for_loop (loop, false, &loop_nest, &datarefs, |
4470 &dependence_relations); | 4535 &dependence_relations); |
4471 | 4536 |
4472 if (dump_file) | 4537 if (dump_file) |
4473 { | 4538 { |
4474 dump_data_dependence_relations (dump_file, dependence_relations); | 4539 dump_data_dependence_relations (dump_file, dependence_relations); |
4482 unsigned nb_top_relations = 0; | 4547 unsigned nb_top_relations = 0; |
4483 unsigned nb_bot_relations = 0; | 4548 unsigned nb_bot_relations = 0; |
4484 unsigned nb_chrec_relations = 0; | 4549 unsigned nb_chrec_relations = 0; |
4485 struct data_dependence_relation *ddr; | 4550 struct data_dependence_relation *ddr; |
4486 | 4551 |
4487 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++) | 4552 FOR_EACH_VEC_ELT (ddr_p, dependence_relations, i, ddr) |
4488 { | 4553 { |
4489 if (chrec_contains_undetermined (DDR_ARE_DEPENDENT (ddr))) | 4554 if (chrec_contains_undetermined (DDR_ARE_DEPENDENT (ddr))) |
4490 nb_top_relations++; | 4555 nb_top_relations++; |
4491 | 4556 |
4492 else if (DDR_ARE_DEPENDENT (ddr) == chrec_known) | 4557 else if (DDR_ARE_DEPENDENT (ddr) == chrec_known) |
4498 | 4563 |
4499 gather_stats_on_scev_database (); | 4564 gather_stats_on_scev_database (); |
4500 } | 4565 } |
4501 } | 4566 } |
4502 | 4567 |
4568 VEC_free (loop_p, heap, loop_nest); | |
4503 free_dependence_relations (dependence_relations); | 4569 free_dependence_relations (dependence_relations); |
4504 free_data_refs (datarefs); | 4570 free_data_refs (datarefs); |
4505 } | 4571 } |
4506 | 4572 |
4507 /* Computes all the data dependences and check that the results of | 4573 /* Computes all the data dependences and check that the results of |
4541 void | 4607 void |
4542 free_dependence_relations (VEC (ddr_p, heap) *dependence_relations) | 4608 free_dependence_relations (VEC (ddr_p, heap) *dependence_relations) |
4543 { | 4609 { |
4544 unsigned int i; | 4610 unsigned int i; |
4545 struct data_dependence_relation *ddr; | 4611 struct data_dependence_relation *ddr; |
4546 VEC (loop_p, heap) *loop_nest = NULL; | 4612 |
4547 | 4613 FOR_EACH_VEC_ELT (ddr_p, dependence_relations, i, ddr) |
4548 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++) | 4614 if (ddr) |
4549 { | |
4550 if (ddr == NULL) | |
4551 continue; | |
4552 if (loop_nest == NULL) | |
4553 loop_nest = DDR_LOOP_NEST (ddr); | |
4554 else | |
4555 gcc_assert (DDR_LOOP_NEST (ddr) == NULL | |
4556 || DDR_LOOP_NEST (ddr) == loop_nest); | |
4557 free_dependence_relation (ddr); | 4615 free_dependence_relation (ddr); |
4558 } | 4616 |
4559 | |
4560 if (loop_nest) | |
4561 VEC_free (loop_p, heap, loop_nest); | |
4562 VEC_free (ddr_p, heap, dependence_relations); | 4617 VEC_free (ddr_p, heap, dependence_relations); |
4563 } | 4618 } |
4564 | 4619 |
4565 /* Free the memory used by the data references from DATAREFS. */ | 4620 /* Free the memory used by the data references from DATAREFS. */ |
4566 | 4621 |
4568 free_data_refs (VEC (data_reference_p, heap) *datarefs) | 4623 free_data_refs (VEC (data_reference_p, heap) *datarefs) |
4569 { | 4624 { |
4570 unsigned int i; | 4625 unsigned int i; |
4571 struct data_reference *dr; | 4626 struct data_reference *dr; |
4572 | 4627 |
4573 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) | 4628 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr) |
4574 free_data_ref (dr); | 4629 free_data_ref (dr); |
4575 VEC_free (data_reference_p, heap, datarefs); | 4630 VEC_free (data_reference_p, heap, datarefs); |
4576 } | 4631 } |
4577 | 4632 |
4578 | 4633 |
4597 | 4652 |
4598 if (v->succ) | 4653 if (v->succ) |
4599 for (e = v->succ; e; e = e->succ_next) | 4654 for (e = v->succ; e; e = e->succ_next) |
4600 fprintf (file, " %d", e->dest); | 4655 fprintf (file, " %d", e->dest); |
4601 | 4656 |
4602 fprintf (file, ") \n"); | 4657 fprintf (file, ")\n"); |
4603 print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS); | 4658 print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS); |
4604 fprintf (file, ")\n"); | 4659 fprintf (file, ")\n"); |
4605 } | 4660 } |
4606 | 4661 |
4607 /* Call dump_rdg_vertex on stderr. */ | 4662 /* Call dump_rdg_vertex on stderr. */ |
4608 | 4663 |
4609 void | 4664 DEBUG_FUNCTION void |
4610 debug_rdg_vertex (struct graph *rdg, int i) | 4665 debug_rdg_vertex (struct graph *rdg, int i) |
4611 { | 4666 { |
4612 dump_rdg_vertex (stderr, rdg, i); | 4667 dump_rdg_vertex (stderr, rdg, i); |
4613 } | 4668 } |
4614 | 4669 |
4633 fprintf (file, ")\n"); | 4688 fprintf (file, ")\n"); |
4634 } | 4689 } |
4635 | 4690 |
4636 /* Call dump_rdg_vertex on stderr. */ | 4691 /* Call dump_rdg_vertex on stderr. */ |
4637 | 4692 |
4638 void | 4693 DEBUG_FUNCTION void |
4639 debug_rdg_component (struct graph *rdg, int c) | 4694 debug_rdg_component (struct graph *rdg, int c) |
4640 { | 4695 { |
4641 dump_rdg_component (stderr, rdg, c, NULL); | 4696 dump_rdg_component (stderr, rdg, c, NULL); |
4642 } | 4697 } |
4643 | 4698 |
4659 BITMAP_FREE (dumped); | 4714 BITMAP_FREE (dumped); |
4660 } | 4715 } |
4661 | 4716 |
4662 /* Call dump_rdg on stderr. */ | 4717 /* Call dump_rdg on stderr. */ |
4663 | 4718 |
4664 void | 4719 DEBUG_FUNCTION void |
4665 debug_rdg (struct graph *rdg) | 4720 debug_rdg (struct graph *rdg) |
4666 { | 4721 { |
4667 dump_rdg (stderr, rdg); | 4722 dump_rdg (stderr, rdg); |
4723 } | |
4724 | |
4725 static void | |
4726 dot_rdg_1 (FILE *file, struct graph *rdg) | |
4727 { | |
4728 int i; | |
4729 | |
4730 fprintf (file, "digraph RDG {\n"); | |
4731 | |
4732 for (i = 0; i < rdg->n_vertices; i++) | |
4733 { | |
4734 struct vertex *v = &(rdg->vertices[i]); | |
4735 struct graph_edge *e; | |
4736 | |
4737 /* Highlight reads from memory. */ | |
4738 if (RDG_MEM_READS_STMT (rdg, i)) | |
4739 fprintf (file, "%d [style=filled, fillcolor=green]\n", i); | |
4740 | |
4741 /* Highlight stores to memory. */ | |
4742 if (RDG_MEM_WRITE_STMT (rdg, i)) | |
4743 fprintf (file, "%d [style=filled, fillcolor=red]\n", i); | |
4744 | |
4745 if (v->succ) | |
4746 for (e = v->succ; e; e = e->succ_next) | |
4747 switch (RDGE_TYPE (e)) | |
4748 { | |
4749 case input_dd: | |
4750 fprintf (file, "%d -> %d [label=input] \n", i, e->dest); | |
4751 break; | |
4752 | |
4753 case output_dd: | |
4754 fprintf (file, "%d -> %d [label=output] \n", i, e->dest); | |
4755 break; | |
4756 | |
4757 case flow_dd: | |
4758 /* These are the most common dependences: don't print these. */ | |
4759 fprintf (file, "%d -> %d \n", i, e->dest); | |
4760 break; | |
4761 | |
4762 case anti_dd: | |
4763 fprintf (file, "%d -> %d [label=anti] \n", i, e->dest); | |
4764 break; | |
4765 | |
4766 default: | |
4767 gcc_unreachable (); | |
4768 } | |
4769 } | |
4770 | |
4771 fprintf (file, "}\n\n"); | |
4772 } | |
4773 | |
4774 /* Display the Reduced Dependence Graph using dotty. */ | |
4775 extern void dot_rdg (struct graph *); | |
4776 | |
4777 DEBUG_FUNCTION void | |
4778 dot_rdg (struct graph *rdg) | |
4779 { | |
4780 /* When debugging, enable the following code. This cannot be used | |
4781 in production compilers because it calls "system". */ | |
4782 #if 0 | |
4783 FILE *file = fopen ("/tmp/rdg.dot", "w"); | |
4784 gcc_assert (file != NULL); | |
4785 | |
4786 dot_rdg_1 (file, rdg); | |
4787 fclose (file); | |
4788 | |
4789 system ("dotty /tmp/rdg.dot &"); | |
4790 #else | |
4791 dot_rdg_1 (stderr, rdg); | |
4792 #endif | |
4668 } | 4793 } |
4669 | 4794 |
4670 /* This structure is used for recording the mapping statement index in | 4795 /* This structure is used for recording the mapping statement index in |
4671 the RDG. */ | 4796 the RDG. */ |
4672 | 4797 |
4728 RDGE_RELATION (e) = ddr; | 4853 RDGE_RELATION (e) = ddr; |
4729 | 4854 |
4730 /* Determines the type of the data dependence. */ | 4855 /* Determines the type of the data dependence. */ |
4731 if (DR_IS_READ (dra) && DR_IS_READ (drb)) | 4856 if (DR_IS_READ (dra) && DR_IS_READ (drb)) |
4732 RDGE_TYPE (e) = input_dd; | 4857 RDGE_TYPE (e) = input_dd; |
4733 else if (!DR_IS_READ (dra) && !DR_IS_READ (drb)) | 4858 else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) |
4734 RDGE_TYPE (e) = output_dd; | 4859 RDGE_TYPE (e) = output_dd; |
4735 else if (!DR_IS_READ (dra) && DR_IS_READ (drb)) | 4860 else if (DR_IS_WRITE (dra) && DR_IS_READ (drb)) |
4736 RDGE_TYPE (e) = flow_dd; | 4861 RDGE_TYPE (e) = flow_dd; |
4737 else if (DR_IS_READ (dra) && !DR_IS_READ (drb)) | 4862 else if (DR_IS_READ (dra) && DR_IS_WRITE (drb)) |
4738 RDGE_TYPE (e) = anti_dd; | 4863 RDGE_TYPE (e) = anti_dd; |
4739 } | 4864 } |
4740 | 4865 |
4741 /* Creates dependence edges in RDG for all the uses of DEF. IDEF is | 4866 /* Creates dependence edges in RDG for all the uses of DEF. IDEF is |
4742 the index of DEF in RDG. */ | 4867 the index of DEF in RDG. */ |
4770 int i; | 4895 int i; |
4771 struct data_dependence_relation *ddr; | 4896 struct data_dependence_relation *ddr; |
4772 def_operand_p def_p; | 4897 def_operand_p def_p; |
4773 ssa_op_iter iter; | 4898 ssa_op_iter iter; |
4774 | 4899 |
4775 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++) | 4900 FOR_EACH_VEC_ELT (ddr_p, ddrs, i, ddr) |
4776 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE) | 4901 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE) |
4777 create_rdg_edge_for_ddr (rdg, ddr); | 4902 create_rdg_edge_for_ddr (rdg, ddr); |
4778 | 4903 |
4779 for (i = 0; i < rdg->n_vertices; i++) | 4904 for (i = 0; i < rdg->n_vertices; i++) |
4780 FOR_EACH_PHI_OR_STMT_DEF (def_p, RDG_STMT (rdg, i), | 4905 FOR_EACH_PHI_OR_STMT_DEF (def_p, RDG_STMT (rdg, i), |
4788 create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts) | 4913 create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts) |
4789 { | 4914 { |
4790 int i, j; | 4915 int i, j; |
4791 gimple stmt; | 4916 gimple stmt; |
4792 | 4917 |
4793 for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++) | 4918 FOR_EACH_VEC_ELT (gimple, stmts, i, stmt) |
4794 { | 4919 { |
4795 VEC (data_ref_loc, heap) *references; | 4920 VEC (data_ref_loc, heap) *references; |
4796 data_ref_loc *ref; | 4921 data_ref_loc *ref; |
4797 struct vertex *v = &(rdg->vertices[i]); | 4922 struct vertex *v = &(rdg->vertices[i]); |
4798 struct rdg_vertex_info *rvi = XNEW (struct rdg_vertex_info); | 4923 struct rdg_vertex_info *rvi = XNEW (struct rdg_vertex_info); |
4814 RDG_MEM_READS_STMT (rdg, i) = false; | 4939 RDG_MEM_READS_STMT (rdg, i) = false; |
4815 if (gimple_code (stmt) == GIMPLE_PHI) | 4940 if (gimple_code (stmt) == GIMPLE_PHI) |
4816 continue; | 4941 continue; |
4817 | 4942 |
4818 get_references_in_stmt (stmt, &references); | 4943 get_references_in_stmt (stmt, &references); |
4819 for (j = 0; VEC_iterate (data_ref_loc, references, j, ref); j++) | 4944 FOR_EACH_VEC_ELT (data_ref_loc, references, j, ref) |
4820 if (!ref->is_read) | 4945 if (!ref->is_read) |
4821 RDG_MEM_WRITE_STMT (rdg, i) = true; | 4946 RDG_MEM_WRITE_STMT (rdg, i) = true; |
4822 else | 4947 else |
4823 RDG_MEM_READS_STMT (rdg, i) = true; | 4948 RDG_MEM_READS_STMT (rdg, i) = true; |
4824 | 4949 |
4864 known_dependences_p (VEC (ddr_p, heap) *dependence_relations) | 4989 known_dependences_p (VEC (ddr_p, heap) *dependence_relations) |
4865 { | 4990 { |
4866 ddr_p ddr; | 4991 ddr_p ddr; |
4867 unsigned int i; | 4992 unsigned int i; |
4868 | 4993 |
4869 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++) | 4994 FOR_EACH_VEC_ELT (ddr_p, dependence_relations, i, ddr) |
4870 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) | 4995 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) |
4871 return false; | 4996 return false; |
4872 | 4997 |
4873 return true; | 4998 return true; |
4874 } | 4999 } |
4922 /* Build the Reduced Dependence Graph (RDG) with one vertex per | 5047 /* Build the Reduced Dependence Graph (RDG) with one vertex per |
4923 statement of the loop nest, and one edge per data dependence or | 5048 statement of the loop nest, and one edge per data dependence or |
4924 scalar dependence. */ | 5049 scalar dependence. */ |
4925 | 5050 |
4926 struct graph * | 5051 struct graph * |
4927 build_rdg (struct loop *loop) | 5052 build_rdg (struct loop *loop, |
4928 { | 5053 VEC (loop_p, heap) **loop_nest, |
4929 int nb_data_refs = 10; | 5054 VEC (ddr_p, heap) **dependence_relations, |
5055 VEC (data_reference_p, heap) **datarefs) | |
5056 { | |
4930 struct graph *rdg = NULL; | 5057 struct graph *rdg = NULL; |
4931 VEC (ddr_p, heap) *dependence_relations; | 5058 VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, 10); |
4932 VEC (data_reference_p, heap) *datarefs; | 5059 |
4933 VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, nb_data_refs); | 5060 compute_data_dependences_for_loop (loop, false, loop_nest, datarefs, |
4934 | 5061 dependence_relations); |
4935 dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ; | 5062 |
4936 datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs); | 5063 if (known_dependences_p (*dependence_relations)) |
4937 compute_data_dependences_for_loop (loop, | 5064 { |
4938 false, | 5065 stmts_from_loop (loop, &stmts); |
4939 &datarefs, | 5066 rdg = build_empty_rdg (VEC_length (gimple, stmts)); |
4940 &dependence_relations); | 5067 create_rdg_vertices (rdg, stmts); |
4941 | 5068 create_rdg_edges (rdg, *dependence_relations); |
4942 if (!known_dependences_p (dependence_relations)) | 5069 } |
4943 { | |
4944 free_dependence_relations (dependence_relations); | |
4945 free_data_refs (datarefs); | |
4946 VEC_free (gimple, heap, stmts); | |
4947 | |
4948 return rdg; | |
4949 } | |
4950 | |
4951 stmts_from_loop (loop, &stmts); | |
4952 rdg = build_empty_rdg (VEC_length (gimple, stmts)); | |
4953 | |
4954 rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info, | |
4955 eq_stmt_vertex_info, hash_stmt_vertex_del); | |
4956 create_rdg_vertices (rdg, stmts); | |
4957 create_rdg_edges (rdg, dependence_relations); | |
4958 | 5070 |
4959 VEC_free (gimple, heap, stmts); | 5071 VEC_free (gimple, heap, stmts); |
4960 return rdg; | 5072 return rdg; |
4961 } | 5073 } |
4962 | 5074 |
4966 free_rdg (struct graph *rdg) | 5078 free_rdg (struct graph *rdg) |
4967 { | 5079 { |
4968 int i; | 5080 int i; |
4969 | 5081 |
4970 for (i = 0; i < rdg->n_vertices; i++) | 5082 for (i = 0; i < rdg->n_vertices; i++) |
4971 free (rdg->vertices[i].data); | 5083 { |
5084 struct vertex *v = &(rdg->vertices[i]); | |
5085 struct graph_edge *e; | |
5086 | |
5087 for (e = v->succ; e; e = e->succ_next) | |
5088 if (e->data) | |
5089 free (e->data); | |
5090 | |
5091 if (v->data) | |
5092 free (v->data); | |
5093 } | |
4972 | 5094 |
4973 htab_delete (rdg->indices); | 5095 htab_delete (rdg->indices); |
4974 free_graph (rdg); | 5096 free_graph (rdg); |
4975 } | 5097 } |
4976 | 5098 |
4990 | 5112 |
4991 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | 5113 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) |
4992 if (gimple_vdef (gsi_stmt (bsi))) | 5114 if (gimple_vdef (gsi_stmt (bsi))) |
4993 VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi)); | 5115 VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi)); |
4994 } | 5116 } |
5117 | |
5118 free (bbs); | |
5119 } | |
5120 | |
5121 /* Returns true when the statement at STMT is of the form "A[i] = 0" | |
5122 that contains a data reference on its LHS with a stride of the same | |
5123 size as its unit type. */ | |
5124 | |
5125 bool | |
5126 stmt_with_adjacent_zero_store_dr_p (gimple stmt) | |
5127 { | |
5128 tree op0, op1; | |
5129 bool res; | |
5130 struct data_reference *dr; | |
5131 | |
5132 if (!stmt | |
5133 || !gimple_vdef (stmt) | |
5134 || !is_gimple_assign (stmt) | |
5135 || !gimple_assign_single_p (stmt) | |
5136 || !(op1 = gimple_assign_rhs1 (stmt)) | |
5137 || !(integer_zerop (op1) || real_zerop (op1))) | |
5138 return false; | |
5139 | |
5140 dr = XCNEW (struct data_reference); | |
5141 op0 = gimple_assign_lhs (stmt); | |
5142 | |
5143 DR_STMT (dr) = stmt; | |
5144 DR_REF (dr) = op0; | |
5145 | |
5146 res = dr_analyze_innermost (dr) | |
5147 && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0)); | |
5148 | |
5149 free_data_ref (dr); | |
5150 return res; | |
5151 } | |
5152 | |
5153 /* Initialize STMTS with all the statements of LOOP that contain a | |
5154 store to memory of the form "A[i] = 0". */ | |
5155 | |
5156 void | |
5157 stores_zero_from_loop (struct loop *loop, VEC (gimple, heap) **stmts) | |
5158 { | |
5159 unsigned int i; | |
5160 basic_block bb; | |
5161 gimple_stmt_iterator si; | |
5162 gimple stmt; | |
5163 basic_block *bbs = get_loop_body_in_dom_order (loop); | |
5164 | |
5165 for (i = 0; i < loop->num_nodes; i++) | |
5166 for (bb = bbs[i], si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) | |
5167 if ((stmt = gsi_stmt (si)) | |
5168 && stmt_with_adjacent_zero_store_dr_p (stmt)) | |
5169 VEC_safe_push (gimple, heap, *stmts, gsi_stmt (si)); | |
4995 | 5170 |
4996 free (bbs); | 5171 free (bbs); |
4997 } | 5172 } |
4998 | 5173 |
4999 /* For a data reference REF, return the declaration of its base | 5174 /* For a data reference REF, return the declaration of its base |
5072 data_ref_loc *ref1, *ref2; | 5247 data_ref_loc *ref1, *ref2; |
5073 | 5248 |
5074 get_references_in_stmt (s1, &refs1); | 5249 get_references_in_stmt (s1, &refs1); |
5075 get_references_in_stmt (s2, &refs2); | 5250 get_references_in_stmt (s2, &refs2); |
5076 | 5251 |
5077 for (i = 0; VEC_iterate (data_ref_loc, refs1, i, ref1); i++) | 5252 FOR_EACH_VEC_ELT (data_ref_loc, refs1, i, ref1) |
5078 { | 5253 { |
5079 tree base1 = ref_base_address (s1, ref1); | 5254 tree base1 = ref_base_address (s1, ref1); |
5080 | 5255 |
5081 if (base1) | 5256 if (base1) |
5082 for (j = 0; VEC_iterate (data_ref_loc, refs2, j, ref2); j++) | 5257 FOR_EACH_VEC_ELT (data_ref_loc, refs2, j, ref2) |
5083 if (base1 == ref_base_address (s2, ref2)) | 5258 if (base1 == ref_base_address (s2, ref2)) |
5084 { | 5259 { |
5085 res = true; | 5260 res = true; |
5086 goto end; | 5261 goto end; |
5087 } | 5262 } |
5113 data_ref_loc *ref; | 5288 data_ref_loc *ref; |
5114 hashval_t res = 0; | 5289 hashval_t res = 0; |
5115 | 5290 |
5116 get_references_in_stmt (stmt, &refs); | 5291 get_references_in_stmt (stmt, &refs); |
5117 | 5292 |
5118 for (i = 0; VEC_iterate (data_ref_loc, refs, i, ref); i++) | 5293 FOR_EACH_VEC_ELT (data_ref_loc, refs, i, ref) |
5119 if (!ref->is_read) | 5294 if (!ref->is_read) |
5120 { | 5295 { |
5121 res = htab_hash_pointer (ref_base_address (stmt, ref)); | 5296 res = htab_hash_pointer (ref_base_address (stmt, ref)); |
5122 break; | 5297 break; |
5123 } | 5298 } |
5163 { | 5338 { |
5164 int i; | 5339 int i; |
5165 VEC (tree,heap) *lambda_parameters = AM_PARAMETERS (access_matrix); | 5340 VEC (tree,heap) *lambda_parameters = AM_PARAMETERS (access_matrix); |
5166 tree lambda_parameter; | 5341 tree lambda_parameter; |
5167 | 5342 |
5168 for (i = 0; VEC_iterate (tree, lambda_parameters, i, lambda_parameter); i++) | 5343 FOR_EACH_VEC_ELT (tree, lambda_parameters, i, lambda_parameter) |
5169 if (lambda_parameter == parameter) | 5344 if (lambda_parameter == parameter) |
5170 return i + AM_NB_INDUCTION_VARS (access_matrix); | 5345 return i + AM_NB_INDUCTION_VARS (access_matrix); |
5171 | 5346 |
5172 return -1; | 5347 return -1; |
5173 } | 5348 } |