| //===- IndexIntrinsicsOpLowering.h - GPU IndexOps Lowering class *- 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 |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef MLIR_CONVERSION_GPUCOMMON_INDEXINTRINSICSOPLOWERING_H_ |
| #define MLIR_CONVERSION_GPUCOMMON_INDEXINTRINSICSOPLOWERING_H_ |
| |
| #include "mlir/Conversion/LLVMCommon/Pattern.h" |
| #include "mlir/Dialect/GPU/GPUDialect.h" |
| #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
| #include "llvm/ADT/StringSwitch.h" |
| |
| namespace mlir { |
| |
| // Rewriting that replaces Op with XOp, YOp, or ZOp depending on the dimension |
| // that Op operates on. Op is assumed to return an `index` value and |
| // XOp, YOp and ZOp are assumed to return an `llvm.i32` value. Depending on |
| // `indexBitwidth`, sign-extend or truncate the resulting value to match the |
| // bitwidth expected by the consumers of the value. |
| template <typename Op, typename XOp, typename YOp, typename ZOp> |
| struct GPUIndexIntrinsicOpLowering : public ConvertOpToLLVMPattern<Op> { |
| private: |
| unsigned indexBitwidth; |
| |
| public: |
| explicit GPUIndexIntrinsicOpLowering(LLVMTypeConverter &typeConverter) |
| : ConvertOpToLLVMPattern<Op>(typeConverter), |
| indexBitwidth(typeConverter.getIndexTypeBitwidth()) {} |
| |
| // Convert the kernel arguments to an LLVM type, preserve the rest. |
| LogicalResult |
| matchAndRewrite(Op op, typename Op::Adaptor adaptor, |
| ConversionPatternRewriter &rewriter) const override { |
| auto loc = op->getLoc(); |
| MLIRContext *context = rewriter.getContext(); |
| Value newOp; |
| switch (op.dimension()) { |
| case gpu::Dimension::x: |
| newOp = rewriter.create<XOp>(loc, IntegerType::get(context, 32)); |
| break; |
| case gpu::Dimension::y: |
| newOp = rewriter.create<YOp>(loc, IntegerType::get(context, 32)); |
| break; |
| case gpu::Dimension::z: |
| newOp = rewriter.create<ZOp>(loc, IntegerType::get(context, 32)); |
| break; |
| } |
| |
| if (indexBitwidth > 32) { |
| newOp = rewriter.create<LLVM::SExtOp>( |
| loc, IntegerType::get(context, indexBitwidth), newOp); |
| } else if (indexBitwidth < 32) { |
| newOp = rewriter.create<LLVM::TruncOp>( |
| loc, IntegerType::get(context, indexBitwidth), newOp); |
| } |
| |
| rewriter.replaceOp(op, {newOp}); |
| return success(); |
| } |
| }; |
| |
| } // namespace mlir |
| |
| #endif // MLIR_CONVERSION_GPUCOMMON_INDEXINTRINSICSOPLOWERING_H_ |