Enable time-passes functionality through PassInstrumentation callbacks
for passes and analyses.
TimePassesHandler class keeps all the callbacks as well as the state needed.
PassTiming class manages timer group and a mapping between PassID and Timer.
Parts of the fix that might be somewhat unobvious:
- mapping of passes into Timer (TimingData) can not be done per-instance. PassID name provided into the callback is common for all the pass invocations. Thus the only way to get a timing with reasonable granularity is to collect timing data per pass invocation, getting a new timer for each BeforePass. Hence the key for TimingData uses a pair of <StringRef/unsigned count> to uniquely identify a pass invocation.
- consequently, this new-pass-manager implementation performs no aggregation of timing data, reporting timings for each pass invocation separately. In that it differs from legacy-pass-manager time-passes implementation that reports timing data aggregated per pass instance.
- pass managers and adaptors are not tracked, similar to how pass managers are not tracked in legacy time-passes.
- TimePassesHandler object keeps a stack of timers that are active, each BeforePass pushes the new timer on stack, each AfterPass pops active timer from stack and stops it.