From 6ddfda8a98c084192e8fd16c56b722fddf53dc5a Mon Sep 17 00:00:00 2001 From: Easwaran Raman Date: Thu, 21 Apr 2011 19:16:57 +0000 Subject: [PATCH] cfgexpand.c (stack_var): Remove OFFSET... 2011-04-21 Easwaran Raman * gcc/cfgexpand.c (stack_var): Remove OFFSET... (add_stack_var): ...and its reference here... (expand_stack_vars): ...and here. (stack_var_cmp): Sort by descending order of size. (partition_stack_vars): Change heuristic. (union_stack_vars): Fix to reflect changes in partition_stack_vars. (dump_stack_var_partition): Add newline after each partition. testsuite/Changelog: 2011-04-21 Easwaran Raman * gcc.dg/stack-layout-2.c: New test. From-SVN: r172837 --- gcc/ChangeLog | 11 ++++ gcc/cfgexpand.c | 76 +++++++-------------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/stack-layout-2.c | 23 ++++++++ 4 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/stack-layout-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 954e58d8f83..8236d5a1af4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2011-04-21 Easwaran Raman + + * gcc/cfgexpand.c (stack_var): Remove OFFSET... + (add_stack_var): ...and its reference here... + (expand_stack_vars): ...and here. + (stack_var_cmp): Sort by descending order of size. + (partition_stack_vars): Change heuristic. + (union_stack_vars): Fix to reflect changes in + partition_stack_vars. + (dump_stack_var_partition): Add newline after each partition. + 2011-04-21 Dimitrios Apostolou Jeff Law diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index e88bec14945..ecf2510a0f4 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -158,11 +158,6 @@ struct stack_var /* The Variable. */ tree decl; - /* The offset of the variable. During partitioning, this is the - offset relative to the partition. After partitioning, this - is relative to the stack frame. */ - HOST_WIDE_INT offset; - /* Initially, the size of the variable. Later, the size of the partition, if this variable becomes it's partition's representative. */ HOST_WIDE_INT size; @@ -268,7 +263,6 @@ add_stack_var (tree decl) v = &stack_vars[stack_vars_num]; v->decl = decl; - v->offset = 0; v->size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1); /* Ensure that all variables have size, so that &a != &b for any two variables that are simultaneously live. */ @@ -405,9 +399,9 @@ stack_var_cmp (const void *a, const void *b) return (int)largeb - (int)largea; /* Secondary compare on size, decreasing */ - if (sizea < sizeb) - return -1; if (sizea > sizeb) + return -1; + if (sizea < sizeb) return 1; /* Tertiary compare on true alignment, decreasing. */ @@ -566,28 +560,19 @@ update_alias_info_with_stack_vars (void) /* A subroutine of partition_stack_vars. The UNION portion of a UNION/FIND partitioning algorithm. Partitions A and B are known to be non-conflicting. - Merge them into a single partition A. - - At the same time, add OFFSET to all variables in partition B. At the end - of the partitioning process we've have a nice block easy to lay out within - the stack frame. */ + Merge them into a single partition A. */ static void -union_stack_vars (size_t a, size_t b, HOST_WIDE_INT offset) +union_stack_vars (size_t a, size_t b) { - size_t i, last; struct stack_var *vb = &stack_vars[b]; bitmap_iterator bi; unsigned u; - /* Update each element of partition B with the given offset, - and merge them into partition A. */ - for (last = i = b; i != EOC; last = i, i = stack_vars[i].next) - { - stack_vars[i].offset += offset; - stack_vars[i].representative = a; - } - stack_vars[last].next = stack_vars[a].next; + gcc_assert (stack_vars[b].next == EOC); + /* Add B to A's partition. */ + stack_vars[b].next = stack_vars[a].next; + stack_vars[b].representative = a; stack_vars[a].next = b; /* Update the required alignment of partition A to account for B. */ @@ -607,16 +592,13 @@ union_stack_vars (size_t a, size_t b, HOST_WIDE_INT offset) partitions constrained by the interference graph. The overall algorithm used is as follows: - Sort the objects by size. + Sort the objects by size in descending order. For each object A { S = size(A) O = 0 loop { Look for the largest non-conflicting object B with size <= S. UNION (A, B) - offset(B) = O - O += size(B) - S -= size(B) } } */ @@ -638,24 +620,23 @@ partition_stack_vars (void) for (si = 0; si < n; ++si) { size_t i = stack_vars_sorted[si]; - HOST_WIDE_INT isize = stack_vars[i].size; unsigned int ialign = stack_vars[i].alignb; - HOST_WIDE_INT offset = 0; - for (sj = si; sj-- > 0; ) + /* Ignore objects that aren't partition representatives. If we + see a var that is not a partition representative, it must + have been merged earlier. */ + if (stack_vars[i].representative != i) + continue; + + for (sj = si + 1; sj < n; ++sj) { size_t j = stack_vars_sorted[sj]; - HOST_WIDE_INT jsize = stack_vars[j].size; unsigned int jalign = stack_vars[j].alignb; /* Ignore objects that aren't partition representatives. */ if (stack_vars[j].representative != j) continue; - /* Ignore objects too large for the remaining space. */ - if (isize < jsize) - continue; - /* Ignore conflicting objects. */ if (stack_var_conflict_p (i, j)) continue; @@ -666,25 +647,8 @@ partition_stack_vars (void) != (jalign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)) continue; - /* Refine the remaining space check to include alignment. */ - if (offset & (jalign - 1)) - { - HOST_WIDE_INT toff = offset; - toff += jalign - 1; - toff &= -(HOST_WIDE_INT)jalign; - if (isize - (toff - offset) < jsize) - continue; - - isize -= toff - offset; - offset = toff; - } - /* UNION the objects, placing J at OFFSET. */ - union_stack_vars (i, j, offset); - - isize -= jsize; - if (isize == 0) - break; + union_stack_vars (i, j); } } @@ -714,9 +678,8 @@ dump_stack_var_partition (void) { fputc ('\t', dump_file); print_generic_expr (dump_file, stack_vars[j].decl, dump_flags); - fprintf (dump_file, ", offset " HOST_WIDE_INT_PRINT_DEC "\n", - stack_vars[j].offset); } + fputc ('\n', dump_file); } } @@ -865,10 +828,9 @@ expand_stack_vars (bool (*pred) (tree)) partition. */ for (j = i; j != EOC; j = stack_vars[j].next) { - gcc_assert (stack_vars[j].offset <= stack_vars[i].size); expand_one_stack_var_at (stack_vars[j].decl, base, base_align, - stack_vars[j].offset + offset); + offset); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b3d70f3ac7..0520b0f74dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-04-21 Easwaran Raman + + * gcc.dg/stack-layout-2.c: New test. + 2011-04-21 Richard Guenther PR lto/48703 diff --git a/gcc/testsuite/gcc.dg/stack-layout-2.c b/gcc/testsuite/gcc.dg/stack-layout-2.c new file mode 100644 index 00000000000..5d5b385f675 --- /dev/null +++ b/gcc/testsuite/gcc.dg/stack-layout-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ +void bar( char *); +int foo() +{ + int i=0; + { + char a[8000]; + bar(a); + i += a[0]; + } + { + char a[8192]; + char b[32]; + bar(a); + i += a[0]; + bar(b); + i += a[0]; + } + return i; +} +/* { dg-final { scan-rtl-dump "size 8192" "expand" } } */ +/* { dg-final { scan-rtl-dump "size 32" "expand" } } */ -- 2.30.2