This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: forcing tail/sibling call optimization


On Sun, 26 Nov 2000 22:55:56 +1100, Fergus Henderson wrote:

  the compiler won't be able to perform sibling call optimization, since
  it can't be sure that bar() doesn't save the addresses of x and y in
  some storage that is accessible to baz().  I would like some way to
  tell the compiler to go ahead and perform the sibling call
  optimization anyway.

Actually, a similar situation exist with "const" calls.
It is possible to mark a function with __attribute__ ((const)),
but not do this for individual calls. 

When passing arguments by reference, it is not possible to
mark a function const, as the compiler will assume the function
will return the same result if the address of the argument has
not changed, even when the value of the argument has.

The example below shows an instance of this problem. I wonder
what would be involved in allowing front-ends to specify what
calls should be considered const. In GNAT for example, this information
is readily available but it cannot be communicated to the backend
easily.

  -Geert

#include <stdio.h>
int calls = 0; /* Used for counting the actual nr of invocations of len */

__attribute__ ((const)) size_t len (const char *string)
   /* Calls to len should be considered considered to be const iff
    * the actual passed to string is const. So, in fact, it should
    * be possible to define the const attribute on a per call basis */
{  calls++; 
   return strlen (string);
}

int words (char *sentence)
{  size_t i;
   int spaces = 0;
   /* sentence is not constant in this context, so calls to len
    * should not be considered to be __attribute__ ((const)) calls */
   for (i = 0; i < len (sentence); i++)
   { if (sentence[i] == '.') sentence[i + 1] = 0;
     if (sentence[i] == ' ') spaces++;
   }
   return len (sentence) > 0 ? spaces + 1 : 0;
} 

int cwords (const char *sentence)
{  size_t i;
   int spaces = 0;
   /* sentence is constant in this context, so len (sentence) is in
    * fact constant */
   for (i = 0; i < len (sentence); i++)
     if (sentence [i] == ' ') spaces++;
   return len (sentence) > 0 ? spaces + 1 : 0;
}

int main ()
{  char s[] = "This is a sentence. This one is not counted.";

   calls = 0;
   printf ("\"%s\" has %i words\n", &s, cwords (s));
   printf ("%i calls to strlen\n", calls);

   calls = 0;
   /* This counts 8 words with -O, while it should count 4. */
   printf ("\"%s\" has %i words\n", &s, words (s) );
   printf ("%i calls to strlen\n", calls);

   return 0;
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]