While scanning predecessors to find an available loaded value, if the predecessor has a single predecessor, we can continue scanning through the single predecessor.
Details
Diff Detail
Event Timeline
lib/Transforms/Scalar/JumpThreading.cpp | ||
---|---|---|
1005 | Why not just transform the single access above into the loop below? Why do you need both? | |
test/Transforms/JumpThreading/thread-loads.ll | ||
312 | Is this just the phi, or is there also a call to fn2(%l2)? If c1/c3 is false and c2 is true, then only fn2 is called, not fn3, which means the new cond3 block has to be only conditionalised via c1 not c2, as in the original IR. | |
326 | Isn't there just one hop here? %l2 -> %l1? I thought you were testing multiple predecessors. |
test/Transforms/JumpThreading/thread-loads.ll | ||
---|---|---|
312 | If c1/c3 is false and c2 is true, only fn2() will be called, so in the new cond2, it unconditionally branch to %end after calling fn2(). I added CHECKs for the branch to %end in cond2 and for the call to fn2(%l2) in cond2. When %c1 is false, it directly branch to %cond3 from entry. We have this CHECK in entry. So, we only branch to cond2 from cond1 by %c1 when c1/c3 is false. | |
326 | It's one hop from cond2 to entry, but cond2 -> cond1 -> entry is two hop. |
include/llvm/Analysis/Loads.h | ||
---|---|---|
89 | Can we use Optional<unsigned &> NumScannedInst here? |
include/llvm/Analysis/Loads.h | ||
---|---|---|
89 | Honestly I don't have much idea about the Optional<>, but it looks okay to use it here. However, I believe we can make a separate patch to consider using the Optional for other parameters, not just for this parameter. Please let me know if we have to use the Optional specifically in this parameter unlikely other parameters. |
include/llvm/Analysis/Loads.h | ||
---|---|---|
89 | I agree this sounds like something for a different patch. |
include/llvm/Analysis/Loads.h | ||
---|---|---|
89 | I agree with you guys. I was only looking at the new parameter and its usage and thought it's appropriate to use Optional<>. |
LGTM, thanks!
test/Transforms/JumpThreading/thread-loads.ll | ||
---|---|---|
326 | Right, now it makes more sense. Thanks! |
Why is the right answer here to improve jump threading and not PRE if you want to catch more "partially redundant" loads ?
Additionally, why is this necessary at all?
-gvn already takes care of both of your testcases.
llvm/trunk/lib/Analysis/Loads.cpp | ||
---|---|---|
316 ↗ | (On Diff #86809) | Scanned |
348 ↗ | (On Diff #86809) | Scanned |
349 ↗ | (On Diff #86809) | Scanned |
Also, for the record, all of these testcases are fully redundant loads.
they are all of the form
load if (...) { load }
This is a full redundancy. The initial load dominates the others, with nothing in between, and so they are fully redundant This is also why every pass we have that does any load elimination will already eliminate them.
A partially redundant load would be
if (a) load a else <nothing> load a
This load is partially redundant because it unnecessarily happens twice when we take the if(a)'s true branch
PRE will turn it into:
if (a) load a else load a result = phi(...)
As mentioned, GVN already does this transformation, so i'd really like to see a testcase where you doing this in jump threading enables an optimization we don't get already.
Can we use
here?