================ @@ -5488,40 +5483,172 @@ convertDeclareTargetAttr(Operation *op, mlir::omp::DeclareTargetAttr attribute, return success(); } -// Returns true if the operation is inside a TargetOp or -// is part of a declare target function. -static bool isTargetDeviceOp(Operation *op) { +namespace { + +/// Implementation of the dialect interface that converts operations belonging +/// to the OpenMP dialect to LLVM IR. +class OpenMPDialectLLVMIRTranslationInterface + : public LLVMTranslationDialectInterface { +public: + using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface; + + /// Translates the given operation to LLVM IR using the provided IR builder + /// and saving the state in `moduleTranslation`. + LogicalResult + convertOperation(Operation *op, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) const final; + + /// Given an OpenMP MLIR attribute, create the corresponding LLVM-IR, + /// runtime calls, or operation amendments + LogicalResult + amendOperation(Operation *op, ArrayRef<llvm::Instruction *> instructions, + NamedAttribute attribute, + LLVM::ModuleTranslation &moduleTranslation) const final; +}; + +} // namespace + +LogicalResult OpenMPDialectLLVMIRTranslationInterface::amendOperation( + Operation *op, ArrayRef<llvm::Instruction *> instructions, + NamedAttribute attribute, + LLVM::ModuleTranslation &moduleTranslation) const { + return llvm::StringSwitch<llvm::function_ref<LogicalResult(Attribute)>>( + attribute.getName()) + .Case("omp.is_target_device", + [&](Attribute attr) { + if (auto deviceAttr = dyn_cast<BoolAttr>(attr)) { + llvm::OpenMPIRBuilderConfig &config = + moduleTranslation.getOpenMPBuilder()->Config; + config.setIsTargetDevice(deviceAttr.getValue()); + return success(); + } + return failure(); + }) + .Case("omp.is_gpu", + [&](Attribute attr) { + if (auto gpuAttr = dyn_cast<BoolAttr>(attr)) { + llvm::OpenMPIRBuilderConfig &config = + moduleTranslation.getOpenMPBuilder()->Config; + config.setIsGPU(gpuAttr.getValue()); + return success(); + } + return failure(); + }) + .Case("omp.host_ir_filepath", + [&](Attribute attr) { + if (auto filepathAttr = dyn_cast<StringAttr>(attr)) { + llvm::OpenMPIRBuilder *ompBuilder = + moduleTranslation.getOpenMPBuilder(); + ompBuilder->loadOffloadInfoMetadata(filepathAttr.getValue()); + return success(); + } + return failure(); + }) + .Case("omp.flags", + [&](Attribute attr) { + if (auto rtlAttr = dyn_cast<omp::FlagsAttr>(attr)) + return convertFlagsAttr(op, rtlAttr, moduleTranslation); + return failure(); + }) + .Case("omp.version", + [&](Attribute attr) { + if (auto versionAttr = dyn_cast<omp::VersionAttr>(attr)) { + llvm::OpenMPIRBuilder *ompBuilder = + moduleTranslation.getOpenMPBuilder(); + ompBuilder->M.addModuleFlag(llvm::Module::Max, "openmp", + versionAttr.getVersion()); + return success(); + } + return failure(); + }) + .Case("omp.declare_target", + [&](Attribute attr) { + if (auto declareTargetAttr = + dyn_cast<omp::DeclareTargetAttr>(attr)) + return convertDeclareTargetAttr(op, declareTargetAttr, + moduleTranslation); + return failure(); + }) + .Case("omp.requires", + [&](Attribute attr) { + if (auto requiresAttr = dyn_cast<omp::ClauseRequiresAttr>(attr)) { + using Requires = omp::ClauseRequires; + Requires flags = requiresAttr.getValue(); + llvm::OpenMPIRBuilderConfig &config = + moduleTranslation.getOpenMPBuilder()->Config; + config.setHasRequiresReverseOffload( + bitEnumContainsAll(flags, Requires::reverse_offload)); + config.setHasRequiresUnifiedAddress( + bitEnumContainsAll(flags, Requires::unified_address)); + config.setHasRequiresUnifiedSharedMemory( + bitEnumContainsAll(flags, Requires::unified_shared_memory)); + config.setHasRequiresDynamicAllocators( + bitEnumContainsAll(flags, Requires::dynamic_allocators)); + return success(); + } + return failure(); + }) + .Case("omp.target_triples", + [&](Attribute attr) { + if (auto triplesAttr = dyn_cast<ArrayAttr>(attr)) { + llvm::OpenMPIRBuilderConfig &config = + moduleTranslation.getOpenMPBuilder()->Config; + config.TargetTriples.clear(); + config.TargetTriples.reserve(triplesAttr.size()); + for (Attribute tripleAttr : triplesAttr) { + if (auto tripleStrAttr = dyn_cast<StringAttr>(tripleAttr)) + config.TargetTriples.emplace_back(tripleStrAttr.getValue()); + else + return failure(); + } + return success(); + } + return failure(); + }) + .Default([](Attribute) { + // Fall through for omp attributes that do not require lowering. + return success(); + })(attribute.getValue()); + + return failure(); +} + +// Returns true if the operation is not inside a TargetOp, it is part of a +// function and that function is not declare target. +static bool isHostDeviceOp(Operation *op) { // Assumes no reverse offloading if (op->getParentOfType<omp::TargetOp>()) - return true; - - // Certain operations return results, and whether utilised in host or - // target there is a chance an LLVM Dialect operation depends on it - // by taking it in as an operand, so we must always lower these in - // some manner or result in an ICE (whether they end up in a no-op - // or otherwise). - if (mlir::isa<omp::ThreadprivateOp>(op)) - return true; + return false; - if (auto parentFn = op->getParentOfType<LLVM::LLVMFuncOp>()) + if (auto parentFn = op->getParentOfType<LLVM::LLVMFuncOp>()) { if (auto declareTargetIface = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>( parentFn.getOperation())) if (declareTargetIface.isDeclareTarget() && declareTargetIface.getDeclareTargetDeviceType() != mlir::omp::DeclareTargetDeviceType::host) - return true; + return false; + + return true; + } return false; ---------------- ergawy wrote:
Shouldn't this be flipped to `true` now? At this path we are neither inside a `target` op nor inside a declare target function. https://github.com/llvm/llvm-project/pull/137201 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits