[llvm-branch-commits] [llvm] 2c63e76 - [XCOFF][AIX] Alternative path in EHStreamer for platforms do not have uleb128 support
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Dec 2 12:07:44 PST 2020
Author: jasonliu
Date: 2020-12-02T20:03:15Z
New Revision: 2c63e7604c87d97723919ca00d80ea38cddca8f9
URL: https://github.com/llvm/llvm-project/commit/2c63e7604c87d97723919ca00d80ea38cddca8f9
DIFF: https://github.com/llvm/llvm-project/commit/2c63e7604c87d97723919ca00d80ea38cddca8f9.diff
LOG: [XCOFF][AIX] Alternative path in EHStreamer for platforms do not have uleb128 support
Summary:
Not all system assembler supports `.uleb128 label2 - label1` form.
When the target do not support this form, we have to take
alternative manual calculation to get the offsets from them.
Reviewed By: hubert.reinterpretcast
Diffierential Revision: https://reviews.llvm.org/D92058
Added:
llvm/test/CodeGen/X86/gnu-eh-alternative.ll
Modified:
llvm/include/llvm/MC/MCAsmInfo.h
llvm/include/llvm/Target/TargetLoweringObjectFile.h
llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
llvm/lib/MC/MCAsmInfo.cpp
llvm/lib/MC/MCAsmInfoXCOFF.cpp
llvm/lib/Target/TargetLoweringObjectFile.cpp
llvm/test/CodeGen/PowerPC/aix-exception.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index 2b889d0ed5fa..c55dab4e7973 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -186,6 +186,9 @@ class MCAsmInfo {
/// alignment is supported.
bool UseDotAlignForAlignment = false;
+ /// True if the target supports LEB128 directives.
+ bool HasLEB128Directives = true;
+
//===--- Data Emission Directives -------------------------------------===//
/// This should be set to the directive used to get some number of zero (and
@@ -575,6 +578,8 @@ class MCAsmInfo {
return UseDotAlignForAlignment;
}
+ bool hasLEB128Directives() const { return HasLEB128Directives; }
+
const char *getZeroDirective() const { return ZeroDirective; }
bool doesZeroDirectiveSupportNonZeroValue() const {
return ZeroDirectiveSupportsNonZeroValue;
diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index edae4bb509ee..90041f077523 100644
--- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -157,7 +157,7 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
unsigned getLSDAEncoding() const { return LSDAEncoding; }
unsigned getTTypeEncoding() const { return TTypeEncoding; }
- unsigned getCallSiteEncoding() const { return CallSiteEncoding; }
+ unsigned getCallSiteEncoding() const;
const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
MCStreamer &Streamer) const;
diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index b6fc83285a20..2ffe8a7b0469 100644
--- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -413,6 +413,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm;
+ bool HasLEB128Directives = Asm->MAI->hasLEB128Directives();
unsigned CallSiteEncoding =
IsSJLJ ? static_cast<unsigned>(dwarf::DW_EH_PE_udata4) :
Asm->getObjFileLowering().getCallSiteEncoding();
@@ -505,6 +506,79 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutStreamer->emitLabel(CstBeginLabel);
};
+ // An alternative path to EmitTypeTableRefAndCallSiteTableEndRef.
+ // For some platforms, the system assembler does not accept the form of
+ // `.uleb128 label2 - label1`. In those situations, we would need to calculate
+ // the size between label1 and label2 manually.
+ // In this case, we would need to calculate the LSDA size and the call
+ // site table size.
+ auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() {
+ assert(CallSiteEncoding == dwarf::DW_EH_PE_udata4 && !HasLEB128Directives &&
+ "Targets supporting .uleb128 do not need to take this path.");
+ if (CallSiteRanges.size() > 1)
+ report_fatal_error(
+ "-fbasic-block-sections is not yet supported on "
+ "platforms that do not have general LEB128 directive support.");
+
+ uint64_t CallSiteTableSize = 0;
+ const CallSiteRange &CSRange = CallSiteRanges.back();
+ for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
+ CallSiteIdx < CSRange.CallSiteEndIdx; ++CallSiteIdx) {
+ const CallSiteEntry &S = CallSites[CallSiteIdx];
+ // Each call site entry consists of 3 udata4 fields (12 bytes) and
+ // 1 ULEB128 field.
+ CallSiteTableSize += 12 + getULEB128Size(S.Action);
+ assert(isUInt<32>(CallSiteTableSize) && "CallSiteTableSize overflows.");
+ }
+
+ Asm->emitEncodingByte(TTypeEncoding, "@TType");
+ if (HaveTTData) {
+ const unsigned ByteSizeOfCallSiteOffset =
+ getULEB128Size(CallSiteTableSize);
+ uint64_t ActionTableSize = 0;
+ for (const ActionEntry &Action : Actions) {
+ // Each action entry consists of two SLEB128 fields.
+ ActionTableSize += getSLEB128Size(Action.ValueForTypeID) +
+ getSLEB128Size(Action.NextAction);
+ assert(isUInt<32>(ActionTableSize) && "ActionTableSize overflows.");
+ }
+
+ const unsigned TypeInfoSize =
+ Asm->GetSizeOfEncodedValue(TTypeEncoding) * MF->getTypeInfos().size();
+
+ const uint64_t LSDASizeBeforeAlign =
+ 1 // Call site encoding byte.
+ + ByteSizeOfCallSiteOffset // ULEB128 encoding of CallSiteTableSize.
+ + CallSiteTableSize // Call site table content.
+ + ActionTableSize; // Action table content.
+
+ const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize;
+ const unsigned ByteSizeOfLSDAWithoutAlign =
+ getULEB128Size(LSDASizeWithoutAlign);
+ const uint64_t DisplacementBeforeAlign =
+ 2 // LPStartEncoding and TypeTableEncoding.
+ + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign;
+
+ // The type info area starts with 4 byte alignment.
+ const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4;
+ uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal;
+ const unsigned ByteSizeOfLSDAWithAlign =
+ getULEB128Size(LSDASizeWithAlign);
+
+ // The LSDASizeWithAlign could use 1 byte less padding for alignment
+ // when the data we use to represent the LSDA Size "needs" to be 1 byte
+ // larger than the one previously calculated without alignment.
+ if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign)
+ LSDASizeWithAlign -= 1;
+
+ Asm->OutStreamer->emitULEB128IntValue(LSDASizeWithAlign,
+ ByteSizeOfLSDAWithAlign);
+ }
+
+ Asm->emitEncodingByte(CallSiteEncoding, "Call site");
+ Asm->OutStreamer->emitULEB128IntValue(CallSiteTableSize);
+ };
+
// SjLj / Wasm Exception handling
if (IsSJLJ || IsWasm) {
Asm->OutStreamer->emitLabel(Asm->getMBBExceptionSym(Asm->MF->front()));
@@ -620,7 +694,10 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->MAI->getCodePointerSize());
}
- EmitTypeTableRefAndCallSiteTableEndRef();
+ if (HasLEB128Directives)
+ EmitTypeTableRefAndCallSiteTableEndRef();
+ else
+ EmitTypeTableOffsetAndCallSiteTableOffset();
for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx;
CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) {
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp
index 9767ee6c1133..0d2d26b0eb47 100644
--- a/llvm/lib/MC/MCAsmInfo.cpp
+++ b/llvm/lib/MC/MCAsmInfo.cpp
@@ -28,6 +28,12 @@ static cl::opt<DefaultOnOff> DwarfExtendedLoc(
clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
cl::init(Default));
+cl::opt<cl::boolOrDefault> UseLEB128Directives(
+ "use-leb128-directives", cl::Hidden,
+ cl::desc(
+ "Disable the usage of LEB128 directives, and generate .byte instead."),
+ cl::init(cl::BOU_UNSET));
+
MCAsmInfo::MCAsmInfo() {
SeparatorString = ";";
CommentString = "#";
@@ -51,6 +57,8 @@ MCAsmInfo::MCAsmInfo() {
WeakDirective = "\t.weak\t";
if (DwarfExtendedLoc != Default)
SupportsExtendedDwarfLocDirective = DwarfExtendedLoc == Enable;
+ if (UseLEB128Directives != cl::BOU_UNSET)
+ HasLEB128Directives = UseLEB128Directives == cl::BOU_TRUE;
// FIXME: Clang's logic should be synced with the logic used to initialize
// this member and the two implementations should be merged.
diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
index eb46deedcd11..2f8bc6a49bb7 100644
--- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
@@ -8,9 +8,12 @@
#include "llvm/MC/MCAsmInfoXCOFF.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
+extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
+
void MCAsmInfoXCOFF::anchor() {}
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
@@ -20,6 +23,8 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
PrivateLabelPrefix = "L..";
SupportsQuotedNames = false;
UseDotAlignForAlignment = true;
+ if (UseLEB128Directives == cl::BOU_UNSET)
+ HasLEB128Directives = false;
ZeroDirective = "\t.space\t";
ZeroDirectiveSupportsNonZeroValue = false;
AsciiDirective = nullptr; // not supported
diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp
index eea0aeea2c45..087d5e3497f9 100644
--- a/llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -20,6 +20,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
@@ -55,6 +56,15 @@ TargetLoweringObjectFile::~TargetLoweringObjectFile() {
delete Mang;
}
+unsigned TargetLoweringObjectFile::getCallSiteEncoding() const {
+ // If target does not have LEB128 directives, we would need the
+ // call site encoding to be udata4 so that the alternative path
+ // for not having LEB128 directives could work.
+ if (!getContext().getAsmInfo()->hasLEB128Directives())
+ return dwarf::DW_EH_PE_udata4;
+ return CallSiteEncoding;
+}
+
static bool isNullOrUndef(const Constant *C) {
// Check that the constant isn't all zeros or undefs.
if (C->isNullValue() || isa<UndefValue>(C))
diff --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll
index edef76c75c68..f2fc323e166f 100644
--- a/llvm/test/CodeGen/PowerPC/aix-exception.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll
@@ -107,11 +107,10 @@ eh.resume: ; preds = %catch.dispatch
; ASM: .byte 255 # @LPStart Encoding = omit
; ASM32: .byte 187 # @TType Encoding = indirect datarel sdata4
; ASM64: .byte 188 # @TType Encoding = indirect datarel sdata8
-; ASM: .uleb128 L..ttbase0-L..ttbaseref0
-; ASM: L..ttbaseref0:
+; ASM32: .byte 37
+; ASM64: .byte 41
; ASM: .byte 3 # Call site Encoding = udata4
-; ASM: .uleb128 L..cst_end0-L..cst_begin0
-; ASM: L..cst_begin0:
+; ASM: .byte 26
; ASM: .vbyte 4, L..tmp0-L..func_begin0 # >> Call Site 1 <<
; ASM: .vbyte 4, L..tmp1-L..tmp0 # Call between L..tmp0 and L..tmp1
; ASM: .vbyte 4, L..tmp2-L..func_begin0 # jumps to L..tmp2
@@ -140,9 +139,9 @@ eh.resume: ; preds = %catch.dispatch
; ASM64: .vbyte 8, GCC_except_table1
; ASM64: .vbyte 8, __xlcxx_personality_v1[DS]
-; ASM: .toc
+; ASM: .toc
; ASM: L..C0:
-; ASM: .tc _ZTIi[TC],_ZTIi[UA]
+; ASM: .tc _ZTIi[TC],_ZTIi[UA]
declare i8* @__cxa_allocate_exception(i32)
declare void @__cxa_throw(i8*, i8*, i8*)
diff --git a/llvm/test/CodeGen/X86/gnu-eh-alternative.ll b/llvm/test/CodeGen/X86/gnu-eh-alternative.ll
new file mode 100644
index 000000000000..b7817e18dcca
--- /dev/null
+++ b/llvm/test/CodeGen/X86/gnu-eh-alternative.ll
@@ -0,0 +1,103 @@
+; RUN: llc -verify-machineinstrs -mtriple x86_64-pc-linux-gnu -filetype=asm < %s | \
+; RUN: FileCheck --check-prefixes=ASM,ULEB128 %s
+; RUN: llc -verify-machineinstrs -mtriple x86_64-pc-linux-gnu -use-leb128-directives=true -filetype=asm < %s | \
+; RUN: FileCheck --check-prefixes=ASM,ULEB128 %s
+; RUN: llc -verify-machineinstrs -mtriple x86_64-pc-linux-gnu -use-leb128-directives=false -filetype=asm < %s | \
+; RUN: FileCheck --check-prefixes=ASM,NO128 %s
+
+ at _ZTIi = external dso_local constant i8*
+
+define dso_local i32 @main() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+ %retval = alloca i32, align 4
+ %exn.slot = alloca i8*, align 8
+ %ehselector.slot = alloca i32, align 4
+ store i32 0, i32* %retval, align 4
+ %exception = call i8* @__cxa_allocate_exception(i64 4) #1
+ %0 = bitcast i8* %exception to i32*
+ store i32 1, i32* %0, align 16
+ invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2
+ to label %unreachable unwind label %lpad
+
+lpad: ; preds = %entry
+ %1 = landingpad { i8*, i32 }
+ catch i8* null
+ %2 = extractvalue { i8*, i32 } %1, 0
+ store i8* %2, i8** %exn.slot, align 8
+ %3 = extractvalue { i8*, i32 } %1, 1
+ store i32 %3, i32* %ehselector.slot, align 4
+ br label %catch
+
+catch: ; preds = %lpad
+ %exn = load i8*, i8** %exn.slot, align 8
+ %4 = call i8* @__cxa_begin_catch(i8* %exn) #1
+ store i32 2, i32* %retval, align 4
+ call void @__cxa_end_catch()
+ br label %return
+
+try.cont: ; No predecessors!
+ store i32 1, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %try.cont, %catch
+ %5 = load i32, i32* %retval, align 4
+ ret i32 %5
+
+unreachable: ; preds = %entry
+ unreachable
+}
+
+; ASM: GCC_except_table0:
+; ASM: .Lexception0:
+; ASM: .byte 255 # @LPStart Encoding = omit
+; ASM: .byte 3 # @TType Encoding = udata4
+
+; NO128: .byte 49
+; NO128: .byte 3 # Call site Encoding = udata4
+; NO128: .byte 39
+; NO128: .long .Lfunc_begin0-.Lfunc_begin0 # >> Call Site 1 <<
+; NO128: .long .Ltmp0-.Lfunc_begin0 # Call between .Lfunc_begin0 and .Ltmp0
+; NO128: .long 0 # has no landing pad
+; NO128: .byte 0 # On action: cleanup
+; NO128: .long .Ltmp0-.Lfunc_begin0 # >> Call Site 2 <<
+; NO128: .long .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
+; NO128: .long .Ltmp2-.Lfunc_begin0 # jumps to .Ltmp2
+; NO128: .byte 1 # On action: 1
+; NO128: .long .Ltmp1-.Lfunc_begin0 # >> Call Site 3 <<
+; NO128: .long .Lfunc_end0-.Ltmp1 # Call between .Ltmp1 and .Lfunc_end0
+; NO128: .long 0 # has no landing pad
+; NO128: .byte 0 # On action: cleanup
+
+; ULEB128: .uleb128 .Lttbase0-.Lttbaseref0
+; ULEB128: .Lttbaseref0:
+; ULEB128: .byte 1 # Call site Encoding = uleb128
+; ULEB128: .uleb128 .Lcst_end0-.Lcst_begin0
+; ULEB128: .Lcst_begin0:
+; ULEB128: .uleb128 .Lfunc_begin0-.Lfunc_begin0 # >> Call Site 1 <<
+; ULEB128: .uleb128 .Ltmp0-.Lfunc_begin0 # Call between .Lfunc_begin0 and .Ltmp0
+; ULEB128: .byte 0 # has no landing pad
+; ULEB128: .byte 0 # On action: cleanup
+; ULEB128: .uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 2 <<
+; ULEB128: .uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
+; ULEB128: .uleb128 .Ltmp2-.Lfunc_begin0 # jumps to .Ltmp2
+; ULEB128: .byte 1 # On action: 1
+; ULEB128: .uleb128 .Ltmp1-.Lfunc_begin0 # >> Call Site 3 <<
+; ULEB128: .uleb128 .Lfunc_end0-.Ltmp1 # Call between .Ltmp1 and .Lfunc_end0
+; ULEB128: .byte 0 # has no landing pad
+; ULEB128: .byte 0 # On action: cleanup
+
+; ASM: .Lcst_end0:
+; ASM: .byte 1 # >> Action Record 1 <<
+; ASM: # Catch TypeInfo 1
+; ASM: .byte 0 # No further actions
+; ASM: .p2align 2
+; ASM: # >> Catch TypeInfos <<
+; ASM: .long 0 # TypeInfo 1
+; ASM: .Lttbase0:
+; ASM: .p2align 2
+
+declare dso_local i8* @__cxa_allocate_exception(i64)
+declare dso_local void @__cxa_throw(i8*, i8*, i8*)
+declare dso_local i32 @__gxx_personality_v0(...)
+declare dso_local i8* @__cxa_begin_catch(i8*)
+declare dso_local void @__cxa_end_catch()
More information about the llvm-branch-commits
mailing list