23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/FileSystem.h"
26#include "llvm/Support/SourceMgr.h"
27#include "llvm/Support/raw_ostream.h"
31#define DEBUG_TYPE "transform-dialect-interpreter-utils"
32#define DBGS() (llvm::dbgs() << "[" DEBUG_TYPE << "]: ")
42 for (
const std::string &path : paths) {
45 if (llvm::sys::fs::is_regular_file(path)) {
46 LLVM_DEBUG(
DBGS() <<
"Adding '" << path <<
"' to list of files\n");
47 fileNames.push_back(path);
51 if (!llvm::sys::fs::is_directory(path)) {
53 <<
"'" << path <<
"' is neither a file nor a directory";
56 LLVM_DEBUG(
DBGS() <<
"Looking for files in '" << path <<
"':\n");
59 for (llvm::sys::fs::directory_iterator it(path, ec), itEnd;
60 it != itEnd && !ec; it.increment(ec)) {
61 const std::string &fileName = it->path();
63 if (it->type() != llvm::sys::fs::file_type::regular_file &&
64 it->type() != llvm::sys::fs::file_type::symlink_file) {
65 LLVM_DEBUG(
DBGS() <<
" Skipping non-regular file '" << fileName
70 if (!StringRef(fileName).ends_with(
".mlir")) {
71 LLVM_DEBUG(
DBGS() <<
" Skipping '" << fileName
72 <<
"' because it does not end with '.mlir'\n");
76 LLVM_DEBUG(
DBGS() <<
" Adding '" << fileName <<
"' to list of files\n");
77 fileNames.push_back(fileName);
81 return emitError(loc) <<
"error while opening files in '" << path
82 <<
"': " << ec.message();
89 MLIRContext *context, llvm::StringRef transformFileName,
91 if (transformFileName.empty()) {
93 DBGS() <<
"no transform file name specified, assuming the transform "
94 "module is embedded in the IR next to the top-level\n");
98 std::string errorMessage;
102 StringAttr::get(context, transformFileName), 0, 0))
103 <<
"failed to open transform file: " << errorMessage;
106 llvm::SourceMgr sourceMgr;
107 sourceMgr.AddNewSourceBuffer(std::move(memoryBuffer), llvm::SMLoc());
110 if (!transformModule) {
121 ->getLibraryModule();
124static transform::TransformOpInterface
127 for (
Block &block : region.getBlocks()) {
128 for (
auto namedSequenceOp : block.getOps<transform::NamedSequenceOp>()) {
129 if (namedSequenceOp.getSymName() == entryPoint) {
130 return cast<transform::TransformOpInterface>(
131 namedSequenceOp.getOperation());
139static transform::TransformOpInterface
141 transform::TransformOpInterface
transform =
nullptr;
143 [&](transform::NamedSequenceOp namedSequenceOp) {
144 if (namedSequenceOp.getSymName() == entryPoint) {
145 transform = cast<transform::TransformOpInterface>(
146 namedSequenceOp.getOperation());
189static transform::TransformOpInterface
191 transform::TransformOpInterface
transform =
198transform::TransformOpInterface
200 StringRef entryPoint) {
211 <<
"could not find a nested named sequence with name: "
227 for (
const std::string &libraryFileName : libraryFileNames) {
230 context, libraryFileName, parsedLibrary)))
232 parsedLibraries.push_back(std::move(parsedLibrary));
238 ModuleOp::create(loc,
"__transform");
240 mergedParsedLibraries.
get()->setAttr(
"transform.with_named_sequence",
241 UnitAttr::get(context));
245 mergedParsedLibraries.
get(), std::move(parsedLibrary))))
246 return parsedLibrary->emitError()
247 <<
"failed to merge symbols into shared library module";
251 transformModule = std::move(mergedParsedLibraries);
261 cast<TransformOpInterface>(transformRoot),
268 if (bindings.
empty()) {
269 return transformRoot.emitError()
270 <<
"expected at least one binding for the root";
272 if (bindings.
at(0).size() != 1) {
273 return transformRoot.emitError()
274 <<
"expected one payload to be bound to the first argument, got "
275 << bindings.
at(0).size();
277 auto *payloadRoot = dyn_cast<Operation *>(bindings.
at(0).front());
279 return transformRoot->emitError() <<
"expected the object bound to the "
280 "first argument to be an operation";
286 if (transformModule && !transformModule->isAncestor(transformRoot)) {
290 std::move(clonedTransformModule)))) {
291 return payloadRoot->emitError() <<
"failed to merge symbols";
295 LLVM_DEBUG(
DBGS() <<
"Apply\n" << *transformRoot <<
"\n");
296 LLVM_DEBUG(
DBGS() <<
"To\n" << *payloadRoot <<
"\n");
static std::string diag(const llvm::Value &value)
static llvm::ManagedStatic< PassManagerOptions > options
Block represents an ordered list of Operations.
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
MLIRContext is the top-level object for a collection of MLIR operations.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Operation is the basic unit of execution within MLIR.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
This class acts as an owning reference to an op, and will automatically destroy the held op on destru...
OpTy get() const
Allow accessing the internal op.
A 2D array where each row may have different length.
void removeFront()
Removes the first subarray in-place. Invalidates iterators to all rows.
bool empty() const
Returns true if the are no rows in the 2D array.
ArrayRef< T > at(size_t pos) const
void push_back(Range &&elements)
Appends the given range of elements as a new row to the 2D array.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
static Operation * getNearestSymbolTable(Operation *from)
Returns the nearest symbol table from a given operation from.
static WalkResult advance()
static WalkResult interrupt()
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
std::unique_ptr< llvm::MemoryBuffer > openInputFile(llvm::StringRef inputFilename, std::string *errorMessage=nullptr)
Open the file specified by its name for reading.
LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block, const ParserConfig &config, LocationAttr *sourceFileLoc=nullptr)
This parses the file specified by the indicated SourceMgr and appends parsed operations to the given ...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...