[PATCH] Extend EarlyCSE to handle basic cases from JumpThreading and CVP
Philip Reames
listmail at philipreames.com
Tue May 19 09:37:36 PDT 2015
On 05/19/2015 08:50 AM, Daniel Berlin wrote:
>> ================
>> Comment at: lib/Transforms/Scalar/EarlyCSE.cpp:471
>> @@ +470,3 @@
>> + if (BasicBlock *Pred = BB->getSinglePredecessor())
>> + // TODO: handle switch with case value as well
>> + if (auto *BI = dyn_cast<BranchInst>(Pred->getTerminator()))
>> ----------------
>> Even GVN does not handle switch with case value, even when it can determine the case value as a constant. It is not as simple as one would thing because it's not about dominance, but control dependence.
>>
>>
>> (and DT->dominates will fail the single edge assertion in those cases, even though it's a reasonable thing to test)
>>
>>
>
> Just to explain this:
>
> getSinglePredecessor returns true if all edges lead to the same block.
> Thus, a switch with multiple edges to the same block will return a
> block to getSinglePredecessor.
Er, I believe this is incorrect. The behavior you're describing is true
of getUniquePredecessor, but not getSinglePredecessor. This is why I'm
explicitly using the getSinglePredecessor version.
>
> Dominates(Edge, anything) asserts isSingleEdge(Edge).
> isSingleEdge asserts that the edge is singular in the sense that
> "multiple edges do not exist from block EdgeStart to block EdgeEnd".
> Thus, getSinglePredecessor will happily give you blocks from switch
> statements that fail this test (any switch with case statements
> leading to the same block), such that you can't test dominance on
> them.
For getUniquePredecessor, I believe the problem you describe is relevant
for branches too. Nothing says a conditional branch can't have both
it's destinations going to the same block. The optimizer would likely
fold such thing away quickly, but it is legal IR.
>
> GVN goes to the trouble of tracking how many edges lead to a target
> block, and only propagates equalities if a single edge reaches a given
> target block to avoid this assert.
>
> This is true *even if* it could prove that only one of the edges to
> the target block is reachable (because it would still hit the
> isSingleEdge assert).
If it can prove this, it should be breaking the other edges. Once
that's done, the assert holds. I don't see the problem?
>
> At some point, that assert should simply be removed (or such was the
> conclusion of the folks who added it when i asked them, since the
> justification given for it makes no sense),
I'm not sure I actually agree here. I don't actively disagree either,
but I've found the assertion quite helpful in finding what would have
otherwise been a subtle performance problem in one of my other changes.
I hadn't *intended* to visit anything other than a single edge and had
managed to phrase the query in a way where I did.
> but it does mean that
> "handling switch with case value" is not a trivial TODO :)
>
> (note, of course, that splitting all critical edges also solves this
> particular problem)
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list