This patch implements elevating instructions across basic blocks that can help in better constant propagation. If there are values that are set to different constants in different blocks of an if-else statement, then elevating the dependent instructions to those blocks individually can help in constant propagation through the dependent instructions. In the test case that has been added, it results in elimination of a few computations via constant folding.
Details
Diff Detail
Event Timeline
Hm, why i'm the reviewer here?
That being said, is "elevation" == "hoisting" here?
That might be a better, more common name..
Thanks for the patch! I plan to have a closer look in the next few days.
In the meantime, could you run clang-format on your patch and update it?
Also, do you have any benchmark results for the new pass or any statistics on how often this hoisting is applied for larger programs (you could use LLVM's Statistic infrastructure http://llvm.org/docs/ProgrammersManual.html#the-statistic-class-stats-option)?
Cheers,
Florian
Sorry, I somehow got the impression that you were also looking after the regression test framework and hence thought that you should review the test case part of it.
That being said, is "elevation" == "hoisting" here?
That might be a better, more common name..
Yes, it actually is so. But since there was already a pass by that name, I thought I'd name mine differently so as not to confuse one with the other. Any suggestions to rename the new pass is most welcome.
Thanks Florian for agreeing to review the patch.
In the meantime, could you run clang-format on your patch and update it?
Yes, I will do so. There are a few lines of code that were added in the last minute by another engineer and I think that caused the divergence from the standards.
Also, do you have any benchmark results for the new pass or any statistics on how often this hoisting is applied for larger programs (you could use LLVM's Statistic infrastructure http://llvm.org/docs/ProgrammersManual.html#the-statistic-class-stats-option)?
I know that there is a piece of code in an industry benchmark that displays this kind of a pattern. In fact, the test case is modelled on that piece of code by changing the structure so as to avoid IP conflicts.
I will nevertheless try the LLVM's Statistic Infrastructure to see if I can get more instances.
Thanks and regards
Ayonam
It is usually best to add the people who last worked on the newly changed code
(git diff --name-only --cached | xargs -n 1 git blame --porcelain | grep "^author " | sort | uniq -c | sort -nr | head -10),
(maybe change --cached to upstream/master..HEAD) and the code owners. (i'm neither here)
That being said, is "elevation" == "hoisting" here?
That might be a better, more common name..Yes, it actually is so. But since there was already a pass by that name, I thought I'd name mine differently so as not to confuse one with the other. Any suggestions to rename the new pass is most welcome.
I would personally think one wouldn't want to end up with dozens of similar passes doing essentially the same thing, but just slightly differently.
Have you looked at the existing pass(es)? How are they different from this code? Perhaps it would be best to extend the existing passes?
Thanks for this tip. I will follow the protocol henceforth.
Yes, it actually is so. But since there was already a pass by that name, I thought I'd name mine differently so as not to confuse one with the other. Any suggestions to rename the new pass is most welcome.
I would personally think one wouldn't want to end up with dozens of similar passes doing essentially the same thing, but just slightly differently.
Have you looked at the existing pass(es)? How are they different from this code? Perhaps it would be best to extend the existing passes?
Yes, I too am of the same opinion. However, the other two passes that hoist code are ConstantHoisting and GVNHoisting. While the former hoists constants the latter hoists expressions from branches to the common dominator. What the Elevate pass does is to hoist expressions from a join block to its predecessors if the expressions can be constant evaluated. (In effect, it does the reverse of what the Sink pass does - to sink expressions into the join block from its predecessors).
I feel that this is a different kind of analysis than the ones that are already being done for the other two hoisting passes and hence it is better if we have a separate pass for this. We might later want to coalesce all the code hoisting passes into one single pass (like we have in SimplifyCFGPass), but I would not like to venture into it for now.
All that is a very good point, and i think it even reinforces my previous point.
I think it would be best to be consistent, and call this InstructionHoisting.
I feel that this is a different kind of analysis than the ones that are already being done for the other two hoisting passes and hence it is better if we have a separate pass for this. We might later want to coalesce all the code hoisting passes into one single pass (like we have in SimplifyCFGPass), but I would not like to venture into it for now.
Yes.
Point taken. I will rename the pass as InstructionHoisting. Once all the other review comments are in, I'll make this change as part of all the other changes that would come with the review comments.
Please include a few simpler testcases, so it's more obvious what the pass actually does. As far as I can tell, this is similar to InstCombiner::foldOpIntoPhi, but it's a lot more aggressive?
It looks like this increases codesize, in general; do we need some limit to prevent codesize from exploding in general? Should that limit depend on optsize?
test/Transforms/Elevate/elevate-if-else.ll | ||
---|---|---|
1 | Please don't use -O3 in opt testcases. |
I feel like pointing out that a "separate IR hoisting pass" has been brought up several times in previous reviews, as the means to potentially drop some stuff out of instcombine e.g.
It looks like this increases codesize, in general; do we need some limit to prevent codesize from exploding in general? Should that limit depend on optsize?
Please don't use -O3 in opt testcases.