1 | //===- VCIXToLLVMIRTranslation.cpp - Translate VCIX to LLVM IR ------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements a translation between the MLIR VCIX dialect and |
10 | // LLVM IR. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h" |
15 | #include "mlir/Dialect/LLVMIR/VCIXDialect.h" |
16 | #include "mlir/IR/BuiltinAttributes.h" |
17 | #include "mlir/IR/Operation.h" |
18 | #include "mlir/Target/LLVMIR/ModuleTranslation.h" |
19 | |
20 | #include "llvm/IR/IRBuilder.h" |
21 | #include "llvm/IR/IntrinsicsRISCV.h" |
22 | #include "llvm/Support/raw_ostream.h" |
23 | |
24 | using namespace mlir; |
25 | using namespace mlir::LLVM; |
26 | using mlir::LLVM::detail::createIntrinsicCall; |
27 | |
28 | /// Infer XLen type from opcode's type. This is done to avoid passing target |
29 | /// option around. |
30 | static llvm::Type *getXlenType(Attribute opcodeAttr, |
31 | LLVM::ModuleTranslation &moduleTranslation) { |
32 | auto intAttr = cast<IntegerAttr>(opcodeAttr); |
33 | unsigned xlenWidth = cast<IntegerType>(intAttr.getType()).getWidth(); |
34 | return llvm::Type::getIntNTy(C&: moduleTranslation.getLLVMContext(), N: xlenWidth); |
35 | } |
36 | |
37 | /// Return VL for VCIX intrinsic. If vl was previously set, return it, |
38 | /// otherwise construct a constant using fixed vector type. |
39 | static llvm::Value *createVL(llvm::IRBuilderBase &builder, llvm::Value *vl, |
40 | VectorType vtype, llvm::Type *xlen, Location loc, |
41 | LLVM::ModuleTranslation &moduleTranslation) { |
42 | if (vl) { |
43 | assert(vtype.isScalable() && |
44 | "vl parameter must be set for scalable vectors" ); |
45 | return builder.CreateZExtOrTrunc(V: vl, DestTy: xlen); |
46 | } |
47 | |
48 | assert(vtype.getRank() == 1 && "Only 1-d fixed vectors are supported" ); |
49 | return mlir::LLVM::detail::getLLVMConstant( |
50 | xlen, |
51 | IntegerAttr::get(IntegerType::get(&moduleTranslation.getContext(), 64), |
52 | vtype.getShape()[0]), |
53 | loc, moduleTranslation); |
54 | } |
55 | |
56 | namespace { |
57 | /// Implementation of the dialect interface that converts operations belonging |
58 | /// to the VCIX dialect to LLVM IR. |
59 | class VCIXDialectLLVMIRTranslationInterface |
60 | : public LLVMTranslationDialectInterface { |
61 | public: |
62 | using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface; |
63 | |
64 | /// Translates the given operation to LLVM IR using the provided IR builder |
65 | /// and saving the state in `moduleTranslation`. |
66 | LogicalResult |
67 | convertOperation(Operation *op, llvm::IRBuilderBase &builder, |
68 | LLVM::ModuleTranslation &moduleTranslation) const final { |
69 | Operation &opInst = *op; |
70 | #include "mlir/Dialect/LLVMIR/VCIXConversions.inc" |
71 | |
72 | return failure(); |
73 | } |
74 | }; |
75 | } // namespace |
76 | |
77 | void mlir::registerVCIXDialectTranslation(DialectRegistry ®istry) { |
78 | registry.insert<vcix::VCIXDialect>(); |
79 | registry.addExtension(extensionFn: +[](MLIRContext *ctx, vcix::VCIXDialect *dialect) { |
80 | dialect->addInterfaces<VCIXDialectLLVMIRTranslationInterface>(); |
81 | }); |
82 | } |
83 | |
84 | void mlir::registerVCIXDialectTranslation(MLIRContext &context) { |
85 | DialectRegistry registry; |
86 | registerVCIXDialectTranslation(registry); |
87 | context.appendDialectRegistry(registry); |
88 | } |
89 | |