Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ using namespace mlir;
static constexpr StringRef varargsAttrName = "func.varargs";
static constexpr StringRef linkageAttrName = "llvm.linkage";
static constexpr StringRef barePtrAttrName = "llvm.bareptr";
static constexpr StringRef noInlineAttrName = "no_inline";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not rely on magic constants in local files and get this somehow from the interface or from specific op classes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the comment, @ftynse!

Would that be acceptable to add the get/set interface methods into FunctionOpInterface and then implement it for func.func, llvm.func, etc.? Or did you mean to suggest something else?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't have a specific suggestion, just observed that such action-at-a-distance is dangerous. The op definition may change the name of the attribute to, e.g., noinline without the underscore, and this code will silently break. Adding interface methods would make sense to be, doubly so if these methods are then used in the inliner logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doubly so if these methods are then used in the inliner logic.

Thanks! It sounds quite reasonable to add such interface methods in FunctionOpInterface.


/// Return `true` if the `op` should use bare pointer calling convention.
static bool shouldUseBarePtrCallConv(Operation *op,
Expand Down Expand Up @@ -381,6 +382,9 @@ mlir::convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp,
newFuncOp.setMemoryEffectsAttr(memoryAttr);
}

// Propagate no_inline attributes
newFuncOp.setNoInline(funcOp->hasAttr(noInlineAttrName));

// Propagate argument/result attributes to all converted arguments/result
// obtained after converting a given original argument/result.
if (ArrayAttr resAttrDicts = funcOp.getAllResultAttrs()) {
Expand Down
8 changes: 8 additions & 0 deletions mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,11 @@ func.func private @badllvmlinkage(i32) attributes { "llvm.linkage" = 3 : i64 } /
func.func @variadic_func(%arg0: i32) attributes { "func.varargs" = true, "llvm.emit_c_interface" } {
return
}

// -----

// Check that no_inline attribute is propagated from func::FuncOp to LLVM::LLVMFuncOp
// CHECK-LABEL: llvm.func @func_with_noinline(%arg0: i32) attributes {no_inline}
func.func @func_with_noinline(%arg0: i32) attributes { no_inline } {
return
}