xref: /llvm-project/flang/lib/Optimizer/Transforms/FunctionAttr.cpp (revision f3cf24fcc46ab1b9612d7dcb55ec5f18ea2dc62f)
104873773SRadu Salavat //===- FunctionAttr.cpp ---------------------------------------------------===//
204873773SRadu Salavat //
304873773SRadu Salavat // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
404873773SRadu Salavat // See https://llvm.org/LICENSE.txt for license information.
504873773SRadu Salavat // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
604873773SRadu Salavat //
704873773SRadu Salavat //===----------------------------------------------------------------------===//
804873773SRadu Salavat 
904873773SRadu Salavat //===----------------------------------------------------------------------===//
1004873773SRadu Salavat /// \file
1104873773SRadu Salavat /// This is a generic pass for adding attributes to functions.
1204873773SRadu Salavat //===----------------------------------------------------------------------===//
13*f3cf24fcSs-watanabe314 #include "flang/Optimizer/Dialect/FIROpsSupport.h"
14*f3cf24fcSs-watanabe314 #include "flang/Optimizer/Support/InternalNames.h"
1504873773SRadu Salavat #include "flang/Optimizer/Transforms/Passes.h"
1604873773SRadu Salavat #include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
1722544e2aSAlex Bradbury #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1804873773SRadu Salavat 
1904873773SRadu Salavat namespace fir {
2004873773SRadu Salavat #define GEN_PASS_DEF_FUNCTIONATTR
2104873773SRadu Salavat #include "flang/Optimizer/Transforms/Passes.h.inc"
2204873773SRadu Salavat } // namespace fir
2304873773SRadu Salavat 
2404873773SRadu Salavat #define DEBUG_TYPE "func-attr"
2504873773SRadu Salavat 
2604873773SRadu Salavat namespace {
2704873773SRadu Salavat 
2804873773SRadu Salavat class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
2904873773SRadu Salavat public:
3004873773SRadu Salavat   FunctionAttrPass(const fir::FunctionAttrOptions &options) {
3104873773SRadu Salavat     framePointerKind = options.framePointerKind;
3222544e2aSAlex Bradbury     noInfsFPMath = options.noInfsFPMath;
3322544e2aSAlex Bradbury     noNaNsFPMath = options.noNaNsFPMath;
3422544e2aSAlex Bradbury     approxFuncFPMath = options.approxFuncFPMath;
3522544e2aSAlex Bradbury     noSignedZerosFPMath = options.noSignedZerosFPMath;
3622544e2aSAlex Bradbury     unsafeFPMath = options.unsafeFPMath;
3704873773SRadu Salavat   }
3804873773SRadu Salavat   FunctionAttrPass() {}
3904873773SRadu Salavat   void runOnOperation() override;
4004873773SRadu Salavat };
4104873773SRadu Salavat 
4204873773SRadu Salavat } // namespace
4304873773SRadu Salavat 
4404873773SRadu Salavat void FunctionAttrPass::runOnOperation() {
4504873773SRadu Salavat   LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n");
4604873773SRadu Salavat   mlir::func::FuncOp func = getOperation();
4704873773SRadu Salavat 
4804873773SRadu Salavat   LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");
4904873773SRadu Salavat 
50*f3cf24fcSs-watanabe314   llvm::StringRef name = func.getSymName();
51*f3cf24fcSs-watanabe314   auto deconstructed = fir::NameUniquer::deconstruct(name);
52*f3cf24fcSs-watanabe314   bool isFromModule = !deconstructed.second.modules.empty();
53*f3cf24fcSs-watanabe314 
54*f3cf24fcSs-watanabe314   if ((isFromModule || !func.isDeclaration()) &&
55*f3cf24fcSs-watanabe314       !fir::hasBindcAttr(func.getOperation())) {
56*f3cf24fcSs-watanabe314     llvm::StringRef nocapture = mlir::LLVM::LLVMDialect::getNoCaptureAttrName();
57*f3cf24fcSs-watanabe314     mlir::UnitAttr unitAttr = mlir::UnitAttr::get(func.getContext());
58*f3cf24fcSs-watanabe314 
59*f3cf24fcSs-watanabe314     for (auto [index, argType] : llvm::enumerate(func.getArgumentTypes())) {
60*f3cf24fcSs-watanabe314       if (mlir::isa<fir::ReferenceType>(argType) &&
61*f3cf24fcSs-watanabe314           !func.getArgAttr(index, fir::getTargetAttrName()) &&
62*f3cf24fcSs-watanabe314           !func.getArgAttr(index, fir::getAsynchronousAttrName()) &&
63*f3cf24fcSs-watanabe314           !func.getArgAttr(index, fir::getVolatileAttrName()))
64*f3cf24fcSs-watanabe314         func.setArgAttr(index, nocapture, unitAttr);
65*f3cf24fcSs-watanabe314     }
66*f3cf24fcSs-watanabe314   }
67*f3cf24fcSs-watanabe314 
6804873773SRadu Salavat   mlir::MLIRContext *context = &getContext();
6904873773SRadu Salavat   if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None)
7004873773SRadu Salavat     func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get(
7104873773SRadu Salavat                                        context, framePointerKind));
7204873773SRadu Salavat 
7322544e2aSAlex Bradbury   auto llvmFuncOpName =
7422544e2aSAlex Bradbury       mlir::OperationName(mlir::LLVM::LLVMFuncOp::getOperationName(), context);
7522544e2aSAlex Bradbury   if (noInfsFPMath)
7622544e2aSAlex Bradbury     func->setAttr(
7722544e2aSAlex Bradbury         mlir::LLVM::LLVMFuncOp::getNoInfsFpMathAttrName(llvmFuncOpName),
7822544e2aSAlex Bradbury         mlir::BoolAttr::get(context, true));
7922544e2aSAlex Bradbury   if (noNaNsFPMath)
8022544e2aSAlex Bradbury     func->setAttr(
8122544e2aSAlex Bradbury         mlir::LLVM::LLVMFuncOp::getNoNansFpMathAttrName(llvmFuncOpName),
8222544e2aSAlex Bradbury         mlir::BoolAttr::get(context, true));
8322544e2aSAlex Bradbury   if (approxFuncFPMath)
8422544e2aSAlex Bradbury     func->setAttr(
8522544e2aSAlex Bradbury         mlir::LLVM::LLVMFuncOp::getApproxFuncFpMathAttrName(llvmFuncOpName),
8622544e2aSAlex Bradbury         mlir::BoolAttr::get(context, true));
8722544e2aSAlex Bradbury   if (noSignedZerosFPMath)
8822544e2aSAlex Bradbury     func->setAttr(
8922544e2aSAlex Bradbury         mlir::LLVM::LLVMFuncOp::getNoSignedZerosFpMathAttrName(llvmFuncOpName),
9022544e2aSAlex Bradbury         mlir::BoolAttr::get(context, true));
9122544e2aSAlex Bradbury   if (unsafeFPMath)
9222544e2aSAlex Bradbury     func->setAttr(
9322544e2aSAlex Bradbury         mlir::LLVM::LLVMFuncOp::getUnsafeFpMathAttrName(llvmFuncOpName),
9422544e2aSAlex Bradbury         mlir::BoolAttr::get(context, true));
9522544e2aSAlex Bradbury 
9604873773SRadu Salavat   LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
9704873773SRadu Salavat }
98