From 0f85d54670a238d3723d4cf65e6b12138a113b76 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 19 Dec 2014 22:19:48 +0000 Subject: [PATCH] Add the ExceptionHandling::MSVC enumeration It is intended to be used for a family of personality functions that have similar IR preparation requirements. Typically when interoperating with MSVC personality functions, bits of functionality need to be outlined from the main function into helper functions. There is also usually more than one landing pad per invoke, which does not match the LLVM IR landingpad representation. None of this is implemented yet. This change just adds a new enum that is active for *-windows-msvc and delegates to the EH removal preparation pass. No functionality change for other targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224625 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAsmInfo.h | 6 ++++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 ++-- lib/CodeGen/AsmPrinter/EHStreamer.cpp | 13 +++++++------ lib/CodeGen/Passes.cpp | 1 + lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 4 +++- lib/Target/X86/X86FrameLowering.cpp | 6 ++---- test/CodeGen/X86/fast-isel-cmp-branch.ll | 2 +- test/CodeGen/X86/fast-isel-gep.ll | 2 +- test/CodeGen/X86/scev-interchange.ll | 2 +- test/CodeGen/X86/win64_eh.ll | 2 +- 10 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 9343b8ff880..9c62adcf196 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -47,6 +47,7 @@ enum class ExceptionHandling { SjLj, /// setjmp/longjmp based exceptions ARM, /// ARM EHABI ItaniumWinEH, /// Itanium EH built on Windows unwind info (.pdata and .xdata) + MSVC, /// MSVC compatible exception handling }; namespace LCOMM { @@ -492,6 +493,11 @@ public: ExceptionsType == ExceptionHandling::ItaniumWinEH); } + bool usesWindowsCFI() const { + return ExceptionsType == ExceptionHandling::ItaniumWinEH || + ExceptionsType == ExceptionHandling::MSVC; + } + bool doesDwarfUseRelocationsAcrossSections() const { return DwarfUsesRelocationsAcrossSections; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8cf05e8d20e..69e3a5df919 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -242,6 +242,7 @@ bool AsmPrinter::doInitialization(Module &M) { ES = new ARMException(this); break; case ExceptionHandling::ItaniumWinEH: + case ExceptionHandling::MSVC: switch (MAI->getWinEHEncodingType()) { default: llvm_unreachable("unsupported unwinding information encoding"); case WinEH::EncodingType::Itanium: @@ -705,8 +706,7 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { } bool AsmPrinter::needsSEHMoves() { - return MAI->getExceptionHandlingType() == ExceptionHandling::ItaniumWinEH && - MF->getFunction()->needsUnwindTableEntry(); + return MAI->usesWindowsCFI() && MF->getFunction()->needsUnwindTableEntry(); } void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/lib/CodeGen/AsmPrinter/EHStreamer.cpp index 2bbffb3f370..d7541ad4e73 100644 --- a/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -208,6 +208,8 @@ computeCallSiteTable(SmallVectorImpl &CallSites, // Whether the last CallSite entry was for an invoke. bool PreviousIsInvoke = false; + bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; + // Visit all instructions in order of address. for (const auto &MBB : *Asm->MF) { for (const auto &MI : MBB) { @@ -237,7 +239,7 @@ computeCallSiteTable(SmallVectorImpl &CallSites, // instruction between the previous try-range and this one may throw, // create a call-site entry with no landing pad for the region between the // try-ranges. - if (SawPotentiallyThrowing && Asm->MAI->usesItaniumLSDAForExceptions()) { + if (SawPotentiallyThrowing && !IsSJLJ) { CallSiteEntry Site = { LastLabel, BeginLabel, nullptr, 0 }; CallSites.push_back(Site); PreviousIsInvoke = false; @@ -259,7 +261,7 @@ computeCallSiteTable(SmallVectorImpl &CallSites, }; // Try to merge with the previous call-site. SJLJ doesn't do this - if (PreviousIsInvoke && Asm->MAI->usesItaniumLSDAForExceptions()) { + if (PreviousIsInvoke && !IsSJLJ) { CallSiteEntry &Prev = CallSites.back(); if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { // Extend the range of the previous entry. @@ -269,7 +271,7 @@ computeCallSiteTable(SmallVectorImpl &CallSites, } // Otherwise, create a new call-site. - if (Asm->MAI->usesItaniumLSDAForExceptions()) + if (!IsSJLJ) CallSites.push_back(Site); else { // SjLj EH must maintain the call sites in the order assigned @@ -287,7 +289,7 @@ computeCallSiteTable(SmallVectorImpl &CallSites, // If some instruction between the previous try-range and the end of the // function may throw, create a call-site entry with no landing pad for the // region following the try-range. - if (SawPotentiallyThrowing && Asm->MAI->usesItaniumLSDAForExceptions()) { + if (SawPotentiallyThrowing && !IsSJLJ) { CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 }; CallSites.push_back(Site); } @@ -519,8 +521,7 @@ void EHStreamer::emitExceptionTable() { Asm->EmitULEB128(S.Action); } } else { - // DWARF Exception handling - assert(Asm->MAI->usesItaniumLSDAForExceptions()); + // Itanium LSDA exception handling // The call-site table is a list of all call sites that may throw an // exception (including C++ 'throw' statements) in the procedure diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 5e1117522db..e53e874cb17 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -451,6 +451,7 @@ void TargetPassConfig::addPassesToHandleExceptions() { case ExceptionHandling::ItaniumWinEH: addPass(createDwarfEHPass(TM)); break; + case ExceptionHandling::MSVC: // FIXME: Add preparation. case ExceptionHandling::None: addPass(createLowerInvokePass()); diff --git a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp index f7af5dd88d0..9a5587cb51d 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -137,7 +137,9 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple) { PrivateLabelPrefix = ".L"; PointerSize = 8; WinEHEncodingType = WinEH::EncodingType::Itanium; - ExceptionsType = ExceptionHandling::ItaniumWinEH; + + // Use MSVC-compatible EH data. + ExceptionsType = ExceptionHandling::MSVC; } AssemblerDialect = AsmWriterFlavor; diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 80f9769b6f5..cf738f41cbd 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -495,8 +495,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const { const bool Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64(); bool IsWin64 = STI.isTargetWin64(); // Not necessarily synonymous with IsWin64. - bool IsWinEH = MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() == - ExceptionHandling::ItaniumWinEH; + bool IsWinEH = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); bool NeedsWinEH = IsWinEH && Fn->needsUnwindTableEntry(); bool NeedsDwarfCFI = !IsWinEH && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry()); @@ -906,8 +905,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, getX86SubSuperRegister(FramePtr, MVT::i64, false) : FramePtr; unsigned StackPtr = RegInfo->getStackRegister(); - bool IsWinEH = MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() == - ExceptionHandling::ItaniumWinEH; + bool IsWinEH = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); bool NeedsWinEH = IsWinEH && MF.getFunction()->needsUnwindTableEntry(); switch (RetOpcode) { diff --git a/test/CodeGen/X86/fast-isel-cmp-branch.ll b/test/CodeGen/X86/fast-isel-cmp-branch.ll index 6e408f89666..684647ca948 100644 --- a/test/CodeGen/X86/fast-isel-cmp-branch.ll +++ b/test/CodeGen/X86/fast-isel-cmp-branch.ll @@ -1,5 +1,5 @@ ; RUN: llc -O0 -mtriple=x86_64-linux -asm-verbose=false < %s | FileCheck %s -; RUN: llc -O0 -mtriple=x86_64-win32 -asm-verbose=false < %s | FileCheck %s +; RUN: llc -O0 -mtriple=x86_64-windows-itanium -asm-verbose=false < %s | FileCheck %s ; rdar://8337108 ; Fast-isel shouldn't try to look through the compare because it's in a diff --git a/test/CodeGen/X86/fast-isel-gep.ll b/test/CodeGen/X86/fast-isel-gep.ll index 4e47c7455c5..a65e0705f2b 100644 --- a/test/CodeGen/X86/fast-isel-gep.ll +++ b/test/CodeGen/X86/fast-isel-gep.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -mtriple=x86_64-linux -O0 | FileCheck %s --check-prefix=X64 -; RUN: llc < %s -mtriple=x86_64-win32 -O0 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-windows-itanium -O0 | FileCheck %s --check-prefix=X64 ; RUN: llc < %s -march=x86 -O0 | FileCheck %s --check-prefix=X32 ; GEP indices are interpreted as signed integers, so they diff --git a/test/CodeGen/X86/scev-interchange.ll b/test/CodeGen/X86/scev-interchange.ll index 71a4d21a9b9..0e7047b4845 100644 --- a/test/CodeGen/X86/scev-interchange.ll +++ b/test/CodeGen/X86/scev-interchange.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 +; RUN: llc < %s -mtriple=x86_64-linux target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" %"struct.DataOutBase::GmvFlags" = type { i32 } diff --git a/test/CodeGen/X86/win64_eh.ll b/test/CodeGen/X86/win64_eh.ll index f1f874eb2f5..4670087b9b4 100644 --- a/test/CodeGen/X86/win64_eh.ll +++ b/test/CodeGen/X86/win64_eh.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -O0 -mcpu=corei7 -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=WIN64 +; RUN: llc < %s -O0 -mcpu=corei7 -mtriple=x86_64-pc-windows-itanium | FileCheck %s -check-prefix=WIN64 ; RUN: llc < %s -O0 -mcpu=corei7 -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=WIN64 ; Check function without prolog