Commit 6ddfda8a by Easwaran Raman Committed by Easwaran Raman

cfgexpand.c (stack_var): Remove OFFSET...

2011-04-21  Easwaran Raman  <eraman@google.com>

	* 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  <eraman@google.com>

	* gcc.dg/stack-layout-2.c: New test.

From-SVN: r172837
parent 8e20e8b1
2011-04-21 Easwaran Raman <eraman@google.com>
* 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 <jimis@gmx.net> 2011-04-21 Dimitrios Apostolou <jimis@gmx.net>
Jeff Law <law@redhat.com> Jeff Law <law@redhat.com>
......
...@@ -158,11 +158,6 @@ struct stack_var ...@@ -158,11 +158,6 @@ struct stack_var
/* The Variable. */ /* The Variable. */
tree decl; 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, /* Initially, the size of the variable. Later, the size of the partition,
if this variable becomes it's partition's representative. */ if this variable becomes it's partition's representative. */
HOST_WIDE_INT size; HOST_WIDE_INT size;
...@@ -268,7 +263,6 @@ add_stack_var (tree decl) ...@@ -268,7 +263,6 @@ add_stack_var (tree decl)
v = &stack_vars[stack_vars_num]; v = &stack_vars[stack_vars_num];
v->decl = decl; v->decl = decl;
v->offset = 0;
v->size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1); v->size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1);
/* Ensure that all variables have size, so that &a != &b for any two /* Ensure that all variables have size, so that &a != &b for any two
variables that are simultaneously live. */ variables that are simultaneously live. */
...@@ -405,9 +399,9 @@ stack_var_cmp (const void *a, const void *b) ...@@ -405,9 +399,9 @@ stack_var_cmp (const void *a, const void *b)
return (int)largeb - (int)largea; return (int)largeb - (int)largea;
/* Secondary compare on size, decreasing */ /* Secondary compare on size, decreasing */
if (sizea < sizeb)
return -1;
if (sizea > sizeb) if (sizea > sizeb)
return -1;
if (sizea < sizeb)
return 1; return 1;
/* Tertiary compare on true alignment, decreasing. */ /* Tertiary compare on true alignment, decreasing. */
...@@ -566,28 +560,19 @@ update_alias_info_with_stack_vars (void) ...@@ -566,28 +560,19 @@ update_alias_info_with_stack_vars (void)
/* A subroutine of partition_stack_vars. The UNION portion of a UNION/FIND /* 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. 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 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]; struct stack_var *vb = &stack_vars[b];
bitmap_iterator bi; bitmap_iterator bi;
unsigned u; unsigned u;
/* Update each element of partition B with the given offset, gcc_assert (stack_vars[b].next == EOC);
and merge them into partition A. */ /* Add B to A's partition. */
for (last = i = b; i != EOC; last = i, i = stack_vars[i].next) stack_vars[b].next = stack_vars[a].next;
{ stack_vars[b].representative = a;
stack_vars[i].offset += offset;
stack_vars[i].representative = a;
}
stack_vars[last].next = stack_vars[a].next;
stack_vars[a].next = b; stack_vars[a].next = b;
/* Update the required alignment of partition A to account for 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) ...@@ -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 partitions constrained by the interference graph. The overall
algorithm used is as follows: algorithm used is as follows:
Sort the objects by size. Sort the objects by size in descending order.
For each object A { For each object A {
S = size(A) S = size(A)
O = 0 O = 0
loop { loop {
Look for the largest non-conflicting object B with size <= S. Look for the largest non-conflicting object B with size <= S.
UNION (A, B) UNION (A, B)
offset(B) = O
O += size(B)
S -= size(B)
} }
} }
*/ */
...@@ -638,24 +620,23 @@ partition_stack_vars (void) ...@@ -638,24 +620,23 @@ partition_stack_vars (void)
for (si = 0; si < n; ++si) for (si = 0; si < n; ++si)
{ {
size_t i = stack_vars_sorted[si]; size_t i = stack_vars_sorted[si];
HOST_WIDE_INT isize = stack_vars[i].size;
unsigned int ialign = stack_vars[i].alignb; 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]; size_t j = stack_vars_sorted[sj];
HOST_WIDE_INT jsize = stack_vars[j].size;
unsigned int jalign = stack_vars[j].alignb; unsigned int jalign = stack_vars[j].alignb;
/* Ignore objects that aren't partition representatives. */ /* Ignore objects that aren't partition representatives. */
if (stack_vars[j].representative != j) if (stack_vars[j].representative != j)
continue; continue;
/* Ignore objects too large for the remaining space. */
if (isize < jsize)
continue;
/* Ignore conflicting objects. */ /* Ignore conflicting objects. */
if (stack_var_conflict_p (i, j)) if (stack_var_conflict_p (i, j))
continue; continue;
...@@ -666,25 +647,8 @@ partition_stack_vars (void) ...@@ -666,25 +647,8 @@ partition_stack_vars (void)
!= (jalign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)) != (jalign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT))
continue; 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 the objects, placing J at OFFSET. */
union_stack_vars (i, j, offset); union_stack_vars (i, j);
isize -= jsize;
if (isize == 0)
break;
} }
} }
...@@ -714,9 +678,8 @@ dump_stack_var_partition (void) ...@@ -714,9 +678,8 @@ dump_stack_var_partition (void)
{ {
fputc ('\t', dump_file); fputc ('\t', dump_file);
print_generic_expr (dump_file, stack_vars[j].decl, dump_flags); 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)) ...@@ -865,10 +828,9 @@ expand_stack_vars (bool (*pred) (tree))
partition. */ partition. */
for (j = i; j != EOC; j = stack_vars[j].next) 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, expand_one_stack_var_at (stack_vars[j].decl,
base, base_align, base, base_align,
stack_vars[j].offset + offset); offset);
} }
} }
......
2011-04-21 Easwaran Raman <eraman@google.com>
* gcc.dg/stack-layout-2.c: New test.
2011-04-21 Richard Guenther <rguenther@suse.de> 2011-04-21 Richard Guenther <rguenther@suse.de>
PR lto/48703 PR lto/48703
......
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment