113 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9//===----------------------------------------------------------------------===//10/// \file11/// This is a generic pass for adding attributes to functions.12//===----------------------------------------------------------------------===//13#include "flang/Optimizer/Dialect/FIROpsSupport.h"14#include "flang/Optimizer/Support/InternalNames.h"15#include "flang/Optimizer/Transforms/Passes.h"16#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"17#include "mlir/Dialect/LLVMIR/LLVMDialect.h"18 19namespace fir {20#define GEN_PASS_DEF_FUNCTIONATTR21#include "flang/Optimizer/Transforms/Passes.h.inc"22} // namespace fir23 24#define DEBUG_TYPE "func-attr"25 26namespace {27 28class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {29public:30 FunctionAttrPass(const fir::FunctionAttrOptions &options) : Base{options} {}31 FunctionAttrPass() = default;32 void runOnOperation() override;33};34 35} // namespace36 37void FunctionAttrPass::runOnOperation() {38 LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n");39 mlir::func::FuncOp func = getOperation();40 41 LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");42 43 llvm::StringRef name = func.getSymName();44 auto deconstructed = fir::NameUniquer::deconstruct(name);45 bool isFromModule = !deconstructed.second.modules.empty();46 47 if ((isFromModule || !func.isDeclaration()) &&48 !fir::hasBindcAttr(func.getOperation())) {49 llvm::StringRef nocapture = mlir::LLVM::LLVMDialect::getNoCaptureAttrName();50 llvm::StringRef noalias = mlir::LLVM::LLVMDialect::getNoAliasAttrName();51 mlir::UnitAttr unitAttr = mlir::UnitAttr::get(func.getContext());52 53 for (auto [index, argType] : llvm::enumerate(func.getArgumentTypes())) {54 bool isNoCapture = false;55 bool isNoAlias = false;56 if (mlir::isa<fir::ReferenceType>(argType) &&57 !func.getArgAttr(index, fir::getTargetAttrName()) &&58 !func.getArgAttr(index, fir::getAsynchronousAttrName()) &&59 !func.getArgAttr(index, fir::getVolatileAttrName())) {60 isNoCapture = true;61 isNoAlias = !fir::isPointerType(argType);62 } else if (mlir::isa<fir::BaseBoxType>(argType)) {63 // !fir.box arguments will be passed as descriptor pointers64 // at LLVM IR dialect level - they cannot be captured,65 // and cannot alias with anything within the function.66 isNoCapture = isNoAlias = true;67 }68 if (isNoCapture && setNoCapture)69 func.setArgAttr(index, nocapture, unitAttr);70 if (isNoAlias && setNoAlias)71 func.setArgAttr(index, noalias, unitAttr);72 }73 }74 75 mlir::MLIRContext *context = &getContext();76 if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None)77 func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get(78 context, framePointerKind));79 80 auto llvmFuncOpName =81 mlir::OperationName(mlir::LLVM::LLVMFuncOp::getOperationName(), context);82 if (!instrumentFunctionEntry.empty())83 func->setAttr(mlir::LLVM::LLVMFuncOp::getInstrumentFunctionEntryAttrName(84 llvmFuncOpName),85 mlir::StringAttr::get(context, instrumentFunctionEntry));86 if (!instrumentFunctionExit.empty())87 func->setAttr(mlir::LLVM::LLVMFuncOp::getInstrumentFunctionExitAttrName(88 llvmFuncOpName),89 mlir::StringAttr::get(context, instrumentFunctionExit));90 if (noInfsFPMath)91 func->setAttr(92 mlir::LLVM::LLVMFuncOp::getNoInfsFpMathAttrName(llvmFuncOpName),93 mlir::BoolAttr::get(context, true));94 if (noNaNsFPMath)95 func->setAttr(96 mlir::LLVM::LLVMFuncOp::getNoNansFpMathAttrName(llvmFuncOpName),97 mlir::BoolAttr::get(context, true));98 if (noSignedZerosFPMath)99 func->setAttr(100 mlir::LLVM::LLVMFuncOp::getNoSignedZerosFpMathAttrName(llvmFuncOpName),101 mlir::BoolAttr::get(context, true));102 if (!reciprocals.empty())103 func->setAttr(104 mlir::LLVM::LLVMFuncOp::getReciprocalEstimatesAttrName(llvmFuncOpName),105 mlir::StringAttr::get(context, reciprocals));106 if (!preferVectorWidth.empty())107 func->setAttr(108 mlir::LLVM::LLVMFuncOp::getPreferVectorWidthAttrName(llvmFuncOpName),109 mlir::StringAttr::get(context, preferVectorWidth));110 111 LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");112}113