> So that was in response to the "if I were implementing a language > from scratch" bit, right?
yes > If I was doing that then I'd be looking at an application > language that would easily integrate with a systems language, > hence high-end features along with C compatibility. > > If I was going for a new systems language then I'd just take C, > modify the syntax for pointers & declarations, and maybe modify > the standard library. Presumably a smaller job than a > from-scratch language. I do not agree. I would go C- for system and application. I don't like my software stack to depend on tons of different languages (because at the end, it's what we get). >>> So you want to hook into the TCC parser itself? >> >> I said, if this has no obvious blockers, we could use fake targets >> that would be optimization passes. They would output C code. > > Yeah, I mostly paid attention to the fake-target bit, since > outputting IL/IC from that seemed like the easiest way into the > "standard route". I don't know what "this standard" route is, all I know is ouputing C code with fake targets to handle some optimization passes seems to be a good tradeoff to avoid a lot of kludge and to minimize impact on tcc internals. >> Regarding the unused code elimitation across compilation units, it >> involves probably the linker. Then the "trick" of the fake target >> may not be as easy. > > That depends, Eliminating unused functions & variables works like > that, but it only requires the ability to detect when you're in > the file-scope instead of a scope contained within a file, and > take that as a signal to place any additional variables or > functions into a new section. That and info on what those > sections need to import are all that you need, and all of that > should (at least presumably, it's been a while since I poked at > object file formats) be supported by your ordinary object file > format. Or, at least, your ordinary library file format. > > Once you have that, it's a matter of creating a linker mode that > will assign two bits (one for "needed", one for "supplied") in a > memory block to each of the sections, and starting a search from > your "root section" (probably the one containing the "main" or > equivalent function, but possibly a file declaring exports too). > Every time that you find a dependency, you ensure that it has > either it's "needed" or "supplied" bit set. Once you've finished > checking through every section that you ALREADY knew to check, > you output it, make a new list of sections to check (they'll be > the ones marked "needed" instead of "supplied"), switch all of > the "needed" sections to be only "supplied" instead, and start > the dependencies search again. You only stop once you run out of > sections that are "needed". > >> We may have to "annotate" the generated C code for the real target >> to insert the proper information in the object file for the >> linker. I bet that optimization pass would be kind of the last >> one. > > Unused function removal works as I stated above: you find a > starting point, find all of it's dependencies, write out the > starting point, and recursively check dependencies for new > dependencies, and write old dependencies out. > > Other forms of unused code removal either never leave the > compiler (e.g. removing if( 0 ) blocks), or should be left for a > later date (some things are more foundational than others). > >> - A compilation unit scoped dead/unused code removal fake target > > Let's worry about unused function removal first, since that > should be the fastest to implement, okay? Depending on details > that Grischka would know but I don't, we might need to build a > parse tree before we can eliminate unused code INSIDE of > functions, in which case the target will be a "parse tree" output > of SOME kind, regardless of whether it's assembly-ish, C-ish, or > something-else-ish. > > Also, by virtue of some of Grischka's comments below, I don't > think that just sticking the optimizations entirely inside a fake > target will be enough: we'll need to build a parse tree for > anything other than the minor stuff, in which case we might as > well have the fake target be the parse tree instead of making it > be the actual optimization. > >> - A C code annotation target which create a dependency tree of >> machine code sections for the linker to optimize out or not. > > Allowing individual sections to have their own dependencies will > do this perfectly fine. Allright, then a fake target to anotate C code which anotations will add extra info in generated elf object, seems a good path for dead code/unused code removal optimization passes, at file scope. Compilation unit scope passes can output C code without the need of anotations for the linker, could start from here. --- But, I'm more concerned with "variable aliasing" optimization passes. As I said before, my general "ground" experience tells me that a lot C code use many variables to get to the same data. (I use aliasing a lot to make my code more readable). And I was wondering how much of the registers/stack space dance we would be able to avoid with such passes. I feel it will give a significant performance boost. I may be wrong though. The goal would be to make tcc reasonably performant on C code in order to drop gcc (since c++ is now mandatory). -- Sylvain _______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
