Skip to content

Commit 2ba09d4

Browse files
jeanPerierschweitzpgi
authored andcommitted
Add intrinsic wrapper for subroutines
1 parent 443c9ca commit 2ba09d4

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

flang/lib/Lower/IntrinsicCall.cpp

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,11 @@ struct IntrinsicLibrary {
248248
mlir::Value outlineInWrapper(GeneratorType, llvm::StringRef name,
249249
mlir::Type resultType,
250250
llvm::ArrayRef<mlir::Value> args);
251-
fir::ExtendedValue outlineInWrapper(ExtendedGenerator, llvm::StringRef name,
252-
mlir::Type resultType,
253-
llvm::ArrayRef<fir::ExtendedValue> args);
251+
template <typename GeneratorType>
252+
fir::ExtendedValue
253+
outlineInExtendedWrapper(GeneratorType, llvm::StringRef name,
254+
llvm::Optional<mlir::Type> resultType,
255+
llvm::ArrayRef<fir::ExtendedValue> args);
254256

255257
template <typename GeneratorType>
256258
mlir::FuncOp getWrapper(GeneratorType, llvm::StringRef name,
@@ -273,7 +275,6 @@ struct IntrinsicLibrary {
273275
mlir::Type resultType,
274276
llvm::ArrayRef<mlir::Value> args);
275277
mlir::Value invokeGenerator(SubroutineGenerator generator,
276-
mlir::Type resultType,
277278
llvm::ArrayRef<mlir::Value> args);
278279

279280
/// Get pointer to unrestricted intrinsic. Generate the related unrestricted
@@ -662,12 +663,16 @@ static mlir::FuncOp getRuntimeFunction(mlir::Location loc,
662663

663664
/// Helpers to get function type from arguments and result type.
664665
static mlir::FunctionType
665-
getFunctionType(mlir::Type resultType, llvm::ArrayRef<mlir::Value> arguments,
666+
getFunctionType(llvm::Optional<mlir::Type> resultType,
667+
llvm::ArrayRef<mlir::Value> arguments,
666668
Fortran::lower::FirOpBuilder &builder) {
667669
llvm::SmallVector<mlir::Type, 2> argumentTypes;
668670
for (auto &arg : arguments)
669671
argumentTypes.push_back(arg.getType());
670-
return mlir::FunctionType::get(argumentTypes, resultType,
672+
llvm::SmallVector<mlir::Type, 1> resultTypes;
673+
if (resultType)
674+
resultTypes.push_back(*resultType);
675+
return mlir::FunctionType::get(argumentTypes, resultTypes,
671676
builder.getModule().getContext());
672677
}
673678

@@ -765,12 +770,12 @@ IntrinsicLibrary::genElementalCall<IntrinsicLibrary::ExtendedGenerator>(
765770
exit(1);
766771
}
767772
if (outline)
768-
return outlineInWrapper(generator, name, resultType, args);
773+
return outlineInExtendedWrapper(generator, name, resultType, args);
769774
return std::invoke(generator, *this, resultType, args);
770775
}
771776

772777
static fir::ExtendedValue
773-
invokeHanlder(IntrinsicLibrary::ElementalGenerator generator,
778+
invokeHandler(IntrinsicLibrary::ElementalGenerator generator,
774779
const IntrinsicHandler &handler,
775780
llvm::Optional<mlir::Type> resultType,
776781
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
@@ -781,7 +786,7 @@ invokeHanlder(IntrinsicLibrary::ElementalGenerator generator,
781786
}
782787

783788
static fir::ExtendedValue
784-
invokeHanlder(IntrinsicLibrary::ExtendedGenerator generator,
789+
invokeHandler(IntrinsicLibrary::ExtendedGenerator generator,
785790
const IntrinsicHandler &handler,
786791
llvm::Optional<mlir::Type> resultType,
787792
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
@@ -791,18 +796,19 @@ invokeHanlder(IntrinsicLibrary::ExtendedGenerator generator,
791796
return lib.genElementalCall(generator, handler.name, *resultType, args,
792797
outline);
793798
if (outline)
794-
return lib.outlineInWrapper(generator, handler.name, *resultType, args);
799+
return lib.outlineInExtendedWrapper(generator, handler.name, *resultType,
800+
args);
795801
return std::invoke(generator, lib, *resultType, args);
796802
}
797803
static fir::ExtendedValue
798-
invokeHanlder(IntrinsicLibrary::SubroutineGenerator generator,
804+
invokeHandler(IntrinsicLibrary::SubroutineGenerator generator,
799805
const IntrinsicHandler &handler,
800806
llvm::Optional<mlir::Type> resultType,
801807
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
802808
IntrinsicLibrary &lib) {
803-
// TODO
804-
// if (outline)
805-
// return outlineInWrapper(generator, handler.name, *resultType, args);
809+
if (outline)
810+
return lib.outlineInExtendedWrapper(generator, handler.name, resultType,
811+
args);
806812
std::invoke(generator, lib, args);
807813
return mlir::Value{};
808814
}
@@ -824,7 +830,7 @@ IntrinsicLibrary::genIntrinsicCall(llvm::StringRef name,
824830
bool outline = handler.outline || outlineAllIntrinsics;
825831
return std::visit(
826832
[&](auto &generator) -> fir::ExtendedValue {
827-
return invokeHanlder(generator, handler, resultType, args, outline,
833+
return invokeHandler(generator, handler, resultType, args, outline,
828834
*this);
829835
},
830836
handler.generator);
@@ -884,7 +890,6 @@ IntrinsicLibrary::invokeGenerator(ExtendedGenerator generator,
884890

885891
mlir::Value
886892
IntrinsicLibrary::invokeGenerator(SubroutineGenerator generator,
887-
mlir::Type resultType,
888893
llvm::ArrayRef<mlir::Value> args) {
889894
llvm::SmallVector<fir::ExtendedValue, 2> extendedArgs;
890895
for (auto arg : args)
@@ -928,12 +933,18 @@ mlir::FuncOp IntrinsicLibrary::getWrapper(GeneratorType generator,
928933
}
929934

930935
IntrinsicLibrary localLib{*localBuilder, localLoc};
931-
mlir::Type resultType;
932-
if (funcType.getNumResults() == 1)
933-
resultType = funcType.getResult(0);
934-
auto result =
935-
localLib.invokeGenerator(generator, resultType, localArguments);
936-
localBuilder->create<mlir::ReturnOp>(localLoc, result);
936+
937+
if constexpr (std::is_same_v<GeneratorType, SubroutineGenerator>) {
938+
localLib.invokeGenerator(generator, localArguments);
939+
localBuilder->create<mlir::ReturnOp>(localLoc);
940+
} else {
941+
assert(funcType.getNumResults() == 1 &&
942+
"expect one result for intrinsic function wrapper type");
943+
auto resultType = funcType.getResult(0);
944+
auto result =
945+
localLib.invokeGenerator(generator, resultType, localArguments);
946+
localBuilder->create<mlir::ReturnOp>(localLoc, result);
947+
}
937948
} else {
938949
// Wrapper was already built, ensure it has the sought type
939950
assert(function.getType() == funcType &&
@@ -977,10 +988,11 @@ IntrinsicLibrary::outlineInWrapper(GeneratorType generator,
977988
return builder.create<fir::CallOp>(loc, wrapper, args).getResult(0);
978989
}
979990

980-
fir::ExtendedValue
981-
IntrinsicLibrary::outlineInWrapper(ExtendedGenerator generator,
982-
llvm::StringRef name, mlir::Type resultType,
983-
llvm::ArrayRef<fir::ExtendedValue> args) {
991+
template <typename GeneratorType>
992+
fir::ExtendedValue IntrinsicLibrary::outlineInExtendedWrapper(
993+
GeneratorType generator, llvm::StringRef name,
994+
llvm::Optional<mlir::Type> resultType,
995+
llvm::ArrayRef<fir::ExtendedValue> args) {
984996
if (hasAbsentOptional(args)) {
985997
// TODO
986998
mlir::emitError(loc, "todo: cannot outline call to intrinsic " +
@@ -993,9 +1005,11 @@ IntrinsicLibrary::outlineInWrapper(ExtendedGenerator generator,
9931005
mlirArgs.emplace_back(toValue(extendedVal, builder, loc));
9941006
auto funcType = getFunctionType(resultType, mlirArgs, builder);
9951007
auto wrapper = getWrapper(generator, name, funcType);
996-
auto mlirResult =
997-
builder.create<fir::CallOp>(loc, wrapper, mlirArgs).getResult(0);
998-
return toExtendedValue(mlirResult, builder, loc);
1008+
auto call = builder.create<fir::CallOp>(loc, wrapper, mlirArgs);
1009+
if (resultType)
1010+
return toExtendedValue(call.getResult(0), builder, loc);
1011+
// Subroutine calls
1012+
return mlir::Value{};
9991013
}
10001014

10011015
IntrinsicLibrary::RuntimeCallGenerator

0 commit comments

Comments
 (0)