On Wed, Apr 20, 2011 at 6:53 AM, Michael Matz <m...@suse.de> wrote: > Hi, > > On Tue, 19 Apr 2011, Easwaran Raman wrote: > >> > That is correct but is also what the use of stack_vars[u].representative >> > achieves alone, ... >> > >> >> I am adding a check to that effect. >> > >> > ... without any check. >> > >> > @@ -596,7 +581,8 @@ >> > if (vb->conflicts) >> > { >> > EXECUTE_IF_SET_IN_BITMAP (vb->conflicts, 0, u, bi) >> > - add_stack_var_conflict (a, stack_vars[u].representative); >> > + if (stack_vars[u].next == EOC && stack_vars[u].representative == >> > u) >> > + add_stack_var_conflict (a, u); >> > BITMAP_FREE (vb->conflicts); >> > } >> > } >> > >> > What's your objective with this change? I find the original code clearer. >> >> Let us say we try to merge 'a' to 'b' and 'a' has conflicts with many >> members of an existing partition C. It is not necessary to add all >> those conflicts to 'b' since they will be never considered in the call >> to union_stack_vars. > > Right, that's why I was objecting to your initial change. a I agree that my initial change - adding a conflict with u - was wrong. > The original > code (adding stack_vars[u].representative to the conflicts of A) made sure > the target conflict bitmap only got representatives added. In my above example, it is not even necessary to add a conflict between 'b' and representative(C) since it is already in a partition. But you're right - not adding that conflict doesn't actually reduce the size of bit maps. Reverting back to what was there originally.
Thanks, Easwaran That's why I > was asking why you changed this area at all. > >> I was motivated by your comment on bit-vector bloat to try this, but if >> this affects readability I'll happily revert back to what it was before. > > > Ciao, > Michael.
Index: gcc/testsuite/gcc.dg/stack-layout-2.c =================================================================== --- gcc/testsuite/gcc.dg/stack-layout-2.c (revision 0) +++ gcc/testsuite/gcc.dg/stack-layout-2.c (revision 0) @@ -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" } } */ Index: gcc/cfgexpand.c =================================================================== --- gcc/cfgexpand.c (revision 171954) +++ gcc/cfgexpand.c (working copy) @@ -158,11 +158,6 @@ /* 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; @@ -267,7 +262,6 @@ 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. */ @@ -403,9 +397,9 @@ 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. */ @@ -564,28 +558,19 @@ /* 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. + 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. */ - 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. */ @@ -605,16 +590,13 @@ 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) } } */ @@ -636,24 +618,23 @@ 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; @@ -664,25 +645,8 @@ != (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); } } @@ -712,9 +676,8 @@ { 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); } } @@ -863,10 +826,9 @@ 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); } }