1*3128b310SMehdi Amini //===- TestLazyLoading.cpp - Pass to test operation lazy loading ---------===//
2*3128b310SMehdi Amini //
3*3128b310SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*3128b310SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
5*3128b310SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*3128b310SMehdi Amini //
7*3128b310SMehdi Amini //===----------------------------------------------------------------------===//
8*3128b310SMehdi Amini
9*3128b310SMehdi Amini #include "TestDialect.h"
10*3128b310SMehdi Amini #include "mlir/Bytecode/BytecodeReader.h"
11*3128b310SMehdi Amini #include "mlir/Bytecode/BytecodeWriter.h"
12*3128b310SMehdi Amini #include "mlir/IR/BuiltinOps.h"
13*3128b310SMehdi Amini #include "mlir/IR/OperationSupport.h"
14*3128b310SMehdi Amini #include "mlir/Pass/Pass.h"
15*3128b310SMehdi Amini #include "llvm/Support/MemoryBufferRef.h"
16*3128b310SMehdi Amini #include "llvm/Support/raw_ostream.h"
17*3128b310SMehdi Amini #include <list>
18*3128b310SMehdi Amini
19*3128b310SMehdi Amini using namespace mlir;
20*3128b310SMehdi Amini
21*3128b310SMehdi Amini namespace {
22*3128b310SMehdi Amini
23*3128b310SMehdi Amini /// This is a test pass which LazyLoads the current operation recursively.
24*3128b310SMehdi Amini struct LazyLoadingPass : public PassWrapper<LazyLoadingPass, OperationPass<>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anond11562330111::LazyLoadingPass25*3128b310SMehdi Amini MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LazyLoadingPass)
26*3128b310SMehdi Amini
27*3128b310SMehdi Amini StringRef getArgument() const final { return "test-lazy-loading"; }
getDescription__anond11562330111::LazyLoadingPass28*3128b310SMehdi Amini StringRef getDescription() const final { return "Test LazyLoading of op"; }
29*3128b310SMehdi Amini LazyLoadingPass() = default;
LazyLoadingPass__anond11562330111::LazyLoadingPass30*3128b310SMehdi Amini LazyLoadingPass(const LazyLoadingPass &) {}
31*3128b310SMehdi Amini
runOnOperation__anond11562330111::LazyLoadingPass32*3128b310SMehdi Amini void runOnOperation() override {
33*3128b310SMehdi Amini Operation *op = getOperation();
34*3128b310SMehdi Amini std::string bytecode;
35*3128b310SMehdi Amini {
36*3128b310SMehdi Amini BytecodeWriterConfig config;
37*3128b310SMehdi Amini if (version >= 0)
38*3128b310SMehdi Amini config.setDesiredBytecodeVersion(version);
39*3128b310SMehdi Amini llvm::raw_string_ostream os(bytecode);
40*3128b310SMehdi Amini if (failed(writeBytecodeToFile(op, os, config))) {
41*3128b310SMehdi Amini op->emitError() << "failed to write bytecode at version "
42*3128b310SMehdi Amini << (int)version;
43*3128b310SMehdi Amini signalPassFailure();
44*3128b310SMehdi Amini return;
45*3128b310SMehdi Amini }
46*3128b310SMehdi Amini }
47*3128b310SMehdi Amini llvm::MemoryBufferRef buffer(bytecode, "test-lazy-loading");
48*3128b310SMehdi Amini Block block;
49*3128b310SMehdi Amini ParserConfig config(op->getContext(), /*verifyAfterParse=*/false);
50*3128b310SMehdi Amini BytecodeReader reader(buffer, config,
51*3128b310SMehdi Amini /*lazyLoad=*/true);
52*3128b310SMehdi Amini std::list<Operation *> toLoadOps;
53*3128b310SMehdi Amini if (failed(reader.readTopLevel(&block, [&](Operation *op) {
54*3128b310SMehdi Amini toLoadOps.push_back(op);
55*3128b310SMehdi Amini return false;
56*3128b310SMehdi Amini }))) {
57*3128b310SMehdi Amini op->emitError() << "failed to read bytecode";
58*3128b310SMehdi Amini return;
59*3128b310SMehdi Amini }
60*3128b310SMehdi Amini
61*3128b310SMehdi Amini llvm::outs() << "Has " << reader.getNumOpsToMaterialize()
62*3128b310SMehdi Amini << " ops to materialize\n";
63*3128b310SMehdi Amini
64*3128b310SMehdi Amini // Recursively print the operations, before and after lazy loading.
65*3128b310SMehdi Amini while (!toLoadOps.empty()) {
66*3128b310SMehdi Amini Operation *toLoad = toLoadOps.front();
67*3128b310SMehdi Amini toLoadOps.pop_front();
68*3128b310SMehdi Amini llvm::outs() << "\n\nBefore Materializing...\n\n";
69*3128b310SMehdi Amini toLoad->print(llvm::outs());
70*3128b310SMehdi Amini llvm::outs() << "\n\nMaterializing...\n\n";
71*3128b310SMehdi Amini if (failed(reader.materialize(toLoad, [&](Operation *op) {
72*3128b310SMehdi Amini toLoadOps.push_back(op);
73*3128b310SMehdi Amini return false;
74*3128b310SMehdi Amini }))) {
75*3128b310SMehdi Amini toLoad->emitError() << "failed to materialize";
76*3128b310SMehdi Amini signalPassFailure();
77*3128b310SMehdi Amini return;
78*3128b310SMehdi Amini }
79*3128b310SMehdi Amini toLoad->print(llvm::outs());
80*3128b310SMehdi Amini llvm::outs() << "\n";
81*3128b310SMehdi Amini llvm::outs() << "Has " << reader.getNumOpsToMaterialize()
82*3128b310SMehdi Amini << " ops to materialize\n";
83*3128b310SMehdi Amini }
84*3128b310SMehdi Amini }
85*3128b310SMehdi Amini Option<int> version{*this, "bytecode-version",
86*3128b310SMehdi Amini llvm::cl::desc("Specifies the bytecode version to use."),
87*3128b310SMehdi Amini llvm::cl::init(-1)};
88*3128b310SMehdi Amini };
89*3128b310SMehdi Amini } // namespace
90*3128b310SMehdi Amini
91*3128b310SMehdi Amini namespace mlir {
registerLazyLoadingTestPasses()92*3128b310SMehdi Amini void registerLazyLoadingTestPasses() { PassRegistration<LazyLoadingPass>(); }
93*3128b310SMehdi Amini } // namespace mlir
94