1 //===-- ConvertVariable.cpp -- bridge to lower to MLIR --------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "flang/Lower/ConvertVariable.h" 14 #include "flang/Lower/AbstractConverter.h" 15 #include "flang/Lower/CallInterface.h" 16 #include "flang/Lower/ConvertExpr.h" 17 #include "flang/Lower/Mangler.h" 18 #include "flang/Lower/PFTBuilder.h" 19 #include "flang/Lower/Support/Utils.h" 20 #include "flang/Lower/SymbolMap.h" 21 #include "flang/Lower/Todo.h" 22 #include "flang/Optimizer/Builder/Character.h" 23 #include "flang/Optimizer/Builder/FIRBuilder.h" 24 #include "flang/Optimizer/Builder/Runtime/Derived.h" 25 #include "flang/Optimizer/Dialect/FIRAttr.h" 26 #include "flang/Optimizer/Dialect/FIRDialect.h" 27 #include "flang/Optimizer/Dialect/FIROps.h" 28 #include "flang/Optimizer/Support/FIRContext.h" 29 #include "flang/Optimizer/Support/FatalError.h" 30 #include "flang/Semantics/tools.h" 31 #include "llvm/Support/Debug.h" 32 33 #define DEBUG_TYPE "flang-lower-variable" 34 35 //===----------------------------------------------------------------===// 36 // Local variables instantiation (not for alias) 37 //===----------------------------------------------------------------===// 38 39 /// Create a stack slot for a local variable. Precondition: the insertion 40 /// point of the builder must be in the entry block, which is currently being 41 /// constructed. 42 static mlir::Value createNewLocal(Fortran::lower::AbstractConverter &converter, 43 mlir::Location loc, 44 const Fortran::lower::pft::Variable &var, 45 mlir::Value preAlloc, 46 llvm::ArrayRef<mlir::Value> shape = {}, 47 llvm::ArrayRef<mlir::Value> lenParams = {}) { 48 if (preAlloc) 49 return preAlloc; 50 fir::FirOpBuilder &builder = converter.getFirOpBuilder(); 51 std::string nm = Fortran::lower::mangle::mangleName(var.getSymbol()); 52 mlir::Type ty = converter.genType(var); 53 const Fortran::semantics::Symbol &ultimateSymbol = 54 var.getSymbol().GetUltimate(); 55 llvm::StringRef symNm = toStringRef(ultimateSymbol.name()); 56 bool isTarg = var.isTarget(); 57 // Let the builder do all the heavy lifting. 58 return builder.allocateLocal(loc, ty, nm, symNm, shape, lenParams, isTarg); 59 } 60 61 /// Instantiate a local variable. Precondition: Each variable will be visited 62 /// such that if its properties depend on other variables, the variables upon 63 /// which its properties depend will already have been visited. 64 static void instantiateLocal(Fortran::lower::AbstractConverter &converter, 65 const Fortran::lower::pft::Variable &var, 66 Fortran::lower::SymMap &symMap) { 67 assert(!var.isAlias()); 68 const Fortran::semantics::Symbol &sym = var.getSymbol(); 69 const bool isDummy = Fortran::semantics::IsDummy(sym); 70 const bool isResult = Fortran::semantics::IsFunctionResult(sym); 71 if (symMap.lookupSymbol(sym)) 72 return; 73 74 const mlir::Location loc = converter.genLocation(sym.name()); 75 if (isDummy) { 76 // This is an argument. 77 if (!symMap.lookupSymbol(sym)) 78 mlir::emitError(loc, "symbol \"") 79 << toStringRef(sym.name()) << "\" must already be in map"; 80 return; 81 } else if (isResult) { 82 // Some Fortran results may be passed by argument (e.g. derived 83 // types) 84 if (symMap.lookupSymbol(sym)) 85 return; 86 } 87 // Otherwise, it's a local variable or function result. 88 mlir::Value local = createNewLocal(converter, loc, var, {}); 89 symMap.addSymbol(sym, local); 90 } 91 92 void Fortran::lower::instantiateVariable(AbstractConverter &converter, 93 const pft::Variable &var, 94 SymMap &symMap) { 95 const Fortran::semantics::Symbol &sym = var.getSymbol(); 96 const mlir::Location loc = converter.genLocation(sym.name()); 97 if (var.isAggregateStore()) { 98 TODO(loc, "instantiateVariable AggregateStore"); 99 } else if (Fortran::semantics::FindCommonBlockContaining( 100 var.getSymbol().GetUltimate())) { 101 TODO(loc, "instantiateVariable Common"); 102 } else if (var.isAlias()) { 103 TODO(loc, "instantiateVariable Alias"); 104 } else if (var.isGlobal()) { 105 TODO(loc, "instantiateVariable Global"); 106 } else { 107 instantiateLocal(converter, var, symMap); 108 } 109 } 110