llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-bolt Author: Amir Ayupov (aaupov) <details> <summary>Changes</summary> Define new JumpTable types for AArch64 based on definitions used in LLVM: https://github.com/llvm/llvm-project/blob/335a4614dee4123ff4f86e6400fc6a305766e227/llvm/lib/Target/AArch64/AArch64InstrInfo.td#L1217-L1225 Parsing and basic support is in a follow up PR #<!-- -->132114. Depends on #<!-- -->132108. --- Full diff: https://github.com/llvm/llvm-project/pull/132109.diff 8 Files Affected: - (modified) bolt/include/bolt/Core/BinaryContext.h (+12-1) - (modified) bolt/include/bolt/Core/JumpTable.h (+26-2) - (modified) bolt/lib/Core/BinaryContext.cpp (+21-17) - (modified) bolt/lib/Core/BinaryEmitter.cpp (+1-1) - (modified) bolt/lib/Core/BinaryFunction.cpp (+10-7) - (modified) bolt/lib/Core/JumpTable.cpp (+3-3) - (modified) bolt/lib/Passes/IndirectCallPromotion.cpp (+2-2) - (modified) bolt/lib/Passes/JTFootprintReduction.cpp (+1-1) ``````````diff diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 485979f1a55a1..d713f1b3721f6 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -435,7 +435,18 @@ class BinaryContext { /// Return size of an entry for the given jump table \p Type. uint64_t getJumpTableEntrySize(JumpTable::JumpTableType Type) const { - return Type == JumpTable::JTT_PIC ? 4 : AsmInfo->getCodePointerSize(); + switch (Type) { + case JumpTable::JTT_X86_64_PIC4: + return 4; + case JumpTable::JTT_X86_64_ABS: + return AsmInfo->getCodePointerSize(); + case JumpTable::JTT_AARCH64_REL1: + return 1; + case JumpTable::JTT_AARCH64_REL2: + return 2; + case JumpTable::JTT_AARCH64_REL4: + return 4; + } } /// Return JumpTable containing a given \p Address. diff --git a/bolt/include/bolt/Core/JumpTable.h b/bolt/include/bolt/Core/JumpTable.h index 52b9ccee1f7e1..7dc0c6581b233 100644 --- a/bolt/include/bolt/Core/JumpTable.h +++ b/bolt/include/bolt/Core/JumpTable.h @@ -47,10 +47,34 @@ class JumpTable : public BinaryData { public: enum JumpTableType : char { - JTT_NORMAL, - JTT_PIC, + JTT_X86_64_FIRST = 0, + JTT_X86_64_ABS = JTT_X86_64_FIRST, + JTT_X86_64_PIC4, + JTT_X86_64_LAST = JTT_X86_64_PIC4, + JTT_AARCH64_FIRST, + JTT_AARCH64_REL1 = JTT_AARCH64_FIRST, + JTT_AARCH64_REL2, + JTT_AARCH64_REL4, + JTT_AARCH64_LAST = JTT_AARCH64_REL4 }; + static StringRef getTypeStr(JumpTableType Type) { + switch (Type) { + case JTT_X86_64_ABS: + return "X86_64_ABS"; + case JTT_X86_64_PIC4: + return "X86_64_PIC4"; + case JTT_AARCH64_REL1: + return "AARCH64_REL1"; + case JTT_AARCH64_REL2: + return "AARCH64_REL2"; + case JTT_AARCH64_REL4: + return "AARCH64_REL4"; + } + } + + const StringRef getTypeStr() { return getTypeStr(Type); } + /// Branch statistics for jump table entries. struct JumpInfo { uint64_t Mispreds{0}; diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index c4902653a9b01..f557f4c06ccd3 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -496,7 +496,7 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF, const MemoryContentsType MemType = analyzeMemoryAt(Address, BF); if (MemType == MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE && IsPCRel) { const MCSymbol *Symbol = - getOrCreateJumpTable(BF, Address, JumpTable::JTT_PIC); + getOrCreateJumpTable(BF, Address, JumpTable::JTT_X86_64_PIC4); return std::make_pair(Symbol, 0); } @@ -540,10 +540,10 @@ MemoryContentsType BinaryContext::analyzeMemoryAt(uint64_t Address, // Start with checking for PIC jump table. We expect non-PIC jump tables // to have high 32 bits set to 0. - if (analyzeJumpTable(Address, JumpTable::JTT_PIC, BF)) + if (analyzeJumpTable(Address, JumpTable::JTT_X86_64_PIC4, BF)) return MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE; - if (analyzeJumpTable(Address, JumpTable::JTT_NORMAL, BF)) + if (analyzeJumpTable(Address, JumpTable::JTT_X86_64_ABS, BF)) return MemoryContentsType::POSSIBLE_JUMP_TABLE; return MemoryContentsType::UNKNOWN; @@ -594,12 +594,9 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address, if (NextJTAddress) UpperBound = std::min(NextJTAddress, UpperBound); - LLVM_DEBUG({ - using JTT = JumpTable::JumpTableType; - dbgs() << formatv("BOLT-DEBUG: analyzeJumpTable @{0:x} in {1}, JTT={2}\n", - Address, BF.getPrintName(), - Type == JTT::JTT_PIC ? "PIC" : "Normal"); - }); + LLVM_DEBUG( + dbgs() << formatv("BOLT-DEBUG: analyzeJumpTable @{0:x} in {1}, JTT={2}\n", + Address, BF, JumpTable::getTypeStr(Type))); const uint64_t EntrySize = getJumpTableEntrySize(Type); for (uint64_t EntryAddress = Address; EntryAddress <= UpperBound - EntrySize; EntryAddress += EntrySize) { @@ -607,13 +604,13 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address, << " -> "); // Check if there's a proper relocation against the jump table entry. if (HasRelocations) { - if (Type == JumpTable::JTT_PIC && + if (Type == JumpTable::JTT_X86_64_PIC4 && !DataPCRelocations.count(EntryAddress)) { LLVM_DEBUG( dbgs() << "FAIL: JTT_PIC table, no relocation for this address\n"); break; } - if (Type == JumpTable::JTT_NORMAL && !getRelocationAt(EntryAddress)) { + if (Type == JumpTable::JTT_X86_64_ABS && !getRelocationAt(EntryAddress)) { LLVM_DEBUG( dbgs() << "FAIL: JTT_NORMAL table, no relocation for this address\n"); @@ -621,10 +618,17 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address, } } - const uint64_t Value = - (Type == JumpTable::JTT_PIC) - ? Address + *getSignedValueAtAddress(EntryAddress, EntrySize) - : *getPointerAtAddress(EntryAddress); + uint64_t Value = 0; + switch (Type) { + case JumpTable::JTT_X86_64_PIC4: + Value = Address + *getSignedValueAtAddress(EntryAddress, EntrySize); + break; + case JumpTable::JTT_X86_64_ABS: + Value = *getPointerAtAddress(EntryAddress); + break; + default: + llvm_unreachable("Unhandled jump table type"); + } // __builtin_unreachable() case. if (Value == UnreachableAddress) { @@ -679,7 +683,7 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address, // Trim direct/normal jump table to exclude trailing unreachable entries that // can collide with a function address. - if (Type == JumpTable::JTT_NORMAL && EntriesAsAddress && + if (Type == JumpTable::JTT_X86_64_ABS && EntriesAsAddress && TrimmedSize != EntriesAsAddress->size() && getBinaryFunctionAtAddress(UnreachableAddress)) EntriesAsAddress->resize(TrimmedSize); @@ -736,7 +740,7 @@ void BinaryContext::populateJumpTables() { // In strict mode, erase PC-relative relocation record. Later we check that // all such records are erased and thus have been accounted for. - if (opts::StrictMode && JT->Type == JumpTable::JTT_PIC) { + if (opts::StrictMode && JT->Type == JumpTable::JTT_X86_64_PIC4) { for (uint64_t Address = JT->getAddress(); Address < JT->getAddress() + JT->getSize(); Address += JT->EntrySize) { diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp index 1aad25242712f..77272045d5bac 100644 --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -850,7 +850,7 @@ void BinaryEmitter::emitJumpTable(const JumpTable &JT, MCSection *HotSection, } LastLabel = LI->second; } - if (JT.Type == JumpTable::JTT_NORMAL) { + if (JT.Type == JumpTable::JTT_X86_64_ABS) { Streamer.emitSymbolValue(Entry, JT.OutputEntrySize); } else { // JTT_PIC const MCSymbolRefExpr *JTExpr = diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index b46ba1a0d1a85..effd3c4799bf6 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -912,7 +912,7 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, "Invalid memory instruction"); const MCExpr *FixedEntryDispExpr = FixedEntryDispOperand->getExpr(); const uint64_t EntryAddress = getExprValue(FixedEntryDispExpr); - uint64_t EntrySize = BC.getJumpTableEntrySize(JumpTable::JTT_PIC); + uint64_t EntrySize = BC.getJumpTableEntrySize(JumpTable::JTT_X86_64_PIC4); ErrorOr<int64_t> Value = BC.getSignedValueAtAddress(EntryAddress, EntrySize); if (!Value) @@ -982,12 +982,14 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, MemoryContentsType MemType; if (JumpTable *JT = BC.getJumpTableContainingAddress(ArrayStart)) { switch (JT->Type) { - case JumpTable::JTT_NORMAL: + case JumpTable::JTT_X86_64_ABS: MemType = MemoryContentsType::POSSIBLE_JUMP_TABLE; break; - case JumpTable::JTT_PIC: + case JumpTable::JTT_X86_64_PIC4: MemType = MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE; break; + default: + llvm_unreachable("Unhandled jump table type"); } } else { MemType = BC.analyzeMemoryAt(ArrayStart, *this); @@ -998,7 +1000,7 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, if (BranchType == IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE) { if (MemType != MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE) return IndirectBranchType::UNKNOWN; - JTType = JumpTable::JTT_PIC; + JTType = JumpTable::JTT_X86_64_PIC4; } else { if (MemType == MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE) return IndirectBranchType::UNKNOWN; @@ -1007,7 +1009,7 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, return IndirectBranchType::POSSIBLE_TAIL_CALL; BranchType = IndirectBranchType::POSSIBLE_JUMP_TABLE; - JTType = JumpTable::JTT_NORMAL; + JTType = JumpTable::JTT_X86_64_ABS; } // Convert the instruction into jump table branch. @@ -1779,7 +1781,8 @@ void BinaryFunction::postProcessJumpTables() { // Create labels for all entries. for (auto &JTI : JumpTables) { JumpTable &JT = *JTI.second; - if (JT.Type == JumpTable::JTT_PIC && opts::JumpTables == JTS_BASIC) { + if (JT.Type == JumpTable::JTT_X86_64_PIC4 && + opts::JumpTables == JTS_BASIC) { opts::JumpTables = JTS_MOVE; BC.outs() << "BOLT-INFO: forcing -jump-tables=move as PIC jump table was " "detected in function " @@ -1974,7 +1977,7 @@ bool BinaryFunction::postProcessIndirectBranches( BC.MIB->unsetJumpTable(Instr); JumpTable *JT = BC.getJumpTableContainingAddress(LastJT); - if (JT->Type == JumpTable::JTT_NORMAL) { + if (JT->Type == JumpTable::JTT_X86_64_ABS) { // Invalidating the jump table may also invalidate other jump table // boundaries. Until we have/need a support for this, mark the // function as non-simple. diff --git a/bolt/lib/Core/JumpTable.cpp b/bolt/lib/Core/JumpTable.cpp index 65e1032c579b5..e780c737c56b5 100644 --- a/bolt/lib/Core/JumpTable.cpp +++ b/bolt/lib/Core/JumpTable.cpp @@ -85,9 +85,9 @@ void bolt::JumpTable::updateOriginal() { uint64_t EntryOffset = BaseOffset; for (MCSymbol *Entry : Entries) { const uint64_t RelType = - Type == JTT_NORMAL ? ELF::R_X86_64_64 : ELF::R_X86_64_PC32; + Type == JTT_X86_64_ABS ? ELF::R_X86_64_64 : ELF::R_X86_64_PC32; const uint64_t RelAddend = - Type == JTT_NORMAL ? 0 : EntryOffset - BaseOffset; + Type == JTT_X86_64_ABS ? 0 : EntryOffset - BaseOffset; // Replace existing relocation with the new one to allow any modifications // to the original jump table. if (BC.HasRelocations) @@ -99,7 +99,7 @@ void bolt::JumpTable::updateOriginal() { void bolt::JumpTable::print(raw_ostream &OS) const { uint64_t Offset = 0; - if (Type == JTT_PIC) + if (Type == JTT_X86_64_PIC4) OS << "PIC "; ListSeparator LS; diff --git a/bolt/lib/Passes/IndirectCallPromotion.cpp b/bolt/lib/Passes/IndirectCallPromotion.cpp index 2b5a591f4c7a2..d70fd0e72e560 100644 --- a/bolt/lib/Passes/IndirectCallPromotion.cpp +++ b/bolt/lib/Passes/IndirectCallPromotion.cpp @@ -246,7 +246,7 @@ IndirectCallPromotion::getCallTargets(BinaryBasicBlock &BB, if (const JumpTable *JT = BF.getJumpTable(Inst)) { // Don't support PIC jump tables for now - if (!opts::ICPJumpTablesByTarget && JT->Type == JumpTable::JTT_PIC) + if (!opts::ICPJumpTablesByTarget && JT->Type == JumpTable::JTT_X86_64_PIC4) return Targets; const Location From(BF.getSymbol()); const std::pair<size_t, size_t> Range = @@ -256,7 +256,7 @@ IndirectCallPromotion::getCallTargets(BinaryBasicBlock &BB, const JumpTable::JumpInfo *JI = JT->Counts.empty() ? &DefaultJI : &JT->Counts[Range.first]; const size_t JIAdj = JT->Counts.empty() ? 0 : 1; - assert(JT->Type == JumpTable::JTT_PIC || + assert(JT->Type == JumpTable::JTT_X86_64_PIC4 || JT->EntrySize == BC.AsmInfo->getCodePointerSize()); for (size_t I = Range.first; I < Range.second; ++I, JI += JIAdj) { MCSymbol *Entry = JT->Entries[I]; diff --git a/bolt/lib/Passes/JTFootprintReduction.cpp b/bolt/lib/Passes/JTFootprintReduction.cpp index 71bdbba950df1..13b37dc3bc6ff 100644 --- a/bolt/lib/Passes/JTFootprintReduction.cpp +++ b/bolt/lib/Passes/JTFootprintReduction.cpp @@ -202,7 +202,7 @@ bool JTFootprintReduction::tryOptimizePIC(BinaryContext &BC, JumpTable->OutputEntrySize = 4; // DePICify - JumpTable->Type = JumpTable::JTT_NORMAL; + JumpTable->Type = JumpTable::JTT_X86_64_ABS; BB.replaceInstruction(Inst, NewFrag.begin(), NewFrag.end()); return true; `````````` </details> https://github.com/llvm/llvm-project/pull/132109 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits