brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · fea511c Raw
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