This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello world, this patch generates fewer temporaries for array assignments by further improving dependency analysis. This should be a safe change even for early stage 3. The patch passes a rather large number of test cases, i.e. the Fortran program generated with the Perl script below. (You'll need 4 GB of RAM and a few minutes to run that test even without any optimization, which is why I don't propose adding the generated program to the testsuite). OK for trunk? Thomas 2010-11-29 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/45159 * dependency.c (check_section_vs_section): Pre-calculate the relationship between the strides and the relationship between the start values. Use an integer constant one for that purpose. Forward dependencies for positive strides apply for where the lhs start <= rhs start and lhs stride <= rhs stride and vice versa for negative stride. No need to compare end expressions in either case (assume no bounds violation). 2010-11-29 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/45159 * gfortran.dg/dependency_38.f90: New test.
Index: dependency.c =================================================================== --- dependency.c (Revision 166873) +++ dependency.c (Arbeitskopie) @@ -1071,8 +1071,10 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc gfc_expr *r_stride; gfc_expr *r_lower; gfc_expr *r_upper; + gfc_expr *one_expr; int r_dir; - bool identical_strides; + int stride_comparison; + int start_comparison; /* If they are the same range, return without more ado. */ if (gfc_is_same_range (l_ar, r_ar, n, 0)) @@ -1126,22 +1128,24 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc if (l_dir == 0 || r_dir == 0) return GFC_DEP_OVERLAP; - /* Determine if the strides are equal. */ + /* Determine the relationship between the strides. Set stride_comparison to + -2 if the dependency cannot be determined + -1 if l_stride < r_stride + 0 if l_stride == r_stride + 1 if l_stride > r_stride + as determined by gfc_dep_compare_expr. */ - if (l_stride) - { - if (r_stride) - identical_strides = gfc_dep_compare_expr (l_stride, r_stride) == 0; - else - identical_strides = gfc_expr_is_one (l_stride, 0) == 1; - } + one_expr = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1); + + stride_comparison = gfc_dep_compare_expr (l_stride ? l_stride : one_expr, + r_stride ? r_stride : one_expr); + + if (l_start && r_start) + start_comparison = gfc_dep_compare_expr (l_start, r_start); else - { - if (r_stride) - identical_strides = gfc_expr_is_one (r_stride, 0) == 1; - else - identical_strides = true; - } + start_comparison = -2; + + gfc_free (one_expr); /* Determine LHS upper and lower bounds. */ if (l_dir == 1) @@ -1237,61 +1241,60 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc #undef IS_CONSTANT_INTEGER - /* Check for forward dependencies x:y vs. x+1:z. */ - if (l_dir == 1 && r_dir == 1 - && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == -1 - && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == -1) - { - if (identical_strides) - return GFC_DEP_FORWARD; - } + /* Check for forward dependencies x:y vs. x+1:z and x:y:z vs. x:y:z+1. */ - /* Check for forward dependencies x:y:-1 vs. x-1:z:-1. */ - if (l_dir == -1 && r_dir == -1 - && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == 1 - && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == 1) - { - if (identical_strides) - return GFC_DEP_FORWARD; - } + if (l_dir == 1 && r_dir == 1 && + (start_comparison == 0 || start_comparison == -1) + && (stride_comparison == 0 || stride_comparison == -1)) + return GFC_DEP_FORWARD; + /* Check for forward dependencies x:y:-1 vs. x-1:z:-1 and + x:y:-1 vs. x:y:-2. */ + if (l_dir == -1 && r_dir == -1 && + (start_comparison == 0 || start_comparison == 1) + && (stride_comparison == 0 || stride_comparison == 1)) + return GFC_DEP_FORWARD; - if (identical_strides) + if (stride_comparison == 0 || stride_comparison == -1) { - if (l_start && IS_ARRAY_EXPLICIT (l_ar->as)) { - /* Check for a(low:y:s) vs. a(z:a:s) where a has a lower bound + /* Check for a(low:y:s) vs. a(z:x:s) or + a(low:y:s) vs. a(z:x:s+1) where a has a lower bound of low, which is always at least a forward dependence. */ if (r_dir == 1 && gfc_dep_compare_expr (l_start, l_ar->as->lower[n]) == 0) return GFC_DEP_FORWARD; + } + } - /* Check for a(high:y:-s) vs. a(z:a:-s) where a has a higher bound + if (stride_comparison == 0 || stride_comparison == 1) + { + if (l_start && IS_ARRAY_EXPLICIT (l_ar->as)) + { + + /* Check for a(high:y:-s) vs. a(z:x:-s) or + a(high:y:-s vs. a(z:x:-s-1) where a has a higher bound of high, which is always at least a forward dependence. */ if (r_dir == -1 && gfc_dep_compare_expr (l_start, l_ar->as->upper[n]) == 0) return GFC_DEP_FORWARD; } + } + + if (stride_comparison == 0) + { /* From here, check for backwards dependencies. */ - /* x:y vs. x+1:z. */ - if (l_dir == 1 && r_dir == 1 - && l_start && r_start - && gfc_dep_compare_expr (l_start, r_start) == 1 - && l_end && r_end - && gfc_dep_compare_expr (l_end, r_end) == 1) + /* x+1:y vs. x:z. */ + if (l_dir == 1 && r_dir == 1 && start_comparison == 1) return GFC_DEP_BACKWARD; - /* x:y:-1 vs. x-1:z:-1. */ - if (l_dir == -1 && r_dir == -1 - && l_start && r_start - && gfc_dep_compare_expr (l_start, r_start) == -1 - && l_end && r_end - && gfc_dep_compare_expr (l_end, r_end) == -1) + /* x-1:y:-1 vs. x:z:-1. */ + if (l_dir == -1 && r_dir == -1 && start_comparison == -1) return GFC_DEP_BACKWARD; }
Attachment:
dep-sub.pl
Description: Perl program
! { dg-do compile } ! { dg-options "-Warray-temporaries" } ! PR 45159 - No temporary should be created for this. program main integer a(100) a(10:16:2) = a(10:16:2) a(10:16:2) = a(10:19:3) a(10:18:2) = a(12:20:2) a(1:10) = a(2:20:2) a(16:10:-2) = a(16:10:-2) a(19:10:-1) = a(19:1:-2) a(19:10:-1) = a(18:9:-1) a(19:11:-1) = a(18:2:-2) end program main
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |