llvm-project/mlir/test/lib/IR/TestLazyLoading.cpp
Mehdi Amini 3128b3105d Add support for Lazyloading to the MLIR bytecode
IsolatedRegions are emitted in sections in order for the reader to be
able to skip over them. A new class is exposed to manage the state and
allow the readers to load these IsolatedRegions on-demand.

Differential Revision: https://reviews.llvm.org/D149515
2023-05-20 15:24:33 -07:00

94 lines
3.2 KiB
C++

//===- TestLazyLoading.cpp - Pass to test operation lazy loading ---------===//
//
// Part of the LLVM Project, 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
//
//===----------------------------------------------------------------------===//
#include "TestDialect.h"
#include "mlir/Bytecode/BytecodeReader.h"
#include "mlir/Bytecode/BytecodeWriter.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/Pass/Pass.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/raw_ostream.h"
#include <list>
using namespace mlir;
namespace {
/// This is a test pass which LazyLoads the current operation recursively.
struct LazyLoadingPass : public PassWrapper<LazyLoadingPass, OperationPass<>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LazyLoadingPass)
StringRef getArgument() const final { return "test-lazy-loading"; }
StringRef getDescription() const final { return "Test LazyLoading of op"; }
LazyLoadingPass() = default;
LazyLoadingPass(const LazyLoadingPass &) {}
void runOnOperation() override {
Operation *op = getOperation();
std::string bytecode;
{
BytecodeWriterConfig config;
if (version >= 0)
config.setDesiredBytecodeVersion(version);
llvm::raw_string_ostream os(bytecode);
if (failed(writeBytecodeToFile(op, os, config))) {
op->emitError() << "failed to write bytecode at version "
<< (int)version;
signalPassFailure();
return;
}
}
llvm::MemoryBufferRef buffer(bytecode, "test-lazy-loading");
Block block;
ParserConfig config(op->getContext(), /*verifyAfterParse=*/false);
BytecodeReader reader(buffer, config,
/*lazyLoad=*/true);
std::list<Operation *> toLoadOps;
if (failed(reader.readTopLevel(&block, [&](Operation *op) {
toLoadOps.push_back(op);
return false;
}))) {
op->emitError() << "failed to read bytecode";
return;
}
llvm::outs() << "Has " << reader.getNumOpsToMaterialize()
<< " ops to materialize\n";
// Recursively print the operations, before and after lazy loading.
while (!toLoadOps.empty()) {
Operation *toLoad = toLoadOps.front();
toLoadOps.pop_front();
llvm::outs() << "\n\nBefore Materializing...\n\n";
toLoad->print(llvm::outs());
llvm::outs() << "\n\nMaterializing...\n\n";
if (failed(reader.materialize(toLoad, [&](Operation *op) {
toLoadOps.push_back(op);
return false;
}))) {
toLoad->emitError() << "failed to materialize";
signalPassFailure();
return;
}
toLoad->print(llvm::outs());
llvm::outs() << "\n";
llvm::outs() << "Has " << reader.getNumOpsToMaterialize()
<< " ops to materialize\n";
}
}
Option<int> version{*this, "bytecode-version",
llvm::cl::desc("Specifies the bytecode version to use."),
llvm::cl::init(-1)};
};
} // namespace
namespace mlir {
void registerLazyLoadingTestPasses() { PassRegistration<LazyLoadingPass>(); }
} // namespace mlir