[AutoDiff] Revamp usefulness propagation in activity analysis. (#28225)
Useful values are those that contribute to (specific) dependent variables,
i.e. function results.
For addresses: all projections of a useful address should be useful.
This has special support:
`DifferentiableActivityInfo::propagateUsefulThroughAddress`.
Previously:
- Usefulness was propagated by iterating through all instructions in
post-dominance order. This is not efficient because irrelevant instructions
may be visited.
- For useful addresses, `propagateUsefulThroughAddress` propagated
usefulness one step to projections, but not recursively to users of the
projections. This caused some values to incorrectly not be marked useful.
Now:
- Usefulness is propagated by following use-def chains, starting from
dependent variables (function results). This is handled by the
following helpers:
- `setUsefulAndPropagateToOperands(SILValue, unsigned)`: marks a value as
useful and recursively propagates usefulness through defining instruction
operands and basic block argument incoming values.
- `propagateUseful(SILInstruction *inst, unsigned)`: propagates usefulness
to the operands of the given instruction.
- `DifferentiableActivityInfo::propagateUsefulThroughAddress` now calls
`propagateUseful` to propagate usefulness recursively through users'
operands.
Effects:
- More values are now (correctly) marked as useful, affecting
non-differentiability diagnostics for active enum values (TF-956) and for-in
loops (TF-957). Both have room for improvement.
Resolves control flow differentiation correctness issue: TF-954.