-
-
Notifications
You must be signed in to change notification settings - Fork 610
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
SROA: allow reconstruction of original aggregate with OPpair #6192
Conversation
5a84458 to
34fd345
Compare
|
LGTM - @MartinNowak wanna take a look? |
|
The FreeBSD 32 failure appears to be a heisenbug timeout. |
| @@ -88,16 +144,30 @@ static void sliceStructs_Replace(SymInfo *sia, elem *e) | |||
| //elem_print(e); | |||
| if (si >= 0 && sia[si].canSlice) | |||
| { | |||
| if (e->Eoffset == 0) // the first slice of the symbol is the same as the original | |||
| if (tysize(e->Ety) == 2 * REGSIZE) | |||
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.
Shouldn't you use usePair here?
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.
No, because not every use of the symbol will be 2*REGSIZE, despite usePair.
| if (!sia[si].accessSlice) | ||
| { | ||
| // If never did access it as a slice, don't slice | ||
| sia[si].canSlice = false; |
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.
Using it this way, doSlice instead of canSlice would better a description.
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 prefer can to be answering a question, and do to actually perform the work.
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.
Well, but here it could be sliced but shouldn't be done (b/c it's not used). Anyhow...
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.
isSliced ?
| sold->Stype->Tcount++; | ||
| snew->Stype = type_fake(TYnptr); | ||
| snew->Stype = type_fake(sia[si].ty1); |
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.
Aren't ty0 and ty1 the types of the fields? Why would you use a different type for the replacement symbol?
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.
Because they may be different types. a.ptr and a.length are different, for example.
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 confusing part here was that you're reusing sold for the new replacement symbol.
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.
just changing its type
|
|
||
| /* OPpair cannot handle XMM registers, cdpair() and fixresult() | ||
| */ | ||
| if (tyfloating(sia[si].ty0) || tyfloating(sia[si].ty1)) |
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.
This branch is a bit confusing b/c it seems to rely on the fact that the else if branch below was run for e->E1 and e->E2 beforehand.
Would be simpler to understand if you changed the order of the branches and added a small comment.
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.
Also notice that the condition at https://github.com/dlang/dmd/pull/6192/files#diff-22b8e2c888085072a0c7f94f80991c4eR81 does the same thing as the test here.
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.
No, it doesn't rely on that at all. E1 and E2 could not have been run beforehand for OPvar, because they don't exist for OPvar elems.
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.
So what's really happening here is that a symbol could be used as fat value, but also could get sliced for field access.
Therefor you have to mutually account for the other case.
I'll comment that to make it understandable in the code.
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.
It does account for the other case. I don't really know what you want to say there - the code is there in the other case.
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.
Yes, it just wasn't obvious how the two branches relate to each other.
They are independent b/c different parts of the expression tree can access the same symbol, one as slice, one as fat value using OPpair.
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.
Could have been simpler to later (during slicing) check for usePair && accessSlice && (tyfloating(ty0) || tyfloating(ty1)) instead of mutating canSlice here. But I guess your XMM OPpair work obsoletes this.
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 need to do OPpair improvements anyway, and am doing so, but I wanted to keep this PR focussed. Once OPpair is working properly, I'll come back and remove this hack.
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.
Thanks, just wasted 3 days debugging a memory corruption based on this :/.
Wasn't too well put here, but as mentioned ty0 and ty1 are still uninitialized if access as fat value happens before any access to a sliced field.
| sia[si].ty0 = tybasic(e->Ety); | ||
| else | ||
| sia[si].ty1 = tybasic(e->Ety); | ||
| if (sia[si].usePair && (tyfloating(sia[si].ty0) || tyfloating(sia[si].ty1))) |
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.
This is weird, when usePair gets set above (if (sz == 2 * REGSIZE)), it expects ty0/1 to already be set. But here where the ty0/1 assignment is done, you're checking for usePair to be set earlier.
How can both cases be valid?
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.
ty0/1 are defaulted to TYnptr. They are set to correct values when a slice case is encountered. If no slice cases are encountered, then slicing is not done.
|
Auto-merge toggled on |
|
Added the comment |
|
Thanks, @MartinNowak |
SROA slices an aggregate into individual variables. Hence, operations needing the original aggregate are disallowed. This PR improves that by allowing loads of the original aggregate by reconstituting it out of the slices using
OPpair.The net result is more cases of SROA can be performed.