//===-- XeVMAttachTarget.cpp - Attach an XeVM target ----------------------===// // // This file is licensed 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 // //===----------------------------------------------------------------------===// // // This file implements the `GpuXeVMAttachTarget` pass, attaching `#xevm.target` // attributes to GPU modules. // //===----------------------------------------------------------------------===// #include "mlir/Dialect/GPU/Transforms/Passes.h" #include "mlir/Dialect/GPU/IR/GPUDialect.h" #include "mlir/Dialect/LLVMIR/XeVMDialect.h" #include "mlir/IR/Builders.h" #include "mlir/Pass/Pass.h" #include "mlir/Target/LLVM/XeVM/Target.h" #include "llvm/Support/Regex.h" namespace mlir { #define GEN_PASS_DEF_GPUXEVMATTACHTARGET #include "mlir/Dialect/GPU/Transforms/Passes.h.inc" } // namespace mlir using namespace mlir; using namespace mlir::xevm; namespace { struct XeVMAttachTarget : public mlir::impl::GpuXeVMAttachTargetBase { using Base::Base; DictionaryAttr getFlags(OpBuilder &builder) const; void runOnOperation() override; void getDependentDialects(DialectRegistry ®istry) const override { registry.insert(); } }; } // namespace DictionaryAttr XeVMAttachTarget::getFlags(OpBuilder &builder) const { SmallVector flags; // Tokenize and set the optional command line options. if (!cmdOptions.empty()) { std::pair> options = gpu::TargetOptions::tokenizeCmdOptions(cmdOptions); if (!options.second.empty()) { llvm::SmallVector xevmOptionAttrs; for (const char *opt : options.second) { xevmOptionAttrs.emplace_back( mlir::StringAttr::get(builder.getContext(), StringRef(opt))); } flags.push_back(builder.getNamedAttr( "cmd-options", mlir::ArrayAttr::get(builder.getContext(), xevmOptionAttrs))); } } if (!flags.empty()) return builder.getDictionaryAttr(flags); return nullptr; } void XeVMAttachTarget::runOnOperation() { OpBuilder builder(&getContext()); ArrayRef libs(linkLibs); SmallVector filesToLink(libs); auto target = builder.getAttr( optLevel, triple, chip, getFlags(builder), filesToLink.empty() ? nullptr : builder.getStrArrayAttr(filesToLink)); llvm::Regex matcher(moduleMatcher); for (Region ®ion : getOperation()->getRegions()) for (Block &block : region.getBlocks()) for (auto module : block.getOps()) { // Check if the name of the module matches. if (!moduleMatcher.empty() && !matcher.match(module.getName())) continue; // Create the target array. SmallVector targets; if (std::optional attrs = module.getTargets()) targets.append(attrs->getValue().begin(), attrs->getValue().end()); targets.push_back(target); // Remove any duplicate targets. targets.erase(llvm::unique(targets), targets.end()); // Update the target attribute array. module.setTargetsAttr(builder.getArrayAttr(targets)); } }