Bug 35561 - Promote written once local aggregates to static
Summary: Promote written once local aggregates to static
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2008-03-12 20:59 UTC by davidxl
Modified: 2023-06-02 00:13 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description davidxl 2008-03-12 20:59:16 UTC
// David Li

In some programs (not so rare), local arrays/aggregates are used to hold some program parameters that never change. Such local arrays are candidates for being promoted into readonly static data, in order to 1) reducing stack size; 2) avoid paying the overhead of the initializing the array each time the routine is entered.

Such optimization can be extended to cases when the local array is defined once on entry of a single entry routine, read within the region, but not live out of it (such cases can be created due to inlining).

Example:

int foo(...)
{
   int coeff_array[30] = {1,2,3.......};

   ..... = coeff_array[i];
   ..
}
Comment 1 Andrew Pinski 2008-03-12 21:07:34 UTC
This should be already done.  
Comment 2 davidxl 2008-03-12 21:12:29 UTC
(In reply to comment #1)
> This should be already done.  
> 

With which option? I tried with -O2/-O3, it does not kick in:


int foo(int n, int* p)
{
   int i,s=0;
   int arr[100] = { 1,2,3,3,4,3,3,3,3,5,6,7,1,1,1,1,1,1,1,1,1,11,1,1,11,1,1,1,11,1,1,11,1,1,11,10};

   for ( i = 0; i < n; i++)
   {
           p[i] += arr[i];
           s+=arr[i];
   }
  return s;
}
Comment 3 Andrew Pinski 2008-03-12 21:15:31 UTC
If there is not enough 0's, then we actually promote the constructor but never the variable.
Comment 4 davidxl 2008-03-12 21:19:02 UTC
(In reply to comment #3)
> If there is not enough 0's, then we actually promote the constructor but never
> the variable.
> 

I am a little confused. How do you promote constructor? By the way, this is a C program.

David
Comment 5 Andrew Pinski 2008-03-12 21:23:34 UTC
By constructor I mean the initializer.
Comment 6 Steven Fuerst 2011-06-23 03:14:13 UTC
Still a problem in 4.6 at all optimization levels.

int foo1(int x)
{
	int a[] = {1,4,7,9};
	
	return a[x];
}


int foo2(int x)
{
	static int a[] = {1,4,7,9};
	
	return a[x];
}

foo1() creates the array on the stack using a series of mov instructions, whereas the code generated for foo2() is much nicer.
Comment 7 Andrew Pinski 2011-06-23 03:17:58 UTC
At one point this was done but it was found it violated C rules.  I can find the bug report but I am being lazy right now but it comes down to if it was promoted then you  have issues if it escaped.  Oh and technically a[i] does take the address of a.
Comment 8 jsm-csl@polyomino.org.uk 2011-06-23 10:32:28 UTC
See bug 38615 for the case when converting an object to static is not 
valid.
Comment 9 Jakub Jelinek 2011-06-23 13:31:01 UTC
Well, we could still optimize it e.g. in leaf functions or in functions that only call leaf functions (__attribute__((leaf))).  But we do this transformation during gimplification, so either we'd need to add an optimization that would turn an automatic aggregate into static aggregate if possible and useful later on (in particular, if it is determined to be never written into and its value doesn't escape current function or current function is leaf or only calls leaf functions and doesn't tail recurse), or we'd need to do some analysis right before gimplification starts to find out if a function must be leaf or only call leaf functions.
Comment 10 davidxl 2011-06-27 20:44:56 UTC
Agree. Such optimization should not be done in gimplication, Nor should the
const keyword be looked at.  It should be done in middle end where local
aggregate are analyzed:

1) the aggregate is only written once with constant initializer -- this
implies that address of such aggregate is not escaped
2) all uses of the aggregate are dominated by the initialization statement
3) address of aggregate is not used comparison.

David


On Thu, Jun 23, 2011 at 6:31 AM, jakub at gcc dot gnu.org <
gcc-bugzilla@gcc.gnu.org> wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35561
>
> Jakub Jelinek <jakub at gcc dot gnu.org> changed:
>
>           What    |Removed                     |Added
>
> ----------------------------------------------------------------------------
>                 CC|                            |jakub at gcc dot gnu.org
>
> --- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-06-23
> 13:31:01 UTC ---
> Well, we could still optimize it e.g. in leaf functions or in functions
> that
> only call leaf functions (__attribute__((leaf))).  But we do this
> transformation during gimplification, so either we'd need to add an
> optimization that would turn an automatic aggregate into static aggregate
> if
> possible and useful later on (in particular, if it is determined to be
> never
> written into and its value doesn't escape current function or current
> function
> is leaf or only calls leaf functions and doesn't tail recurse), or we'd
> need to
> do some analysis right before gimplification starts to find out if a
> function
> must be leaf or only call leaf functions.
>
> --
> Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You reported the bug.
>