rust-embedded / svd2rust

Generate Rust register maps (`struct`s) from SVD files
Apache License 2.0
674 stars 147 forks source link

no_mangle on DEVICE_PERIPHERALS prevents optimizing write away #833

Open bauen1 opened 3 months ago

bauen1 commented 3 months ago

For fun (and profit) I'm trying to reduce the .bss usage of a rust embedded program down to zero, relying only on the stack for memory.

Actually the only users of .bss apart from the stack are the singleton guards of the stm32l4r5::CorePeripherals and stm32l4r5::Peripherals structs.

And by replacing take with steal, since I'm sure that main will only be called "once", these should have been eliminated, however for some weird reason DEVICE_PERIPHERALS persisted.

The reason for that is outlined in the short snippet below:

// Type your code here, or load an example.
#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
    loop {}
}

// As of Rust 1.75, small functions are automatically
// marked as `#[inline]` so they will not show up in
// the output when compiling with optimisations. Use
// `#[no_mangle]` or `#[inline(never)]` to work around
// this issue.
// See https://github.com/compiler-explorer/compiler-explorer/issues/5939

// If you use `main()`, declare it as `pub` to see it in the output:
// pub fn main() { ... }

#[no_mangle]
static mut USED1: bool = false;

static mut USED2: bool = false;

#[inline(never)]
pub fn main() -> () {

  unsafe { USED1 = true };

  unsafe { USED2 = true };

  loop {

  }
}

[godbolt](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,selection:(endColumn:1,endLineNumber:21,positionColumn:1,positionLineNumber:21,selectionStartColumn:1,selectionStartLineNumber:21,startColumn:1,startLineNumber:21),source:'//+Type+your+code+here,+or+load+an+example.%0A%23!!%5Bno_std%5D%0A%23!!%5Bno_main%5D%0A%0Ause+core::panic::PanicInfo%3B%0A%0A%23%5Bpanic_handler%5D%0Afn+panic(_panic:+%26PanicInfo%3C!'_%3E)+-%3E+!!+%7B%0A++++loop+%7B%7D%0A%7D%0A%0A//+As+of+Rust+1.75,+small+functions+are+automatically%0A//+marked+as+%60%23%5Binline%5D%60+so+they+will+not+show+up+in%0A//+the+output+when+compiling+with+optimisations.+Use%0A//+%60%23%5Bno_mangle%5D%60+or+%60%23%5Binline(never)%5D%60+to+work+around%0A//+this+issue.%0A//+See+https://github.com/compiler-explorer/compiler-explorer/issues/5939%0A%0A//+If+you+use+%60main()%60,+declare+it+as+%60pub%60+to+see+it+in+the+output:%0A//+pub+fn+main()+%7B+...+%7D%0A%0A%23%5Bno_mangle%5D%0Astatic+mut+USED1:+bool+%3D+false%3B%0A%0Astatic+mut+USED2:+bool+%3D+false%3B%0A%0A%23%5Binline(never)%5D%0Apub+fn+main()+-%3E+()+%7B%0A%0A++unsafe+%7B+USED1+%3D+true+%7D%3B%0A%0A++unsafe+%7B+USED2+%3D+true+%7D%3B%0A%0A++loop+%7B%0A%0A++%7D%0A%7D'),l:'5',n:'0',o:'Rust+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:nightly,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,libs:!(),options:'-O+--codegen%3Dlto%3Dyes',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+rustc+nightly+(Editor+%231)',t:'0')),header:(),k:50,l:'4',m:52.41312741312741,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+12.0.0+(assertions)',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+rustc+nightly+(Compiler+%231)',t:'0')),l:'4',m:47.58687258687259,n:'0',o:'',s:0,t:'0')),k:50,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

Only USED1 appears in the output, USED2 is optimized away. Maybe you could also use no_mangle in the same way cortex-m does ? https://docs.rs/cortex-m/latest/src/cortex_m/peripheral/mod.rs.html#156-162

When using the steal method, LLVM is then actually smart enough to completely eliminate the variable that's written only once, like https://github.com/rust-embedded/svd2rust/issues/151#issuecomment-334947973 thought.