On 10/21/2021 12:20 PM, Jeff Law wrote:


So if we're referring to those temporary const/copy propagations
"escaping" into Ranger, then I would fully expect that to cause
problems.  Essentially they're path sensitive const/copy propagations
and may not be valid on all the paths through the CFG to the statement
where the propagation occurs
Yeah.  disabling the global ranger should help, plus making sure you
don't use the ranger in the midst of the path sensitive changes.
I think we should first try to remove those temporary const/copy propagations.  As I noted in a different follow-up, I can't remember if they were done as part of the original non-copying threader or if they enabled further optimizations in the copying threader.  If its the former, then they can go away and that would be my preference. I'll try to poke at that over the weekend.
OK.  So those temporary propagations are still useful.  Here's a simple example (pr36550, but there are others):


[ ... ]
;;   basic block 3, loop depth 0, count 536870912 (estimated locally), maybe hot
;;    prev block 2, next block 4, flags: (NEW, VISITED)
;;    pred:       2 [50.0% (guessed)]  count:536870912 (estimated locally) (TRUE_VALUE,EXECUTABLE)
  # VUSE <.MEM_10>
  _20 = *argv_12(D);
  if (_20 != 0B)
    goto <bb 4>; [70.00%]
  else
    goto <bb 7>; [30.00%]
;;    succ:       4 [70.0% (guessed)]  count:375809640 (estimated locally) (TRUE_VALUE,EXECUTABLE) ;;                7 [30.0% (guessed)]  count:161061272 (estimated locally) (FALSE_VALUE,EXECUTABLE)

[ ... ]

;;   basic block 7, loop depth 0, count 536763538 (estimated locally), maybe hot
;;    prev block 6, next block 8, flags: (NEW, VISITED)
;;    pred:       3 [30.0% (guessed)]  count:161061272 (estimated locally) (FALSE_VALUE,EXECUTABLE) ;;                4 [always]  count:375809640 (estimated locally) (FALLTHRU,EXECUTABLE)
  # argv_32 = PHI <argv_12(D)(3), argv_21(4)>
  # bug_33 = PHI <bug_16(D)(3), bug_22(4)>
  # VUSE <.MEM_10>
  _3 = *argv_32;
  if (_3 == 0B)
    goto <bb 9>; [18.09%]
  else
    goto <bb 8>; [81.91%]
;;    succ:       9 [18.1% (guessed)]  count:97100524 (estimated locally) (TRUE_VALUE,EXECUTABLE) ;;                8 [81.9% (guessed)]  count:439663014 (estimated locally) (FALSE_VALUE,EXECUTABLE)


So when we reach block 7 directly from block 3 we'll have _20 = *argv_12(MEM_10) = _20 in the expression hash table and _20 = 0 in the const/copies table.

The first statement in block #7 loads *argv_32.  Without the temporary propagation we'll lookup *argv_32(MEM_10) in the hash table which misses and we're unable to thread the subsequent conditional in block #7.

With the temporary propagation instead of looking up *argv_32(MEM_10), we propagate argv_12 for argv32 and lookup *argv32(MEM_10) which hits with the LHS value _20 which we then lookup in const/copies getting the constant 0.   Thus we know *argv_32 will have the value 0 when block 7 is reached directly via block 3.  That in turn allows us to know that the conditional at the end of block #7 is threadable when reached via block #3.

In this particular testcase we end up getting a failure because... drumroll.... the failure to thread 3->7->9 leaves an infeasible path in the CFG which in turn causes a bogus Wuninitialized warning.

Instead of actually propagating the arguments into the statement, we could revamp the hashing bits so that they used the data from the const/copy tables.    That would avoid twiddling the IL.  Though I'm still not sure how the IL twiddling could be escaping at this point.

jeff


Reply via email to