Skip to content

Instantly share code, notes, and snippets.

@arielb1
Created September 23, 2016 22:27
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save arielb1/77f989e8c6f2ee8d9e2e0a4cb22a0bf0 to your computer and use it in GitHub Desktop.
#[repr(result)]
enum Result<O,E> {
Ok(O),
Err(E)
}
fn foo() -> Result<Dest, Error> {
let result = make_result();
match result.set_up() {
Ok(()) => {},
Err(e) => return Err(e)
}
Ok(result)
}
Optimized MIR for `foo`:
ret_Ok : Dest
ret_Err : Error
tmp0: &Dest
start:
ret_Ok = call make_result(), [panic -> ...]
tmp0 = &ret_Ok
(Ok -> (), Err -> ret@Err) = call set_up(tmp), [Ok -> on_ok, Err -> on_err, panic -> ...]
on_ok:
ret_Discr = Ok
goto exit
on_err:
ret_Discr = Err
drop ret_Ok ; requires ret@Ok to not be corrupted
goto exit
exit:
return
Unoptimized MIR for `let x = foo();`
x_Err : Error
x_Ok : Dest
x : Result<Ok, Error>
start:
(Ok -> x_Ok, Err -> x_Err) = call foo() [Ok -> on_ok, Err -> on_err, panic -> ...]
on_ok:
(x as Ok) = x_Ok
x.<discr> = Ok
goto succ
on_err:
(x as Err) = x_Err
x.<discr> = Err
goto succ
succ:
...
Destination propagation should be able to eliminate 1 of the copies. If this is followed by a `match`, branch unswitching
should be able to get us the optimal code.
ABI: there are several options. need to decide how to pick one in each case (ABI-dependant)
1) Return the discriminant, use 2 out ptrs
2) Return the result directly (if it fits in %rax:%rdx, keep in mind that you can encode Result<usize, TraitObject>
using alignment).
3) Return an Option<O>/Option<E>, use an out ptr for the other one.
@arielb1
Copy link
Author

arielb1 commented Sep 23, 2016

At the ABI label, we could allow the 2 out-pointers to overlap, but that might require quite a bit of optimizer complexity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment