This is an archive of the discontinued LLVM Phabricator instance.

[PassManager] Add pretty stack entries before P->run() call.
ClosedPublic

Authored by fhahn on Mar 4 2022, 6:07 AM.

Details

Summary

This patch adds PrettyStackEntries before running passes. The entries
include the pass name and the IR unit the pass runs on.

The information is used the print additional information when a pass
crashes, including the name and a reference to the IR unit on which it
crashed. This is similar to the behavior of the legacy pass manager.

The improved stack trace now includes:

Stack dump:
0. Program arguments: bin/opt -loop-vectorize -force-vector-width=4 crash.ll

  1. Running pass 'ModuleToFunctionPassAdaptor' on module 'crash.ll'
  2. Running pass 'LoopVectorizePass' on function '@a'

Diff Detail

Event Timeline

fhahn created this revision.Mar 4 2022, 6:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2022, 6:07 AM
fhahn requested review of this revision.Mar 4 2022, 6:07 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2022, 6:07 AM
myhsu added a subscriber: myhsu.Mar 4 2022, 10:30 AM

I think this is a really neat feature :-)
Please remember to fix the clang-format errors.

llvm/lib/IR/PassManager.cpp
166

I don't think MF->getName() should be commented

fhahn updated this revision to Diff 413121.Mar 4 2022, 1:08 PM

Fix formatting, replace commented out code with explanation why the code doesn't call MF->getName().

fhahn marked an inline comment as done.Mar 4 2022, 1:13 PM
fhahn added inline comments.
llvm/lib/IR/PassManager.cpp
166

Ah thanks, I forgot about that. Replaced with a comment.

Definitely seems good.
This should be added for all adaptors (module->cgscc,module->function,cgscc->function,function->loop) and pass managers (loop/cgscc are implemented separately)
PassManager.h/cpp, LoopPassManager.h/cpp, CGSCCPassManager.h/cpp

Could be tested with the crash pass that was supposed to be landed in https://reviews.llvm.org/D86657, which needs to be relanded

llvm/lib/IR/PassManager.cpp
177–180

We'll either have a Loop, Function, SCC, or Module (MachineFunction doesn't work yet, but I guess it doesn't hurt to add)
See StandardInstrumentations.cpp for similar code

fhahn updated this revision to Diff 413809.Mar 8 2022, 7:52 AM
fhahn marked an inline comment as done.

Definitely seems good.
This should be added for all adaptors (module->cgscc,module->function,cgscc->function,function->loop) and pass managers (loop/cgscc are implemented separately)
PassManager.h/cpp, LoopPassManager.h/cpp, CGSCCPassManager.h/cpp

Could be tested with the crash pass that was supposed to be landed in https://reviews.llvm.org/D86657, which needs to be relanded

I added the missing implementations and added crashing passes for all of them.

aeubanks added inline comments.Mar 8 2022, 9:10 AM
llvm/lib/Passes/PassBuilder.cpp
395 ↗(On Diff #413809)

CrashingCGSCCPass

llvm/test/Other/crash-module.ll
7 ↗(On Diff #413809)

this is failing on windows, I don't think we need to be so strict on checking this line

fhahn updated this revision to Diff 413839.Mar 8 2022, 9:39 AM
fhahn marked an inline comment as done.

Fix CGSCC template arg, do not check specific arguments in test.

fhahn marked an inline comment as done.Mar 8 2022, 9:40 AM
fhahn added inline comments.
llvm/lib/Passes/PassBuilder.cpp
395 ↗(On Diff #413809)

Thanks, that should bet tied now.

llvm/test/Other/crash-module.ll
7 ↗(On Diff #413809)

Was the issue that part after Program arguments:? I dropped that from the checks.

aeubanks added inline comments.Mar 8 2022, 9:52 AM
llvm/lib/Transforms/Scalar/LoopPassManager.cpp
297 ↗(On Diff #413839)

this might be UAF if L is deleted in the loop pass before we crash (see runAfterPassInvalidated below where we don't reference L for this reason), but given that this is for crash stack traces, it probably doesn't matter

llvm/test/Other/crash-module.ll
7 ↗(On Diff #413809)

the presubmit said the test was failing, likely due to opt vs opt.exe, but I didn't look too closely
I think this works

aeubanks accepted this revision.Mar 8 2022, 9:53 AM
This revision is now accepted and ready to land.Mar 8 2022, 9:53 AM
fhahn updated this revision to Diff 414054.Mar 9 2022, 3:07 AM
fhahn marked an inline comment as done.

Reduce size of class, relax check lines to account for stack dump not always being printed.

This revision was landed with ongoing or failed builds.Mar 9 2022, 5:01 AM
This revision was automatically updated to reflect the committed changes.
fhahn added a comment.Mar 9 2022, 8:17 AM

Yeah that's not great. I'll revert it in a bit and check if there's anything in particular that's very expensive.

Yeah that's not great. I'll revert it in a bit and check if there's anything in particular that's very expensive.

If I had to guess, it might be eagerly retrieving loop names or cgscc names since they can be pretty big if the scc contains a lot of functions or if the loop has a lot of blocks
we could start without the cgscc name and using the function name for loop passes

myhsu added a comment.Mar 9 2022, 9:31 AM

Yeah that's not great. I'll revert it in a bit and check if there's anything in particular that's very expensive.

My ballpark guess is that the whole SIGINFO printing feature is kinda expensive, since we're forced to load GlobalSigInfoGenerationCounter every time, but the feature is actually never used upstream.

fhahn added a comment.Mar 10 2022, 7:24 AM

Yeah that's not great. I'll revert it in a bit and check if there's anything in particular that's very expensive.

If I had to guess, it might be eagerly retrieving loop names or cgscc names since they can be pretty big if the scc contains a lot of functions or if the loop has a lot of blocks
we could start without the cgscc name and using the function name for loop passes

I tried splitting off the loop & CGSCC handling into separate classes that only take pointers to Loop/ SCC. The compile-time impact is better, but still noticeable (worst config: +0.17% on ReleastThinLTO - https://llvm-compile-time-tracker.com/compare.php?from=af98b0af6705df3859ee3c98525b57025d40d9e8&to=bc328a534f528fbf8d7a37eaf08e70bd78b75896&stat=instructions)

Yeah that's not great. I'll revert it in a bit and check if there's anything in particular that's very expensive.

If I had to guess, it might be eagerly retrieving loop names or cgscc names since they can be pretty big if the scc contains a lot of functions or if the loop has a lot of blocks
we could start without the cgscc name and using the function name for loop passes

I tried splitting off the loop & CGSCC handling into separate classes that only take pointers to Loop/ SCC. The compile-time impact is better, but still noticeable (worst config: +0.17% on ReleastThinLTO - https://llvm-compile-time-tracker.com/compare.php?from=af98b0af6705df3859ee3c98525b57025d40d9e8&to=bc328a534f528fbf8d7a37eaf08e70bd78b75896&stat=instructions)

A few ideas that might be worth considering (if they help), if you can't get it as cheap as it should be:

  1. Add a -cc1 option to clang for whether to add pretty stack tracing; turn it on by default, but have the driver pass -skip-pretty-stack-traces-in-passes=true to turn it off in release builds (checking NDEBUG, like -discard-value-names=true or whatever it is).
  2. Land it but only handle the passes where the granularity is coarse enough that it's "cheap" (e.g., maybe just module/cgscc/function passes?).
  3. Both: check for everything by default, but have the driver pass a -cc1 option that turns off the expensive ones.