Skip to content

Commit cfc4860

Browse files
committed
[flang][NFC] Move Procedure designator lowering in its own file
Code move without any change, the goal is to re-use this piece of code for procedure designator lowering in HLFIR since there is no significant changes in the way procedure designators will be lowered. Differential Revision: https://reviews.llvm.org/D143563
1 parent 1af3f59 commit cfc4860

File tree

4 files changed

+143
-70
lines changed

4 files changed

+143
-70
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===- ConvertProcedureDesignator.h -- Procedure Designators ----*- C++ -*-===//
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+
/// Lowering of evaluate::ProcedureDesignator to FIR and HLFIR.
14+
///
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef FORTRAN_LOWER_CONVERT_PROCEDURE_DESIGNATOR_H
18+
#define FORTRAN_LOWER_CONVERT_PROCEDURE_DESIGNATOR_H
19+
20+
namespace mlir {
21+
class Location;
22+
}
23+
namespace fir {
24+
class ExtendedValue;
25+
}
26+
namespace Fortran::evaluate {
27+
struct ProcedureDesignator;
28+
}
29+
30+
namespace Fortran::lower {
31+
class AbstractConverter;
32+
class StatementContext;
33+
class SymMap;
34+
35+
/// Lower a procedure designator to a fir::ExtendedValue that can be a
36+
/// fir::CharBoxValue for character procedure designator (the CharBoxValue
37+
/// length carries the result length if it is known).
38+
fir::ExtendedValue convertProcedureDesignator(
39+
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
40+
const Fortran::evaluate::ProcedureDesignator &proc,
41+
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx);
42+
43+
} // namespace Fortran::lower
44+
#endif // FORTRAN_LOWER_CONVERT_PROCEDURE_DESIGNATOR_H

flang/lib/Lower/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_flang_library(FortranLower
99
ConvertConstant.cpp
1010
ConvertExpr.cpp
1111
ConvertExprToHLFIR.cpp
12+
ConvertProcedureDesignator.cpp
1213
ConvertType.cpp
1314
ConvertVariable.cpp
1415
ComponentPath.cpp

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 3 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "flang/Lower/ComponentPath.h"
2525
#include "flang/Lower/ConvertCall.h"
2626
#include "flang/Lower/ConvertConstant.h"
27+
#include "flang/Lower/ConvertProcedureDesignator.h"
2728
#include "flang/Lower/ConvertType.h"
2829
#include "flang/Lower/ConvertVariable.h"
2930
#include "flang/Lower/CustomIntrinsicCall.h"
@@ -403,16 +404,6 @@ static bool isParenthesizedVariable(const Fortran::evaluate::Expr<T> &expr) {
403404
}
404405
}
405406

406-
/// Does \p expr only refer to symbols that are mapped to IR values in \p symMap
407-
/// ?
408-
static bool allSymbolsInExprPresentInMap(const Fortran::lower::SomeExpr &expr,
409-
Fortran::lower::SymMap &symMap) {
410-
for (const auto &sym : Fortran::evaluate::CollectSymbols(expr))
411-
if (!symMap.lookupSymbol(sym))
412-
return false;
413-
return true;
414-
}
415-
416407
/// Generate a load of a value from an address. Beware that this will lose
417408
/// any dynamic type information for polymorphic entities (note that unlimited
418409
/// polymorphic cannot be loaded and must not be provided here).
@@ -880,66 +871,8 @@ class ScalarExprLowering {
880871
/// The type of the function indirection is not guaranteed to match the one
881872
/// of the ProcedureDesignator due to Fortran implicit typing rules.
882873
ExtValue genval(const Fortran::evaluate::ProcedureDesignator &proc) {
883-
mlir::Location loc = getLoc();
884-
if (const Fortran::evaluate::SpecificIntrinsic *intrinsic =
885-
proc.GetSpecificIntrinsic()) {
886-
mlir::FunctionType signature =
887-
Fortran::lower::translateSignature(proc, converter);
888-
// Intrinsic lowering is based on the generic name, so retrieve it here in
889-
// case it is different from the specific name. The type of the specific
890-
// intrinsic is retained in the signature.
891-
std::string genericName =
892-
converter.getFoldingContext().intrinsics().GetGenericIntrinsicName(
893-
intrinsic->name);
894-
mlir::SymbolRefAttr symbolRefAttr =
895-
fir::getUnrestrictedIntrinsicSymbolRefAttr(builder, loc, genericName,
896-
signature);
897-
mlir::Value funcPtr =
898-
builder.create<fir::AddrOfOp>(loc, signature, symbolRefAttr);
899-
return funcPtr;
900-
}
901-
const Fortran::semantics::Symbol *symbol = proc.GetSymbol();
902-
assert(symbol && "expected symbol in ProcedureDesignator");
903-
mlir::Value funcPtr;
904-
mlir::Value funcPtrResultLength;
905-
if (Fortran::semantics::IsDummy(*symbol)) {
906-
Fortran::lower::SymbolBox val = symMap.lookupSymbol(*symbol);
907-
assert(val && "Dummy procedure not in symbol map");
908-
funcPtr = val.getAddr();
909-
if (fir::isCharacterProcedureTuple(funcPtr.getType(),
910-
/*acceptRawFunc=*/false))
911-
std::tie(funcPtr, funcPtrResultLength) =
912-
fir::factory::extractCharacterProcedureTuple(builder, loc, funcPtr);
913-
} else {
914-
std::string name = converter.mangleName(*symbol);
915-
mlir::func::FuncOp func =
916-
Fortran::lower::getOrDeclareFunction(name, proc, converter);
917-
funcPtr = builder.create<fir::AddrOfOp>(loc, func.getFunctionType(),
918-
builder.getSymbolRefAttr(name));
919-
}
920-
if (Fortran::lower::mustPassLengthWithDummyProcedure(proc, converter)) {
921-
// The result length, if available here, must be propagated along the
922-
// procedure address so that call sites where the result length is assumed
923-
// can retrieve the length.
924-
Fortran::evaluate::DynamicType resultType = proc.GetType().value();
925-
if (const auto &lengthExpr = resultType.GetCharLength()) {
926-
// The length expression may refer to dummy argument symbols that are
927-
// meaningless without any actual arguments. Leave the length as
928-
// unknown in that case, it be resolved on the call site
929-
// with the actual arguments.
930-
if (allSymbolsInExprPresentInMap(toEvExpr(*lengthExpr), symMap)) {
931-
mlir::Value rawLen = fir::getBase(genval(*lengthExpr));
932-
// F2018 7.4.4.2 point 5.
933-
funcPtrResultLength =
934-
fir::factory::genMaxWithZero(builder, getLoc(), rawLen);
935-
}
936-
}
937-
if (!funcPtrResultLength)
938-
funcPtrResultLength = builder.createIntegerConstant(
939-
loc, builder.getCharacterLengthType(), -1);
940-
return fir::CharBoxValue{funcPtr, funcPtrResultLength};
941-
}
942-
return funcPtr;
874+
return Fortran::lower::convertProcedureDesignator(getLoc(), converter, proc,
875+
symMap, stmtCtx);
943876
}
944877
ExtValue genval(const Fortran::evaluate::NullPointer &) {
945878
return builder.createNullConstant(getLoc());
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===- ConvertProcedureDesignator.cpp -- Procedure Designator ---*- C++ -*-===//
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+
#include "flang/Lower/ConvertProcedureDesignator.h"
10+
#include "flang/Evaluate/intrinsics.h"
11+
#include "flang/Lower/AbstractConverter.h"
12+
#include "flang/Lower/CallInterface.h"
13+
#include "flang/Lower/ConvertCall.h"
14+
#include "flang/Lower/ConvertVariable.h"
15+
#include "flang/Lower/Support/Utils.h"
16+
#include "flang/Lower/SymbolMap.h"
17+
#include "flang/Optimizer/Builder/Character.h"
18+
#include "flang/Optimizer/Builder/IntrinsicCall.h"
19+
#include "flang/Optimizer/Dialect/FIROps.h"
20+
21+
static bool areAllSymbolsInExprMapped(const Fortran::evaluate::ExtentExpr &expr,
22+
Fortran::lower::SymMap &symMap) {
23+
for (const auto &sym : Fortran::evaluate::CollectSymbols(expr))
24+
if (!symMap.lookupSymbol(sym))
25+
return false;
26+
return true;
27+
}
28+
29+
fir::ExtendedValue Fortran::lower::convertProcedureDesignator(
30+
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
31+
const Fortran::evaluate::ProcedureDesignator &proc,
32+
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) {
33+
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
34+
35+
if (const Fortran::evaluate::SpecificIntrinsic *intrinsic =
36+
proc.GetSpecificIntrinsic()) {
37+
mlir::FunctionType signature =
38+
Fortran::lower::translateSignature(proc, converter);
39+
// Intrinsic lowering is based on the generic name, so retrieve it here in
40+
// case it is different from the specific name. The type of the specific
41+
// intrinsic is retained in the signature.
42+
std::string genericName =
43+
converter.getFoldingContext().intrinsics().GetGenericIntrinsicName(
44+
intrinsic->name);
45+
mlir::SymbolRefAttr symbolRefAttr =
46+
fir::getUnrestrictedIntrinsicSymbolRefAttr(builder, loc, genericName,
47+
signature);
48+
mlir::Value funcPtr =
49+
builder.create<fir::AddrOfOp>(loc, signature, symbolRefAttr);
50+
return funcPtr;
51+
}
52+
const Fortran::semantics::Symbol *symbol = proc.GetSymbol();
53+
assert(symbol && "expected symbol in ProcedureDesignator");
54+
mlir::Value funcPtr;
55+
mlir::Value funcPtrResultLength;
56+
if (Fortran::semantics::IsDummy(*symbol)) {
57+
Fortran::lower::SymbolBox val = symMap.lookupSymbol(*symbol);
58+
assert(val && "Dummy procedure not in symbol map");
59+
funcPtr = val.getAddr();
60+
if (fir::isCharacterProcedureTuple(funcPtr.getType(),
61+
/*acceptRawFunc=*/false))
62+
std::tie(funcPtr, funcPtrResultLength) =
63+
fir::factory::extractCharacterProcedureTuple(builder, loc, funcPtr);
64+
} else {
65+
std::string name = converter.mangleName(*symbol);
66+
mlir::func::FuncOp func =
67+
Fortran::lower::getOrDeclareFunction(name, proc, converter);
68+
funcPtr = builder.create<fir::AddrOfOp>(loc, func.getFunctionType(),
69+
builder.getSymbolRefAttr(name));
70+
}
71+
if (Fortran::lower::mustPassLengthWithDummyProcedure(proc, converter)) {
72+
// The result length, if available here, must be propagated along the
73+
// procedure address so that call sites where the result length is assumed
74+
// can retrieve the length.
75+
Fortran::evaluate::DynamicType resultType = proc.GetType().value();
76+
if (const auto &lengthExpr = resultType.GetCharLength()) {
77+
// The length expression may refer to dummy argument symbols that are
78+
// meaningless without any actual arguments. Leave the length as
79+
// unknown in that case, it be resolved on the call site
80+
// with the actual arguments.
81+
if (areAllSymbolsInExprMapped(*lengthExpr, symMap)) {
82+
mlir::Value rawLen = fir::getBase(
83+
converter.genExprValue(toEvExpr(*lengthExpr), stmtCtx));
84+
// F2018 7.4.4.2 point 5.
85+
funcPtrResultLength =
86+
fir::factory::genMaxWithZero(builder, loc, rawLen);
87+
}
88+
}
89+
if (!funcPtrResultLength)
90+
funcPtrResultLength = builder.createIntegerConstant(
91+
loc, builder.getCharacterLengthType(), -1);
92+
return fir::CharBoxValue{funcPtr, funcPtrResultLength};
93+
}
94+
return funcPtr;
95+
}

0 commit comments

Comments
 (0)