From: esedlar@analogous.COM (Eric Sedlar)
Subject: Optimization: constant folding
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 9 Apr 1992 01:58:30 GMT

Hi.  I wanted to make a suggestion for an improvement in the way
optimization works in GCC.

It it often the case that I wish to have a descriptor for an object
which contains a type field.  Each of the operations on that object
will have to test this type (with either a switch or an if) to
determine how to do this operation.  If I setup the function
operating on that object as a macro testing that type, I would like
the test to be optimized away if the type is constant.  Note that this
will also reduce the size of my executable image, as the function not
taken is not linked in.

Example:

#define delete_from_list(list_type, listp, el) \
((list_type==DOUBLY_LINKED)?delete_dbl_list(listp,el):\
delete_sng_list(listp,el))

This kind of thing happens in libraries (e.g. if I wanted to write a
generic linked list manager), where an application only wants to use a
specific type of object supported by the library.  Optimizing this
test is helpful in writing a library that doesn't lose efficiency for
flexibility.

Anyway, I ran a few tests to see when GCC optimizes out constants.  I
tried this with both GCC 1.4 and GCC 2.1 with -O (and -O2 on GCC 2.1).
A construction like if (1) then <blah> else <blah> is reduced, but the
following example does not.  This was run on a Sparc IPX, SunOS 4.1.1.

C-file: (foo.c)
-------
const int i=3;

struct bar 
{
  int i;
  int j;
};

#define STUFF {1,0}

static const struct bar foo = 
{
  3,0
  }
;

main()
{
  if (((struct bar)STUFF).j)
  {
    printf("%d\n",i);
  }
  else
  {    
    printf("%d\n",i+2);
  }
}  

The assembler output (attached at the end for completeness) still
contains a branch.  With the way structure types are handled in
ANSI-C, I would think that this would work automatically.  I would
also like it to work if I used the const structure (foo) as well.  I
would think that this would have to be an additional "-f"
optimization, since ANSI const declarations have historically not done
too much on some compilers.  However, I think that GCC should evaluate
any expression to see if is constant (variables declared const are
placed in the text segment, on most compilers, and so they can be
folded in before runtime).  I realize that doing this with variables
declared in other files wouldn't work without post-link optimization,
but I do think that as long as the compiler knows about it, and the
variable is const, optimizations should be performed in expressions.

Anyway, please tell me what you think about this.

Thanks very much,

  Eric Sedlar



Output of (with GCC 2.1)
gcc -O2 -S foo.c:

gcc2_compiled.:
	.global _i
.text
	.align 4
_i:
	.word 3
	.global _foo
	.align 4
_foo:
	.word 3
	.word 0
	.align 4
LC0:
	.word 1
	.word 0
	.align 4
LC1:
	.ascii "%d\12\0"
	.align 4
	.global _main
	.proc 1
_main:
	!#PROLOGUE# 0
	save %sp,-136,%sp
	!#PROLOGUE# 1
	call ___main,0
	nop
	sethi %hi(LC0+4),%o0
	ld [%o0+%lo(LC0+4)],%o0
	cmp %o0,0
	be L2
	sethi %hi(_i),%o0
	ld [%o0+%lo(_i)],%o1
	sethi %hi(LC1),%o0
	call _printf,0
	or %o0,%lo(LC1),%o0
	b,a L3
L2:
	ld [%o0+%lo(_i)],%o1
	sethi %hi(LC1),%o0
	or %o0,%lo(LC1),%o0
	call _printf,0
	add %o1,2,%o1
L3:
	ret
	restore


Newsgroups: gnu.gcc.bug