How to make closure inline?

I have modify() and modify_field() functions implemented to manipulate cpu registers as follows:

#[inline]
pub fn modify<F: FnOnce($t) -> $t>(f: F) {
    write(f(read()));
}

#[inline]
pub fn modify_field(field_value: RegisterFieldValue<$t>) {
    let m = field_value.field().mask();
    let v = field_value.raw_value();
    modify(|r| (r & !m) | v);
}

However, this code does not get inlined and in disassembly I get function call:

...
str	x30, [sp, #-16]!
// lots of stuff that gets inlined
mov	w0, #0x1                   	// #1
mov	w1, wzr
mov	w2, #0x1                   	// #1
bl	label
...
label:
lsl	x8, x2, x1
mrs	x9, sctlr_el1
bic	x9, x9, x0
orr	x8, x9, x8
msr	sctlr_el1, x8
ret

How can I force it to be inlined in the main routine? Also, it would be great if someone could explain at a lower level why does it behave like this? Thanks in advance for your help

1 Like

The #[inline] attribute is a hint to the compiler to include metadata about a function so it can be inlined when compiling later crates. It doesn't force every call to modify() to be inlined, for that you can use #[inline(always)].

Keep in mind that overriding the optimiser's decision to inline with #[inline(always)] is often warned against because it can sometimes actually decrease performance.

(link to the #[inline] section in The Rust Reference)

Also, it's worth asking if you've compiled with cargo build --release? Debug builds won't normally get optimisations like inlining.

1 Like

yes, I build as --release. Also, after upgrading rust nightly from 1.42 to 1.45 I started getting an error when try to use -C lto=yes:

error: options `-C bitcode-in-rlib=no` and `-C lto` are incompatible

But I didn't yet tried to figure out what is bitcode-in-rlib option doing and how they correlate

1 Like

I'm guessing you're using nightly? If so, I'd check the issue tracker and create a ticket if there isn't one already.

I'd say bitcode-in-rlib is referring to that #[inline] "metadata" I was talking about. If we wanted to let users inline foo() in crate bar, we'd compile foo's body to bitcode and embed it in libbar.rlib so crates depending on bar can use it.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.