brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · fa3d00e Raw
100 lines · cpp
1//===-- EnvironmentDefaults.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#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"10#include "flang/Lower/EnvironmentDefault.h"11#include "flang/Optimizer/Builder/BoxValue.h"12#include "flang/Optimizer/Builder/FIRBuilder.h"13#include "flang/Optimizer/Support/InternalNames.h"14#include "llvm/ADT/ArrayRef.h"15 16mlir::Value fir::runtime::genEnvironmentDefaults(17    fir::FirOpBuilder &builder, mlir::Location loc,18    const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults) {19  std::string envDefaultListPtrName =20      fir::NameUniquer::doGenerated("EnvironmentDefaults");21 22  mlir::MLIRContext *context = builder.getContext();23  mlir::StringAttr linkOnce = builder.createLinkOnceLinkage();24  mlir::IntegerType intTy = builder.getIntegerType(8 * sizeof(int));25  fir::ReferenceType charRefTy =26      fir::ReferenceType::get(builder.getIntegerType(8));27  fir::SequenceType itemListTy = fir::SequenceType::get(28      envDefaults.size(),29      mlir::TupleType::get(context, {charRefTy, charRefTy}));30  mlir::TupleType envDefaultListTy = mlir::TupleType::get(31      context, {intTy, fir::ReferenceType::get(itemListTy)});32  fir::ReferenceType envDefaultListRefTy =33      fir::ReferenceType::get(envDefaultListTy);34 35  // If no defaults were specified, initialize with a null pointer.36  if (envDefaults.empty()) {37    mlir::Value nullVal = builder.createNullConstant(loc, envDefaultListRefTy);38    return nullVal;39  }40 41  // Create the Item list.42  mlir::IndexType idxTy = builder.getIndexType();43  mlir::IntegerAttr zero = builder.getIntegerAttr(idxTy, 0);44  mlir::IntegerAttr one = builder.getIntegerAttr(idxTy, 1);45  std::string itemListName = envDefaultListPtrName + ".items";46  auto listBuilder = [&](fir::FirOpBuilder &builder) {47    mlir::Value list = fir::UndefOp::create(builder, loc, itemListTy);48    llvm::SmallVector<mlir::Attribute, 2> idx = {mlir::Attribute{},49                                                 mlir::Attribute{}};50    auto insertStringField = [&](const std::string &s,51                                 llvm::ArrayRef<mlir::Attribute> idx) {52      mlir::Value stringAddress = fir::getBase(53          fir::factory::createStringLiteral(builder, loc, s + '\0'));54      mlir::Value addr = builder.createConvert(loc, charRefTy, stringAddress);55      return fir::InsertValueOp::create(builder, loc, itemListTy, list, addr,56                                        builder.getArrayAttr(idx));57    };58 59    size_t n = 0;60    for (const Fortran::lower::EnvironmentDefault &def : envDefaults) {61      idx[0] = builder.getIntegerAttr(idxTy, n);62      idx[1] = zero;63      list = insertStringField(def.varName, idx);64      idx[1] = one;65      list = insertStringField(def.defaultValue, idx);66      ++n;67    }68    fir::HasValueOp::create(builder, loc, list);69  };70  builder.createGlobalConstant(loc, itemListTy, itemListName, listBuilder,71                               linkOnce);72 73  // Define the EnviornmentDefaultList object.74  auto envDefaultListBuilder = [&](fir::FirOpBuilder &builder) {75    mlir::Value envDefaultList =76        fir::UndefOp::create(builder, loc, envDefaultListTy);77    mlir::Value numItems =78        builder.createIntegerConstant(loc, intTy, envDefaults.size());79    envDefaultList = fir::InsertValueOp::create(builder, loc, envDefaultListTy,80                                                envDefaultList, numItems,81                                                builder.getArrayAttr(zero));82    fir::GlobalOp itemList = builder.getNamedGlobal(itemListName);83    assert(itemList && "missing environment default list");84    mlir::Value listAddr = fir::AddrOfOp::create(85        builder, loc, itemList.resultType(), itemList.getSymbol());86    envDefaultList = fir::InsertValueOp::create(builder, loc, envDefaultListTy,87                                                envDefaultList, listAddr,88                                                builder.getArrayAttr(one));89    fir::HasValueOp::create(builder, loc, envDefaultList);90  };91  fir::GlobalOp envDefaultList = builder.createGlobalConstant(92      loc, envDefaultListTy, envDefaultListPtrName + ".list",93      envDefaultListBuilder, linkOnce);94 95  // Define the pointer to the list used by the runtime.96  mlir::Value addr = fir::AddrOfOp::create(97      builder, loc, envDefaultList.resultType(), envDefaultList.getSymbol());98  return addr;99}100