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