> Date: Mon, 23 Sep 2013 14:22:16 +0200 > From: Sylvain BERTRAND <[email protected]> > To: [email protected] > Subject: Re: [Tinycc-devel] inline assembly and optimization passes > Message-ID: <20130923122216.GB754@freedom> > 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 <[email protected]> > To: [email protected] > Subject: Re: [Tinycc-devel] inline assembly and optimization passes > Message-ID: <20130923122940.GC754@freedom> > 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 <[email protected]> > To: [email protected] > Subject: Re: [Tinycc-devel] inline assembly and optimization passes > Message-ID: > <cablwns-fasftcxjxyfqes8t1w8khg+c52e7p11zfs3b_iry...@mail.gmail.com> > Content-Type: text/plain; charset=UTF-8 > > On Fri, Sep 20, 2013 at 3:08 AM, Sylvain BERTRAND <[email protected]> > 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 <[email protected]> > To: "Thomas Preud'homme" <[email protected]> > Cc: [email protected] > Subject: Re: [Tinycc-devel] inline assembly and optimization passes > Message-ID: > <cablwns_tiqyaww7blm2ioxcfpvwg+vymnaufjwqrk61vznm...@mail.gmail.com> > Content-Type: text/plain; charset=UTF-8 > > On Mon, Sep 23, 2013 at 3:45 PM, Thomas Preud'homme <[email protected]> > 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. _______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
