aboutsummaryrefslogtreecommitdiff
path: root/flang/lib
diff options
context:
space:
mode:
authorRadu Salavat <radu.salavat@arm.com>2023-12-28 17:41:27 +0200
committerGitHub <noreply@github.com>2023-12-28 15:41:27 +0000
commit04873773821b891277a054e94282fe66e09e0aff (patch)
treed45bf05a169e3a047ecfdbb08c0ae7094086b227 /flang/lib
parent554feb0058980ae3c6159a61ffdae2c2d345bf7a (diff)
downloadllvm-04873773821b891277a054e94282fe66e09e0aff.zip
llvm-04873773821b891277a054e94282fe66e09e0aff.tar.gz
llvm-04873773821b891277a054e94282fe66e09e0aff.tar.bz2
[flang] Pass to add frame pointer attribute (#74598)
Pass to add frame pointer attribute in Flang
Diffstat (limited to 'flang/lib')
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp17
-rw-r--r--flang/lib/Optimizer/Transforms/CMakeLists.txt1
-rw-r--r--flang/lib/Optimizer/Transforms/FunctionAttr.cpp62
3 files changed, 80 insertions, 0 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 4ce6171..b65b6e3 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -245,6 +245,23 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.AliasAnalysis = opts.OptimizationLevel > 0;
+ // -mframe-pointer=none/non-leaf/all option.
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) {
+ std::optional<llvm::FramePointerKind> val =
+ llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue())
+ .Case("none", llvm::FramePointerKind::None)
+ .Case("non-leaf", llvm::FramePointerKind::NonLeaf)
+ .Case("all", llvm::FramePointerKind::All)
+ .Default(std::nullopt);
+
+ if (!val.has_value()) {
+ diags.Report(clang::diag::err_drv_invalid_value)
+ << a->getAsString(args) << a->getValue();
+ } else
+ opts.setFramePointer(val.value());
+ }
+
for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
opts.LLVMPassPlugins.push_back(a->getValue());
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 03b6710..fc067ad 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -20,6 +20,7 @@ add_flang_library(FIRTransforms
OMPFunctionFiltering.cpp
OMPMarkDeclareTarget.cpp
VScaleAttr.cpp
+ FunctionAttr.cpp
DEPENDS
FIRDialect
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
new file mode 100644
index 0000000..55b908b
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -0,0 +1,62 @@
+//===- FunctionAttr.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+/// \file
+/// This is a generic pass for adding attributes to functions.
+//===----------------------------------------------------------------------===//
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+
+namespace fir {
+#define GEN_PASS_DECL_FUNCTIONATTR
+#define GEN_PASS_DEF_FUNCTIONATTR
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+#define DEBUG_TYPE "func-attr"
+
+namespace {
+
+class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
+public:
+ FunctionAttrPass(const fir::FunctionAttrOptions &options) {
+ framePointerKind = options.framePointerKind;
+ }
+ FunctionAttrPass() {}
+ void runOnOperation() override;
+};
+
+} // namespace
+
+void FunctionAttrPass::runOnOperation() {
+ LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n");
+ mlir::func::FuncOp func = getOperation();
+
+ LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");
+
+ mlir::MLIRContext *context = &getContext();
+ if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None)
+ func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get(
+ context, framePointerKind));
+
+ LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
+}
+
+std::unique_ptr<mlir::Pass>
+fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) {
+ FunctionAttrOptions opts;
+ // Frame pointer
+ opts.framePointerKind = functionAttr.framePointerKind;
+
+ return std::make_unique<FunctionAttrPass>(opts);
+}
+
+std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass() {
+ return std::make_unique<FunctionAttrPass>();
+}