Skip to content

Commit

Permalink
[MLIR][SPIRVToLLVM] Add skeleton for SPIR-V to LLVM dialect conversion
Browse files Browse the repository at this point in the history
These commits set up the skeleton for SPIR-V to LLVM dialect conversion.
I created SPIR-V to LLVM pass, registered it in Passes.td, InitAllPasses.h.
Added a pattern for `spv.BitwiseAndOp` and tests for it. Integer, float
and vector types are converted through LLVMTypeConverter.

Differential Revision: https://reviews.llvm.org/D81100
  • Loading branch information
georgemitenkov authored and antiagainst committed Jun 8, 2020
1 parent a6d6b0a commit fda5192
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 1 deletion.
9 changes: 9 additions & 0 deletions mlir/include/mlir/Conversion/Passes.td
Expand Up @@ -206,6 +206,15 @@ def ConvertShapeToStandard : Pass<"convert-shape-to-std", "ModuleOp"> {
let constructor = "mlir::createConvertShapeToStandardPass()";
}

//===----------------------------------------------------------------------===//
// SPIRVToLLVM
//===----------------------------------------------------------------------===//

def ConvertSPIRVToLLVM : Pass<"convert-spirv-to-llvm", "ModuleOp"> {
let summary = "Convert SPIR-V dialect to LLVM dialect";
let constructor = "mlir::createConvertSPIRVToLLVMPass()";
}

//===----------------------------------------------------------------------===//
// StandardToLLVM
//===----------------------------------------------------------------------===//
Expand Down
30 changes: 30 additions & 0 deletions mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
@@ -0,0 +1,30 @@
//===- ConvertSPIRVToLLVM.h - Convert SPIR-V to LLVM 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
//
//===----------------------------------------------------------------------===//
//
// Provides patterns to convert SPIR-V dialect to LLVM dialect.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H

#include "mlir/Transforms/DialectConversion.h"

namespace mlir {
class LLVMTypeConverter;
class MLIRContext;
class ModuleOp;

/// Populates the given list with patterns that convert from SPIR-V to LLVM.
void populateSPIRVToLLVMConversionPatterns(MLIRContext *context,
LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns);

} // namespace mlir

#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVM_H
28 changes: 28 additions & 0 deletions mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h
@@ -0,0 +1,28 @@
//===- ConvertSPIRVToLLVMPass.h - SPIR-V dialect to LLVM pass ---*- 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
//
//===----------------------------------------------------------------------===//
//
// Provides a pass to lower from SPIR-V dialect to LLVM dialect.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H
#define MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H

#include <memory>

namespace mlir {
class ModuleOp;
template <typename T>
class OperationPass;

/// Creates a pass to convert SPIR-V operations to the LLVMIR dialect.
std::unique_ptr<OperationPass<ModuleOp>> createConvertSPIRVToLLVMPass();

} // namespace mlir

#endif // MLIR_CONVERSION_SPIRVTOLLVM_CONVERTSPIRVTOLLVMPASS_H_
Expand Up @@ -13,7 +13,8 @@
namespace mlir {
class LLVMTypeConverter;
class ModuleOp;
template <typename T> class OperationPass;
template <typename T>
class OperationPass;

/// Collect a set of patterns to convert from Vector contractions to LLVM Matrix
/// Intrinsics. To lower to assembly, the LLVM flag -lower-matrix-intrinsics
Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/InitAllPasses.h
Expand Up @@ -25,6 +25,7 @@
#include "mlir/Conversion/LinalgToStandard/LinalgToStandard.h"
#include "mlir/Conversion/SCFToGPU/SCFToGPUPass.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
#include "mlir/Conversion/ShapeToStandard/ShapeToStandard.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.h"
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Conversion/CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ add_subdirectory(LinalgToStandard)
add_subdirectory(SCFToGPU)
add_subdirectory(SCFToStandard)
add_subdirectory(ShapeToStandard)
add_subdirectory(SPIRVToLLVM)
add_subdirectory(StandardToLLVM)
add_subdirectory(StandardToSPIRV)
add_subdirectory(VectorToLLVM)
Expand Down
18 changes: 18 additions & 0 deletions mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt
@@ -0,0 +1,18 @@
add_mlir_conversion_library(MLIRSPIRVToLLVM
ConvertSPIRVToLLVM.cpp
ConvertSPIRVToLLVMPass.cpp

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/SPIRVToLLVM

DEPENDS
MLIRConversionPassIncGen
intrinsics_gen

LINK_LIBS PUBLIC
MLIRSPIRV
MLIRLLVMIR
MLIRStandardToLLVM
MLIRIR
MLIRTransforms
)
53 changes: 53 additions & 0 deletions mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
@@ -0,0 +1,53 @@
//===- ConvertSPIRVToLLVM.cpp - SPIR-V dialect to LLVM dialect conversion -===//
//
// 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 patterns to convert SPIR-V dialect to LLVM dialect.
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
#include "mlir/Dialect/SPIRV/SPIRVOps.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/Module.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/DialectConversion.h"

using namespace mlir;

namespace {

class BitwiseAndOpConversion : public ConvertToLLVMPattern {
public:
explicit BitwiseAndOpConversion(MLIRContext *context,
LLVMTypeConverter &typeConverter)
: ConvertToLLVMPattern(spirv::BitwiseAndOp::getOperationName(), context,
typeConverter) {}

LogicalResult
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {
auto bitwiseAndOp = cast<spirv::BitwiseAndOp>(op);
auto dstType = typeConverter.convertType(bitwiseAndOp.getType());
if (!dstType)
return failure();
rewriter.replaceOpWithNewOp<LLVM::AndOp>(bitwiseAndOp, dstType, operands);
return success();
}
};
} // namespace

void mlir::populateSPIRVToLLVMConversionPatterns(
MLIRContext *context, LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns) {
patterns.insert<BitwiseAndOpConversion>(context, typeConverter);
}
54 changes: 54 additions & 0 deletions mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
@@ -0,0 +1,54 @@
//===- ConvertSPIRVToLLVMPass.cpp - Convert SPIR-V ops to LLVM ops --------===//
//
// 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 a pass to convert MLIR SPIR-V ops into LLVM ops
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
#include "../PassDetail.h"
#include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/SPIRV/SPIRVDialect.h"

using namespace mlir;

namespace {
/// A pass converting MLIR SPIR-V operations into LLVM dialect.
class ConvertSPIRVToLLVMPass
: public ConvertSPIRVToLLVMBase<ConvertSPIRVToLLVMPass> {
void runOnOperation() override;
};
} // namespace

void ConvertSPIRVToLLVMPass::runOnOperation() {
MLIRContext *context = &getContext();
ModuleOp module = getOperation();
LLVMTypeConverter converter(&getContext());

OwningRewritePatternList patterns;
populateSPIRVToLLVMConversionPatterns(context, converter, patterns);

// Currently pulls in Std to LLVM conversion patterns
// that help with testing. This allows to convert
// function arguments to LLVM.
populateStdToLLVMConversionPatterns(converter, patterns);

ConversionTarget target(getContext());
target.addIllegalDialect<spirv::SPIRVDialect>();
target.addLegalDialect<LLVM::LLVMDialect>();

if (failed(applyPartialConversion(module, target, patterns, &converter)))
signalPassFailure();
}

std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertSPIRVToLLVMPass() {
return std::make_unique<ConvertSPIRVToLLVMPass>();
}
13 changes: 13 additions & 0 deletions mlir/test/Conversion/SPIRVToLLVM/convert-to-llvm.mlir
@@ -0,0 +1,13 @@
// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s

func @bitwise_and_scalar(%arg0: i32, %arg1: i32) {
// CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm.i32
%0 = spv.BitwiseAnd %arg0, %arg1 : i32
return
}

func @bitwise_and_vector(%arg0: vector<4xi64>, %arg1: vector<4xi64>) {
// CHECK: %{{.*}} = llvm.and %{{.*}}, %{{.*}} : !llvm<"<4 x i64>">
%0 = spv.BitwiseAnd %arg0, %arg1 : vector<4xi64>
return
}

0 comments on commit fda5192

Please sign in to comment.