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