[Mlir-commits] [mlir] [MLIR] Add support for frame pointers in MLIR (PR #72145)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Nov 13 10:13:43 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm
Author: Radu Salavat (Radu2k)
<details>
<summary>Changes</summary>
Add support for frame pointers in MLIR.
---
Full diff: https://github.com/llvm/llvm-project/pull/72145.diff
8 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td (+19)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+2-1)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+23-2)
- (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+10-1)
- (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+4)
- (modified) mlir/test/Dialect/LLVMIR/func.mlir (+6)
- (added) mlir/test/Target/LLVMIR/Import/frame-pointer.ll (+7)
- (added) mlir/test/Target/LLVMIR/frame-pointer.mlir (+8)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
index f05230526c21f55..446850d6dc7bb96 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
@@ -664,4 +664,23 @@ def ModRefInfoEnum : LLVM_EnumAttr<
let cppNamespace = "::mlir::LLVM";
}
+//===----------------------------------------------------------------------===//
+// FramePointerAttr
+//===----------------------------------------------------------------------===//
+
+def FramePointerKindNone
+ : LLVM_EnumAttrCase<"None", "none", "None", 0>;
+def FramePointerKindNonLeaf
+ : LLVM_EnumAttrCase<"NonLeaf", "non-leaf", "NonLeaf", 1>;
+def FramePointerKindAll
+ : LLVM_EnumAttrCase<"All", "all", "All", 2>;
+
+def FramePointerKindAttr : LLVM_EnumAttr<
+ "FramePointerKind",
+ "::llvm::FramePointerKind",
+ "LLVM FramePointerKind",
+ [FramePointerKindNone, FramePointerKindNonLeaf, FramePointerKindAll]> {
+ let cppNamespace = "::mlir::LLVM";
+}
+
#endif // LLVMIR_ENUMS
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 9fa6f23ce4de2dd..3feb20bc9faa4f2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1390,7 +1390,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
OptionalAttr<StrAttr>:$section,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<LLVM_VScaleRangeAttr>:$vscale_range
+ OptionalAttr<LLVM_VScaleRangeAttr>:$vscale_range,
+ OptionalAttr<FramePointerKindAttr>:$frame_pointer
);
let regions = (region AnyRegion:$body);
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index f6c8f388732c3da..510d81e46cbb43a 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2309,7 +2309,7 @@ ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {
IntegerAttr::get(intTy, minRange),
IntegerAttr::get(intTy, maxRange)));
}
- // Parse the optional comdat selector.
+ // Parse the optional comdat selector.:q
if (succeeded(parser.parseOptionalKeyword("comdat"))) {
SymbolRefAttr comdat;
if (parser.parseLParen() || parser.parseAttribute(comdat) ||
@@ -2319,6 +2319,23 @@ ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {
result.addAttribute(getComdatAttrName(result.name), comdat);
}
+ // Parse the optional frame_pointer
+ if (succeeded(parser.parseOptionalKeyword("frame_pointer"))) {
+ std::string string;
+
+ if (parser.parseEqual() || parser.parseString(&string))
+ return failure();
+ if (!LLVM::symbolizeFramePointerKind(string))
+ {
+ llvm::outs() << "failure: frame-pointer option not recognized: " << string << "\n";
+ return failure();
+ }
+
+ result.addAttribute(getFramePointerAttrName(result.name),
+ LLVM::FramePointerKindAttr::get(parser.getContext(),
+ LLVM::symbolizeFramePointerKind(string).value()));
+ }
+
if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes)))
return failure();
function_interface_impl::addArgAndResultAttrs(
@@ -2373,13 +2390,17 @@ void LLVMFuncOp::print(OpAsmPrinter &p) {
// Print the optional comdat selector.
if (auto comdat = getComdat())
p << " comdat(" << *comdat << ')';
+
+ // Print the optional frame pointer option.
+ if (std::optional<FramePointerKind> frame_pointer = getFramePointer())
+ p << " frame_pointer=" << "\"" << stringifyFramePointerKind(frame_pointer.value()) << "\"";
function_interface_impl::printFunctionAttributes(
p, *this,
{getFunctionTypeAttrName(), getArgAttrsAttrName(), getResAttrsAttrName(),
getLinkageAttrName(), getCConvAttrName(), getVisibility_AttrName(),
getComdatAttrName(), getUnnamedAddrAttrName(),
- getVscaleRangeAttrName()});
+ getVscaleRangeAttrName(), getFramePointerAttrName()});
// Print the body if this is not an external function.
Region &body = getBody();
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index dd2da66caf428bf..e3b08ce4e868b7f 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1602,7 +1602,9 @@ static void processPassthroughAttrs(llvm::Function *func, LLVMFuncOp funcOp) {
// explicit attribute.
// Also skip the vscale_range, it is also an explicit attribute.
if (attrName == "aarch64_pstate_sm_enabled" ||
- attrName == "aarch64_pstate_sm_body" || attrName == "vscale_range")
+ attrName == "aarch64_pstate_sm_body" ||
+ attrName == "vscale_range" ||
+ attrName == "frame-pointer")
continue;
if (attr.isStringAttribute()) {
@@ -1650,6 +1652,13 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
context, IntegerAttr::get(intTy, attr.getVScaleRangeMin()),
IntegerAttr::get(intTy, attr.getVScaleRangeMax().value_or(0))));
}
+
+ // Process frame-pointer attribute
+ if (func->hasFnAttribute("frame-pointer")) {
+ llvm::StringRef stringRefFramePointerKind = func->getFnAttribute("frame-pointer").getValueAsString();
+ funcOp.setFramePointerAttr(LLVM::FramePointerKindAttr::get(funcOp.getContext(),
+ symbolizeFramePointerKind(stringRefFramePointerKind).value()));
+ }
}
DictionaryAttr
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 388ae61958b78b9..d97d4a1b1e50b2d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -894,6 +894,10 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
getLLVMContext(), attr->getMinRange().getInt(),
attr->getMaxRange().getInt()));
+
+ // Add function attribute frame-pointer, if found.
+ if (auto attr = func.getFramePointerAttr())
+ llvmFunc->addFnAttr("frame-pointer", stringifyFramePointerKind(attr.getValue()));
// First, create all blocks so we can jump to them.
llvm::LLVMContext &llvmContext = llvmFunc->getContext();
diff --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir
index 63e20b1d8fc31ab..9e68a3dff4bca85 100644
--- a/mlir/test/Dialect/LLVMIR/func.mlir
+++ b/mlir/test/Dialect/LLVMIR/func.mlir
@@ -249,6 +249,12 @@ module {
// CHECK-SAME: vscale_range(1, 2)
llvm.return
}
+
+ llvm.func @frame_pointer_roundtrip() frame_pointer="non-leaf" {
+ // CHECK: @frame_pointer_roundtrip()
+ // CHECK-SAME: frame_pointer="non-leaf"
+ llvm.return
+ }
}
// -----
diff --git a/mlir/test/Target/LLVMIR/Import/frame-pointer.ll b/mlir/test/Target/LLVMIR/Import/frame-pointer.ll
new file mode 100644
index 000000000000000..698771f4ae04c3e
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/frame-pointer.ll
@@ -0,0 +1,7 @@
+; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
+
+define void @frame_pointer_func() "frame-pointer"="non-leaf" {
+ ; CHECK: llvm.func @frame_pointer_func()
+ ; CHECK-SAME: frame_pointer="non-leaf"
+ ret void
+}
diff --git a/mlir/test/Target/LLVMIR/frame-pointer.mlir b/mlir/test/Target/LLVMIR/frame-pointer.mlir
new file mode 100644
index 000000000000000..543b6b1af1761b8
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/frame-pointer.mlir
@@ -0,0 +1,8 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+llvm.func @frame_pointer_func() frame_pointer="non-leaf" {
+ // CHECK-LABEL: define void @frame_pointer_func
+ // CHECK: attributes #{{.*}} = { "frame-pointer"="non-leaf" }
+ llvm.return
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/72145
More information about the Mlir-commits
mailing list