diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -286,6 +286,13 @@ MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const override; + + /// For functions, this will return the LSDA section. If option + /// -ffunction-sections is on, this will return a unique csect with the + /// function name appended to .gcc_except_table as a suffix of the LSDA + /// section name. + MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym, + const TargetMachine &TM) const override; }; class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile { diff --git a/llvm/include/llvm/MC/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h --- a/llvm/include/llvm/MC/MCSectionXCOFF.h +++ b/llvm/include/llvm/MC/MCSectionXCOFF.h @@ -116,6 +116,7 @@ Optional getDwarfSubtypeFlags() const { return DwarfSubtypeFlags; } + Optional getCsectProp() const { return CsectProp; } }; } // end namespace llvm diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -37,8 +38,19 @@ // unsigned long personality; /* Pointer to the personality routine */ // } - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getCompactUnwindSection()); + auto *EHInfo = + cast(Asm->getObjFileLowering().getCompactUnwindSection()); + if (Asm->TM.getFunctionSections()) { + // If option -ffunction-sections is on, append the function name to the + // name of EH Info Table csect so that each function has its own EH Info + // Table csect. This helps the linker to garbage-collect EH info of unused + // functions. + SmallString<128> NameStr = EHInfo->getName(); + raw_svector_ostream(NameStr) << '.' << Asm->MF->getFunction().getName(); + EHInfo = Asm->OutContext.getXCOFFSection(NameStr, EHInfo->getKind(), + EHInfo->getCsectProp()); + } + Asm->OutStreamer->SwitchSection(EHInfo); MCSymbol *EHInfoLabel = TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF); Asm->OutStreamer->emitLabel(EHInfoLabel); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2565,6 +2565,20 @@ XCOFF::XTY_SD)); } +MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( + const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { + auto *LSDA = cast(LSDASection); + if (TM.getFunctionSections()) { + // If option -ffunction-sections is on, append the function name to the + // name of the LSDA csect so that each function has its own LSDA csect. + // This helps the linker to garbage-collect EH info of unused functions. + SmallString<128> NameStr = LSDA->getName(); + raw_svector_ostream(NameStr) << '.' << F.getName(); + LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(), + LSDA->getCsectProp()); + } + return LSDA; +} //===----------------------------------------------------------------------===// // GOFF //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll --- a/llvm/test/CodeGen/PowerPC/aix-exception.ll +++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll @@ -1,10 +1,20 @@ ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \ ; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 < %s | \ -; RUN: FileCheck --check-prefixes=ASM,ASM32 %s +; RUN: FileCheck --check-prefixes=ASM,ASMNFS,ASM32 %s ; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ ; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 < %s | \ -; RUN: FileCheck --check-prefixes=ASM,ASM64 %s +; RUN: FileCheck --check-prefixes=ASM,ASMNFS,ASM64 %s + +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 \ +; RUN: -function-sections < %s | \ +; RUN: FileCheck --check-prefixes=ASM,ASMFS,ASM32 %s + +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec -simplifycfg-require-and-preserve-domtree=1 \ +; RUN: -function-sections < %s | \ +; RUN: FileCheck --check-prefixes=ASM,ASMFS,ASM64 %s @_ZTIi = external constant i8* @@ -17,7 +27,8 @@ unreachable } -; ASM: ._Z9throwFuncv: +; ASMNFS: ._Z9throwFuncv: +; ASMFS: .csect ._Z9throwFuncv[PR],2 ; ASM: bl .__cxa_allocate_exception[PR] ; ASM: nop ; ASM32: lwz 4, L..C0(2) @@ -78,7 +89,8 @@ resume { i8*, i32 } %lpad.val3 } -; ASM: ._Z9catchFuncv: +; ASMNFS: ._Z9catchFuncv: +; ASMFS: .csect ._Z9catchFuncv[PR],2 ; ASM: L..func_begin0: ; ASM: # %bb.0: # %entry ; ASM: mflr 0 @@ -114,7 +126,8 @@ ; ASM: .byte 0x80 # +HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 0 ; ASM: .byte 0x00 # NumberOfFixedParms = 0 ; ASM: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack -; ASM: .vbyte 4, L.._Z9catchFuncv0-._Z9catchFuncv # Function size +; ASMNFS: .vbyte 4, L.._Z9catchFuncv0-._Z9catchFuncv # Function size +; ASMFS: .vbyte 4, L.._Z9catchFuncv0-._Z9catchFuncv[PR] # Function size ; ASM: .vbyte 2, 0x000d # Function name len = 13 ; ASM: .byte "_Z9catchFuncv" # Function Name ; ASM: .byte 0x08 # ExtensionTableFlag = TB_EH_INFO @@ -123,7 +136,8 @@ ; ASM64: .vbyte 8, L..C1-TOC[TC0] # EHInfo Table ; ASM: L..func_end0: -; ASM: .csect .gcc_except_table[RO],2 +; ASMNFS: .csect .gcc_except_table[RO],2 +; ASMFS: .csect .gcc_except_table._Z9catchFuncv[RO],2 ; ASM: .align 2 ; ASM: GCC_except_table1: ; ASM: L..exception0: @@ -153,7 +167,8 @@ ; ASM: L..ttbase0: ; ASM: .align 2 -; ASM: .csect .eh_info_table[RW],2 +; ASMNFS: .csect .eh_info_table[RW],2 +; ASMFS: .csect .eh_info_table._Z9catchFuncv[RW],2 ; ASM: __ehinfo.1: ; ASM: .vbyte 4, 0 ; ASM32: .align 2