Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Riscv simd #311

Merged
merged 1 commit into from
Dec 30, 2024
Merged

Riscv simd #311

merged 1 commit into from
Dec 30, 2024

Conversation

vorosl
Copy link
Contributor

@vorosl vorosl commented Dec 3, 2024

No description provided.

Copy link
Collaborator

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice patch, but lots of syntax errors. And some parts should be made nicer with macros.

src/jit/Backend.cpp Show resolved Hide resolved
@@ -456,6 +456,8 @@ static void simdOperandToArg(sljit_compiler* compiler, Operand* operand, JITArg&
#include "SimdArm64Inl.h"
#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
#include "SimdArm32Inl.h"
#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defined __riscv_vector ? Or shall we include everything all the time?

#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
prefix = "F";
savedStart = SLJIT_FR(SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS);
savedEnd = SLJIT_FS0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could keep the original code, and just use an "if" to overwrite the values. Less #if / #else is needed

@@ -196,6 +196,7 @@ static void emitSplatSIMD(sljit_compiler* compiler, Instruction* instr)

sljit_s32 type = 0;


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need this newline.

, m_floatSet(numberOfFloatScratchRegs, numberOfFloatSavedRegs, false)
, m_floatSet(SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS, SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS, false)
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
, m_vectorSet(SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS - 1, SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS, false)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -1 is not riscv only thing?

#endif
}


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline

// sljit_s32 mask = SLJIT_VR0;
// simdEmitTypedOp(compiler, SLJIT_SIMD_ELEM_64, SimdOp::vmv_vx, tmp, 0, rd, SimdOp::rm_gpreg)
// simdEmitCompare(compiler, )
// }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be deleted?

return false;
}


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline.

/*if (!sljit_has_cpu_feature(SLJIT_HAS_AVX) && dst != args[2].arg) {
sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | srcType, dst, args[2].arg, 0);
args[2].arg = dst;
}*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many commented out parts. Do you need them? We have no AVX on RISCV.

if (SLJIT_IS_MEM(args[2].arg)) {
sljit_emit_simd_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | type, dst, args[2].arg, args[2].argw);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline.

@vorosl vorosl force-pushed the riscv-simd branch 2 times, most recently from ff1f463 to 1cfd073 Compare December 11, 2024 08:15
@vorosl vorosl requested a review from zherczeg December 11, 2024 08:23
prefix = PREFIX;
savedStart = SAVED_START;
savedEnd = SAVED_END;
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look nice.

Keep the else part as default.

Then add an #if part for vector registers, which tests V128 and overwrites the prefix and other variables.

@@ -20,6 +20,17 @@
#include "jit/Compiler.h"
#include <set>

#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
#define SHORTIF(COND, VECTOR, FLOAT) \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about VECTOR_SELECT?

#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
uint8_t toCPUVectorReg(uint8_t reg)
{
return m_vectorSet.toCPUReg(reg, SLJIT_VR1, SLJIT_VS0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SLJIT_VR1 is riscv only thing. Maybe you could introduce a macro for the first register, and use it everywhere. SLJIT_VR1 on riscv, SLJIT_VR0 everywhere else.

regs.floatReserve(reg);
instr->setRequiredReg(reuseTmpIndex, regs.toCPUFloatReg(reg));
SHORTIF(((*nextType & Instruction::TypeMask) == Instruction::V128Operand), regs.vectorReserve(reg), regs.floatReserve(reg))
SHORTIF(((*nextType & Instruction::TypeMask) == Instruction::V128Operand), instr->setRequiredReg(reuseTmpIndex, regs.toCPUVectorReg(reg)), instr->setRequiredReg(reuseTmpIndex, regs.toCPUFloatReg(reg)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use a (a, b) comma separated list for commands. This way you don't need to duplicate the macro (if).

E.g: (regs.vectorReserve(reg), instr->setRequiredReg(reuseTmpIndex, regs.toCPUVectorReg(reg)))

#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
uint32_t nextVectorIndex = SLJIT_VR1;
#else /* !SLJIT_CONFIG_RISCV */
uint32_t nextVectorIndex = SLJIT_VR0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have the macro for the first register, this will simplify.

static void simdEmitOp(sljit_compiler* compiler, uint32_t opcode, sljit_s32 rd, sljit_s32 rn, sljit_s32 rm, uint32_t optype = 0)
{
rd = sljit_get_register_index((optype & SimdOp::rd_gpreg) ? SLJIT_GP_REGISTER : SLJIT_SIMD_REG_128, rd);
if (!(optype & SimdOp::rn_imm) && !(optype & SimdOp::rn_gpreg) && rn >= SLJIT_VR0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can rn be zero in this case? If not, it should be an assert. Similar cases below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, at simdEmitFminMax rn is SLJIT_VR0.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(rn == SLJIT_VR0) >= SLJIT_VR0, so it is still true without an extra >=

simdEmitOp(compiler, SimdOp::vmerge_vi, rd, tmp, reverseMask ? 0 : (0x1F), SimdOp::rm_imm);
}

static void simdEmitExtend(sljit_compiler* compiler, sljit_s32 type, bool low, bool s, sljit_s32 rd, sljit_s32 rn)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s = signed? Could have a longer name. What is low?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low is true if the operator is ExtendLow, and false if the operator is ExtendHigh

sljit_emit_op_custom(compiler, &opC, sizeof(uint32_t));
simdEmitOp(compiler, SimdOp::vfadd_vf ^ SimdOp::vm, rd, rn, ftmp);
}
static void simdEmitFMinMax(sljit_compiler* compiler, sljit_s32 type, sljit_s32 opcode, sljit_s32 rd, sljit_s32 rn, sljit_s32 rm)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline before.

simdEmitTypedOp(compiler, type, SimdOp::vmflt_vv, mask, min ? rm : rn, min ? rn : rm);
simdEmitOp(compiler, SimdOp::vmerge_vv, rd, rn, rm);
}
static void simdEmitPopcnt(sljit_compiler* compiler, sljit_s32 type, sljit_s32 rd, sljit_s32 rn, sljit_s32 rt)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline before.

}
}


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline.

case ByteCode::V128BitSelectOpcode:
break;
case ByteCode::I8X16RelaxedLaneSelectOpcode:
case ByteCode::I16X8RelaxedLaneSelectOpcode:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing break.

{
Operand* operands = instr->operands();
JITArg args[3];

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline.

const bool isImm = SLJIT_IS_IMM(args[1].arg);
sljit_s32 type = SLJIT_SIMD_ELEM_8;


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single newline.

};

enum OperandTypes : uint32_t {
rn_imm = 1 << 1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think rnImm is the valid syntax in Walrus.

enum OperandTypes : uint32_t {
rn_imm = 1 << 1,
rm_imm = 1 << 2,
rn_gpreg = 1 << 3,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rnIsGpr sounds better to me. Maybe rnIsImm sounds better as well.

Copy link
Collaborator

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only minor things remained.

{
}

RegisterSet& integerSet() { return m_integerSet; }
RegisterSet& floatSet() { return m_floatSet; }

// clang-format off
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the format is that bad? Maybe we could turn all one liners to three lines, where the { and } in different line.

@@ -717,7 +778,7 @@ void JITCompiler::allocateRegisters()

if (type & Instruction::FloatOperandMarker) {
if (resultVariable->reg1 != VariableList::kUnusedReg) {
regs.floatReserve(resultVariable->reg1);
VECTOR_SELECT((type == Instruction::V128Operand), regs.vectorReserve(resultVariable->reg1), regs.floatReserve(resultVariable->reg1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the () around type ==? For me it looks better without it.

@@ -761,8 +829,9 @@ void JITCompiler::allocateRegisters()
regs.floatReserve(resultReg + 1);
}
#endif /* SLJIT_CONFIG_ARM_32 */
regs.floatReserve(resultReg);
resultReg = regs.toCPUFloatReg(resultReg);
VECTOR_SELECT(type == Instruction::V128Operand,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized this form looks much better, than the single long line.

RegisterSet& integerSet()
{
return m_integerSet;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add newline after each }

Signed-off-by: Laszlo Voros <vorosl@inf.u-szeged.hu>
Copy link
Collaborator

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@clover2123 clover2123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW is it possible to run our tests for RISC-V based JIT?

@clover2123 clover2123 merged commit 94f2a42 into Samsung:main Dec 30, 2024
15 checks passed
@zherczeg
Copy link
Collaborator

This patch focuses on simple implementations, some operations are still missing, so several tests will fail. We continue the work on fixing the missing tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants