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.

Reply via email to