Skip to content

Conversation

@nnethercote
Copy link
Collaborator

It currently produces silly verbose code like this:

fn add(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    #[allow(unused_variables)]
    let needs_i128_emulation = false || self.is_i128(a) || self.is_i128(b);
    if needs_i128_emulation {
        let args_vec: Vec<&'ll Value> = <[_]>::into_vec(
            ::alloc::boxed::box_new([a, b]),
        );
        match "add" {
            "add" | "unchecked_uadd" | "unchecked_sadd" => {
                assert_eq!(args_vec.len(), 2);
                return self.emulate_i128_add(args_vec[0], args_vec[1]);
            }
            "sub" | "unchecked_usub" | "unchecked_ssub" => { ... }
            "mul" | "unchecked_umul" | "unchecked_smul" => { ... }
            "and" => { ... }
            ...
            _ => { self.cx.fatal(...); }
        }
    }
    unsafe { ... }
}

and relies on constant folding to eliminate most of the code.

This commit changes the macro to produce code like this:

fn add(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    if self.is_i128(a) || self.is_i128(b) {
        self.emulate_i128_add(a, b)
    } else {
        unsafe { ... }
    }

and float ops are even shorter, because they don't need a u128 check and are now done with a new, separate macro:

fn fadd(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    unsafe { ... }
}

The generated code is much shorter: cargo expand's length has reduced from 34,636 lines to 26,356 lines, a 24% reduction.

The original code is also a little shorter. arg_vecs is gone because it isn't needed. The asserts are gone because they were very low value. There is now a tiny bit of code duplication, but it's trivial and not worth trying to avoid.

It currently produces silly verbose code like this:
```
fn add(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    #[allow(unused_variables)]
    let needs_i128_emulation = false || self.is_i128(a) || self.is_i128(b);
    if needs_i128_emulation {
        let args_vec: Vec<&'ll Value> = <[_]>::into_vec(
            ::alloc::boxed::box_new([a, b]),
        );
        match "add" {
            "add" | "unchecked_uadd" | "unchecked_sadd" => {
                assert_eq!(args_vec.len(), 2);
                return self.emulate_i128_add(args_vec[0], args_vec[1]);
            }
            "sub" | "unchecked_usub" | "unchecked_ssub" => { ... }
            "mul" | "unchecked_umul" | "unchecked_smul" => { ... }
            "and" => { ... }
            ...
            _ => { self.cx.fatal(...); }
        }
    }
    unsafe { ... }
}
```
and relies on constant folding to eliminate most of the code.

This commit changes the macro to produce code like this:
```
fn add(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    if self.is_i128(a) || self.is_i128(b) {
        self.emulate_i128_add(a, b)
    } else {
        unsafe { ... }
    }
```
and float ops are even shorter, because they don't need a u128 check and
are now done with a new, separate macro:
```
fn fadd(&mut self, a: &'ll Value, b: &'ll Value) -> &'ll Value {
    unsafe { ... }
}
```

The generated code is much shorter: `cargo expand`'s length has reduced
from 34,636 lines to 26,356 lines, a 24% reduction.

The original code is also a little shorter. `arg_vecs` is gone because
it isn't needed. The asserts are gone because they were very low value.
There is now a tiny bit of code duplication, but it's trivial and not
worth trying to avoid.
@LegNeato LegNeato merged commit 51eca39 into Rust-GPU:main Sep 22, 2025
12 checks passed
@LegNeato
Copy link
Contributor

Awesome! 🍻

@nnethercote nnethercote deleted the improve-math_builder_methods branch September 22, 2025 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants