Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small structs should be passed in registers #6612

Closed
huonw opened this issue May 19, 2013 · 3 comments
Closed

Small structs should be passed in registers #6612

huonw opened this issue May 19, 2013 · 3 comments

Comments

@huonw
Copy link
Member

huonw commented May 19, 2013

In the following code, there is an extra layer of indirection in foo in the final code.

pub struct IString(uint);
impl Eq for IString {
    fn eq(&self, other: &IString) -> bool { **self == **other }
    fn ne(&self, other: &IString) -> bool { **self != **other }
}

pub fn foo(a: IString, b: IString) -> bool { a==b }
pub fn bar(a: uint, b: uint) -> bool { a==b }

Compiling with -O -S generates the following (trimmed to the relevant parts):

_ZN3foo17_4341c964988316ba3_00E:
    movq    (%rdx), %rax
    cmpq    (%rcx), %rax
    sete    %al
    popq    %rbp
    ret

_ZN3bar16_df80e259bc1a8923_00E:
    cmpq    %rcx, %rdx
    sete    %al
    popq    %rbp
    ret

i.e. the IStrings are passed as pointers, not directly in registers.

(I'm on x64 linux.)

@cscott
Copy link

cscott commented May 19, 2013

Note that the extra indirection is not present in the C++ equivalent (when compiled with -O9 for inlining):

class IString {
public:
    int operator==(const IString& other);
private:
    int id;
};
int IString::operator==(const IString& other) {
    return id == other.id;
}

int foo(IString a, IString b) { return a==b; }

Not sure that's useful, just another data point.

Also: the extra indirection also happens when declaring IString as struct IString { id: uint } -- when this bug is fixed, it would be nice if 1-element structs are optimized as well as newtypes.

@cscott
Copy link

cscott commented May 19, 2013

(This bug might also be renamed, "small structs should be passed in registers"?)

@nikomatsakis
Copy link
Contributor

Yes, the reason is that our predicate "type_is_immediate" just considers all structs to be non-immediate, which is an oversimplification.

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 a pull request may close this issue.

3 participants