-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[mlir][EmitC] Expand the MemRefToEmitC pass - Lowering CopyOp
#151206
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: main
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 |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
#include "mlir/IR/Attributes.h" | ||
#include "mlir/Pass/Pass.h" | ||
#include "mlir/Transforms/DialectConversion.h" | ||
#include "llvm/ADT/StringRef.h" | ||
|
||
namespace mlir { | ||
#define GEN_PASS_DEF_CONVERTMEMREFTOEMITC | ||
|
@@ -27,6 +28,25 @@ namespace mlir { | |
using namespace mlir; | ||
|
||
namespace { | ||
|
||
emitc::IncludeOp addStandardHeader(OpBuilder &builder, ModuleOp module, | ||
StringRef headerName) { | ||
StringAttr includeAttr = builder.getStringAttr(headerName); | ||
return builder.create<emitc::IncludeOp>( | ||
module.getLoc(), includeAttr, | ||
/*is_standard_include=*/builder.getUnitAttr()); | ||
} | ||
|
||
bool isExpectedStandardInclude(ConvertMemRefToEmitCOptions options, | ||
emitc::IncludeOp includeOp) { | ||
return ((options.lowerToCpp && | ||
(includeOp.getInclude() == cppStandardLibraryHeader || | ||
includeOp.getInclude() == cppStringLibraryHeader)) || | ||
(!options.lowerToCpp && | ||
(includeOp.getInclude() == cStandardLibraryHeader || | ||
includeOp.getInclude() == cStringLibraryHeader))); | ||
} | ||
|
||
struct ConvertMemRefToEmitCPass | ||
: public impl::ConvertMemRefToEmitCBase<ConvertMemRefToEmitCPass> { | ||
using Base::Base; | ||
|
@@ -57,31 +77,30 @@ struct ConvertMemRefToEmitCPass | |
mlir::ModuleOp module = getOperation(); | ||
module.walk([&](mlir::emitc::CallOpaqueOp callOp) { | ||
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. Not sure this works as expected: the same module may contain both |
||
if (callOp.getCallee() != alignedAllocFunctionName && | ||
callOp.getCallee() != mallocFunctionName) { | ||
callOp.getCallee() != mallocFunctionName && | ||
callOp.getCallee() != memcpyFunctionName) | ||
return mlir::WalkResult::advance(); | ||
} | ||
|
||
for (auto &op : *module.getBody()) { | ||
emitc::IncludeOp includeOp = llvm::dyn_cast<mlir::emitc::IncludeOp>(op); | ||
if (!includeOp) { | ||
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. Change itself is good (removing braces from single-line blocks) but should be done on a separate PR to avoid cluttering this one with unrelated modifications. 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. ideally, yes. 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.
Practically too. It's not about the number of lines or their proximity to other changes. LLVM's contribution policy requires patches to be minimal. More specifically:
|
||
if (!includeOp) | ||
continue; | ||
} | ||
|
||
if (includeOp.getIsStandardInclude() && | ||
((options.lowerToCpp && | ||
includeOp.getInclude() == cppStandardLibraryHeader) || | ||
(!options.lowerToCpp && | ||
includeOp.getInclude() == cStandardLibraryHeader))) { | ||
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. Same here. 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. yes, i should! |
||
isExpectedStandardInclude(options, includeOp)) | ||
return mlir::WalkResult::interrupt(); | ||
} | ||
} | ||
|
||
mlir::OpBuilder builder(module.getBody(), module.getBody()->begin()); | ||
StringAttr includeAttr = | ||
builder.getStringAttr(options.lowerToCpp ? cppStandardLibraryHeader | ||
: cStandardLibraryHeader); | ||
builder.create<mlir::emitc::IncludeOp>( | ||
module.getLoc(), includeAttr, | ||
/*is_standard_include=*/builder.getUnitAttr()); | ||
StringRef headerName; | ||
if (callOp.getCallee() == memcpyFunctionName) | ||
headerName = | ||
options.lowerToCpp ? cppStringLibraryHeader : cStringLibraryHeader; | ||
else | ||
headerName = options.lowerToCpp ? cppStandardLibraryHeader | ||
: cStandardLibraryHeader; | ||
|
||
addStandardHeader(builder, module, headerName); | ||
return mlir::WalkResult::interrupt(); | ||
}); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// RUN: mlir-opt -convert-memref-to-emitc="lower-to-cpp=true" %s -split-input-file | FileCheck %s --check-prefix=CPP | ||
// RUN: mlir-opt -convert-memref-to-emitc="lower-to-cpp=false" %s -split-input-file | FileCheck %s --check-prefix=NOCPP | ||
|
||
func.func @copying(%arg0 : memref<9x4x5x7xf32>, %arg1 : memref<9x4x5x7xf32>) { | ||
memref.copy %arg0, %arg1 : memref<9x4x5x7xf32> to memref<9x4x5x7xf32> | ||
return | ||
} | ||
|
||
// NOCPP: module { | ||
// NOCPP-NEXT: emitc.include <"string.h"> | ||
// NOCPP-LABEL: copying | ||
// NOCPP-SAME: %[[arg0:.*]]: memref<9x4x5x7xf32>, %[[arg1:.*]]: memref<9x4x5x7xf32> | ||
// NOCPP-NEXT: %0 = builtin.unrealized_conversion_cast %arg1 : memref<9x4x5x7xf32> to !emitc.array<9x4x5x7xf32> | ||
// NOCPP-NEXT: %1 = builtin.unrealized_conversion_cast %arg0 : memref<9x4x5x7xf32> to !emitc.array<9x4x5x7xf32> | ||
// NOCPP-NEXT: %2 = "emitc.constant"() <{value = 0 : index}> : () -> index | ||
// NOCPP-NEXT: %3 = emitc.subscript %1[%2, %2, %2, %2] : (!emitc.array<9x4x5x7xf32>, index, index, index, index) -> !emitc.lvalue<f32> | ||
// NOCPP-NEXT: %4 = emitc.apply "&"(%3) : (!emitc.lvalue<f32>) -> !emitc.ptr<f32> | ||
// NOCPP-NEXT: %5 = emitc.subscript %0[%2, %2, %2, %2] : (!emitc.array<9x4x5x7xf32>, index, index, index, index) -> !emitc.lvalue<f32> | ||
// NOCPP-NEXT: %6 = emitc.apply "&"(%5) : (!emitc.lvalue<f32>) -> !emitc.ptr<f32> | ||
// NOCPP-NEXT: %7 = emitc.call_opaque "sizeof"() {args = [f32]} : () -> !emitc.size_t | ||
// NOCPP-NEXT: %8 = "emitc.constant"() <{value = 1260 : index}> : () -> index | ||
// NOCPP-NEXT: %9 = emitc.mul %7, %8 : (!emitc.size_t, index) -> !emitc.size_t | ||
// NOCPP-NEXT: emitc.call_opaque "memcpy"(%6, %4, %9) : (!emitc.ptr<f32>, !emitc.ptr<f32>, !emitc.size_t) -> () | ||
// NOCPP-NEXT: return | ||
// NOCPP-NEXT: } | ||
// NOCPP-NEXT:} | ||
|
||
// CPP: module { | ||
// CPP-NEXT: emitc.include <"cstring"> | ||
// CPP-LABEL: copying | ||
// CPP-SAME: %[[arg0:.*]]: memref<9x4x5x7xf32>, %[[arg1:.*]]: memref<9x4x5x7xf32> | ||
// CPP-NEXT: %0 = builtin.unrealized_conversion_cast %arg1 : memref<9x4x5x7xf32> to !emitc.array<9x4x5x7xf32> | ||
// CPP-NEXT: %1 = builtin.unrealized_conversion_cast %arg0 : memref<9x4x5x7xf32> to !emitc.array<9x4x5x7xf32> | ||
// CPP-NEXT: %2 = "emitc.constant"() <{value = 0 : index}> : () -> index | ||
// CPP-NEXT: %3 = emitc.subscript %1[%2, %2, %2, %2] : (!emitc.array<9x4x5x7xf32>, index, index, index, index) -> !emitc.lvalue<f32> | ||
// CPP-NEXT: %4 = emitc.apply "&"(%3) : (!emitc.lvalue<f32>) -> !emitc.ptr<f32> | ||
// CPP-NEXT: %5 = emitc.subscript %0[%2, %2, %2, %2] : (!emitc.array<9x4x5x7xf32>, index, index, index, index) -> !emitc.lvalue<f32> | ||
// CPP-NEXT: %6 = emitc.apply "&"(%5) : (!emitc.lvalue<f32>) -> !emitc.ptr<f32> | ||
// CPP-NEXT: %7 = emitc.call_opaque "sizeof"() {args = [f32]} : () -> !emitc.size_t | ||
// CPP-NEXT: %8 = "emitc.constant"() <{value = 1260 : index}> : () -> index | ||
// CPP-NEXT: %9 = emitc.mul %7, %8 : (!emitc.size_t, index) -> !emitc.size_t | ||
// CPP-NEXT: emitc.call_opaque "memcpy"(%6, %4, %9) : (!emitc.ptr<f32>, !emitc.ptr<f32>, !emitc.size_t) -> () | ||
// CPP-NEXT: return | ||
// CPP-NEXT: } | ||
// CPP-NEXT:} |
Uh oh!
There was an error while loading. Please reload this page.