Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
92e2fd6
Work in Progress: BOLT PPC support
kostasalv May 20, 2025
087c00e
[PPC][BOLT] Port createPushRegisters for PowerPC
kostasalv May 20, 2025
ea23773
[PPC][BOLT] Add CMakeLists
kostasalv May 20, 2025
d6e90c4
[PPC][BOLT] Adding PowerPC in parent CMakeLists
kostasalv May 20, 2025
f95555a
[PPC][BOLT] Adding factory function
kostasalv May 20, 2025
7d91a5e
[PPC][BOLT] Adding PCC factory function declaration
kostasalv May 20, 2025
ec46103
[PPC][BOLT] Update selection logic to invoke the PCC factory when PCC…
kostasalv May 20, 2025
cf14cf7
[PPC][BOLT] Define macro for POWERPC_AVAILABLE
kostasalv May 20, 2025
252544d
[PPC][BOLT]Fixing build
kostasalv May 20, 2025
e1df96e
[PPC][BOLT] Fix deprecated include
kostasalv May 20, 2025
7b01283
[PPC][BOLT] Cleaning includes to fix build error
kostasalv May 20, 2025
bfcb0d6
Fix build error, include generated headers, to resolve the undeclared…
kostasalv May 20, 2025
a52fabe
Fix build error, include generated headers
kostasalv May 20, 2025
4ebd40a
Fix build error, include generated headers
kostasalv May 20, 2025
9457f2b
[PPC][BOLT] Fix build error, copy PPGenInstrInfo.inc to include dir a…
kostasalv May 21, 2025
e74c4fa
[PPC][BOLT] Fix build error, copy PPCGenRegisterInfo.inc to include d…
kostasalv May 21, 2025
792ed13
[PPC][BOLT] Make enums STDU, PCC visible
kostasalv May 21, 2025
efd806e
[PPC][BOLT] clang-format
kostasalv May 21, 2025
04e648b
[BOLT][PPC] Add unit test.
kostasalv Jun 12, 2025
4b547ad
[PPC][BOLT] Use PPCMCTargetDesc.h to include generated .inc files
kostasalv Aug 26, 2025
8be1d9a
[PPC][BOLT] Add minimal PowerPC MCSymbolizer.
kostasalv Sep 19, 2025
7b58ba9
CI: retry code-format
kostasalv Sep 19, 2025
33cf3eb
[BOLT][PPC] Add PowerPC support to BinaryContext
kostasalv Sep 20, 2025
23fd9a8
[BOLT][PPC] Initial support for PPC64 relocations.
kostasalv Sep 20, 2025
3ffdc94
[PPC][BOLT] Updating Relocation to enable BOLT to run.
kostasalv Sep 20, 2025
4749935
[PPC][BOLT]
kostasalv Sep 20, 2025
b37c749
[PPC][BOLT]
kostasalv Sep 20, 2025
187edbe
[PPC][BOLT]
kostasalv Sep 20, 2025
c0ed4f0
[PPC][BOLT]
kostasalv Sep 20, 2025
f2dc56a
[PPC][BOLT]
kostasalv Sep 20, 2025
b187925
[PPC][BOLT]
kostasalv Sep 20, 2025
a38694c
[PPC][BOLT] Skip verification for PPC64 split-immediate and TOC16 rel…
kostasalv Sep 20, 2025
b5294ae
[BOLT][PPC] Safeguard symbol lookups in analyzeRelocation.
kostasalv Sep 20, 2025
ef8ea80
[PCC][BOLT] Update handleRelocation to avoid crashes on missing symbols
kostasalv Sep 20, 2025
c1046de
[PPC][BOLT]
kostasalv Sep 20, 2025
4e9edbc
[PPC][BOLT] Add shouldRecordCodeRelocation so PPCMCPlusBuilder. Overr…
kostasalv Sep 20, 2025
d4e0550
[PPC][BOLT] Skip 'verifyExtractedValue()' on PPC64 for relocation typ…
kostasalv Sep 20, 2025
42017b9
[PPC][BOLT] Add debug block to find relocation type that mismatched
kostasalv Sep 20, 2025
3e08a7f
[PPC][BOLT] Override analyzeIndirectBranch
kostasalv Sep 20, 2025
967c6f6
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
b1c1c85
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
36b7a4d
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
a390bb1
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
85b1e32
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
1f9eb2f
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
455ffc1
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 20, 2025
d1773be
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 22, 2025
1353afe
[PPC][BOLT] Add stub implementations for MCPlusBuilder methods to unb…
kostasalv Sep 22, 2025
3b1e7d2
[PPC][BOLT] Add disassemblePLTSectionPPC64 support.
kostasalv Sep 26, 2025
f359347
[PPC][BOLT] Implement convertJmpToTailCall for PowerPC.
kostasalv Sep 27, 2025
d3bee76
[PPC][BOLT] Add relocation support and fix PC-relative operant detect…
kostasalv Sep 27, 2025
03712a5
[PPC][BOLT] Implement isIndirectBranch() for PowerPC.
kostasalv Sep 28, 2025
ec0bb65
Fix replaceBranchTarget() when it is called on an instruction where b…
kostasalv Sep 28, 2025
941cf5a
[PPC][BOLT] Insert post-call NOP for ELFv2 to satisfy JITLink r2/TOC …
kostasalv Sep 28, 2025
0f929bd
[PPC][BOLT] Overriding isCall method to avoid default "not a call" so…
kostasalv Sep 29, 2025
f88b928
[PPC][BOLT] NOP is not added at the end. Adding debugging statements …
kostasalv Sep 29, 2025
de6778b
[PPC][BOLT] Add debug statements to figure out why NOP is not emitted.
kostasalv Sep 29, 2025
97c760b
[PPC][BOLT] Skip evaluateBracnh for PPC calls.
kostasalv Sep 29, 2025
929bb04
[PPC][BOLT] Implement evaluateMemOperandTarget() and refine PC-rel de…
kostasalv Sep 29, 2025
2509c82
[PPC][BOLT] Disable PC-rel operand evaluation for calls/branches.
kostasalv Sep 29, 2025
5678d12
[PPC][BOLT] Implement missing createNoop for PPC so the emitter can i…
kostasalv Sep 29, 2025
875969c
Revert "[PPC][BOLT] Skip evaluateBracnh for PPC calls."
kostasalv Sep 30, 2025
d99ed36
[PPC][BOLT] Fix PC-relative branch operand handing.
kostasalv Sep 30, 2025
ddcae49
[PPC][BOLT] Detect TOC-restore after calls and skip inserting NOP.
kostasalv Oct 1, 2025
9f0fa53
[PPC][BOLT] Fix condition bug.
kostasalv Oct 1, 2025
bc3c781
[PPC][BOLT] Added debug statements to troubleshoot.
kostasalv Oct 1, 2025
432e40a
[PPC][BOLT]
kostasalv Oct 1, 2025
ee2cde7
[PPC][BOLT] Neutralise PPC64 createPushRegister method to leave r1 un…
kostasalv Oct 2, 2025
819c2b0
[PPC][BOLT] Add debugging to troubleshoot the duplicate ld after bl
kostasalv Oct 2, 2025
3e98cd8
[PPC][BOLT] To fix operand comparison in method isTOCRestoreAfterCall…
kostasalv Oct 2, 2025
6456b38
[PPC][BOLT]
kostasalv Oct 2, 2025
c58161e
[PPC][BOLT] Resolve BOLT-WARNING "failed to analyze relocation TOC16_…
kostasalv Oct 5, 2025
857cc49
[PPC][BOLT] Update the unit test.
kostasalv Oct 5, 2025
966b070
[PPC][BOLT] Add support for Doubleword Storage form instructions.
kostasalv Oct 6, 2025
3faf3ae
[PPC][BOLT] Compute PPC64 ELFv2 TOC base as .got + 0x8000
kostasalv Oct 8, 2025
143d450
[PPC][BOLT] Fix compilation error "variable 'G' with type 'const auto…
kostasalv Oct 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bolt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ endif() # standalone

# Determine default set of targets to build -- the intersection of
# those BOLT supports and those LLVM is targeting.
set(BOLT_TARGETS_TO_BUILD_all "AArch64;X86;RISCV")
set(BOLT_TARGETS_TO_BUILD_all "AArch64;X86;RISCV;PowerPC")
set(BOLT_TARGETS_TO_BUILD_default)
foreach (tgt ${BOLT_TARGETS_TO_BUILD_all})
if (tgt IN_LIST LLVM_TARGETS_TO_BUILD)
Expand Down
5 changes: 5 additions & 0 deletions bolt/include/bolt/Core/BinaryContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,11 @@ class BinaryContext {
TheTriple->getArch() == llvm::Triple::x86_64;
}

bool isPPC64() const {
return TheTriple->getArch() == llvm::Triple::ppc64 ||
TheTriple->getArch() == llvm::Triple::ppc64le;
}

bool isRISCV() const { return TheTriple->getArch() == llvm::Triple::riscv64; }

// AArch64-specific functions to check if symbol is used to delimit
Expand Down
7 changes: 7 additions & 0 deletions bolt/include/bolt/Core/MCPlusBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,8 @@ class MCPlusBuilder {
return isCall(Inst) && getEHInfo(Inst);
}

virtual bool isTOCRestoreAfterCall(const MCInst &Inst) const { return false; }

/// Return true if \p Inst is an instruction that potentially traps when
/// working with addresses not aligned to the size of the operand.
virtual bool requiresAlignedAddress(const MCInst &Inst) const {
Expand Down Expand Up @@ -2373,6 +2375,11 @@ MCPlusBuilder *createRISCVMCPlusBuilder(const MCInstrAnalysis *,
const MCRegisterInfo *,
const MCSubtargetInfo *);

MCPlusBuilder *createPowerPCMCPlusBuilder(const MCInstrAnalysis *,
const MCInstrInfo *,
const MCRegisterInfo *,
const MCSubtargetInfo *);

} // namespace bolt
} // namespace llvm

Expand Down
11 changes: 11 additions & 0 deletions bolt/include/bolt/Rewrite/RewriteInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ class RewriteInstance {
/// is the expected .plt \p Section entry function size.
void disassemblePLTSectionX86(BinarySection &Section, uint64_t EntrySize);

/// Disassemble ppc64-specific .plt \p Section auxiliary function
void disassemblePLTSectionPPC64(BinarySection &Section);

/// Disassemble riscv-specific .plt \p Section auxiliary function
void disassemblePLTSectionRISCV(BinarySection &Section);

Expand Down Expand Up @@ -514,6 +517,14 @@ class RewriteInstance {
/// Flag indicating runtime library linking just started.
bool StartLinkingRuntimeLib{false};

/// PPC64 TOC (Table of Contents) base address used for resolving function and
/// data references on PPC64 binaries. Set when processing PPC64 binaries with
/// a TOC base present.
uint64_t PPC64TOCBase = 0;

/// Flag indicating whether PPC64TOCBase has been set and is valid for use.
bool HavePPC64TOCBase = false;

/// Information on special Procedure Linkage Table sections. There are
/// multiple variants generated by different linkers.
struct PLTSectionInfo {
Expand Down
81 changes: 81 additions & 0 deletions bolt/include/bolt/Target/PowerPC/PPCMCPlusBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#pragma once

#include "bolt/Core/MCPlusBuilder.h"

namespace llvm {
namespace bolt {

class PPCMCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;

static void createPushRegisters(MCInst &Inst1, MCInst &Inst2, MCPhysReg Reg1,
MCPhysReg Reg2);

bool shouldRecordCodeRelocation(unsigned Type) const override;

bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
uint64_t &Target) const override;

bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,
uint64_t Address = 0,
uint64_t Size = 0) const override;
bool hasPCRelOperand(const MCInst &I) const override;
int getPCRelOperandNum(const MCInst &Inst) const;

int getMemoryOperandNo(const MCInst &Inst) const override;

void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB,
MCContext *Ctx) const override;
bool isIndirectBranch(const MCInst &I) const override;

const MCSymbol *getTargetSymbol(const MCInst &Inst,
unsigned OpNum = 0) const override;

bool convertJmpToTailCall(MCInst &Inst) override;

bool isCall(const MCInst &Inst) const override;

bool isBranch(const MCInst &Inst) const override;

bool isTailCall(const MCInst &Inst) const;
bool isReturn(const MCInst &Inst) const override;
bool isConditionalBranch(const MCInst &Inst) const override;
bool isUnconditionalBranch(const MCInst &Inst) const override;

const MCInst *getConditionalTailCall(const MCInst &Inst) const;

IndirectBranchType
analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin,
InstructionIterator End, const unsigned PtrSize,
MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut,
unsigned &IndexRegNumOut, int64_t &DispValueOut,
const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut,
MCInst *&FixedEntryLoadInstr) const override;

bool isNoop(const MCInst &Inst) const override;
void createNoop(MCInst &Nop) const override;

bool analyzeBranch(InstructionIterator Begin, InstructionIterator End,
const llvm::MCSymbol *&Tgt,
const llvm::MCSymbol *&Fallthrough, llvm::MCInst *&CondBr,
llvm::MCInst *&UncondBr) const override;

bool lowerTailCall(llvm::MCInst &Inst) override;

uint64_t analyzePLTEntry(MCInst &Instruction, InstructionIterator Begin,
InstructionIterator End,
uint64_t BeginPC) const override;

void createLongTailCall(std::vector<MCInst> &Seq, const MCSymbol *Target,
MCContext *Ctx) override;

std::optional<Relocation>
createRelocation(const MCFixup &Fixup,
const MCAsmBackend &MAB) const override;

bool isTOCRestoreAfterCall(const MCInst &I) const override;
};

} // namespace bolt
} // namespace llvm
14 changes: 14 additions & 0 deletions bolt/lib/Core/BinaryContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
ArchName = "aarch64";
FeaturesStr = "+all";
break;
case llvm::Triple::ppc64:
if (Features)
return createFatalBOLTError(
"PowerPC target does not use SubtargetFeatures");
ArchName = "ppc64";
FeaturesStr = "";
break;
case llvm::Triple::ppc64le:
if (Features)
return createFatalBOLTError(
"PowerPC target does not use SubtargetFeatures");
ArchName = "ppc64le";
FeaturesStr = "";
break;
case llvm::Triple::riscv64: {
ArchName = "riscv64";
if (!Features)
Expand Down
58 changes: 58 additions & 0 deletions bolt/lib/Core/BinaryEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "llvm/Support/SMLoc.h"

#define DEBUG_TYPE "bolt"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace bolt;
Expand Down Expand Up @@ -471,10 +473,24 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
Streamer.emitLabel(EntrySymbol);
}

bool LastWasCall = false;
SMLoc LastLocSeen;
for (auto I = BB->begin(), E = BB->end(); I != E; ++I) {
MCInst &Instr = *I;

// PPC64 ELFv2: JITLink expects a NOP at call+4 and will rewrite it to
// 'ld r2,24(r1)'. The static linker already emits the LD and then
// JITLink asserts that it expects NOP at call+4. Normalise here so
// JITLink doesn't assert.
if (BC.isPPC64() && LastWasCall && BC.MIB->isTOCRestoreAfterCall(Instr)) {
LLVM_DEBUG(dbgs() << "PPC emit: normalizing TOC-restore after call\n");
MCInst Nop;
BC.MIB->createNoop(Nop); // ori r0,r0,0
Streamer.emitInstruction(Nop, *BC.STI);
LastWasCall = false;
continue;
}

if (EmitCodeOnly && BC.MIB->isPseudo(Instr))
continue;

Expand Down Expand Up @@ -519,7 +535,49 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
}
}

LLVM_DEBUG(dbgs() << "EMIT " << BC.MII->getName(Instr.getOpcode())
<< "\n");

Streamer.emitInstruction(Instr, *BC.STI);
LastWasCall = BC.MIB->isCall(Instr);

if (BC.isPPC64() && BC.MIB->isTOCRestoreAfterCall(Instr))
LLVM_DEBUG(dbgs() << "EMIT is TOC-restore\n");

// --- PPC64 ELFv2: guarantee a post-call NOP (call slot)
if (BC.isPPC64() && BC.MIB->isCall(Instr)) {
bool NeedSlot = true;
LLVM_DEBUG(dbgs() << "PPC emit: call, considering slot after\n");

// If the next IR instruction exists and is already a NOP or TOC-restore
// , don't inject.
auto NextI = std::next(I);
LLVM_DEBUG({
dbgs() << "PPC emit: CALL seen: next=";
if (NextI == E)
dbgs() << "<end>\n";
else
dbgs() << BC.MII->getName(NextI->getOpcode())
<< (BC.MIB->isTOCRestoreAfterCall(*NextI)
? " (TOC restore)\n"
: "\n");
});
if (NextI != E &&
(BC.MIB->isNoop(*NextI) || BC.MIB->isTOCRestoreAfterCall(*NextI))) {
NeedSlot = false;
}

if (NeedSlot) {
LLVM_DEBUG(dbgs() << "PPC emit: inserting post-call NOP\n");
MCInst N;
BC.MIB->createNoop(N);
Streamer.emitInstruction(N, *BC.STI);
LLVM_DEBUG(dbgs() << "PPC: inserted NOP after call at "
<< BF.getPrintName() << "\n");
} else {
LLVM_DEBUG(dbgs() << "PPC emit: post-call NOP not needed\n");
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,7 @@ Error BinaryFunction::disassemble() {
setIgnored();

if (MIB->isBranch(Instruction) || MIB->isCall(Instruction)) {

uint64_t TargetAddress = 0;
if (MIB->evaluateBranch(Instruction, AbsoluteInstrAddr, Size,
TargetAddress)) {
Expand Down
Loading
Loading