Different range metadata can lead to different optimizations in later
passes, possibly breaking the semantics of the merged function. So range
metadata must be taken into consideration when comparing Load
instructions.
Details
- Reviewers
dyatkovskiy
Diff Detail
Event Timeline
Hi Bjorn,
You have found really interesting point :-)
For this changes set, please, read inline comments.
In general. We can merge such cases (and it's good to merge them), but we also have to merge metadata.
Two loads:
1.: %0 = load i8* %check_place, !range !0
2.: %0 = load i8* %check_place, !range !1
With metadata:
!0 = metadata !{i8 0, i8 2}
!1 = metadata !{i8 5, i8 7}
Could be merged into:
%0 = load i8* %check_place, !range !0
With metadata:
!0 = metadata !{i8 0, i8 2, i8 5, i8 7}
I think you could do this check "MergeFunctions::insert": if destination or source function contains load with "range" - extend 'range' metadata with new values.
Could you provide such patch after this one?
test/Transforms/MergeFunc/ranges.ll | ||
---|---|---|
13 | This is valid check, but IMHO it's a bit fragile. | |
23 | The same. I'd prefer to see that whole function remains unchanged. |
I wasn't sure about expanding the range to be more generic, since I thought that that might defeat some optimizations in other passes. I'll update the patch later today.
Updated the patch to merge the range metadata for the loads instead of not
merging such functions at all. I found mergeTwoFunctions() to be a better place
than insert() to call the new method that handles the merge of the range
metadata. I hope this is what you had in mind.
Hi Bjorn (sorry I don't have o-umlaut on my keyboard :-) ),
Yes. This is proper way.
Only critical thing is: we have to avoid extra function body scanning. So in this context, try to introduce the way of noticing such loads on cmpOperation stage. So we could avoid rescan whole function again while merging. It possible by associating structure for each function, that would keep usefull information we collect while scanning. You can do that by introducing new field in ComparableFunction, and store anything suspicious you find about 'load' insts :-)
Then on merging stage you won't scan functions again, but just check ComparableFunction fields.
But...
I hope, we will replace ComparableFunction soon with similar structure ( during O(N*log(N) optimization). So that's why I'd propose to commit it just as fix for now (so you had to fix your tests only in first patch version).
And then it would be really good, if you proceed to work on this subject, so we could create good optimization for 'ranges' metadata.
Thanks for working on it!
Hi Stepan,
my bad, I just always forget that the hashmap contains ComparableFunctions, not just Functions, so I didn't see where to put the list of load instructions.
Just to make sure that I didn't misunderstand you and implement the wrong thing, you want me to go back to the initial patch that removes the merge of such function and fix the tests to ensure that the whole body is retained. And then later once you reworked ComparableFunction, I could go and implement the merge of ranges in a proper way, right?
Thanks!
Björn
PS: No worries about the o-umlaut, I'm used to losing that on the internet ;-)
Yes. Exactly ) For now, I propose to come back to initial patch; make sure tests has been fixed as I asked you in inline comments and, I think we apply it (Nick didn't object about it yesterday).
Then, after we replace ComparableFunction with new structure, you could introduce 'range' metadata merging.
Thanks for working on it!
Reverted back to the patch the avoids the merge in case of different range
metadata and adjusted the tests to check for the whole function body remaining
unchanged.
Hi Nick,
Can I commit it for Björn?
Thanks!
-Stepan
Björn Steinbrink wrote:
Hi Stepan,
yes, I need someone to commit this for me.
This is valid check, but IMHO it's a bit fragile.
Could you check full function contents here. It has only 5 lines :-)