1 //===- ControlFlowToSPIRV.cpp - ControlFlow to SPIR-V Patterns ------------===//
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 patterns to convert standard dialect to SPIR-V dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "mlir/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.h"
14 #include "../SPIRVCommon/Pattern.h"
15 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
16 #include "mlir/Dialect/SPIRV/IR/SPIRVDialect.h"
17 #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
18 #include "mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h"
19 #include "mlir/Dialect/SPIRV/Utils/LayoutUtils.h"
20 #include "mlir/IR/AffineMap.h"
21 #include "mlir/Support/LogicalResult.h"
22 #include "llvm/ADT/SetVector.h"
23 #include "llvm/Support/Debug.h"
24 
25 #define DEBUG_TYPE "cf-to-spirv-pattern"
26 
27 using namespace mlir;
28 
29 //===----------------------------------------------------------------------===//
30 // Operation conversion
31 //===----------------------------------------------------------------------===//
32 
33 namespace {
34 
35 /// Converts cf.br to spv.Branch.
36 struct BranchOpPattern final : public OpConversionPattern<cf::BranchOp> {
37   using OpConversionPattern<cf::BranchOp>::OpConversionPattern;
38 
39   LogicalResult
40   matchAndRewrite(cf::BranchOp op, OpAdaptor adaptor,
41                   ConversionPatternRewriter &rewriter) const override {
42     rewriter.replaceOpWithNewOp<spirv::BranchOp>(op, op.getDest(),
43                                                  adaptor.getDestOperands());
44     return success();
45   }
46 };
47 
48 /// Converts cf.cond_br to spv.BranchConditional.
49 struct CondBranchOpPattern final
50     : public OpConversionPattern<cf::CondBranchOp> {
51   using OpConversionPattern<cf::CondBranchOp>::OpConversionPattern;
52 
53   LogicalResult
54   matchAndRewrite(cf::CondBranchOp op, OpAdaptor adaptor,
55                   ConversionPatternRewriter &rewriter) const override {
56     rewriter.replaceOpWithNewOp<spirv::BranchConditionalOp>(
57         op, op.getCondition(), op.getTrueDest(), adaptor.getTrueDestOperands(),
58         op.getFalseDest(), adaptor.getFalseDestOperands());
59     return success();
60   }
61 };
62 } // namespace
63 
64 //===----------------------------------------------------------------------===//
65 // Pattern population
66 //===----------------------------------------------------------------------===//
67 
68 void mlir::cf::populateControlFlowToSPIRVPatterns(
69     SPIRVTypeConverter &typeConverter, RewritePatternSet &patterns) {
70   MLIRContext *context = patterns.getContext();
71 
72   patterns.add<BranchOpPattern, CondBranchOpPattern>(typeConverter, context);
73 }
74