-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Condensing codegen output size #108
Comments
Quick note on something to research more in the future: I'm carooming around the (psuedo-)assembler output of For example: in looking at this output on a schema-schema run, I see a None of which I really expected to see here. This method being autogenerated, sure. I was hoping to see it be mostly inlined, and then mostly stripped away to become relatively compact, though... this is one of the statically ( These observations are made from go1.15.1 and should probably be verified again on a newer compiler version. |
Let's talk about the codegen output size.
Codegen is a useful tool. However, the lighter its requirements, the more useful and widely usable it becomes. Output size, if it grows out of hand, can limit the usability of codegen systems. So, we should keep an eye on output size, and try to minimize it where possible.
what is output size, what does it affect, and how do we prioritize it?
Output size can refer to one of two things:
The generated source size can affect a couple of things:
Output size is not our only priority of course: there are a number of priorities we balance in the design of codegen. A HACKME_tradeoffs document in the codegen directory has a nice enumeration of these values (and that document also talks about which ones have been prioritized).
I suspect we're going to find that in this implementation, we mostly care about generated source size, and mostly for its UX reasons. (This implementation is meant to be very featureful; if someone has a hard constraint on assembly output size, it's likely they either won't use codegen at all (schema systems do have runtime implementations too!) or will use a different codegen implementation entirely that was designed with a maximum priority on assembly size[‡].) But we can still try to minimize all dimensions of output size.
There's probably lots of stuff we can do to improve those two traits, and much of it which won't trade down on other values (such as speed) as long as we implement it well. But... what, exactly?
how can we measure this?
Before we go on to ideas for improvements, let's talk about how to measure this.
Total size is fairly easy:
go build -o
, look at the output file size. (This is arguably an approximation, but probably a survivable one. We should probably primarily track linux-amd64 just for consistency; beyond that, as far as I know, I'm willing to just hope other architectures won't have orders-of-mag different results.)Figuring out where to actually target for improvements: harder:
-gcflags -S
output, separate by function and type name, and do some simple counting of instruction count. (Does tooling like this exist already? Or are there easier ways to hook for this kind of info?)I'd suggest we might use the schema-schema as a corpus for these tests. Other cases and some reduced cases will also be good for study. The schema-schema provides a good holistic example for a large synthesized real system.
ideas for improvements
Some things that come to mind as very likely to produce improvements:
ma.state
andla.state
in assemblers are very redundant right now. Extracting them to helper methods that take params of pointers to the relevant state might be possible and should reduce GSLOC significantly.valueFinishTidy
helper function that's type-specific and really ought to be concrete for inlining/performance reasons, and that'll be tricky.na.m
switches. Assembler state transitions based on the 'maybe' state are very redundant right now.ma.state
swtich extraction. (Sometimes thena.m
switches return ErrWrongKind, which contains more specific info, and might complicate efficient extraction.)AssignNode
bodies have very duplicated output that should be easy to extract. Especially the non-type-specific fallback paths.Node
interfaces anyway, so extracting it is trivial and should have no performance hit.AssignNull
bodies might be in a similar realm asAssignNode
: fairly duplicated bodies.na.m
switches".)Node
andNodeAssembler
interfaces, but are just stubs that emit a constant ErrWrongKind, are very unfortunate and definitely a large weight.This is a non-scientific list of what's come to mind first as I've scrolled around in some output. It's not an exclusive list; it's very likely there's other ideas that would also make great improvements.
footnotes
[‡] - It does occur to me that we may be approaching the point where it will be a good idea to pull this codegen system out into its own repo, with its own issue tracker, yes. We have a codegen system which has been incubated in this core repo; it is not intended to be the only codegen system ever: competing implementations will be very welcome, especially those with different priorities. I'm not sure if today's the day to bite that bullet, but it's getting closer.
The text was updated successfully, but these errors were encountered: