diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -805,20 +805,44 @@ // The following fields are decoded from the Metadata field. The encoding // happens in AsmPrinter.cpp:getBBAddrMapMetadata. - bool HasReturn; // If this block ends with a return (or tail call). - bool HasTailCall; // If this block ends with a tail call. - bool IsEHPad; // If this is an exception handling block. - bool CanFallThrough; // If this block can fall through to its next. - - BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, uint32_t Metadata) - : ID(ID), Offset(Offset), Size(Size), HasReturn(Metadata & 1), - HasTailCall(Metadata & (1 << 1)), IsEHPad(Metadata & (1 << 2)), - CanFallThrough(Metadata & (1 << 3)){}; + struct Metadata { + bool HasReturn : 1; // If this block ends with a return (or tail call). + bool HasTailCall : 1; // If this block ends with a tail call. + bool IsEHPad : 1; // If this is an exception handling block. + bool CanFallThrough : 1; // If this block can fall through to its next. + bool operator==(const Metadata &Other) const { + return memcmp(this, &Other, sizeof(Metadata)) == 0; + } + unsigned encode() const { + return ((unsigned)HasReturn) | (HasTailCall << 1) | (IsEHPad << 2) | + (CanFallThrough << 3); + } + static Metadata decode(unsigned V) { + return Metadata{ + static_cast(V & 1), static_cast(V & (1 << 1)), + static_cast(V & (1 << 2)), static_cast(V & (1 << 3))}; + } + } MD; + + bool hasReturn() const { return MD.HasReturn; } + bool hasTailCall() const { return MD.HasTailCall; } + bool isEHPad() const { return MD.IsEHPad; } + bool canFallThrough() const { return MD.CanFallThrough; } + + BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD) + : ID(ID), Offset(Offset), Size(Size), MD(MD){}; + // HasReturn(Metadata & 1), + // HasTailCall(Metadata & (1 << 1)), IsEHPad(Metadata & (1 << 2)), + // CanFallThrough(Metadata & (1 << 3)), HasIndirectBranch(Metdata & (1 << + // 4)) {}; bool operator==(const BBEntry &Other) const { return ID == Other.ID && Offset == Other.Offset && Size == Other.Size && - HasReturn == Other.HasReturn && HasTailCall == Other.HasTailCall && - IsEHPad == Other.IsEHPad && CanFallThrough == Other.CanFallThrough; + MD == Other.MD; + + // HasReturn == Other.HasReturn && HasTailCall == Other.HasTailCall && + // IsEHPad == Other.IsEHPad && CanFallThrough == Other.CanFallThrough && + // HasIndirectBranch == Other.HasIndirectBranch; } }; std::vector BBEntries; // Basic block entries for this function. diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -99,6 +99,7 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" +#include "llvm/Object/ELFTypes.h" #include "llvm/Pass.h" #include "llvm/Remarks/RemarkStreamer.h" #include "llvm/Support/Casting.h" @@ -1340,10 +1341,11 @@ /// The remaining bits are zero. static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) { const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); - return ((unsigned)MBB.isReturnBlock()) | - ((!MBB.empty() && TII->isTailCall(MBB.back())) << 1) | - (MBB.isEHPad() << 2) | - (const_cast(MBB).canFallThrough() << 3); + return object::BBAddrMap::BBEntry::Metadata{ + MBB.isReturnBlock(), !MBB.empty() && TII->isTailCall(MBB.back()), + const_cast(MBB).canFallThrough(), + !MBB.empty() && MBB.rbegin()->isIndirectBranch()} + .encode(); } void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -721,13 +721,14 @@ uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex; uint32_t Offset = ReadULEB128AsUInt32(); uint32_t Size = ReadULEB128AsUInt32(); - uint32_t Metadata = ReadULEB128AsUInt32(); + uint32_t MD = ReadULEB128AsUInt32(); if (Version >= 1) { // Offset is calculated relative to the end of the previous BB. Offset += PrevBBEndOffset; PrevBBEndOffset = Offset + Size; } - BBEntries.push_back({ID, Offset, Size, Metadata}); + BBEntries.push_back( + {ID, Offset, Size, BBAddrMap::BBEntry::Metadata::decode(MD)}); } FunctionEntries.push_back({Address, std::move(BBEntries)}); } diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -7337,10 +7337,10 @@ W.printNumber("ID", BBE.ID); W.printHex("Offset", BBE.Offset); W.printHex("Size", BBE.Size); - W.printBoolean("HasReturn", BBE.HasReturn); - W.printBoolean("HasTailCall", BBE.HasTailCall); - W.printBoolean("IsEHPad", BBE.IsEHPad); - W.printBoolean("CanFallThrough", BBE.CanFallThrough); + W.printBoolean("HasReturn", BBE.hasReturn()); + W.printBoolean("HasTailCall", BBE.hasTailCall()); + W.printBoolean("IsEHPad", BBE.isEHPad()); + W.printBoolean("CanFallThrough", BBE.canFallThrough()); } } } diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp --- a/llvm/unittests/Object/ELFObjectFileTest.cpp +++ b/llvm/unittests/Object/ELFObjectFileTest.cpp @@ -661,10 +661,10 @@ Metadata: 0x8 )"); - BBAddrMap E1 = {0x11111, {{1, 0x0, 0x1, 0x2}}}; - BBAddrMap E2 = {0x22222, {{2, 0x0, 0x2, 0x4}}}; - BBAddrMap E3 = {0x33333, {{0, 0x0, 0x3, 0x6}}}; - BBAddrMap E4 = {0x44444, {{0, 0x0, 0x4, 0x8}}}; + BBAddrMap E1 = {0x11111, {{1, 0x0, 0x1, {false, true, false, false}}}}; + BBAddrMap E2 = {0x22222, {{2, 0x0, 0x2, {false, false, true, false}}}}; + BBAddrMap E3 = {0x33333, {{0, 0x0, 0x3, {false, true, true, false}}}}; + BBAddrMap E4 = {0x44444, {{0, 0x0, 0x4, {false, false, false, true}}}}; std::vector Section0BBAddrMaps = {E4}; std::vector Section1BBAddrMaps = {E3};