Skip to content

Commit

Permalink
[AIX][XCOFF] generate eh_info when vector registers are saved accordi…
Browse files Browse the repository at this point in the history
…ng to the traceback table.

Summary:

generate eh_info when vector registers are saved according to the traceback table.

struct eh_info_t {

unsigned version;       /* EH info version 0 */
#if defined(64BIT)

char _pad[4];           /* padding */
#endif

unsigned long lsda;     /* Pointer to Language Specific Data Area */
unsigned long personality; /* Pointer to the personality routine */
};

the value of lsda and personality is zero when the number of vector registers saved is large zero and there is not personality of the function

Reviewers: Jason Liu
Differential Revision: https://reviews.llvm.org/D103651
  • Loading branch information
diggerlin committed Jun 22, 2021
1 parent d797a7f commit bd240b3
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 22 deletions.
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
}

void AIXException::endFunction(const MachineFunction *MF) {
// There is no easy way to access register information in `AIXException`
// class. when ShouldEmitEHBlock is false and VRs are saved, A dumy eh info
// table are emitted in PPCAIXAsmPrinter::emitFunctionBodyEnd.
if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF))
return;

Expand Down
77 changes: 56 additions & 21 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
GOAliasMap;

uint16_t getNumberOfVRSaved();
void emitTracebackTable();

SmallVector<const GlobalVariable *, 8> TOCDataGlobalVars;
Expand Down Expand Up @@ -1881,12 +1882,53 @@ void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
return AsmPrinter::SetupMachineFunction(MF);
}

uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
// Calculate the number of VRs be saved.
// Vector registers 20 through 31 are marked as reserved and cannot be used
// in the default ABI.
const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
TM.getAIXExtendedAltivecABI()) {
const MachineRegisterInfo &MRI = MF->getRegInfo();
for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
if (MRI.isPhysRegModified(Reg))
// Number of VRs saved.
return PPC::V31 - Reg + 1;
}
return 0;
}

void PPCAIXAsmPrinter::emitFunctionBodyEnd() {

if (!TM.getXCOFFTracebackTable())
return;

emitTracebackTable();

// If ShouldEmitEHBlock returns true, then the eh info table
// will be emitted via `AIXException::endFunction`. Otherwise, we
// need to emit a dumy eh info table when VRs are saved. We could not
// consolidate these two places into one because there is no easy way
// to access register information in `AIXException` class.
if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF) &&
(getNumberOfVRSaved() > 0)) {
// Emit dummy EH Info Table.
OutStreamer->SwitchSection(getObjFileLowering().getCompactUnwindSection());
MCSymbol *EHInfoLabel =
TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF);
OutStreamer->emitLabel(EHInfoLabel);

// Version number.
OutStreamer->emitInt32(0);

const DataLayout &DL = MMI->getModule()->getDataLayout();
const unsigned PointerSize = DL.getPointerSize();
// Add necessary paddings in 64 bit mode.
OutStreamer->emitValueToAlignment(PointerSize);

OutStreamer->emitIntValue(0, PointerSize);
OutStreamer->emitIntValue(0, PointerSize);
}
}

void PPCAIXAsmPrinter::emitTracebackTable() {
Expand Down Expand Up @@ -2041,7 +2083,10 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
if (FI->hasVectorParms() || HasVectorInst)
SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;

bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
uint16_t NumOfVRSaved = getNumberOfVRSaved();
bool ShouldEmitEHBlock =
TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF) || NumOfVRSaved > 0;

if (ShouldEmitEHBlock)
SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;

Expand Down Expand Up @@ -2151,26 +2196,16 @@ void PPCAIXAsmPrinter::emitTracebackTable() {

if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
uint16_t VRData = 0;
// Calculate the number of VRs be saved.
// Vector registers 20 through 31 are marked as reserved and cannot be used
// in the default ABI.
const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
TM.getAIXExtendedAltivecABI()) {
for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
if (MRI.isPhysRegModified(Reg)) {
// Number of VRs saved.
VRData |=
((PPC::V31 - Reg + 1) << TracebackTable::NumberOfVRSavedShift) &
TracebackTable::NumberOfVRSavedMask;
// This bit is supposed to set only when the special register
// VRSAVE is saved on stack.
// However, IBM XL compiler sets the bit when any vector registers
// are saved on the stack. We will follow XL's behavior on AIX
// so that we don't get surprise behavior change for C code.
VRData |= TracebackTable::IsVRSavedOnStackMask;
break;
}
if (NumOfVRSaved) {
// Number of VRs saved.
VRData |= (NumOfVRSaved << TracebackTable::NumberOfVRSavedShift) &
TracebackTable::NumberOfVRSavedMask;
// This bit is supposed to set only when the special register
// VRSAVE is saved on stack.
// However, IBM XL compiler sets the bit when any vector registers
// are saved on the stack. We will follow XL's behavior on AIX
// so that we don't get surprise behavior change for C code.
VRData |= TracebackTable::IsVRSavedOnStackMask;
}

// Set has_varargs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ entry:
; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
; COMMON-NEXT: .byte 0xc0 # +HasVectorInfo, +HasExtensionTable, NumOfGPRsSaved = 0
; COMMON-NEXT: .byte 0x00 # NumberOfFixedParms = 0
; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
; CHECK-ASM-NEXT: .vbyte 4, L..foov0-.foov # Function size
Expand All @@ -80,4 +80,17 @@ entry:
; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction
; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type =
; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
; COMMON-NEXT: .byte 0x08 # ExtensionTableFlag = TB_EH_INFO
; COMMON-NEXT: .align 2
; COMMON-NEXT: .vbyte 4, L..C2-TOC[TC0] # EHInfo Table

; COMMON: .csect .eh_info_table[RW],2
; COMMON-NEXT:__ehinfo.1:
; COMMON-NEXT: .vbyte 4, 0
; COMMON-NEXT: .align 2
; COMMON-NEXT: .vbyte 4, 0
; COMMON-NEXT: .vbyte 4, 0
; COMMON-NEXT: # -- End function
; COMMON: .toc
; COMMON: L..C2:
; COMMON-NEXT: .tc __ehinfo.1[TC],__ehinfo.1

0 comments on commit bd240b3

Please sign in to comment.