Skip to content

Commit

Permalink
Include the generated file in header
Browse files Browse the repository at this point in the history
Generating an includable file in header requires the TableGen backend
to be independent of the headers, if not a cyclic dependency occurs.
A macro based generation is prioritised and its manipulation is done
in the header file by constexpr lookups.
  • Loading branch information
eymay committed Jan 6, 2024
1 parent f82213b commit b5ee968
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 203 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set(LLVM_TABLEGEN_PROJECT LLVM_HEADERS)

add_subdirectory(CodeGen)
add_subdirectory(ExecutionEngine)
add_subdirectory(IR)
add_subdirectory(Support)
add_subdirectory(Frontend)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/ExecutionEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(JITLink)
3 changes: 3 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
tablegen(LLVM JITLinkAArch32.inc -gen-jitlink-aarch32-instr-info -I ${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
add_public_tablegen_target(JITLinkAArch32TableGen)
103 changes: 99 additions & 4 deletions llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,77 @@ struct HalfWords {
const uint16_t Lo; // Second halfword
};

enum InstrName {

#define GET_INSTR(name, opcode, opcode_mask, imm_mask, reg_mask) name,

#include "llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc"
#undef GET_INSTR
INSTR_COUNT,
NONE = INSTR_COUNT,
};

constexpr InstrName getInstrFromJITLinkEdgeKind(Edge::Kind Kind) {
switch (Kind) {
case Arm_Call:
return InstrName::NONE;
case aarch32::Arm_Jump24:
return InstrName::NONE;
case aarch32::Arm_MovwAbsNC:
return InstrName::MOVi16;
case aarch32::Arm_MovtAbs:
return InstrName::MOVTi16;
case aarch32::Thumb_Call:
return InstrName::NONE;
case aarch32::Thumb_Jump24:
return InstrName::NONE;
case aarch32::Thumb_MovwAbsNC:
case aarch32::Thumb_MovwPrelNC:
return InstrName::t2MOVi16;
case aarch32::Thumb_MovtAbs:
case aarch32::Thumb_MovtPrel:
return InstrName::t2MOVTi16;
default:
return InstrName::NONE;
}
}

struct InstrInfo {
uint32_t Opcode;
uint32_t OpcodeMask;
uint32_t ImmMask;
uint32_t RegMask;
};

static constexpr InstrInfo InstrTable[INSTR_COUNT] = {
#define GET_INSTR(name, opcode, opcode_mask, imm_mask, reg_mask) \
{opcode, opcode_mask, imm_mask, reg_mask},
#include "llvm/ExecutionEngine/JITLink/JITLinkAArch32.inc"
#undef GET_INSTR
};

/// FixupInfo base class is required for dynamic lookups.
struct FixupInfoBase {
static const FixupInfoBase *getDynFixupInfo(Edge::Kind K);
virtual ~FixupInfoBase() {}
};

/// FixupInfo checks for Arm edge kinds work on 32-bit words
struct FixupInfoArm : public FixupInfoBase {
struct FixupInfoArmBase : public FixupInfoBase {
bool (*checkOpcode)(uint32_t Wd) = nullptr;
};

/// FixupInfo checks for Arm edge kinds work on 32-bit words
template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoArmBase {
static constexpr uint32_t Opcode =
InstrTable[getInstrFromJITLinkEdgeKind(Kind)].Opcode;
static constexpr uint32_t OpcodeMask =
InstrTable[getInstrFromJITLinkEdgeKind(Kind)].OpcodeMask;
static constexpr uint32_t ImmMask =
InstrTable[getInstrFromJITLinkEdgeKind(Kind)].ImmMask;
static constexpr uint32_t RegMask =
InstrTable[getInstrFromJITLinkEdgeKind(Kind)].RegMask;
};

/// FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
struct FixupInfoThumb : public FixupInfoBase {
bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
Expand All @@ -192,10 +252,10 @@ struct FixupInfoThumb : public FixupInfoBase {
/// RegMask - Mask with all bits set that encode the register
///
/// Specializations can add further custom fields without restrictions.
///

template <EdgeKind_aarch32 Kind> struct FixupInfo {};

struct FixupInfoArmBranch : public FixupInfoArm {
struct FixupInfoArmBranch : public FixupInfoArmBase {
static constexpr uint32_t Opcode = 0x0a000000;
static constexpr uint32_t ImmMask = 0x00ffffff;
};
Expand All @@ -212,6 +272,19 @@ template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {
static constexpr uint32_t BitBlx = 0x10000000;
};

template <EdgeKind_aarch32 Kind>
struct FixupInfoArmMov : public FixupInfoArm<Kind> {
static constexpr uint32_t OpcodeMask = 0x0ff00000;
static constexpr uint32_t ImmMask = 0x000f0fff;
static constexpr uint32_t RegMask = 0x0000f000;
};

template <>
struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov<Arm_MovtAbs> {};

template <>
struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov<Arm_MovwAbsNC> {};

template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
static constexpr HalfWords Opcode{0xf000, 0x9000};
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
Expand All @@ -226,6 +299,28 @@ template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
static constexpr uint16_t LoBitNoBlx = 0x1000;
};

struct FixupInfoThumbMov : public FixupInfoThumb {
static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
static constexpr HalfWords ImmMask{0x040f, 0x70ff};
static constexpr HalfWords RegMask{0x0000, 0x0f00};
};

template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
};

template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
};

template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};

template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};

/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind);
Expand Down
9 changes: 3 additions & 6 deletions llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
set(LLVM_TARGET_DEFINITIONS COFFOptions.td)
tablegen(LLVM COFFOptions.inc -gen-opt-parser-defs)
add_public_tablegen_target(JITLinkCOFFTableGen)

include_directories(${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
tablegen(LLVM JITLinkAArch32.inc -gen-jitlink-aarch32-instr-info)

add_public_tablegen_target(JITLinkTableGen)

add_llvm_component_library(LLVMJITLink
DWARFRecordSectionSplitter.cpp
Expand Down Expand Up @@ -53,7 +49,8 @@ add_llvm_component_library(LLVMJITLink

DEPENDS
intrinsics_gen
JITLinkTableGen
JITLinkCOFFTableGen
JITLinkAArch32TableGen

LINK_COMPONENTS
BinaryFormat
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"

#include "JITLinkAArch32.inc"

#define DEBUG_TYPE "jitlink"

namespace llvm {
Expand Down Expand Up @@ -318,7 +316,7 @@ static Error checkOpcode(LinkGraph &G, const ArmRelocation &R,
assert(Kind >= FirstArmRelocation && Kind <= LastArmRelocation &&
"Edge kind must be Arm relocation");
const FixupInfoBase *Entry = DynFixupInfos->getEntry(Kind);
const FixupInfoArm &Info = *static_cast<const FixupInfoArm *>(Entry);
const FixupInfoArmBase &Info = *static_cast<const FixupInfoArmBase *>(Entry);
assert(Info.checkOpcode && "Opcode check is mandatory for Arm edges");
if (!Info.checkOpcode(R.Wd))
return makeUnexpectedOpcodeError(G, R, Kind);
Expand Down
4 changes: 1 addition & 3 deletions llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

#include "gtest/gtest.h"

#include "JITLinkAArch32.inc"

using namespace llvm;
using namespace llvm::jitlink;
using namespace llvm::jitlink::aarch32;
Expand Down Expand Up @@ -74,7 +72,7 @@ TEST(AArch32_ELF, DynFixupInfos) {
for (Edge::Kind K = FirstArmRelocation; K < LastArmRelocation; K += 1) {
const auto *Info = FixupInfoBase::getDynFixupInfo(K);
EXPECT_NE(Info, nullptr);
const auto *InfoArm = static_cast<const FixupInfoArm *>(Info);
const auto *InfoArm = static_cast<const FixupInfoArmBase *>(Info);
EXPECT_NE(InfoArm->checkOpcode, nullptr);
EXPECT_FALSE(InfoArm->checkOpcode(0x00000000));
}
Expand Down
58 changes: 0 additions & 58 deletions llvm/unittests/ExecutionEngine/JITLink/JITLinkAArch32.inc

This file was deleted.

6 changes: 1 addition & 5 deletions llvm/utils/TableGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_llvm_library(LLVMTableGenCommon STATIC OBJECT EXCLUDE_FROM_ALL
CodeGenIntrinsics.cpp
DirectiveEmitter.cpp
IntrinsicEmitter.cpp
JITLinkAArch32InstrInfo.cpp
RISCVTargetDefEmitter.cpp
SDNodeProperties.cpp
VTEmitter.cpp
Expand Down Expand Up @@ -66,7 +67,6 @@ add_tablegen(llvm-tblgen LLVM
InfoByHwMode.cpp
InstrInfoEmitter.cpp
InstrDocsEmitter.cpp
JITLinkAArch32InstrInfo.cpp
OptEmitter.cpp
OptParserEmitter.cpp
OptRSTEmitter.cpp
Expand All @@ -91,10 +91,6 @@ add_tablegen(llvm-tblgen LLVM
WebAssemblyDisassemblerEmitter.cpp
$<TARGET_OBJECTS:obj.LLVMTableGenCommon>

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/JITLink


DEPENDS
intrinsics_gen # via llvm-min-tablegen
)
Expand Down
Loading

0 comments on commit b5ee968

Please sign in to comment.