diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17765ab88f7..1e4b928d682 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2006-10-06 Jakub Jelinek + PR tree-optimization/29330 + * tree-data-ref.c (free_data_ref): Use DR_FREE_ACCESS_FNS macro. + (initialize_data_dependence_relation): Clear DDR_LOOP_NEST pointer + on newly allocated ddrs. + (find_loop_nest_1, find_loop_nest): Change LOOP_NEST to a pointer + to VEC (loop_p, heap) pointer. + (compute_data_dependences_for_loop): Adjust caller. + (free_dependence_relations): Free DDR_LOOP_NEST. + + * tree-loop-linear.c (linear_transform_loops): Don't forget to + free DEPENDENCE_RELATIONS and DATAREFS. + PR target/28924 * builtins.c (expand_builtin_sync_operation, expand_builtin_compare_and_swap, expand_builtin_lock_test_and_set): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e16cecd218..dad477eeee3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2006-10-06 Jakub Jelinek + PR tree-optimization/29330 + * gcc.dg/pr29330.c: New test. + PR target/28924 * gcc.c-torture/compile/20061005-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr29330.c b/gcc/testsuite/gcc.dg/pr29330.c new file mode 100644 index 00000000000..e673b216630 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr29330.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/29330 */ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-loop-linear" } */ + +int buf[2][2][2][2]; + +void +f (void) +{ + for (int a = 0; a < 2; ++a) + for (int b = 0; b < 2; ++b) + for (int c = 0; c < 2; ++c) + for (int d = 0; d < 2; ++d) + buf[a][b][c][d] = 0; +} diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 30d745a4238..2e47a25ac90 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1913,11 +1913,7 @@ analyze_offset (tree offset, tree *invariant, tree *constant) static void free_data_ref (data_reference_p dr) { - if (DR_TYPE(dr) == ARRAY_REF_TYPE) - VEC_free (tree, heap, dr->object_info.access_fns); - else - VEC_free (tree, heap, dr->first_location.access_fns); - + DR_FREE_ACCESS_FNS (dr); free (dr); } @@ -2171,6 +2167,7 @@ initialize_data_dependence_relation (struct data_reference *a, res = XNEW (struct data_dependence_relation); DDR_A (res) = a; DDR_B (res) = b; + DDR_LOOP_NEST (res) = NULL; if (a == NULL || b == NULL) { @@ -4205,7 +4202,7 @@ find_data_references_in_loop (struct loop *loop, /* Recursive helper function. */ static bool -find_loop_nest_1 (struct loop *loop, VEC (loop_p, heap) *loop_nest) +find_loop_nest_1 (struct loop *loop, VEC (loop_p, heap) **loop_nest) { /* Inner loops of the nest should not contain siblings. Example: when there are two consecutive loops, @@ -4224,7 +4221,7 @@ find_loop_nest_1 (struct loop *loop, VEC (loop_p, heap) *loop_nest) if (loop->next) return false; - VEC_safe_push (loop_p, heap, loop_nest, loop); + VEC_safe_push (loop_p, heap, *loop_nest, loop); if (loop->inner) return find_loop_nest_1 (loop->inner, loop_nest); return true; @@ -4236,9 +4233,9 @@ find_loop_nest_1 (struct loop *loop, VEC (loop_p, heap) *loop_nest) appear in the classic distance vector. */ static bool -find_loop_nest (struct loop *loop, VEC (loop_p, heap) *loop_nest) +find_loop_nest (struct loop *loop, VEC (loop_p, heap) **loop_nest) { - VEC_safe_push (loop_p, heap, loop_nest, loop); + VEC_safe_push (loop_p, heap, *loop_nest, loop); if (loop->inner) return find_loop_nest_1 (loop->inner, loop_nest); return true; @@ -4265,7 +4262,7 @@ compute_data_dependences_for_loop (struct loop *loop, is not computable, give up without spending time to compute other dependences. */ if (!loop_nest - || !find_loop_nest (loop_nest, vloops) + || !find_loop_nest (loop_nest, &vloops) || find_data_references_in_loop (loop, datarefs) == chrec_dont_know) { struct data_dependence_relation *ddr; @@ -4435,10 +4432,22 @@ free_dependence_relations (VEC (ddr_p, heap) *dependence_relations) { unsigned int i; struct data_dependence_relation *ddr; + VEC (loop_p, heap) *loop_nest = NULL; for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++) - free_dependence_relation (ddr); + { + if (ddr == NULL) + continue; + if (loop_nest == NULL) + loop_nest = DDR_LOOP_NEST (ddr); + else + gcc_assert (DDR_LOOP_NEST (ddr) == NULL + || DDR_LOOP_NEST (ddr) == loop_nest); + free_dependence_relation (ddr); + } + if (loop_nest) + VEC_free (loop_p, heap, loop_nest); VEC_free (ddr_p, heap, dependence_relations); } diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c index 2ef7eacec13..2840e9be4b7 100644 --- a/gcc/tree-loop-linear.c +++ b/gcc/tree-loop-linear.c @@ -308,7 +308,7 @@ linear_transform_loops (struct loops *loops) { if (dump_file) fprintf (dump_file, "Won't transform loop. Optimal transform is the identity transform\n"); - continue; + goto free_and_continue; } /* Check whether the transformation is legal. */ @@ -316,15 +316,15 @@ linear_transform_loops (struct loops *loops) { if (dump_file) fprintf (dump_file, "Can't transform loop, transform is illegal:\n"); - continue; + goto free_and_continue; } before = gcc_loopnest_to_lambda_loopnest (loops, loop_nest, &oldivs, &invariants); if (!before) - continue; - + goto free_and_continue; + if (dump_file) { fprintf (dump_file, "Before:\n"); @@ -346,6 +346,7 @@ linear_transform_loops (struct loops *loops) if (dump_file) fprintf (dump_file, "Successfully transformed loop.\n"); + free_and_continue: free_dependence_relations (dependence_relations); free_data_refs (datarefs); }