| //===-- MIFCommon.cpp -------------------------------------------*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "flang/Optimizer/Builder/MIFCommon.h" | |
| #include "flang/Optimizer/Builder/HLFIRTools.h" | |
| #include "flang/Optimizer/Dialect/MIF/MIFOps.h" | |
| #include "flang/Optimizer/HLFIR/HLFIROps.h" | |
| #include "llvm/ADT/TypeSwitch.h" | |
| std::string mif::getFullUniqName(mlir::Value addr) { | |
| mlir::Operation *op = addr.getDefiningOp(); | |
| if (auto designateOp = mlir::dyn_cast<hlfir::DesignateOp>(op)) { | |
| if (designateOp.getComponent()) | |
| return getFullUniqName(designateOp.getMemref()) + "." + | |
| designateOp.getComponent()->getValue().str(); | |
| return getFullUniqName(designateOp.getMemref()); | |
| } else if (auto declareOp = mlir::dyn_cast<hlfir::DeclareOp>(op)) | |
| return declareOp.getUniqName().getValue().str(); | |
| else if (auto declareOp = mlir::dyn_cast<fir::DeclareOp>(op)) | |
| return declareOp.getUniqName().getValue().str(); | |
| else if (auto load = mlir::dyn_cast<fir::LoadOp>(op)) | |
| return getFullUniqName(load.getMemref()); | |
| else if (auto ba = mlir::dyn_cast<fir::BoxAddrOp>(op)) | |
| return getFullUniqName(ba.getVal()); | |
| else if (auto rb = mlir::dyn_cast<fir::ReboxOp>(op)) | |
| return getFullUniqName(rb.getBox()); | |
| else if (auto eb = mlir::dyn_cast<fir::EmboxOp>(op)) | |
| return getFullUniqName(eb.getMemref()); | |
| else if (auto ebc = mlir::dyn_cast<fir::EmboxCharOp>(op)) | |
| return getFullUniqName(ebc.getMemref()); | |
| else if (auto c = mlir::dyn_cast<fir::CoordinateOp>(op)) { | |
| if (c.getFieldIndicesAttr()) { | |
| mlir::Type eleTy = fir::getFortranElementType(c.getRef().getType()); | |
| std::string uniqName = getFullUniqName(c.getRef()); | |
| for (auto index : c.getIndices()) { | |
| llvm::TypeSwitch<fir::IntOrValue>(index) | |
| .Case<mlir::IntegerAttr>([&](mlir::IntegerAttr intAttr) { | |
| if (auto recordType = llvm::dyn_cast<fir::RecordType>(eleTy)) { | |
| int fieldId = intAttr.getInt(); | |
| if (fieldId < static_cast<int>(recordType.getNumFields())) { | |
| auto nameAndType = recordType.getTypeList()[fieldId]; | |
| auto rrr = getFullUniqName(c.getRef()) + "." + | |
| std::get<std::string>(nameAndType); | |
| uniqName += "." + std::get<std::string>(nameAndType); | |
| } | |
| } | |
| }) | |
| .Case<mlir::Value>( | |
| [&](mlir::Value v) { return getFullUniqName(v); }); | |
| } | |
| return uniqName; | |
| } | |
| return getFullUniqName(c.getRef()); | |
| } | |
| return ""; | |
| } | |
| mlir::Value mif::genImageIndex(fir::FirOpBuilder &builder, mlir::Location loc, | |
| mlir::Value coarray, mlir::Value sub, | |
| mlir::Value team) { | |
| mlir::Type newSubType = | |
| fir::changeElementType(sub.getType(), builder.getI64Type(), false); | |
| if (newSubType == sub.getType()) | |
| return mif::ImageIndexOp::create(builder, loc, coarray, sub, team); | |
| auto subCastAndCleanup = hlfir::genTypeAndKindConvert( | |
| loc, builder, hlfir::Entity{sub}, newSubType, true); | |
| auto [exv, cleanup] = | |
| hlfir::convertToBox(loc, builder, subCastAndCleanup.first, newSubType); | |
| auto imageIndex = | |
| mif::ImageIndexOp::create(builder, loc, coarray, fir::getBase(exv), team); | |
| if (cleanup) | |
| (*cleanup)(); | |
| if (subCastAndCleanup.second) | |
| (*subCastAndCleanup.second)(); | |
| return imageIndex; | |
| } | |
| mlir::func::FuncOp mif::getOrCreateInitFunc(fir::FirOpBuilder &builder, | |
| mlir::ModuleOp mod, | |
| llvm::StringRef name) { | |
| mlir::Location loc = mod.getLoc(); | |
| auto funcType = builder.getFunctionType({}, {}); | |
| auto func = builder.createFunction(loc, name, funcType); | |
| if (!func.empty()) | |
| return func; | |
| func.setPublic(); | |
| mlir::OpBuilder::InsertionGuard guard(builder); | |
| builder.setInsertionPointToEnd(mod.getBody()); | |
| func.addEntryBlock(); | |
| builder.setInsertionPointToEnd(&func.getBody().front()); | |
| mif::InitOp::create(builder, loc); | |
| mlir::func::ReturnOp::create(builder, loc); | |
| return func; | |
| } |