# Scope and goals of rust-lang/rust optimizations As a reminder, problem statement/goal of the meeting: > Most of rustc's optimizations are currently found in LLVM. However, there is a significant amount optimization code in rust-lang/rust as well, in the form of mir opts. To the extent that I can tell, there was never any overarching technical design for mir opts. The "real" discussion that I would like to have is this one: If we were to redesign rust-lang/rust optimizations from scratch today, what would they look like? Does the path we are on lead to a point that reasonably approximates that ideal? > > Unfortunately, having that discussion today would be extremely difficult, because we cannot answer the "how would we design..." question without knowing *what we are designing for.* The goal of this meeting is to have a discussion to inform the drafting of a policy on this last question. Specifically, I would like to come up with a list of "guardrails" - limitations on what kind of optimizations we are interested in having in rust-lang/rust - in addition to some guidelines on the cost/benefit analysis against which optimizations are evaluated. The hope is that this will suffice to be able to meaningfully have the "what would optimizations look like if they were designed from scratch today" conversation mentioned above. ### Guardrails Jakob thinks we should have #### Only one opsem As both Mir and LLVM have shown, coming up with a well-defined semantics for an IR - especially one that admits the optimizations we want - is hard. We should not do it twice. T-opsem is going to be picking some IR to use to define Rust semantics. Those are the semantics that should be used for rust-lang/rust optimizations. However, this does not mean opsem-IR is the only IR rustc can use. It is probably desirable to deviate from opsem-IR in some ways - that's fine, such deviations just need to be simple enough that they have an obvious and unambiguous interpretation in terms of the existing semantics. Mir already does this today by having different dialects, all of which might end up being different from opsem-IR. #### Consistent level of abstraction for codegen backends The interface to codegen backends currently has a level of abstraction that is (uncoincidentally) just right for generating LLVM IR. We should keep this level of abstraction the same. That does not mean the interface is stable, it just means that we shouldn't start directly emitting asm or expecting each backend to handle generator lowering. #### Target independence This is similar to the previous item but not quite the same - rust-lang/rust opts ought to be target independent. That doesn't mean opts can't look at type layouts, it just means that we shouldn't be implementing regalloc or inserting target specific intrinsics. It's worth noting that neither this document or this meeting is arguing in favor of a ban in rust-lang/rust on modifying the level of abstraction or doing more target dependant things. The argument is only that the engineering tradeoffs are against rust-lang/rust *changing these practices in the near future and for the purpose of enabling more optimizations.* ### Other discussion points in no particular order #### Can we have "minimum value added" requirements? Optimizations are hard to write, maintain, and review, especially if we want them to be correct (and maybe even useful). There's a natural temptation to say that we should only accept them if they meet some minimum bar for how "good" they are - "must yield 1% compile time improvements per 500 lines of code" or whatever. Obviously the point isn't to have strict requirements, but rather to think about whether we can/should reject PRs on the basis of "this might help a little bit, but it doesn't pull its own weight." I think it would probably really hard. Even if we wanted to do it, opts are typically designed to do one thing really well and often only pay off when combined. This means that when trying to apply this kind of reasoning to any individual contribution, the result is likely to have at least as much to do with what other optimizations are currently available in the repo as it has to do with the actual code being added. #### What about LLVM? One important component of this conversation that probably can't be ignored is this: What is T-compiler's long term strategy/attitude towards LLVM? Are we going to find ourselves in a situation regretting the hardness of our dependency on it? Powerful optimizations within rust-lang/rust are potentially a major step towards making other codegen backends much more likely to be viable for production uses. I don't really expect us to make any progress on this question today, but it at least seems worth keeping in mind. <details> <summary> Lang/Opsem side of things</summary> A final thing that may be worth pointing out is that - although we have also made some effort to avoid it - language decisions have been made in the past as a result of specific strenghts/weaknesses of LLVM. A concrete example here is that T-opsem is currently treating supporting certain LLVM constructs (eg `noalias`) as requirements. Not having to do that would certainly be nice. </details> ## Questions ### Unavoidabilty of doing *some* optimizations pnkfelix: My recent investigation into generator layout overheads has led me to believe that we cannot avoid doing some amount of mir-optimization. (This document seems like its largely written with that perspective in mind; I just figured it was worth pointing out.) The questions this raises: 1. Which optimizations are unavoidable, and 2. What can/should we do to make the implementations of those optimizations as readable+maintanable as possible. The first question (and thus the second as well) seems like one to which we cannot fully predict the answers. ### Benefits of MIR optimizations pnkfelix: When establishing the criteria for what MIR optimizations should be accepted, we need to consider both 1. impact on compile-times (aka execution time for rustc itself, because optimizing the MIR may bypass more expensive analyses in LLVM) and 2. impact on output object code quality. Namely, there are going to be cases where LLVM cannot do the optimization itself (generator layout stuff is my primary example here), and thus to optimize object code quality, you might have to be willing to potentially take a (presumably small) regression on compilation times.