+ /* For PHI operands it matters from where the control flow arrives
+ to the BB. Consider the following example:
+
+ a=exp1;
+ b=exp2;
+ if (test)
+ ;
+ else
+ ;
+ c=PHI(a,b)
+
+ We need to mark control dependence of the empty basic blocks, since they
+ contains computation of PHI operands.
+
+ Doing so is too restrictive in the case the predecestor block is in
+ the loop. Consider:
+
+ if (b)
+ {
+ int i;
+ for (i = 0; i<1000; ++i)
+ ;
+ j = 0;
+ }
+ return j;
+
+ There is PHI for J in the BB containing return statement.
+ In this case the control dependence of predecestor block (that is
+ within the empty loop) also contains the block determining number
+ of iterations of the block that would prevent removing of empty
+ loop in this case.
+
+ This scenario can be avoided by splitting critical edges.
+ To save the critical edge splitting pass we identify how the control
+ dependence would look like if the edge was split.
+
+ Consider the modified CFG created from current CFG by splitting
+ edge B->C. In the postdominance tree of modified CFG, C' is
+ always child of C. There are two cases how chlids of C' can look
+ like:
+
+ 1) C' is leaf
+
+ In this case the only basic block C' is control dependent on is B.
+
+ 2) C' has single child that is B
+
+ In this case control dependence of C' is same as control
+ dependence of B in original CFG except for block B itself.
+ (since C' postdominate B in modified CFG)
+
+ Now how to decide what case happens? There are two basic options:
+
+ a) C postdominate B. Then C immediately postdominate B and
+ case 2 happens iff there is no other way from B to C except
+ the edge B->C.
+
+ There is other way from B to C iff there is succesor of B that
+ is not postdominated by B. Testing this condition is somewhat
+ expensive, because we need to iterate all succesors of B.
+ We are safe to assume that this does not happen: we will mark B
+ as needed when processing the other path from B to C that is
+ conrol dependent on B and marking control dependencies of B
+ itself is harmless because they will be processed anyway after
+ processing control statement in B.
+
+ b) C does not postdominate B. Always case 1 happens since there is
+ path from C to exit that does not go through B and thus also C'. */
+
+ if (aggressive && !degenerate_phi_p (stmt))