Skip to content

Commit

Permalink
[Exegesis][RISCV] Add RISCV support for llvm-exegesis (llvm#120419)
Browse files Browse the repository at this point in the history
This patch also makes following amendments to core exegesis:
* Added distinction between regular registers aliasing check and
registers used as memory address in instruction.
* Added scratch memory space pointer register.
* General exegesis options were amended:
        * mattr - new option to pass a list of enabled target features

Llvm-exegesis RISCV port is a result of team effort. Below everyone
involved listed.
Co-authored-by: Konstantin Vladimirov
<konstantin.vladimirov@syntacore.com>
Co-authored-by: Dmitrii Petrov <dmitrii.petrov@syntacore.com>
Co-authored-by: Dmitry Bushev <dmitry.bushev@syntacore.com>
Co-authored-by: Mark Goncharov <mark.goncharov@syntacore.com>
Co-authored-by: Anastasiya Chernikova
<anastasiya.chernikova@syntacore.com>

---------

Co-authored-by: Anastasiya Chernikova <anastasiya.chernikova@syntacore.com>
  • Loading branch information
dybv-sc and AnastasiyaChernikova authored Dec 18, 2024
1 parent 76714be commit 6993d32
Show file tree
Hide file tree
Showing 12 changed files with 483 additions and 29 deletions.
59 changes: 59 additions & 0 deletions llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-A.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOAND_D -mattr="+a" | FileCheck --check-prefix=AMOAND_D %s

AMOAND_D: ---
AMOAND_D-NEXT: mode: latency
AMOAND_D-NEXT: key:
AMOAND_D-NEXT: instructions:
AMOAND_D-NEXT: - 'AMOAND_D [[RE01:X[0-9]+]] X10 [[RE01:X[0-9]+]]'
AMOAND_D-NEXT: config: ''
AMOAND_D-NEXT: register_initial_values:
AMOAND_D-NEXT: - '[[RE01:X[0-9]+]]=0x0'
AMOAND_D-DAG: ...

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOADD_W -mattr="+a" | FileCheck --check-prefix=AMOADD_W %s

AMOADD_W: ---
AMOADD_W-NEXT: mode: latency
AMOADD_W-NEXT: key:
AMOADD_W-NEXT: instructions:
AMOADD_W-NEXT: - 'AMOADD_W [[RE02:X[0-9]+]] X10 [[RE02:X[0-9]+]]'
AMOADD_W-NEXT: config: ''
AMOADD_W-NEXT: register_initial_values:
AMOADD_W-NEXT: - '[[RE02:X[0-9]+]]=0x0'
AMOADD_W-DAG: ...

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOMAXU_D -mattr="+a" | FileCheck --check-prefix=AMOMAXU_D %s

AMOMAXU_D: ---
AMOMAXU_D-NEXT: mode: latency
AMOMAXU_D-NEXT: key:
AMOMAXU_D-NEXT: instructions:
AMOMAXU_D-NEXT: - 'AMOMAXU_D [[RE03:X[0-9]+]] X10 [[RE03:X[0-9]+]]'
AMOMAXU_D-NEXT: config: ''
AMOMAXU_D-NEXT: register_initial_values:
AMOMAXU_D-NEXT: - '[[RE03:X[0-9]+]]=0x0'
AMOMAXU_D-DAG: ...

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOMIN_W -mattr="+a" | FileCheck --check-prefix=AMOMIN_W %s

AMOMIN_W: ---
AMOMIN_W-NEXT: mode: latency
AMOMIN_W-NEXT: key:
AMOMIN_W-NEXT: instructions:
AMOMIN_W-NEXT: - 'AMOMIN_W [[RE04:X[0-9]+]] X10 [[RE04:X[0-9]+]]'
AMOMIN_W-NEXT: config: ''
AMOMIN_W-NEXT: register_initial_values:
AMOMIN_W-NEXT: - '[[RE04:X[0-9]+]]=0x0'
AMOMIN_W-DAG: ...

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOXOR_D -mattr="+a" | FileCheck --check-prefix=AMOXOR_D %s

AMOXOR_D: ---
AMOXOR_D-NEXT: mode: latency
AMOXOR_D-NEXT: key:
AMOXOR_D-NEXT: instructions:
AMOXOR_D-NEXT: - 'AMOXOR_D [[RE05:X[0-9]+]] X10 [[RE05:X[0-9]+]]'
AMOXOR_D-NEXT: config: ''
AMOXOR_D-NEXT: register_initial_values:
AMOXOR_D-NEXT: - '[[RE05:X[0-9]+]]=0x0'
AMOXOR_D-DAG: ...
48 changes: 48 additions & 0 deletions llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ADDI -mattr=+c | FileCheck --check-prefix=C_ADDI %s

C_ADDI: ---
C_ADDI-NEXT: mode: latency
C_ADDI-NEXT: key:
C_ADDI-NEXT: instructions:
C_ADDI-NEXT: - 'C_ADDI [[REG01:X[0-9]+]] [[RE02:X[0-9]+]] [[IMM0:i_0x[0-9]+]]'

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ADDIW -mattr=+c | FileCheck --check-prefix=C_ADDIW %s

C_ADDIW: ---
C_ADDIW-NEXT: mode: latency
C_ADDIW-NEXT: key:
C_ADDIW-NEXT: instructions:
C_ADDIW-NEXT: - 'C_ADDIW [[REG11:X[0-9]+]] [[RE12:X[0-9]+]] [[IMM1:i_0x[0-9]+]]'

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ANDI -mattr=+c | FileCheck --check-prefix=C_ANDI %s

C_ANDI: ---
C_ANDI-NEXT: mode: latency
C_ANDI-NEXT: key:
C_ANDI-NEXT: instructions:
C_ANDI-NEXT: - 'C_ANDI [[REG31:X[0-9]+]] [[REG32:X[0-9]+]] [[IMM3:i_0x[0-9]+]]'

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SLLI -mattr=+c | FileCheck --check-prefix=C_SLLI %s

C_SLLI: ---
C_SLLI-NEXT: mode: latency
C_SLLI-NEXT: key:
C_SLLI-NEXT: instructions:
C_SLLI-NEXT: - 'C_SLLI [[REG81:X[0-9]+]] [[REG82:X[0-9]+]] [[IMM8:i_0x[0-9]+]]'

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SRAI -mattr=+c | FileCheck --check-prefix=C_SRAI %s

C_SRAI: ---
C_SRAI-NEXT: mode: latency
C_SRAI-NEXT: key:
C_SRAI-NEXT: instructions:
C_SRAI-NEXT: - 'C_SRAI [[REG91:X[0-9]+]] [[REG92:X[0-9]+]] [[IMM9:i_0x[0-9]+]]'

# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SRLI -mattr=+c | FileCheck --check-prefix=C_SRLI %s

C_SRLI: ---
C_SRLI-NEXT: mode: latency
C_SRLI-NEXT: key:
C_SRLI-NEXT: instructions:
C_SRLI-NEXT: - 'C_SRLI [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]'
C_SRLI-DAG: ...
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# RUN: llvm-exegesis -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -mode=latency --benchmark-phase=assemble-measured-code -mattr=+d -opcode-name=FADD_D | FileCheck %s

CHECK: ---
CHECK-NEXT: mode: latency
CHECK-NEXT: key:
CHECK-NEXT: instructions:
CHECK-NEXT: - 'FADD_D [[REG1:F[0-9]+_D]] [[REG2:F[0-9]+_D]] [[REG3:F[0-9]+_D]] i_0x7'
CHECK-NEXT: config: ''
CHECK-NEXT: register_initial_values:
CHECK-DAG: - '[[REG1]]=0x0'
CHECK-DAG: ...
3 changes: 3 additions & 0 deletions llvm/test/tools/llvm-exegesis/RISCV/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if not ("RISCV" in config.root.targets):
# We need support for RISCV.
config.unsupported = True
3 changes: 3 additions & 0 deletions llvm/tools/llvm-exegesis/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ endif()
if (LLVM_TARGETS_TO_BUILD MATCHES "Mips")
list(APPEND LLVM_EXEGESIS_TARGETS "Mips")
endif()
if(LLVM_TARGETS_TO_BUILD MATCHES "RISCV")
list(APPEND LLVM_EXEGESIS_TARGETS "RISCV")
endif()

set(LLVM_EXEGESIS_TARGETS ${LLVM_EXEGESIS_TARGETS} PARENT_SCOPE)

Expand Down
18 changes: 15 additions & 3 deletions llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ Instruction::Instruction(const MCInstrDesc *Description, StringRef Name,
const BitVector *ImplDefRegs,
const BitVector *ImplUseRegs,
const BitVector *AllDefRegs,
const BitVector *AllUseRegs)
const BitVector *AllUseRegs,
const BitVector *NonMemoryRegs)
: Description(*Description), Name(Name), Operands(std::move(Operands)),
Variables(std::move(Variables)), ImplDefRegs(*ImplDefRegs),
ImplUseRegs(*ImplUseRegs), AllDefRegs(*AllDefRegs),
AllUseRegs(*AllUseRegs) {}
AllUseRegs(*AllUseRegs), NonMemoryRegs(*NonMemoryRegs) {}

std::unique_ptr<Instruction>
Instruction::create(const MCInstrInfo &InstrInfo,
Expand Down Expand Up @@ -166,6 +167,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
BitVector ImplUseRegs = RATC.emptyRegisters();
BitVector AllDefRegs = RATC.emptyRegisters();
BitVector AllUseRegs = RATC.emptyRegisters();
BitVector NonMemoryRegs = RATC.emptyRegisters();

for (const auto &Op : Operands) {
if (Op.isReg()) {
const auto &AliasingBits = Op.getRegisterAliasing().aliasedBits();
Expand All @@ -177,6 +180,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
ImplDefRegs |= AliasingBits;
if (Op.isUse() && Op.isImplicit())
ImplUseRegs |= AliasingBits;
if (Op.isUse() && !Op.isMemory())
NonMemoryRegs |= AliasingBits;
}
}
// Can't use make_unique because constructor is private.
Expand All @@ -185,7 +190,8 @@ Instruction::create(const MCInstrInfo &InstrInfo,
std::move(Variables), BVC.getUnique(std::move(ImplDefRegs)),
BVC.getUnique(std::move(ImplUseRegs)),
BVC.getUnique(std::move(AllDefRegs)),
BVC.getUnique(std::move(AllUseRegs))));
BVC.getUnique(std::move(AllUseRegs)),
BVC.getUnique(std::move(NonMemoryRegs))));
}

const Operand &Instruction::getPrimaryOperand(const Variable &Var) const {
Expand Down Expand Up @@ -240,6 +246,12 @@ bool Instruction::hasAliasingRegisters(
ForbiddenRegisters);
}

bool Instruction::hasAliasingNotMemoryRegisters(
const BitVector &ForbiddenRegisters) const {
return anyCommonExcludingForbidden(AllDefRegs, NonMemoryRegs,
ForbiddenRegisters);
}

bool Instruction::hasOneUseOrOneDef() const {
return AllDefRegs.count() || AllUseRegs.count();
}
Expand Down
11 changes: 10 additions & 1 deletion llvm/tools/llvm-exegesis/lib/MCInstrDescView.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ struct Instruction {
// aliasing Use and Def registers.
bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const;

// Whether this instruction is self aliasing through some registers.
// Repeating this instruction may execute sequentially by picking aliasing
// Def and Not Memory Use registers. It may also execute in parallel by
// picking non aliasing Def and Not Memory Use registers.
bool hasAliasingNotMemoryRegisters(const BitVector &ForbiddenRegisters) const;

// Whether this instruction's registers alias with OtherInstr's registers.
bool hasAliasingRegistersThrough(const Instruction &OtherInstr,
const BitVector &ForbiddenRegisters) const;
Expand Down Expand Up @@ -160,12 +166,15 @@ struct Instruction {
const BitVector &ImplUseRegs; // The set of aliased implicit use registers.
const BitVector &AllDefRegs; // The set of all aliased def registers.
const BitVector &AllUseRegs; // The set of all aliased use registers.
// The set of all aliased not memory use registers.
const BitVector &NonMemoryRegs;

private:
Instruction(const MCInstrDesc *Description, StringRef Name,
SmallVector<Operand, 8> Operands,
SmallVector<Variable, 4> Variables, const BitVector *ImplDefRegs,
const BitVector *ImplUseRegs, const BitVector *AllDefRegs,
const BitVector *AllUseRegs);
const BitVector *AllUseRegs, const BitVector *NonMemoryRegs);
};

// Instructions are expensive to instantiate. This class provides a cache of
Expand Down
22 changes: 22 additions & 0 deletions llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include_directories(
${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV
${LLVM_BINARY_DIR}/lib/Target/RISCV
)

set(LLVM_LINK_COMPONENTS
CodeGen
RISCV
Exegesis
Core
Support
)

add_llvm_library(LLVMExegesisRISCV
DISABLE_LLVM_LINK_LLVM_DYLIB
STATIC
Target.cpp

DEPENDS
intrinsics_gen
RISCVCommonTableGen
)
Loading

0 comments on commit 6993d32

Please sign in to comment.