Skip to content

Commit

Permalink
[MLIR][VCIX] Support VCIX intrinsics in LLVMIR dialect (#75875)
Browse files Browse the repository at this point in the history
The changeset extends LLVMIR intrinsics with VCIX intrinsics.
The VCIX intrinsics allow MLIR users to interact with RISC-V
co-processors that are compatible with `XSfvcp` extension

Source:
https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
  • Loading branch information
nikolaypanchenko committed Feb 7, 2024
1 parent caf537e commit 9f6c005
Show file tree
Hide file tree
Showing 19 changed files with 1,222 additions and 0 deletions.
8 changes: 8 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,11 @@ mlir_tablegen(ROCDLConversions.inc -gen-llvmir-conversions)
mlir_tablegen(ROCDLOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rocdl)
mlir_tablegen(ROCDLOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rocdl)
add_public_tablegen_target(MLIRROCDLConversionsIncGen)

add_mlir_dialect(VCIXOps vcix)
add_mlir_doc(VCIXOps VCIXDialect Dialects/ -gen-dialect-doc -dialect=vcix)
set(LLVM_TARGET_DEFINITIONS VCIXOps.td)
mlir_tablegen(VCIXConversions.inc -gen-llvmir-conversions)
mlir_tablegen(VCIXOpsAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=vcix)
mlir_tablegen(VCIXOpsAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=vcix)
add_public_tablegen_target(MLIRVCIXConversionsIncGen)
40 changes: 40 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/VCIXDialect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===- VCIXDialect.h - MLIR VCIX IR dialect -------------------*- C++ ---*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// The file defines the basic operations for the VCIX dialect.
//
// The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
// to extend application processors with custom coprocessors and
// variable-latency arithmetic units. The interface offers throughput comparable
// to that of standard RISC-V vector instructions. To accelerate performance,
// system designers may use VCIX as a low-latency, high-throughput interface to
// a coprocessor
//
// https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_
#define MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_

#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

///// Ops /////
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.h.inc"

#define GET_OP_CLASSES
#include "mlir/Dialect/LLVMIR/VCIXOps.h.inc"

#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.h.inc"

#endif /* MLIR_DIALECT_LLVMIR_VCIXDIALECT_H_ */
132 changes: 132 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//===-- VCIX.td - VCIX dialect operation definitions *- tablegen -*--------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// The file defines the basic operations for the VCIX dialect.
//
// The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
// to extend application processors with custom coprocessors and
// variable-latency arithmetic units. The interface offers throughput comparable
// to that of standard RISC-V vector instructions. To accelerate performance,
// system designers may use VCIX as a low-latency, high-throughput interface to
// a coprocessor
//
// https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
//
//===----------------------------------------------------------------------===//

#ifndef VCIXIR_OPS

include "mlir/IR/OpBase.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"

//===----------------------------------------------------------------------===//
// VCIX dialect definition.
//===----------------------------------------------------------------------===//

def VCIX_Dialect : Dialect {
let name = "vcix";
let cppNamespace = "::mlir::vcix";
let dependentDialects = ["LLVM::LLVMDialect"];
let description = [{
The SiFive Vector Coprocessor Interface (VCIX) provides a flexible mechanism
to extend application processors with custom coprocessors and
variable-latency arithmetic units. The interface offers throughput comparable
to that of standard RISC-V vector instructions. To accelerate performance,
system designers may use VCIX as a low-latency, high-throughput interface to
a coprocessor

https://www.sifive.com/document-file/sifive-vector-coprocessor-interface-vcix-software
}];
}

// Special version for intrinsic version where int attr is zext to i32 or i64
// depending on xlen of the target.
def VCIX_VectorOrScalar
: AnyTypeOf<[LLVM_AnyVector, I<64>, I<32>, F<16>, F<32>, F<64>]>;
def VCIX_OpcodeAttr : AnyAttrOf<[I32Attr, I64Attr]>;
def VCIX_Register : AnyTypeOf<[I32, I64]>;
def VCIX_ImmAttr : AnyAttrOf<[I32Attr, I64Attr]>;
def VCIX_VL : AnyTypeOf<[I<64>, I<32>]>;

class VCIX_Op<string mnemonic, list<Trait> traits = []>
: LLVM_OpBase<VCIX_Dialect, mnemonic, traits> {
}

def VCIX_BinaryImmOp : VCIX_Op<"v.iv">,
Results<(outs LLVM_AnyVector: $res)>,
Arguments<(ins VCIX_OpcodeAttr: $opcode,
LLVM_AnyVector: $vs2,
VCIX_ImmAttr: $imm,
Optional<VCIX_VL>: $vl)> {
let summary = "Binary VCIX operation with an immediate second operand";
let description = [{
Binary VCIX operation with an immediate second operand.

Correponds to:
|Mnemonic|funct6|vm|rs2|rs1|funct3|rd|Destination|Sources|
|--|--|--|--|--|--|--|--|--|
|sf.vc.v.iv|0010--|0|vs2|simm|011|vd|vector vd| simm[4:0] vector vs2|
}];

string llvmBuilder = [{
llvm::Type *xlen =getXlenType($opcode, moduleTranslation);
llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
xlen, $opcode, $_location, moduleTranslation);
llvm::Value *immConst = mlir::LLVM::detail::getLLVMConstant(
xlen, $imm, $_location, moduleTranslation);
VectorType vt = op.getResult().getType().cast<VectorType>();
llvm::Value *vl =
createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
$res = createIntrinsicCall(
builder, llvm::Intrinsic::riscv_sf_vc_v_iv_se,
{opcodeConst, $vs2, immConst, vl},
{$_resultType, xlen, $vs2->getType(), xlen, xlen});
}];
}

def VCIX_BinaryOp : VCIX_Op<"v.sv">,
Results<(outs LLVM_AnyVector: $res)>,
Arguments<(ins VCIX_OpcodeAttr: $opcode,
LLVM_AnyVector: $vs2,
VCIX_VectorOrScalar: $op,
Optional<VCIX_VL>: $vl)> {
let summary = "Binary VCIX operation";
let description = [{
Binary VCIX operation with an integer scalar, or floating pointer scalar or
vector second operand.

Correponds to:
|Mnemonic|funct6|vm|rs2|rs1|funct3|rd|Destination| Sources|
|--|--|--|--|--|--|--|--|--|--|
|sf.vc.v.vv|0010--|0|vs2|vs1|000|vd|vector vd|vector vs1, vector vs|
|sf.vc.v.xv|0010--|0|vs2|xs1|100|vd|vector vd|scalar xs1, vector vs2|
|sf.vc.v.fv|0010--|0|vs2|fs1|101|vd|vector vd|scalar fs1, vector vs2|
}];

string llvmBuilder = [{
llvm::Type *xlen = getXlenType($opcode, moduleTranslation);
llvm::Value *opcodeConst = mlir::LLVM::detail::getLLVMConstant(
xlen, $opcode, $_location, moduleTranslation);
llvm::Intrinsic::ID id;
llvm::Type *opType = $op->getType();
if (opType->isVectorTy()) {
id = llvm::Intrinsic::riscv_sf_vc_v_vv_se;
} else if (opType->isIntegerTy()) {
id = llvm::Intrinsic::riscv_sf_vc_v_xv_se;
} else {
id = llvm::Intrinsic::riscv_sf_vc_v_fv_se;
}
VectorType vt = op.getResult().getType().cast<VectorType>();
llvm::Value *vl =
createVL(builder, $vl, vt, xlen, $_location, moduleTranslation);
$res = createIntrinsicCall(
builder, id, {opcodeConst, $vs2, $op, vl},
{$_resultType, xlen, $vs2->getType(), $op->getType(), xlen});
}];
}

#endif // VCIXIR_OPS
2 changes: 2 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/Dialect/All.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/X86Vector/X86VectorToLLVMIRTranslation.h"

namespace mlir {
Expand All @@ -48,6 +49,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry &registry) {
registerOpenMPDialectTranslation(registry);
registerROCDLDialectTranslation(registry);
registerSPIRVDialectTranslation(registry);
registerVCIXDialectTranslation(registry);
registerX86VectorDialectTranslation(registry);

// Extension required for translating GPU offloading Ops.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===- VCIXToLLVMIRTranslation.h - VCIX to LLVM IR ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for VCIX dialect to LLVM IR translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
#define MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the VCIX dialect and the translation from it to the LLVM IR in the
/// given registry.
void registerVCIXDialectTranslation(DialectRegistry &registry);

/// Register the VCIX dialect and the translation from it in the registry
/// associated with the given context.
void registerVCIXDialectTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_LLVMIR_DIALECT_VCIX_VCIXTOLLVMIRTRANSLATION_H
22 changes: 22 additions & 0 deletions mlir/lib/Dialect/LLVMIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,25 @@ add_mlir_dialect_library(MLIRROCDLDialect
MLIRLLVMDialect
MLIRSideEffectInterfaces
)

add_mlir_dialect_library(MLIRVCIXDialect
IR/VCIXDialect.cpp

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/LLVMIR

DEPENDS
MLIRGPUCompilationAttrInterfacesIncGen
MLIRVCIXOpsIncGen
MLIRVCIXConversionsIncGen
intrinsics_gen

LINK_COMPONENTS
AsmParser
Core

LINK_LIBS PUBLIC
MLIRIR
MLIRLLVMDialect
MLIRSideEffectInterfaces
)
54 changes: 54 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/VCIXDialect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//===- VCIXDialect.cpp - MLIR VCIX ops implementation ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the VCIX dialect and its operations.
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/LLVMIR/VCIXDialect.h"

#include "mlir/Dialect/GPU/IR/CompilationInterfaces.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Operation.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/SourceMgr.h"

using namespace mlir;
using namespace vcix;

#include "mlir/Dialect/LLVMIR/VCIXOpsDialect.cpp.inc"

//===----------------------------------------------------------------------===//
// VCIXDialect initialization, type parsing, and registration.
//===----------------------------------------------------------------------===//

void VCIXDialect::initialize() {
addOperations<
#define GET_OP_LIST
#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"
>();

addAttributes<
#define GET_ATTRDEF_LIST
#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
>();
}

#define GET_OP_CLASSES
#include "mlir/Dialect/LLVMIR/VCIXOps.cpp.inc"

#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/LLVMIR/VCIXOpsAttributes.cpp.inc"
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
MLIROpenMPToLLVMIRTranslation
MLIRROCDLToLLVMIRTranslation
MLIRSPIRVToLLVMIRTranslation
MLIRVCIXToLLVMIRTranslation
)

add_mlir_translation_library(MLIRTargetLLVMIRImport
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ add_subdirectory(OpenACC)
add_subdirectory(OpenMP)
add_subdirectory(ROCDL)
add_subdirectory(SPIRV)
add_subdirectory(VCIX)
add_subdirectory(X86Vector)
16 changes: 16 additions & 0 deletions mlir/lib/Target/LLVMIR/Dialect/VCIX/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
add_mlir_translation_library(MLIRVCIXToLLVMIRTranslation
VCIXToLLVMIRTranslation.cpp

DEPENDS
MLIRVCIXConversionsIncGen

LINK_COMPONENTS
Core

LINK_LIBS PUBLIC
MLIRIR
MLIRLLVMDialect
MLIRVCIXDialect
MLIRSupport
MLIRTargetLLVMIRExport
)
Loading

0 comments on commit 9f6c005

Please sign in to comment.