tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] inline assembly and optimization passes


From: Jared Maddox
Subject: Re: [Tinycc-devel] inline assembly and optimization passes
Date: Mon, 23 Sep 2013 21:44:06 -0500

> Date: Mon, 23 Sep 2013 14:22:16 +0200
> From: Sylvain BERTRAND <address@hidden>
> To: address@hidden
> Subject: Re: [Tinycc-devel] inline assembly and optimization passes
> Message-ID: <address@hidden>
> Content-Type: text/plain; charset=us-ascii
>
>> Thoughts?
>
> Wow... :) You totally missed my point.
>
> My idea is to have a langage which has a lower implementation
> technical cost. That's why I was saying "the other way".
>

Are you talking about the IL/IC, or the other one we were talking
about? Because I talked about two there, not one.


> Date: Mon, 23 Sep 2013 14:29:40 +0200
> From: Sylvain BERTRAND <address@hidden>
> To: address@hidden
> Subject: Re: [Tinycc-devel] inline assembly and optimization passes
> Message-ID: <address@hidden>
> Content-Type: text/plain; charset=us-ascii
>
>> Sorry about the delay, I receive digests, so I didn't get this until
>> after I'd sent out my last message.
>>
>> The reason why C is normally not used as an IL/IC is because you can
>> design languages that are easier to parse than C. Simple as that. Your
>> stereo typical assembly language, where each line of code corresponds
>> to a single discrete action and it's arguments is much easier to parse
>> than C. So, C normally doesn't get used in that role, because someone
>> who can write a parser for any variant of C is likely to have a much
>> easier time writing a parser for some specialized language instead.
>>
>> C isn't as difficult to parse as C++, but when you consider that
>> you'll be having to parse all of this again in a completely different
>> program, it becomes easy to see why you'd favor simplicity of parsing.
>
> The whole point was to re-use the tinycc parser and keep things
> reasonnable.
>

So you want to hook into the TCC parser itself? I'm unconvinced that
this is the right route, but I don't think it should pose any HARM
either. I think the correct location is PROBABLY line 794 in libtcc.c,
inside the tcc_compile(  ) function. In case of intervening commits,
it's between:
         decl(VT_CONST);
         if (tok != TOK_EOF)
             expect("declaration");
         if (pvtop != vtop)
             tcc_warning("internal compiler error: vstack leak? (%d)",
vtop - pvtop);
and:
         /* end of translation unit info */
         if (s1->do_debug) {
             put_stabs_r(NULL, N_SO, 0, 0,
                         text_section->data_offset, text_section, section_sym);
         }

decl(  ) comes from tccgen.c, and looks like the bottom-level function
in the parser proper. I ASSUME that when it finishes, you'll have a
ready-to-use parse tree in the active TCCState. At the moment the
active TCCState is always stored in a global, but in the future it
might be passed as an argument, so your hook function should take it
as such.

All this having been said, the correct location might actually be
after gen_inline_functions(), and before sym_pop(), on line 809. The
relevant section of code is this:
     /* reset define stack, but leave -Dsymbols (may be incorrect if
        they are undefined) */
     free_defines(define_start);

     gen_inline_functions();

     sym_pop(&global_stack, NULL);
     sym_pop(&local_stack, NULL);

     return s1->nb_errors != 0 ? -1 : 0;

If you do decide to go this route, then I'd suggest moving the
tcc_compile(  ) code into a tcc_compile2(  ) or similar function,
accepting (a) callback(s) to use in the relevant location(s), and just
have tcc_compile(  ) be a wrapper around that which provides a null
value for the callback.

Note that this is not the same as the correct location for
code-generator output: I haven't spent the time to analyze TCC enough
to be certain where that is. I do, however, fear that it might be
performed inside the parsing stage itself, in which case the parse
tree might be thrown away in pieces as the parse proceeds. If this
proves to be the case, then I'd suggest going back to my suggestion of
an IL/IC target, though you technically could implement this as a
series of calls into a C library, rather than as a distinct language.
The call sequence would then produce a parse tree, instead of an extra
parser producing the tree. Unfortunately, in this case your plan would
need a dedicated parse-tree reader to "lower" the parse tree back into
C, but it hopefully wouldn't be a big deal.



> Date: Mon, 23 Sep 2013 14:31:04 +0200
> From: Vittorio Giovara <address@hidden>
> To: address@hidden
> Subject: Re: [Tinycc-devel] inline assembly and optimization passes
> Message-ID:
>       <address@hidden>
> Content-Type: text/plain; charset=UTF-8
>
> On Fri, Sep 20, 2013 at 3:08 AM, Sylvain BERTRAND <address@hidden>
> wrote:
>> Hi,
>>
>> ----
>>
>> I wonder if the internals of tinycc can easily supports basic
>> optimization passes. The idea is not to compete with gcc and its
>> hundred of passes, but my guess is that very few optimization
>> passes would be required to give a significant performance boost
>> to generated code. Just need to select the "right" ones...
>
> In my opinion, tinycc can remain without optimizations because it is
> not one of the compiler design goals.
> However there is one optimization that's more like a feature these
> days: dead code elimination.
> There are quite a few programs that completely rely on that and when
> compiled with tcc plainly fail with a 'undefined symbol' error for
> functions that are actually unused.
>
> It would be really nice to have some compiler switch (if not
> integrated) that enable this functionality.
>
> Vittorio
>

What kind of dead code? If you're talking about getting rid of ifs,
whiles, etc., that you can theoretically know at compile-time will
never be used, then they fall into two categories:
1) those that are constants entirely within the argument to the
conditional ( e.g. if( 0 ), and at a higher level if( a / a > 1 ) ),
and
2) those that are constrained to a range of values within the
conditional that will always evaluate to false, but are not strictly
constants.

Category 1, and especially it's first sub-case, are relatively easy to
deal with, and should be possible to optimize out of TCC within the
current framework. Subcase 2 is a little more complicated, because you
need to use elimination or similar to determine that one or more
things are actually just a distraction within the expression, and
theoretically shouldn't have any effect; however, in the real
bit-limited world, this can technically have an effect by interfering
with floating point accuracy calculations, so it should probably be
placed under a higher-level optimization flag.

Category 2 requires a more in-depth analysis, which is, in turn,
relevant when inlining functions from other compilation contexts as
well. Thus, I'd say that both because of it's greater complexity, and
because of it's utility when operating on the output of other
compilation stages, treatment for category 2 should be kept separate
from TCC proper.


> Date: Mon, 23 Sep 2013 17:05:35 +0200
> From: Vittorio Giovara <address@hidden>
> To: "Thomas Preud'homme" <address@hidden>
> Cc: address@hidden
> Subject: Re: [Tinycc-devel] inline assembly and optimization passes
> Message-ID:
>       <address@hidden>
> Content-Type: text/plain; charset=UTF-8
>
> On Mon, Sep 23, 2013 at 3:45 PM, Thomas Preud'homme <address@hidden>
> wrote:
>> Le lundi 23 septembre 2013 14:31:04 Vittorio Giovara a ?crit :
>>>
>>> In my opinion, tinycc can remain without optimizations because it is
>>> not one of the compiler design goals.
>>> However there is one optimization that's more like a feature these
>>> days: dead code elimination.
>>> There are quite a few programs that completely rely on that and when
>>> compiled with tcc plainly fail with a 'undefined symbol' error for
>>> functions that are actually unused.
>>>
>>> It would be really nice to have some compiler switch (if not
>>> integrated) that enable this functionality.
>>
>> Patches are welcome :)
>
> Umh, why not, can you give me a few pointers?
> Never touched compiler code so in depth, I'll need some hand-holding ;)
>
> Vittorio
>

If, on the other hand, you're talking about dead code elimination in
the sense of getting rid of functions that aren't used, then see the
following. This interplays with getting rid of similar code inside of
functions, but is easier in some ways.

Try looking here:
https://lists.nongnu.org/archive/html/tinycc-devel/2012-10/msg00044.html

The gcc compiler & linker flags mentioned there are directly relevant
to this, and basically describe the relevant operations: each function
and variable goes into a separate section within the object file (or,
in the case of TCC, sometimes just in memory), and either all of the
sections get stored into a library file, or only the ones actually
used get stored into an object or executable file. So, multi-step
process, but the end result is definitely useful.

AFTER that gets done you can worry about invoking the optimization
with a single flag, since those capabilities are just as useful by
themselves as they are when grouped together.

Note: I had actually thought that I read somewhere that TCC already
had this capability, but I didn't see it pop up anywhere when I
Googled.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]