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
This commit is contained in:
Reid Kleckner 2014-12-19 22:19:48 +00:00
parent 9ccbf1a260
commit 0f85d54670
10 changed files with 25 additions and 17 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -208,6 +208,8 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &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<CallSiteEntry> &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<CallSiteEntry> &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<CallSiteEntry> &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<CallSiteEntry> &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

View File

@ -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());

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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