When we run dynamic pass pipeline via LogicalResult pass::runPipeline(OpPassManager &pipeline, Operation *op) within a pass, the timing infra will print the pass's timing at the top level, instead of nesting it. Meanwhile, we can find a negative Rest field in the timing report, which might be due to the nested pass pipeline are double counted.
The minimal example to reproduce is inliner pass which nest itself with a Canonicalizer pass. We can see that the Canonicalizer pass was shown at top level and there is a -5.5% Rest field.
build/install/bin/mlir-opt -inline mlir/test/Transforms/inlining-repeated-use.mlir -mlir-timing
===-------------------------------------------------------------------------===
... Execution time report ...
===-------------------------------------------------------------------------===
Total Execution Time: 0.0009 seconds
----Wall Time---- ----Name----
0.0003 ( 40.1%) Parser
0.0003 ( 37.5%) Inliner
0.0000 ( 1.3%) (A) CallGraph
0.0001 ( 7.9%) 'func.func' Pipeline
0.0001 ( 7.7%) Canonicalizer
0.0002 ( 19.9%) Output
-0.0000 ( -5.5%) Rest
0.0009 (100.0%) Total
From the source code mlir/lib/Pass/PassTiming.cpp#L60-L67, it seems the nested pass does not have a parentTimer so they will fallback to the root timer and lead to this phenomenon. Is this by design or need a fix?