Comments (5)
in practice we've been using the cfg!(feature = "optimize_for_size")
macro a bunch, which would rely on the optimizer evaluating and simplifying boolean conditions and then removing branches or blocks. I suspect in practice this is reliable enough. Certainly on small examples in godbolt this seems to work fine.
More generally, the point of this flag is really --release
mode. The size of a debug binary is just not representative at all. Especially on embedded, --release
is effectively standard: you don't want to wait for your debug binary to be pushed through a wire to your device. Because optimization passes in general don't really give guarantees I think it's fine that the optimizer may miss some opportunities in a debug build.
I say that in part because using proper conditional compilation would make the code harder to maintain, to the point where we may require completely separate functions for when the flag is enabled or not. We've been trying to prevent completely separate implementations from happening so far: that won't always work but when we can I think the result is better.
from rust.
Small aside, but do you think that code using optimize_for_size
should be always optimized for size, or only in release mode? Since a lot of the submitted PRs use cfg!(feature = "optimize_for_size")
to test, and I'm not sure that dead code removal will always work in these cases without optimizations enabled.
Obviously, to get the best benefits, you're going to want optimizations anyway, but I'm thinking that we probably do want to ensure that code actually isn't compiled in all cases using conditional compilation, rather than just conditions. This also might help building on memory-constrained environments since the code won't have to be kept in memory before it's removed.
I also think that longer-term, there should be an easier flag to enable this feature that also takes into account optimization options (making sure loops aren't unrolled, etc.) but at least for now, while it's just a Cargo feature, it makes sense to at least figure out what cases we should optimize for.
from rust.
I would be extremely surprised if any cfg-ed out code survived even in debug mode without optimizations. Even something like this:
fn main() {
#[cfg(feature = "foo")]
println!("hellorust");
}
Doesn't contain the hellorust
string in the final binary in a debug build when the feature is disabled.
from rust.
I would be extremely surprised if any cfg-ed out code survived even in debug mode without optimizations. Even something like this:
fn main() { #[cfg(feature = "foo")] println!("hellorust"); }Doesn't contain the
hellorust
string in the final binary in a debug build when the feature is disabled.
Right, note that this is different from:
fn main() {
if cfg!(feature = "foo") {
println!("hellorust");
}
}
since #[cfg(...)]
will prevent the code from even compiling, whereas this will compile the code but leave it inside a dead branch under if false
.
I say that in part because using proper conditional compilation would make the code harder to maintain, to the point where we may require completely separate functions for when the flag is enabled or not. We've been trying to prevent completely separate implementations from happening so far: that won't always work but when we can I think the result is better.
I agree here, mostly just wanted to ask because options do exist (like the currently unstable cfg_match
macro). And while you might not explicitly push debug code to a device, you might run tests on it off the device in debug mode, and it's important to ensure that these tests are accurate. I can imagine also wanting to compare generated assembly between debug and release mode to see what optimisations are done, without having the non-size-optimised code getting in the way.
Basically agree with the current implementation, but think it's important to properly clarify so folks are aware of the best way to implement things.
from rust.
Ah, sorry, I didn't realize that with cfg!
it is different. Well, I would be also extremely surprised if if false
survived even in debug mode 😆 But happy to see a counterexample.
from rust.
Related Issues (20)
- Error code E0116 causes high volume of incorrect compiler errors HOT 1
- ICE when specific compilation optimization passes are enabled/disabled HOT 4
- compiletest: technically potential false positives for filecheck annotations HOT 2
- Missed optimization when checking slice index greater than accessed slice index HOT 3
- `extern "rust-cold" fn`s should not trigger `improper_ctypes` lint
- `feature(effects)` lazily evaluates whether traits are const HOT 1
- internal error: relating different kinds: `jni::objects::JObject<'?14> '?1` HOT 3
- `addr_of!` a `static mut` should not require `unsafe` HOT 11
- Decide for precise capturing: `impl use<..> Trait` vs `use<..> impl Trait`
- ICE: mir_const_qualif: `index out of bounds: the len is 0 but the index is 0`
- ICE: type_of_opaque: `unexpected bound ty in binder: 0` HOT 1
- ICE: `expected type differs from actual type` HOT 2
- ICE: `could not resolve DefId `
- False compile error on associated type bounds HOT 1
- ICE: `no successor` HOT 2
- ICE: `TyKind::CVarArgs` should have been handled elsewhere HOT 5
- ICE when compiling for `x86_64-pc-windows-gnu` when passing a ZST using the `"sysv64"` ABI HOT 1
- ICE in OnDiskCache decode_tagged for TAG_FILE_FOOTER HOT 1
- [WASI] Consistency Issue with io::ErrorKind in wasm32-wasip1-threads HOT 1
- Duplicate argument names allowed in extern function declarations HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust.