This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH RFC: stdio optimization
- To: law at cygnus dot com
- Subject: Re: PATCH RFC: stdio optimization
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Date: Mon, 13 Dec 1999 13:25:34 -0500 (EST)
- Cc: egcs-patches at egcs dot cygnus dot com
> From: Jeffrey A Law <law@cygnus.com>
>
> I'm not sure how often we'll find an fputc->putc optimization opportunity,
> but it can happen.
The gcc sources have 647 calls to fputc. There are also around 250
places in the sources where fprintf is called with a one character
constant string or with a "%c" format string. Another 65 places where
fputs is called with a one character constant string. My goal is to
get these one character fprintfs/fputs to transform to the expansion
of the putc macro like this: fprintf->builtin_fputs->builtin_fputc.
I'm starting with the lowest common denomenator and working my way
backwards.
> Note that you can't blindly turn every fputc into a
> builtin -- consider if fputc is used as an argument to a function. In fact,
> that is one of the main reasons why fputc exists in the first place.
Yes I know. I believe the builtin mechanism won't mess with the code
when you take the address of a function. Otherwise all the current
builtins (like strcpy, etc) would fail on this too.
> > I had to fake this by using a ptr_type_node. It seems to work, but
> > please double check where I set fputc_ftype whether this is correct or
> > not.
> That will probably work OK until you actually try to use it to implement
> putc :-) There's probably also issues with C++ here.
I don't intend to implement putc, the inline container will obtain it
for me.
Perhaps C++ will have a problem, I don't know. I'll check into that
once I get it working for C.
> > 3. How do I properly setup gcc to insert an *inline* function once
> > I've trapped the place where the original goes?
> You must have already seen an implementation of the function *before* the
> call site where you wish to inline it.
I already did that, that's what the __gcc_builtin_fputc_via_putc
function is supposed to do. I think Gavin's reply might explain the
problem.
> > I think if we can settle these issues, this first optimization will
> > work.
> My gut tells me to go after printf -> puts first since you can avoid the
> FILE * issue. It'll limit you in some ways, but you can start building
> the pieces you need and still get something useful out of the optimization
> while you're building the rest of the pieces.
>
> For printf->puts conversion you'd want to verify that the string has no format
> chars and ends in a newline. You'd want to pass a modified version of the
> string (no newline) to puts.
> jeff
Yup, working on it. Here are the initial tranformations I intend to do.
printf ("string\n"); -> builtin_puts (string);
fprintf (stream, "string"); -> builtin_fputs ("string", stream);
sprintf (buf, "string"); -> builtin_strcpy (buf, "string");
(The above transformations are only valid if "string" does not contain
"%%". Or I could pass "string" to asprintf at compile time to resolve
these automatically. Yes I think I'll do that.)
printf ("%s\n", foo); -> builtin_puts (foo);
fputs ("x", stream); -> builtin_fputc ('x', stream);
fputc ('x', stream); -> expanded_putc_macro ('x', stream);
etc.
Given that I can already replace a call to one extern function
with another extern one, all the above should be doable. The only
issue I can see is maintaining the same return value sematics. The
*printf functions already match *puts in returning the number of
characters printed. The trick will be with fputs->fputc and
sprintf->strcpy. I may need more inline wrappers to handle these two
so I have control over the return value.
--Kaveh
--
Kaveh R. Ghazi Engagement Manager / Project Services
ghazi@caip.rutgers.edu Qwest Internet Solutions