|
| 1 | +// Copyright (C) Intel |
| 2 | + |
| 3 | +//===--- SYCLToLLVM.cpp ---------------------------------------------------===// |
| 4 | +// |
| 5 | +// MLIR-SYCL is under the Apache License v2.0 with LLVM Exceptions. |
| 6 | +// See https://llvm.org/LICENSE.txt for license information. |
| 7 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 8 | +// |
| 9 | +//===----------------------------------------------------------------------===// |
| 10 | +// |
| 11 | +// This file implements a pass to convert SYCL dialects types to their |
| 12 | +// corresponding LLVM dialect types. |
| 13 | +// |
| 14 | +//===----------------------------------------------------------------------===// |
| 15 | + |
| 16 | +#include "SYCL/SYCLToLLVM.h" |
| 17 | +#include "SYCL/SYCLOpsTypes.h" |
| 18 | +#include "mlir/Conversion/LLVMCommon/Pattern.h" |
| 19 | +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
| 20 | + |
| 21 | +using namespace mlir; |
| 22 | + |
| 23 | +namespace { |
| 24 | +// Get the LLVM type of "class.cl::sycl::detail::array" with number of |
| 25 | +// dimentions \p dimNum and element type \p type. |
| 26 | +static Type getSYCLArrayTy(MLIRContext &context, unsigned dimNum, Type type) { |
| 27 | + assert((dimNum == 1 || dimNum == 2 || dimNum == 3) && |
| 28 | + "Expecting number of dimensions to be 1, 2, or 3."); |
| 29 | + auto structTy = LLVM::LLVMStructType::getIdentified( |
| 30 | + &context, "class.cl::sycl::detail::array." + std::to_string(dimNum)); |
| 31 | + if (!structTy.isInitialized()) { |
| 32 | + auto arrayTy = LLVM::LLVMArrayType::get(type, dimNum); |
| 33 | + auto res = structTy.setBody({arrayTy}, /*isPacked=*/false); |
| 34 | + assert(succeeded(res) && |
| 35 | + "Unexpected failure from LLVMStructType::setBody."); |
| 36 | + } |
| 37 | + return structTy; |
| 38 | +} |
| 39 | + |
| 40 | +// Get the LLVM type of a SYCL range or id type, given \p type - the type in |
| 41 | +// SYCL, \p name - the expected LLVM type name, \p converter - LLVM type |
| 42 | +// converter. |
| 43 | +template <typename T> |
| 44 | +static Type getSYCLRangeOrIDTy(T type, StringRef name, |
| 45 | + LLVMTypeConverter &converter) { |
| 46 | + unsigned dimNum = type.getDimension(); |
| 47 | + auto structTy = LLVM::LLVMStructType::getIdentified( |
| 48 | + &converter.getContext(), name.str() + "." + std::to_string(dimNum)); |
| 49 | + if (!structTy.isInitialized()) { |
| 50 | + auto res = structTy.setBody(getSYCLArrayTy(converter.getContext(), dimNum, |
| 51 | + converter.getIndexType()), |
| 52 | + /*isPacked=*/false); |
| 53 | + assert(succeeded(res) && |
| 54 | + "Unexpected failure from LLVMStructType::setBody."); |
| 55 | + } |
| 56 | + return LLVM::LLVMPointerType::get(structTy); |
| 57 | +} |
| 58 | +} // namespace |
| 59 | + |
| 60 | +void mlir::sycl::populateSYCLToLLVMConversionPatterns( |
| 61 | + LLVMTypeConverter &converter, RewritePatternSet &patterns) { |
| 62 | + converter.addConversion([&](mlir::sycl::IDType type) { |
| 63 | + return getSYCLRangeOrIDTy<mlir::sycl::IDType>(type, "class.cl::sycl::id", |
| 64 | + converter); |
| 65 | + }); |
| 66 | + converter.addConversion([&](mlir::sycl::RangeType type) { |
| 67 | + return getSYCLRangeOrIDTy<mlir::sycl::RangeType>( |
| 68 | + type, "class.cl::sycl::range", converter); |
| 69 | + }); |
| 70 | +} |
0 commit comments