-
-
Notifications
You must be signed in to change notification settings - Fork 613
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
Lower CmpExp between classes to __cmp call #9629
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -853,11 +853,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null) | |
{ | ||
// Rewrite (e1 op e2) as e2.opfunc(e1) | ||
result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s); | ||
// When reversing operands of comparison operators, | ||
// need to reverse the sense of the op | ||
if (pop) | ||
*pop = reverseRelation(e.op); | ||
} | ||
// When reversing operands of comparison operators, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this change necessary? Why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I belive it is: you only need to reverse the |
||
// need to reverse the sense of the op | ||
if (pop) | ||
*pop = reverseRelation(e.op); | ||
return; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class A | ||
{ | ||
int x; | ||
this(int a) { x = a; } | ||
|
||
alias opCmp = Object.opCmp; | ||
alias opCmp = my_cmp; | ||
|
||
final int my_cmp(A a) | ||
{ | ||
return x - a.x; | ||
} | ||
} | ||
|
||
void main() | ||
{ | ||
auto a1 = new A(1); | ||
auto a2 = new A(2); | ||
A a_null = null; | ||
assert(a1 > a_null); | ||
assert(a_null < a1); | ||
assert(!(a1 < a1)); | ||
assert(a1 < a2); | ||
assert(a2 > a1); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you also have to verify that the call is actually to Object.opCmp, as it can be redirected to other functions aswell, e.g.
The comparison currently results in a non-virtual call to my_cmp. Does the lowered template do the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lowered template doest the same. I don't think the lowering should change the current behaviour.
Why do you want the behaviour to be different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want observable changes, and AFAICT the actual call stays the same - that's good. But the template adds some additional checks that are not there so far. This might duplicate
null
checks in existing custom implementations ofopCmp
, or it might work differently. The spec doesn't seem to cover the comparison tonull
. I'm not against adding the checks, just saying they should be added to the spec (similar toopEquals
) if the change is deliberate.BTW: dmd is unable to inline the
__cmp
template, it can if it is written asreturn lhs is rhs ? 0 : lhs is null ? -1 : rhs is null ? 1 : lhs.opCmp(rhs);
. dmd doesn't eliminate unnecessary checks, though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change is deliberate. I’ll update the spec to mention the changes.
Hmm, rewritting it this way would make the code much harder to understand. Imho, we shouldn’t make the code harder to understand just so we improve dmd’s inlining. If this also affects ldc and gdc (haven’t checked yet) then we should modify the call.
I think the issue at hand is related to how dmd is able to inline such constructs. I think that should be a separate improvement done in dmd, as it will benefit other existing user code bases.