@@ -248,9 +248,11 @@ struct IntrinsicLibrary {
248
248
mlir::Value outlineInWrapper (GeneratorType, llvm::StringRef name,
249
249
mlir::Type resultType,
250
250
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);
254
256
255
257
template <typename GeneratorType>
256
258
mlir::FuncOp getWrapper (GeneratorType, llvm::StringRef name,
@@ -273,7 +275,6 @@ struct IntrinsicLibrary {
273
275
mlir::Type resultType,
274
276
llvm::ArrayRef<mlir::Value> args);
275
277
mlir::Value invokeGenerator (SubroutineGenerator generator,
276
- mlir::Type resultType,
277
278
llvm::ArrayRef<mlir::Value> args);
278
279
279
280
// / Get pointer to unrestricted intrinsic. Generate the related unrestricted
@@ -662,12 +663,16 @@ static mlir::FuncOp getRuntimeFunction(mlir::Location loc,
662
663
663
664
// / Helpers to get function type from arguments and result type.
664
665
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,
666
668
Fortran::lower::FirOpBuilder &builder) {
667
669
llvm::SmallVector<mlir::Type, 2 > argumentTypes;
668
670
for (auto &arg : arguments)
669
671
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,
671
676
builder.getModule ().getContext ());
672
677
}
673
678
@@ -765,12 +770,12 @@ IntrinsicLibrary::genElementalCall<IntrinsicLibrary::ExtendedGenerator>(
765
770
exit (1 );
766
771
}
767
772
if (outline)
768
- return outlineInWrapper (generator, name, resultType, args);
773
+ return outlineInExtendedWrapper (generator, name, resultType, args);
769
774
return std::invoke (generator, *this , resultType, args);
770
775
}
771
776
772
777
static fir::ExtendedValue
773
- invokeHanlder (IntrinsicLibrary::ElementalGenerator generator,
778
+ invokeHandler (IntrinsicLibrary::ElementalGenerator generator,
774
779
const IntrinsicHandler &handler,
775
780
llvm::Optional<mlir::Type> resultType,
776
781
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
@@ -781,7 +786,7 @@ invokeHanlder(IntrinsicLibrary::ElementalGenerator generator,
781
786
}
782
787
783
788
static fir::ExtendedValue
784
- invokeHanlder (IntrinsicLibrary::ExtendedGenerator generator,
789
+ invokeHandler (IntrinsicLibrary::ExtendedGenerator generator,
785
790
const IntrinsicHandler &handler,
786
791
llvm::Optional<mlir::Type> resultType,
787
792
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
@@ -791,18 +796,19 @@ invokeHanlder(IntrinsicLibrary::ExtendedGenerator generator,
791
796
return lib.genElementalCall (generator, handler.name , *resultType, args,
792
797
outline);
793
798
if (outline)
794
- return lib.outlineInWrapper (generator, handler.name , *resultType, args);
799
+ return lib.outlineInExtendedWrapper (generator, handler.name , *resultType,
800
+ args);
795
801
return std::invoke (generator, lib, *resultType, args);
796
802
}
797
803
static fir::ExtendedValue
798
- invokeHanlder (IntrinsicLibrary::SubroutineGenerator generator,
804
+ invokeHandler (IntrinsicLibrary::SubroutineGenerator generator,
799
805
const IntrinsicHandler &handler,
800
806
llvm::Optional<mlir::Type> resultType,
801
807
llvm::ArrayRef<fir::ExtendedValue> args, bool outline,
802
808
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);
806
812
std::invoke (generator, lib, args);
807
813
return mlir::Value{};
808
814
}
@@ -824,7 +830,7 @@ IntrinsicLibrary::genIntrinsicCall(llvm::StringRef name,
824
830
bool outline = handler.outline || outlineAllIntrinsics;
825
831
return std::visit (
826
832
[&](auto &generator) -> fir::ExtendedValue {
827
- return invokeHanlder (generator, handler, resultType, args, outline,
833
+ return invokeHandler (generator, handler, resultType, args, outline,
828
834
*this );
829
835
},
830
836
handler.generator );
@@ -884,7 +890,6 @@ IntrinsicLibrary::invokeGenerator(ExtendedGenerator generator,
884
890
885
891
mlir::Value
886
892
IntrinsicLibrary::invokeGenerator (SubroutineGenerator generator,
887
- mlir::Type resultType,
888
893
llvm::ArrayRef<mlir::Value> args) {
889
894
llvm::SmallVector<fir::ExtendedValue, 2 > extendedArgs;
890
895
for (auto arg : args)
@@ -928,12 +933,18 @@ mlir::FuncOp IntrinsicLibrary::getWrapper(GeneratorType generator,
928
933
}
929
934
930
935
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
+ }
937
948
} else {
938
949
// Wrapper was already built, ensure it has the sought type
939
950
assert (function.getType () == funcType &&
@@ -977,10 +988,11 @@ IntrinsicLibrary::outlineInWrapper(GeneratorType generator,
977
988
return builder.create <fir::CallOp>(loc, wrapper, args).getResult (0 );
978
989
}
979
990
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) {
984
996
if (hasAbsentOptional (args)) {
985
997
// TODO
986
998
mlir::emitError (loc, " todo: cannot outline call to intrinsic " +
@@ -993,9 +1005,11 @@ IntrinsicLibrary::outlineInWrapper(ExtendedGenerator generator,
993
1005
mlirArgs.emplace_back (toValue (extendedVal, builder, loc));
994
1006
auto funcType = getFunctionType (resultType, mlirArgs, builder);
995
1007
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{};
999
1013
}
1000
1014
1001
1015
IntrinsicLibrary::RuntimeCallGenerator
0 commit comments