Skip to content

Commit

Permalink
[SOL] Revive BTF/CO-RE crud from bitrot.
Browse files Browse the repository at this point in the history
BTF/CO-RE has been disabled for Solana since:
#37

This patch updates related code (and all applicable unit tests) from roughly
a year of bitrot. This is in preparation for its possible use in the Move
project.

Additionally, a few other 14.0.2022-03-02 -> 15.0-2022-08-09 BPF patches
were reflected in the SBF back-end (e.g., bugfixes).
  • Loading branch information
nvjle authored and LucasSte committed Aug 19, 2024
1 parent 6d946f1 commit 7a6f5f7
Show file tree
Hide file tree
Showing 176 changed files with 16,144 additions and 53 deletions.
13 changes: 7 additions & 6 deletions llvm/lib/Target/SBF/Disassembler/SBFDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static const unsigned GPRDecoderTable[] = {

static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t /*Address*/,
const void * /*Decoder*/) {
const MCDisassembler * /*Decoder*/) {
if (RegNo > 11)
return MCDisassembler::Fail;

Expand All @@ -108,9 +108,9 @@ static const unsigned GPR32DecoderTable[] = {
SBF::W0, SBF::W1, SBF::W2, SBF::W3, SBF::W4, SBF::W5,
SBF::W6, SBF::W7, SBF::W8, SBF::W9, SBF::W10, SBF::W11};

static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t /*Address*/,
const void * /*Decoder*/) {
static DecodeStatus
DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
const MCDisassembler * /*Decoder*/) {
if (RegNo > 11)
return MCDisassembler::Fail;

Expand All @@ -120,7 +120,8 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
}

static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
uint64_t Address,
const MCDisassembler *Decoder) {
unsigned Register = (Insn >> 16) & 0xf;
if (Register > 11)
return MCDisassembler::Fail;
Expand Down Expand Up @@ -216,4 +217,4 @@ DecodeStatus SBFDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
}

typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder);
const MCDisassembler *Decoder);
5 changes: 5 additions & 0 deletions llvm/lib/Target/SBF/MCTargetDesc/SBFAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void SBFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
}
} else {
assert(Fixup.getKind() == FK_PCRel_2);

int64_t ByteOff = (int64_t)Value - 8;
if (ByteOff > INT16_MAX * 8 || ByteOff < INT16_MIN * 8)
report_fatal_error("Branch target out of insn range");

Value = (uint16_t)((Value - 8) / 8);
support::endian::write<uint16_t>(&Data[Fixup.getOffset() + 2], Value,
Endian);
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Target/SBF/MCTargetDesc/SBFMCAsmInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,4 @@ SBFMCAsmInfo::SBFMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) {
// section will be parsable, but with odd offsets and
// line numbers, etc.
CodePointerSize = 8;

UseIntegratedAssembler = false;
}
5 changes: 2 additions & 3 deletions llvm/lib/Target/SBF/MCTargetDesc/SBFMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ using namespace llvm;
namespace {

class SBFMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
const MCRegisterInfo &MRI;
bool IsLittleEndian;

public:
SBFMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri,
SBFMCCodeEmitter(const MCInstrInfo &, const MCRegisterInfo &mri,
bool IsLittleEndian)
: MCII(mcii), MRI(mri), IsLittleEndian(IsLittleEndian) {}
: MRI(mri), IsLittleEndian(IsLittleEndian) {}
SBFMCCodeEmitter(const SBFMCCodeEmitter &) = delete;
void operator=(const SBFMCCodeEmitter &) = delete;
~SBFMCCodeEmitter() override = default;
Expand Down
45 changes: 31 additions & 14 deletions llvm/lib/Target/SBF/SBFAbstractMemberAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class SBFAbstractMemberAccess final {
struct CallInfo {
uint32_t Kind;
uint32_t AccessIndex;
Align RecordAlignment;
MaybeAlign RecordAlignment;
MDNode *Metadata;
Value *Base;
};
Expand All @@ -142,9 +142,9 @@ class SBFAbstractMemberAccess final {
Module *M = nullptr;

static std::map<std::string, GlobalVariable *> GEPGlobals;
// A map to link preserve_*_access_index instrinsic calls.
// A map to link preserve_*_access_index intrinsic calls.
std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
// A map to hold all the base preserve_*_access_index instrinsic calls.
// A map to hold all the base preserve_*_access_index intrinsic calls.
// The base call is not an input of any other preserve_*
// intrinsics.
std::map<CallInst *, CallInfo> BaseAICalls;
Expand Down Expand Up @@ -176,7 +176,7 @@ class SBFAbstractMemberAccess final {
uint32_t &StartBitOffset, uint32_t &EndBitOffset);
uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
uint32_t AccessIndex, uint32_t PatchImm,
Align RecordAlignment);
MaybeAlign RecordAlignment);

Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo,
std::string &AccessKey, MDNode *&BaseMeta);
Expand Down Expand Up @@ -410,6 +410,8 @@ bool SBFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call,
report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
if (Flag == SBFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE)
CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_EXISTENCE;
else if (Flag == SBFCoreSharedInfo::PRESERVE_TYPE_INFO_MATCH)
CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_MATCH;
else
CInfo.AccessIndex = SBFCoreSharedInfo::TYPE_SIZE;
return true;
Expand Down Expand Up @@ -669,10 +671,20 @@ void SBFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
uint32_t &EndBitOffset) {
uint32_t MemberBitSize = MemberTy->getSizeInBits();
uint32_t MemberBitOffset = MemberTy->getOffsetInBits();

if (RecordAlignment > 8) {
// If the Bits are within an aligned 8-byte, set the RecordAlignment
// to 8, other report the fatal error.
if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
"requiring too big alignment");
RecordAlignment = Align(8);
}

uint32_t AlignBits = RecordAlignment.value() * 8;
if (RecordAlignment > 8 || MemberBitSize > AlignBits)
if (MemberBitSize > AlignBits)
report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
"requiring too big alignment");
"bitfield size greater than record alignment");

StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
Expand All @@ -685,7 +697,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
DICompositeType *CTy,
uint32_t AccessIndex,
uint32_t PatchImm,
Align RecordAlignment) {
MaybeAlign RecordAlignment) {
if (InfoKind == SBFCoreSharedInfo::FIELD_EXISTENCE)
return 1;

Expand All @@ -701,7 +713,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
PatchImm += MemberTy->getOffsetInBits() >> 3;
} else {
unsigned SBitOffset, NextSBitOffset;
GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset,
GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
NextSBitOffset);
PatchImm += SBitOffset >> 3;
}
Expand All @@ -720,7 +732,8 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
return SizeInBits >> 3;

unsigned SBitOffset, NextSBitOffset;
GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
NextSBitOffset);
SizeInBits = NextSBitOffset - SBitOffset;
if (SizeInBits & (SizeInBits - 1))
report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info");
Expand Down Expand Up @@ -780,7 +793,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
}

unsigned SBitOffset, NextSBitOffset;
GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
if (NextSBitOffset - SBitOffset > 64)
report_fatal_error("too big field size for llvm.bpf.preserve.field.info");

Expand Down Expand Up @@ -811,7 +824,7 @@ uint32_t SBFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
}

unsigned SBitOffset, NextSBitOffset;
GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
if (NextSBitOffset - SBitOffset > 64)
report_fatal_error("too big field size for llvm.bpf.preserve.field.info");

Expand Down Expand Up @@ -1000,7 +1013,8 @@ MDNode *SBFAbstractMemberAccess::computeAccessKey(CallInst *Call,

int64_t PatchImm;
std::string AccessStr("0");
if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_EXISTENCE) {
if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_EXISTENCE ||
CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_MATCH) {
PatchImm = 1;
} else if (CInfo.AccessIndex == SBFCoreSharedInfo::TYPE_SIZE) {
// typedef debuginfo type has size 0, get the eventual base type.
Expand All @@ -1010,8 +1024,11 @@ MDNode *SBFAbstractMemberAccess::computeAccessKey(CallInst *Call,
// ENUM_VALUE_EXISTENCE and ENUM_VALUE
IsInt32Ret = false;

const auto *CE = cast<ConstantExpr>(Call->getArgOperand(1));
const GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
// The argument could be a global variable or a getelementptr with base to
// a global variable depending on whether the clang option `opaque-options`
// is set or not.
const GlobalVariable *GV =
cast<GlobalVariable>(Call->getArgOperand(1)->stripPointerCasts());
assert(GV->hasInitializer());
const ConstantDataArray *DA = cast<ConstantDataArray>(GV->getInitializer());
assert(DA->isString());
Expand Down
10 changes: 8 additions & 2 deletions llvm/lib/Target/SBF/SBFAdjustOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,16 @@ bool SBFAdjustOptImpl::serializeICMPCrossBB(BasicBlock &BB) {
return false;

if (Cond1Op == ICmpInst::ICMP_SGT || Cond1Op == ICmpInst::ICMP_SGE) {
if (Cond2Op != ICmpInst::ICMP_SLT && Cond1Op != ICmpInst::ICMP_SLE)
if (Cond2Op != ICmpInst::ICMP_SLT && Cond2Op != ICmpInst::ICMP_SLE)
return false;
} else if (Cond1Op == ICmpInst::ICMP_SLT || Cond1Op == ICmpInst::ICMP_SLE) {
if (Cond2Op != ICmpInst::ICMP_SGT && Cond1Op != ICmpInst::ICMP_SGE)
if (Cond2Op != ICmpInst::ICMP_SGT && Cond2Op != ICmpInst::ICMP_SGE)
return false;
} else if (Cond1Op == ICmpInst::ICMP_ULT || Cond1Op == ICmpInst::ICMP_ULE) {
if (Cond2Op != ICmpInst::ICMP_UGT && Cond2Op != ICmpInst::ICMP_UGE)
return false;
} else if (Cond1Op == ICmpInst::ICMP_UGT || Cond1Op == ICmpInst::ICMP_UGE) {
if (Cond2Op != ICmpInst::ICMP_ULT && Cond2Op != ICmpInst::ICMP_ULE)
return false;
} else {
return false;
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/SBF/SBFAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"

extern cl::opt<unsigned> SBFAsmWriterVariant;
static cl::opt<bool> SBFEnableBTFEmission(
"sbf-enable-btf-emission", cl::Hidden, cl::init(false),
cl::desc("Enable BTF debuginfo sections to be emitted"));

namespace {
class SBFAsmPrinter : public AsmPrinter {
Expand Down Expand Up @@ -62,9 +65,10 @@ bool SBFAsmPrinter::doInitialization(Module &M) {
AsmPrinter::doInitialization(M);

// Only emit BTF when debuginfo available.
// Unsupported for Solana: https://github.com/solana-labs/llvm-project/issues/37
// Unsupported for Solana:
// https://github.com/solana-labs/llvm-project/issues/37
if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty() &&
!TM.getMCSubtargetInfo()->hasFeature(SBF::FeatureSolana) && TM.getTargetTriple().getArch() != Triple::sbf) {
SBFEnableBTFEmission) {
BTF = new BTFX::BTFDebug(this);
Handlers.push_back(HandlerInfo(std::unique_ptr<BTFX::BTFDebug>(BTF), "emit",
"Debug Info Emission", "BTF",
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SBF/SBFCORE.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class SBFCoreSharedInfo {
TYPE_SIZE,
ENUM_VALUE_EXISTENCE,
ENUM_VALUE,
TYPE_MATCH,

MAX_FIELD_RELOC_KIND,
};
Expand All @@ -46,6 +47,7 @@ class SBFCoreSharedInfo {
enum PreserveTypeInfo : uint32_t {
PRESERVE_TYPE_INFO_EXISTENCE = 0,
PRESERVE_TYPE_INFO_SIZE,
PRESERVE_TYPE_INFO_MATCH,

MAX_PRESERVE_TYPE_INFO_FLAG,
};
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/SBF/SBFInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ bool SBFInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
}

// If the block has any instructions after a J, delete them.
while (std::next(I) != MBB.end())
std::next(I)->eraseFromParent();
MBB.erase(std::next(I), MBB.end());
Cond.clear();
FBB = nullptr;

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ def FI_ri
let Inst{47-32} = 0;
let Inst{31-0} = 0;
let SBFClass = SBF_LD;
bit isPseudo = true;
}

def LD_pseudo
Expand Down
23 changes: 19 additions & 4 deletions llvm/lib/Target/SBF/SBFMISimplifyPatchable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include <set>

using namespace llvm;

Expand All @@ -52,9 +53,12 @@ struct SBFMISimplifyPatchable : public MachineFunctionPass {
}

private:
std::set<MachineInstr *> SkipInsts;

// Initialize class variables.
void initialize(MachineFunction &MFParm);

bool isLoadInst(unsigned Opcode);
bool removeLD();
void processCandidate(MachineRegisterInfo *MRI, MachineBasicBlock &MBB,
MachineInstr &MI, Register &SrcReg, Register &DstReg,
Expand Down Expand Up @@ -88,6 +92,12 @@ void SBFMISimplifyPatchable::initialize(MachineFunction &MFParm) {
LLVM_DEBUG(dbgs() << "*** SBF simplify patchable insts pass ***\n\n");
}

bool SBFMISimplifyPatchable::isLoadInst(unsigned Opcode) {
return Opcode == SBF::LDD || Opcode == SBF::LDW || Opcode == SBF::LDH ||
Opcode == SBF::LDB || Opcode == SBF::LDW32 || Opcode == SBF::LDH32 ||
Opcode == SBF::LDB32;
}

void SBFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI,
MachineOperand *RelocOp, const GlobalValue *GVal) {
const MachineInstr *Inst = RelocOp->getParent();
Expand Down Expand Up @@ -229,6 +239,11 @@ void SBFMISimplifyPatchable::processDstReg(MachineRegisterInfo *MRI,
void SBFMISimplifyPatchable::processInst(MachineRegisterInfo *MRI,
MachineInstr *Inst, MachineOperand *RelocOp, const GlobalValue *GVal) {
unsigned Opcode = Inst->getOpcode();
if (isLoadInst(Opcode)) {
SkipInsts.insert(Inst);
return;
}

if (Opcode == SBF::ADD_rr)
checkADDrr(MRI, RelocOp, GVal);
else if (Opcode == SBF::SLL_rr)
Expand All @@ -253,10 +268,10 @@ bool SBFMISimplifyPatchable::removeLD() {
}

// Ensure the register format is LOAD <reg>, <reg>, 0
if (MI.getOpcode() != SBF::LDD && MI.getOpcode() != SBF::LDW &&
MI.getOpcode() != SBF::LDH && MI.getOpcode() != SBF::LDB &&
MI.getOpcode() != SBF::LDW32 && MI.getOpcode() != SBF::LDH32 &&
MI.getOpcode() != SBF::LDB32)
if (!isLoadInst(MI.getOpcode()))
continue;

if (SkipInsts.find(&MI) != SkipInsts.end())
continue;

if (!MI.getOperand(0).isReg() || !MI.getOperand(1).isReg())
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/CodeGen/SBF/BTF/align.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; RUN: llc -sbf-enable-btf-emission -march=sbf -filetype=obj < %s | llvm-readelf -S - | FileCheck %s
; Source:
; int foo() { return 0; }
; Compilation flags:
; clang -target bpf -O2 -g -S -emit-llvm t.c

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
define dso_local i32 @foo() local_unnamed_addr #0 !dbg !7 {
entry:
ret i32 0, !dbg !12
}
; CHECK: Name Type Address Off Size ES Flg Lk Inf Al
; CHECK: .BTF PROGBITS 0000000000000000 {{[0-9a-f]+}} {{[0-9a-f]+}} 00 0 0 4
; CHECK: .BTF.ext PROGBITS 0000000000000000 {{[0-9a-f]+}} {{[0-9a-f]+}} 00 0 0 4

attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git b1ab2a57b83e4b7224c38b534532500cc90e5b9a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "t.c", directory: "/tmp/home/yhs/work/tests/llvm/align")
!2 = !{i32 7, !"Dwarf Version", i32 4}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"frame-pointer", i32 2}
!6 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git b1ab2a57b83e4b7224c38b534532500cc90e5b9a)"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
!8 = !DISubroutineType(types: !9)
!9 = !{!10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !{}
!12 = !DILocation(line: 1, column: 13, scope: !7)
Loading

0 comments on commit 7a6f5f7

Please sign in to comment.