brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · e4d02e9 Raw
173 lines · cpp
1//===-- FIROpenACCOpsInterfaces.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// Implementation of external operation interfaces for FIR.10//11//===----------------------------------------------------------------------===//12 13#include "flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h"14 15#include "flang/Optimizer/Dialect/FIROps.h"16#include "flang/Optimizer/HLFIR/HLFIROps.h"17#include "flang/Optimizer/Support/InternalNames.h"18#include "mlir/IR/SymbolTable.h"19#include "llvm/ADT/SmallSet.h"20 21namespace fir::acc {22 23template <>24mlir::Value PartialEntityAccessModel<fir::ArrayCoorOp>::getBaseEntity(25    mlir::Operation *op) const {26  return mlir::cast<fir::ArrayCoorOp>(op).getMemref();27}28 29template <>30mlir::Value PartialEntityAccessModel<fir::CoordinateOp>::getBaseEntity(31    mlir::Operation *op) const {32  return mlir::cast<fir::CoordinateOp>(op).getRef();33}34 35template <>36mlir::Value PartialEntityAccessModel<hlfir::DesignateOp>::getBaseEntity(37    mlir::Operation *op) const {38  return mlir::cast<hlfir::DesignateOp>(op).getMemref();39}40 41mlir::Value PartialEntityAccessModel<fir::DeclareOp>::getBaseEntity(42    mlir::Operation *op) const {43  return mlir::cast<fir::DeclareOp>(op).getStorage();44}45 46bool PartialEntityAccessModel<fir::DeclareOp>::isCompleteView(47    mlir::Operation *op) const {48  // Return false (partial view) only if storage is present49  // Return true (complete view) if storage is absent50  return !getBaseEntity(op);51}52 53mlir::Value PartialEntityAccessModel<hlfir::DeclareOp>::getBaseEntity(54    mlir::Operation *op) const {55  return mlir::cast<hlfir::DeclareOp>(op).getStorage();56}57 58bool PartialEntityAccessModel<hlfir::DeclareOp>::isCompleteView(59    mlir::Operation *op) const {60  // Return false (partial view) only if storage is present61  // Return true (complete view) if storage is absent62  return !getBaseEntity(op);63}64 65mlir::SymbolRefAttr AddressOfGlobalModel::getSymbol(mlir::Operation *op) const {66  return mlir::cast<fir::AddrOfOp>(op).getSymbolAttr();67}68 69bool GlobalVariableModel::isConstant(mlir::Operation *op) const {70  auto globalOp = mlir::cast<fir::GlobalOp>(op);71  return globalOp.getConstant().has_value();72}73 74mlir::Region *GlobalVariableModel::getInitRegion(mlir::Operation *op) const {75  auto globalOp = mlir::cast<fir::GlobalOp>(op);76  return globalOp.hasInitializationBody() ? &globalOp.getRegion() : nullptr;77}78 79// Helper to recursively process address-of operations in derived type80// descriptors and collect all needed fir.globals.81static void processAddrOfOpInDerivedTypeDescriptor(82    fir::AddrOfOp addrOfOp, mlir::SymbolTable &symTab,83    llvm::SmallSet<mlir::Operation *, 16> &globalsSet,84    llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols) {85  if (auto globalOp = symTab.lookup<fir::GlobalOp>(86          addrOfOp.getSymbol().getLeafReference().getValue())) {87    if (globalsSet.contains(globalOp))88      return;89    globalsSet.insert(globalOp);90    symbols.push_back(addrOfOp.getSymbolAttr());91    globalOp.walk([&](fir::AddrOfOp op) {92      processAddrOfOpInDerivedTypeDescriptor(op, symTab, globalsSet, symbols);93    });94  }95}96 97// Utility to collect referenced symbols for type descriptors of derived types.98// This is the common logic for operations that may require type descriptor99// globals.100static void collectReferencedSymbolsForType(101    mlir::Type ty, mlir::Operation *op,102    llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols,103    mlir::SymbolTable *symbolTable) {104  ty = fir::getDerivedType(fir::unwrapRefType(ty));105 106  // Look for type descriptor globals only if it's a derived (record) type107  if (auto recTy = mlir::dyn_cast_if_present<fir::RecordType>(ty)) {108    // If no symbol table provided, simply add the type descriptor name109    if (!symbolTable) {110      symbols.push_back(mlir::SymbolRefAttr::get(111          op->getContext(),112          fir::NameUniquer::getTypeDescriptorName(recTy.getName())));113      return;114    }115 116    // Otherwise, do full lookup and recursive processing117    llvm::SmallSet<mlir::Operation *, 16> globalsSet;118 119    fir::GlobalOp globalOp = symbolTable->lookup<fir::GlobalOp>(120        fir::NameUniquer::getTypeDescriptorName(recTy.getName()));121    if (!globalOp)122      globalOp = symbolTable->lookup<fir::GlobalOp>(123          fir::NameUniquer::getTypeDescriptorAssemblyName(recTy.getName()));124 125    if (globalOp) {126      globalsSet.insert(globalOp);127      symbols.push_back(128          mlir::SymbolRefAttr::get(op->getContext(), globalOp.getSymName()));129      globalOp.walk([&](fir::AddrOfOp addrOp) {130        processAddrOfOpInDerivedTypeDescriptor(addrOp, *symbolTable, globalsSet,131                                               symbols);132      });133    }134  }135}136 137template <>138void IndirectGlobalAccessModel<fir::AllocaOp>::getReferencedSymbols(139    mlir::Operation *op, llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols,140    mlir::SymbolTable *symbolTable) const {141  auto allocaOp = mlir::cast<fir::AllocaOp>(op);142  collectReferencedSymbolsForType(allocaOp.getType(), op, symbols, symbolTable);143}144 145template <>146void IndirectGlobalAccessModel<fir::EmboxOp>::getReferencedSymbols(147    mlir::Operation *op, llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols,148    mlir::SymbolTable *symbolTable) const {149  auto emboxOp = mlir::cast<fir::EmboxOp>(op);150  collectReferencedSymbolsForType(emboxOp.getMemref().getType(), op, symbols,151                                  symbolTable);152}153 154template <>155void IndirectGlobalAccessModel<fir::ReboxOp>::getReferencedSymbols(156    mlir::Operation *op, llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols,157    mlir::SymbolTable *symbolTable) const {158  auto reboxOp = mlir::cast<fir::ReboxOp>(op);159  collectReferencedSymbolsForType(reboxOp.getBox().getType(), op, symbols,160                                  symbolTable);161}162 163template <>164void IndirectGlobalAccessModel<fir::TypeDescOp>::getReferencedSymbols(165    mlir::Operation *op, llvm::SmallVectorImpl<mlir::SymbolRefAttr> &symbols,166    mlir::SymbolTable *symbolTable) const {167  auto typeDescOp = mlir::cast<fir::TypeDescOp>(op);168  collectReferencedSymbolsForType(typeDescOp.getInType(), op, symbols,169                                  symbolTable);170}171 172} // namespace fir::acc173