91 lines · cpp
1//===------------------------------------------------------------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements methods from LLVMImportInterface.10//11//===----------------------------------------------------------------------===//12 13#include "mlir/Target/LLVMIR/LLVMImportInterface.h"14#include "mlir/Target/LLVMIR/ModuleImport.h"15 16using namespace mlir;17using namespace mlir::LLVM;18using namespace mlir::LLVM::detail;19 20LogicalResult mlir::LLVMImportInterface::convertUnregisteredIntrinsic(21 OpBuilder &builder, llvm::CallInst *inst,22 LLVM::ModuleImport &moduleImport) {23 StringRef intrinName = inst->getCalledFunction()->getName();24 25 SmallVector<llvm::Value *> args(inst->args());26 ArrayRef<llvm::Value *> llvmOperands(args);27 28 SmallVector<llvm::OperandBundleUse> llvmOpBundles;29 llvmOpBundles.reserve(inst->getNumOperandBundles());30 for (unsigned i = 0; i < inst->getNumOperandBundles(); ++i)31 llvmOpBundles.push_back(inst->getOperandBundleAt(i));32 33 SmallVector<Value> mlirOperands;34 SmallVector<NamedAttribute> mlirAttrs;35 if (failed(moduleImport.convertIntrinsicArguments(36 llvmOperands, llvmOpBundles, /*requiresOpBundles=*/false,37 /*immArgPositions=*/{}, /*immArgAttrNames=*/{}, mlirOperands,38 mlirAttrs)))39 return failure();40 41 Type resultType = moduleImport.convertType(inst->getType());42 auto op = CallIntrinsicOp::create(43 builder, moduleImport.translateLoc(inst->getDebugLoc()),44 isa<LLVMVoidType>(resultType) ? TypeRange{} : TypeRange{resultType},45 StringAttr::get(builder.getContext(), intrinName),46 ValueRange{mlirOperands}, FastmathFlagsAttr{});47 48 moduleImport.setFastmathFlagsAttr(inst, op);49 moduleImport.convertArgAndResultAttrs(inst, op);50 51 // Update importer tracking of results.52 unsigned numRes = op.getNumResults();53 if (numRes == 1)54 moduleImport.mapValue(inst) = op.getResult(0);55 else if (numRes == 0)56 moduleImport.mapNoResultOp(inst);57 else58 return op.emitError(59 "expected at most one result from target intrinsic call");60 61 return success();62}63 64/// Converts the LLVM intrinsic to an MLIR operation if a conversion exists.65/// Returns failure otherwise.66LogicalResult mlir::LLVMImportInterface::convertIntrinsic(67 OpBuilder &builder, llvm::CallInst *inst,68 LLVM::ModuleImport &moduleImport) const {69 // Lookup the dialect interface for the given intrinsic.70 // Verify the intrinsic identifier maps to an actual intrinsic.71 llvm::Intrinsic::ID intrinId = inst->getIntrinsicID();72 assert(intrinId != llvm::Intrinsic::not_intrinsic);73 74 // First lookup the intrinsic across different dialects for known75 // supported conversions, examples include arm-neon, nvm-sve, etc.76 Dialect *dialect = nullptr;77 78 if (!moduleImport.useUnregisteredIntrinsicsOnly())79 dialect = intrinsicToDialect.lookup(intrinId);80 81 // No specialized (supported) intrinsics, attempt to generate a generic82 // version via llvm.call_intrinsic (if available).83 if (!dialect)84 return convertUnregisteredIntrinsic(builder, inst, moduleImport);85 86 // Dispatch the conversion to the dialect interface.87 const LLVMImportDialectInterface *iface = getInterfaceFor(dialect);88 assert(iface && "expected to find a dialect interface");89 return iface->convertIntrinsic(builder, inst, moduleImport);90}91