diff options
author | Paul Kirth <paulkirth@google.com> | 2022-10-21 18:22:03 +0000 |
---|---|---|
committer | Paul Kirth <paulkirth@google.com> | 2022-10-27 00:51:45 +0000 |
commit | 2e1e2f52f357768186ecfcc5ac53d5fa53d1b094 (patch) | |
tree | 8052c5c9023585196ce8049547d30f5f4b147c3c /llvm/lib/CodeGen/PrologEpilogInserter.cpp | |
parent | 70324cd88328c0924e605fa81b696572560aa5c9 (diff) | |
download | llvm-2e1e2f52f357768186ecfcc5ac53d5fa53d1b094.zip llvm-2e1e2f52f357768186ecfcc5ac53d5fa53d1b094.tar.gz llvm-2e1e2f52f357768186ecfcc5ac53d5fa53d1b094.tar.bz2 |
[CodeGen] Improve large stack frame diagnostic
Add statistics about how much memory is used, in variables, spills, and
unsafestack.
Issue #58168 describes some of the difficulty diagnosing stack size issues
identified by -Wframe-larger-than. D135488 addresses some of those issues by
giving developers a method to view the stack layout and thereby understand
where and how stack memory is used.
However, that solution requires an additional pass, when a short summary about
how the compiler has allocated stack memory can inform developers about where
they should investigate. When they need the complete context, D135488 can
provide them with a more comprehensive set of diagnostics.
Reviewed By: nickdesaulniers
Differential Revision: https://reviews.llvm.org/D136484
Diffstat (limited to 'llvm/lib/CodeGen/PrologEpilogInserter.cpp')
-rw-r--r-- | llvm/lib/CodeGen/PrologEpilogInserter.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index b7f764c..4f85499 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -57,6 +57,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -283,13 +284,35 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) { assert(!Failed && "Invalid warn-stack-size fn attr value"); (void)Failed; } - if (MF.getFunction().hasFnAttribute(Attribute::SafeStack)) { - StackSize += MFI.getUnsafeStackSize(); - } + uint64_t UnsafeStackSize = MFI.getUnsafeStackSize(); + if (MF.getFunction().hasFnAttribute(Attribute::SafeStack)) + StackSize += UnsafeStackSize; + if (StackSize > Threshold) { DiagnosticInfoStackSize DiagStackSize(F, StackSize, Threshold, DS_Warning); F.getContext().diagnose(DiagStackSize); + int64_t SpillSize = 0; + for (int Idx = MFI.getObjectIndexBegin(), End = MFI.getObjectIndexEnd(); + Idx != End; ++Idx) { + if (MFI.isSpillSlotObjectIndex(Idx)) + SpillSize += MFI.getObjectSize(Idx); + } + + float SpillPct = + static_cast<float>(SpillSize) / static_cast<float>(StackSize); + float VarPct = 1.0f - SpillPct; + int64_t VariableSize = StackSize - SpillSize; + dbgs() << formatv("{0}/{1} ({3:P}) spills, {2}/{1} ({4:P}) variables", + SpillSize, StackSize, VariableSize, SpillPct, VarPct); + if (UnsafeStackSize != 0) { + float UnsafePct = + static_cast<float>(UnsafeStackSize) / static_cast<float>(StackSize); + dbgs() << formatv(", {0}/{2} ({1:P}) unsafe stack", UnsafeStackSize, + UnsafePct, StackSize); + } + dbgs() << "\n"; } + ORE->emit([&]() { return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "StackSize", MF.getFunction().getSubprogram(), |