1//===- FunctionAttr.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9//===----------------------------------------------------------------------===//
10/// \file
11/// This is a generic pass for adding attributes to functions.
12//===----------------------------------------------------------------------===//
13#include "flang/Optimizer/Transforms/Passes.h"
14#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
15#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
16
17namespace fir {
18#define GEN_PASS_DECL_FUNCTIONATTR
19#define GEN_PASS_DEF_FUNCTIONATTR
20#include "flang/Optimizer/Transforms/Passes.h.inc"
21} // namespace fir
22
23#define DEBUG_TYPE "func-attr"
24
25namespace {
26
27class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
28public:
29 FunctionAttrPass(const fir::FunctionAttrOptions &options) {
30 framePointerKind = options.framePointerKind;
31 noInfsFPMath = options.noInfsFPMath;
32 noNaNsFPMath = options.noNaNsFPMath;
33 approxFuncFPMath = options.approxFuncFPMath;
34 noSignedZerosFPMath = options.noSignedZerosFPMath;
35 unsafeFPMath = options.unsafeFPMath;
36 }
37 FunctionAttrPass() {}
38 void runOnOperation() override;
39};
40
41} // namespace
42
43void FunctionAttrPass::runOnOperation() {
44 LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n");
45 mlir::func::FuncOp func = getOperation();
46
47 LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");
48
49 mlir::MLIRContext *context = &getContext();
50 if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None)
51 func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get(
52 context, framePointerKind));
53
54 auto llvmFuncOpName =
55 mlir::OperationName(mlir::LLVM::LLVMFuncOp::getOperationName(), context);
56 if (noInfsFPMath)
57 func->setAttr(
58 mlir::LLVM::LLVMFuncOp::getNoInfsFpMathAttrName(llvmFuncOpName),
59 mlir::BoolAttr::get(context, true));
60 if (noNaNsFPMath)
61 func->setAttr(
62 mlir::LLVM::LLVMFuncOp::getNoNansFpMathAttrName(llvmFuncOpName),
63 mlir::BoolAttr::get(context, true));
64 if (approxFuncFPMath)
65 func->setAttr(
66 mlir::LLVM::LLVMFuncOp::getApproxFuncFpMathAttrName(llvmFuncOpName),
67 mlir::BoolAttr::get(context, true));
68 if (noSignedZerosFPMath)
69 func->setAttr(
70 mlir::LLVM::LLVMFuncOp::getNoSignedZerosFpMathAttrName(llvmFuncOpName),
71 mlir::BoolAttr::get(context, true));
72 if (unsafeFPMath)
73 func->setAttr(
74 mlir::LLVM::LLVMFuncOp::getUnsafeFpMathAttrName(llvmFuncOpName),
75 mlir::BoolAttr::get(context, true));
76
77 LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
78}
79
80std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass(
81 fir::FunctionAttrTypes &functionAttr, bool noInfsFPMath, bool noNaNsFPMath,
82 bool approxFuncFPMath, bool noSignedZerosFPMath, bool unsafeFPMath) {
83 FunctionAttrOptions opts;
84 // Frame pointer
85 opts.framePointerKind = functionAttr.framePointerKind;
86 opts.noInfsFPMath = noInfsFPMath;
87 opts.noNaNsFPMath = noNaNsFPMath;
88 opts.approxFuncFPMath = approxFuncFPMath;
89 opts.noSignedZerosFPMath = noSignedZerosFPMath;
90 opts.unsafeFPMath = unsafeFPMath;
91
92 return std::make_unique<FunctionAttrPass>(opts);
93}
94
95std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass() {
96 return std::make_unique<FunctionAttrPass>();
97}
98

source code of flang/lib/Optimizer/Transforms/FunctionAttr.cpp