-
Notifications
You must be signed in to change notification settings - Fork 54
Дормидонтов Егор. Лабораторная работа 4. MLIR. Вариант 4. #194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: course-spring-2025
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
set(Title "MaxLoopRegionDepthPass") | ||
set(Student "Dormidontov_Egor") | ||
set(Group "FIIT2") | ||
set(TARGET_NAME "${Title}_${Student}_${Group}_MLIR") | ||
|
||
file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) | ||
|
||
add_llvm_pass_plugin(${TARGET_NAME} | ||
${SOURCES} | ||
DEPENDS | ||
intrinsics_gen | ||
MLIRBuiltinLocationAttributesIncGen | ||
BUILDTREE_ONLY | ||
) | ||
|
||
set(MLIR_TEST_DEPENDS ${TARGET_NAME} ${MLIR_TEST_DEPENDS} PARENT_SCOPE) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "mlir/Dialect/Affine/IR/AffineOps.h" | ||
#include "mlir/Dialect/Func/IR/FuncOps.h" | ||
#include "mlir/Dialect/SCF/IR/SCF.h" | ||
#include "mlir/IR/Builders.h" | ||
#include "mlir/IR/BuiltinOps.h" | ||
#include "mlir/Pass/Pass.h" | ||
#include "mlir/Tools/Plugins/PassPlugin.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
using namespace mlir; | ||
|
||
namespace { | ||
int computeMaxLoopDepth(func::FuncOp funcOp) { | ||
int maxDepth = 0; | ||
std::function<void(Operation *, int)> visit = [&](Operation *op, | ||
int curDepth) { | ||
if (isa<scf::ForOp, scf::WhileOp, scf::IfOp, affine::AffineForOp>(op)) | ||
++curDepth; | ||
if (curDepth > maxDepth) | ||
maxDepth = curDepth; | ||
for (Region ®ion : op->getRegions()) { | ||
for (Block &block : region) { | ||
for (Operation &nestedOp : block) { | ||
visit(&nestedOp, curDepth); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
visit(funcOp.getOperation(), 0); | ||
|
||
return maxDepth; | ||
} | ||
|
||
class MaxLoopRegionDepthPass | ||
: public PassWrapper<MaxLoopRegionDepthPass, OperationPass<ModuleOp>> { | ||
public: | ||
StringRef getArgument() const final { | ||
return "MaxLoopRegionDepthPass_Dormidontov_Egor_FIIT2_MLIR"; | ||
} | ||
StringRef getDescription() const final { | ||
return "Attach max region nest depth for each loop to function"; | ||
} | ||
|
||
void runOnOperation() override { | ||
ModuleOp moduleOp = getOperation(); | ||
OpBuilder builder(moduleOp); | ||
|
||
moduleOp.walk([&](func::FuncOp funcOp) { | ||
int maxDepth = computeMaxLoopDepth(funcOp); | ||
funcOp->setAttr("max_loop_region_depth", | ||
builder.getI32IntegerAttr(maxDepth)); | ||
llvm::outs() << "Func " << funcOp.getName() | ||
<< ": max_loop_region_depth = " << maxDepth << "\n"; | ||
}); | ||
} | ||
}; | ||
} // namespace | ||
|
||
MLIR_DECLARE_EXPLICIT_TYPE_ID(MaxLoopRegionDepthPass) | ||
MLIR_DEFINE_EXPLICIT_TYPE_ID(MaxLoopRegionDepthPass) | ||
|
||
mlir::PassPluginLibraryInfo getMaxLoopRegionDepthPassPluginInfo() { | ||
return {MLIR_PLUGIN_API_VERSION, "MaxLoopRegionDepthPass", "1.0", | ||
[]() { mlir::PassRegistration<MaxLoopRegionDepthPass>(); }}; | ||
} | ||
|
||
extern "C" LLVM_ATTRIBUTE_WEAK mlir::PassPluginLibraryInfo | ||
mlirGetPassPluginInfo() { | ||
return getMaxLoopRegionDepthPassPluginInfo(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// RUN: mlir-opt -load-pass-plugin=%mlir_lib_dir/MaxLoopRegionDepthPass_Dormidontov_Egor_FIIT2_MLIR%shlibext \ | ||
// RUN: --pass-pipeline="builtin.module(MaxLoopRegionDepthPass_Dormidontov_Egor_FIIT2_MLIR)" %s | FileCheck %s | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have an implementation for affine loops, but do not have tests for them |
||
// ###Простая функция без циклов/if | ||
// CHECK-LABEL: func.func @no_loops | ||
// CHECK: attributes {max_loop_region_depth = 0 : i32} | ||
func.func @no_loops() -> () { | ||
%c0 = arith.constant 0 : index | ||
return | ||
} | ||
|
||
// ###Одна петля, глубина = 1 | ||
// CHECK-LABEL: func.func @simple_loop | ||
// CHECK: attributes {max_loop_region_depth = 1 : i32} | ||
func.func @simple_loop() -> () { | ||
%c0 = arith.constant 0 : index | ||
%c1 = arith.constant 1 : index | ||
%c10 = arith.constant 10 : index | ||
scf.for %i = %c0 to %c10 step %c1 { | ||
// level 1 | ||
} | ||
return | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, add the test where
|
||
// ###Вложенный цикл, глубина = 2 | ||
// CHECK-LABEL: func.func @nested_loops | ||
// CHECK: attributes {max_loop_region_depth = 2 : i32} | ||
func.func @nested_loops() -> () { | ||
%c0 = arith.constant 0 : index | ||
%c1 = arith.constant 1 : index | ||
%c10 = arith.constant 10 : index | ||
scf.for %i = %c0 to %c10 step %c1 { | ||
scf.for %j = %c0 to %c10 step %c1 { | ||
// level 2 | ||
} | ||
} | ||
return | ||
} | ||
|
||
// ###Цикл с if внутри и if во вложении, глубина = 3 | ||
// CHECK-LABEL: func.func @deep_nest | ||
// CHECK: attributes {max_loop_region_depth = 3 : i32} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your tests do not check that attributes attached to the right loop |
||
func.func @deep_nest(%arg0: i1) -> () { | ||
%c0 = arith.constant 0 : index | ||
%c1 = arith.constant 1 : index | ||
%c10 = arith.constant 10 : index | ||
scf.for %i = %c0 to %c10 step %c1 { | ||
scf.if %arg0 { | ||
scf.if %arg0 { | ||
} | ||
} | ||
} | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.