aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2020-09-10 13:33:00 +0300
committerMartin Storsjö <martin@martin.st>2020-09-21 23:42:59 +0300
commit36c64af9d7f97414d48681b74352c9684077259b (patch)
treec0dd701564a4c9dc0bccd1bdc5b275505d263190 /llvm/lib/CodeGen/AsmPrinter/WinException.cpp
parent4d85444b317a00a3e15da63cdb693d272c99a0cc (diff)
downloadllvm-36c64af9d7f97414d48681b74352c9684077259b.zip
llvm-36c64af9d7f97414d48681b74352c9684077259b.tar.gz
llvm-36c64af9d7f97414d48681b74352c9684077259b.tar.bz2
[CodeGen] [WinException] Only produce handler data at the end of the function if needed
If we are going to write handler data (that is written as variable length data following after the unwind info in .xdata), we need to emit the handler data immediately, but for cases where no such info is going to be written, skip emitting it right away. (Unwind info for all remaining functions that hasn't gotten it emitted directly is emitted at the end.) This does slightly change the ordering of sections (triggering a bunch of updates to DebugInfo/COFF tests), but the change should be benign. This also matches GCC's assembly output, which doesn't output .seh_handlerdata unless it actually is needed. For ARM64, the unwind info can be packed into the runtime function entry itself (leaving no data in the .xdata section at all), but that can only be done if there's no follow-on data in the .xdata section. If emission of the unwind info is triggered via EmitWinEHHandlerData (or the .seh_handlerdata directive), which implicitly switches to the .xdata section, there's a chance of the caller wanting to pass further data there, so the packed format can't be used in that case. Differential Revision: https://reviews.llvm.org/D87448
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index c47ac7e..08f259c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -258,11 +258,11 @@ void WinException::endFuncletImpl() {
if (F.hasPersonalityFn())
Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
- // Emit an UNWIND_INFO struct describing the prologue.
- Asm->OutStreamer->EmitWinEHHandlerData();
-
if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality &&
!CurrentFuncletEntry->isCleanupFuncletEntry()) {
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+
// If this is a C++ catch funclet (or the parent function),
// emit a reference to the LSDA for the parent function.
StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
@@ -271,9 +271,22 @@ void WinException::endFuncletImpl() {
Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
} else if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets() &&
!CurrentFuncletEntry->isEHFuncletEntry()) {
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+
// If this is the parent function in Win64 SEH, emit the LSDA immediately
// following .seh_handlerdata.
emitCSpecificHandlerTable(MF);
+ } else if (shouldEmitPersonality || shouldEmitLSDA) {
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+ // In these cases, no further info is written to the .xdata section
+ // right here, but is written by e.g. emitExceptionTable in endFunction()
+ // above.
+ } else {
+ // No need to emit the EH handler data right here if nothing needs
+ // writing to the .xdata section; it will be emitted for all
+ // functions that need it in the end anyway.
}
// Switch back to the funclet start .text section now that we are done