On Tue 2024-07-30 14:34:54, Richard Biener wrote:
> On Tue, 30 Jul 2024, Filip Kastl wrote:
> 
> > > > > Ah, I see you fix those up.  Then 2.) is left - the final block.  Iff
> > > > > the final block needs adjustment you know there was a path from
> > > > > the default case to it which means one of its predecessors is 
> > > > > dominated
> > > > > by the default case?  In that case, adjust the dominator to cond_bb,
> > > > > otherwise leave it at switch_bb?
> > > > 
> > > > Yes, what I'm saying is that if I want to know idom of final_bb after 
> > > > the
> > > > transformation, I have to know if there is a path between default_bb and
> > > > final_bb.  It is because of these two cases:
> > > > 
> > > > 1.
> > > > 
> > > > cond BB ---------+
> > > >    |             |
> > > > switch BB ---+   |
> > > > /  |  \       \  |
> > > > case BBs    default BB
> > > > \  |  /       /
> > > > final BB <---+  <- this may be an edge or a path
> > > >    |
> > > > 
> > > > 2.
> > > > 
> > > > cond BB ---------+
> > > >    |             |
> > > > switch BB ---+   |
> > > > /  |  \       \  |
> > > > case BBs    default BB
> > > > \  |  /       /
> > > > final BB     / <- this may be an edge or a path
> > > >    |        /
> > > > 
> > > > In the first case, there is a path between default_bb and final_bb and 
> > > > in the
> > > > second there isn't.  Otherwise the cases are the same.  In the first 
> > > > case idom
> > > > of final_bb should be cond_bb.  In the second case idom of final_bb 
> > > > should be
> > > > switch_bb. Algorithm deciding what should be idom of final_bb therefore 
> > > > has to
> > > > know if there is a path between default_bb and final_bb.
> > > > 
> > > > You said that if there is a path between default_bb and final_bb, one 
> > > > of the
> > > > predecessors of final_bb is dominated by default_bb.  That would indeed 
> > > > give a
> > > > nice way to check existence of a path between default_bb and final_bb.  
> > > > But
> > > > does it hold?  Consider this situation:
> > > > 
> > > >    |         |
> > > > cond BB --------------+
> > > >    |         |        |
> > > > switch BB --------+   |
> > > > /  |  \      |     \  |
> > > > case BBs     |    default BB
> > > > \  |  /      |        /
> > > > final BB <- pred BB -+
> > > >    |
> > > > 
> > > > Here no predecessors of final_bb are dominated by default_bb but at the 
> > > > same
> > > > time there does exist a path from default_bb to final_bb.  Or is this 
> > > > CFG
> > > > impossible for some reason?
> > > 
> > > I think in this case the dominator simply need not change - the only case
> > > you need to adjust it is when the immediate dominator of final BB was
> > > switch BB before the transform, and then we know we have to update it
> > > too cond BB, no?
> > 
> > Ah, my bad.  Yes, my counterexample actually isn't a problem.  I was glad 
> > when
> > I realized that and started thinking that this...
> > 
> > if (original idom(final bb) == switch bb)
> > {
> >   if (exists a pred of final bb dominated by default bb)
> >   {
> >     idom(final bb) = cond bb;
> >   }
> >   else
> >   {
> >     idom(final bb) = switch bb;
> >   }
> > }
> > else
> > {
> >   // idom(final bb) doesn't change
> > }
> > 
> > ...might be the final solution.  But after thinking about it for a while I
> > (saddly) came up with another counterexample.
> > 
> >    |          
> > cond BB --------------+
> >    |                  |
> > switch BB --------+   |
> > /  |  \            \  |
> > case BBs          default BB
> > \  |  /               /
> > final BB <- pred BB -+
> >    |           ^
> >    |           |
> >    +-----------+  <- this may be a path or an edge I guess
> > 
> > Here there *is* a path between default_bb and final_bb but since no 
> > predecessor
> > of final_bb is dominated by default_bb we incorrectly decide that there is 
> > no
> > such path.  Therefore we incorrectly assign idom(final_bb) = switch_bb 
> > instead
> > of idom(final_bb) = cond_bb.
> >
> > So unless I'm missing something, "final has a pred dominated by default" 
> > isn't
> > equivalent with "there is a path between default and final" even when we 
> > assume
> > that the original idom of final_bb was switch_bb.  Therefore I think we're 
> > back
> > to searching for a nice way to test "there is a path between default and
> > final".
> 
> Hmm.
> 
> > Maybe you can spot a flaw in my logic or maybe you see a solution I don't.
> > Meanwhile I'll look into source code of the rest of the switch conversion 
> > pass.
> > Switch conversion pass inserts conditions similar to what I'm doing so 
> > someone
> > before me may have already solved how to properly fix dominators in this
> > situation.
> 
> OK, as I see in your next followup that uses iterate_fix_dominators as 
> well.
> 
> So your patch is OK as-is.
> 
> It might be nice to factor out a common helper from gen_inbound_check
> and your "copy" of it though.  As followup, if you like.
> 
> Thanks and sorry for the confusion,
> Richard.

Alright, I pushed the patch.  I bootstrapped and regtested it once again to be
sure nothing breaks on the new master.  I also noticed that I didn't fill out
the changelog in the commit message of the second version of the patch so I
fixed that and I fixed two other mistakes I found in the commit message.

I'm adding the task of factoring out the common code to my list of possible
future projects.

It's a shame that we didn't manage to figure out the final bb idom.  For a
while, it looked like the predecessor dominated by default idea would really
work.

Thank you for all the guidance with this patch.

Cheers,
Filip Kastl

Reply via email to