aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/intrinsics.cpp
diff options
context:
space:
mode:
authorjiajie zhang <56027356+JumpMasterJJ@users.noreply.github.com>2024-05-18 01:00:25 +0800
committerGitHub <noreply@github.com>2024-05-18 01:00:25 +0800
commitdc8d70acf7afd6d8c9eef7d240fb8c917eddab50 (patch)
treea8fa1c882b8f264c820cfe027a5dc01af93ab232 /flang/lib/Evaluate/intrinsics.cpp
parentd74bc823beabbb7067a4b4ae2d69a36d874f5132 (diff)
downloadllvm-dc8d70acf7afd6d8c9eef7d240fb8c917eddab50.zip
llvm-dc8d70acf7afd6d8c9eef7d240fb8c917eddab50.tar.gz
llvm-dc8d70acf7afd6d8c9eef7d240fb8c917eddab50.tar.bz2
[reland][flang] Add ETIME runtime and lowering intrinsics implementation (#92571)
This is same as https://github.com/llvm/llvm-project/pull/90578 with an added fix. This PR updated tests of etime intrinsic due to Lowering changes for assigning dummy_scope to hlfir.declare. Referring to https://github.com/llvm/llvm-project/pull/92472 and https://github.com/llvm/llvm-project/pull/90989
Diffstat (limited to 'flang/lib/Evaluate/intrinsics.cpp')
-rw-r--r--flang/lib/Evaluate/intrinsics.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 441a762..ded2778 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -454,6 +454,10 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"erf", {{"x", SameReal}}, SameReal},
{"erfc", {{"x", SameReal}}, SameReal},
{"erfc_scaled", {{"x", SameReal}}, SameReal},
+ {"etime",
+ {{"values", TypePattern{RealType, KindCode::exactKind, 4}, Rank::vector,
+ Optionality::required, common::Intent::Out}},
+ TypePattern{RealType, KindCode::exactKind, 4}},
{"exp", {{"x", SameFloating}}, SameFloating},
{"exp", {{"x", SameFloating}}, SameFloating},
{"exponent", {{"x", AnyReal}}, DefaultInt},
@@ -1342,6 +1346,12 @@ static const IntrinsicInterface intrinsicSubroutine[]{
{"values", AnyInt, Rank::vector, Optionality::optional,
common::Intent::Out}},
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
+ {"etime",
+ {{"values", TypePattern{RealType, KindCode::exactKind, 4}, Rank::vector,
+ Optionality::required, common::Intent::Out},
+ {"time", TypePattern{RealType, KindCode::exactKind, 4},
+ Rank::scalar, Optionality::required, common::Intent::Out}},
+ {}, Rank::elemental, IntrinsicClass::impureSubroutine},
{"execute_command_line",
{{"command", DefaultChar, Rank::scalar},
{"wait", AnyLogical, Rank::scalar, Optionality::optional},
@@ -2484,6 +2494,7 @@ public:
bool IsIntrinsic(const std::string &) const;
bool IsIntrinsicFunction(const std::string &) const;
bool IsIntrinsicSubroutine(const std::string &) const;
+ bool IsDualIntrinsic(const std::string &) const;
IntrinsicClass GetIntrinsicClass(const std::string &) const;
std::string GetGenericIntrinsicName(const std::string &) const;
@@ -2545,6 +2556,17 @@ bool IntrinsicProcTable::Implementation::IsIntrinsic(
const std::string &name) const {
return IsIntrinsicFunction(name) || IsIntrinsicSubroutine(name);
}
+bool IntrinsicProcTable::Implementation::IsDualIntrinsic(
+ const std::string &name) const {
+ // Collection for some intrinsics with function and subroutine form,
+ // in order to pass the semantic check.
+ static const std::string dualIntrinsic[]{{"etime"}};
+
+ return std::find_if(std::begin(dualIntrinsic), std::end(dualIntrinsic),
+ [&name](const std::string &dualName) {
+ return dualName == name;
+ }) != std::end(dualIntrinsic);
+}
IntrinsicClass IntrinsicProcTable::Implementation::GetIntrinsicClass(
const std::string &name) const {
@@ -3083,7 +3105,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
return specificCall;
}
}
- if (IsIntrinsicFunction(call.name)) {
+ if (IsIntrinsicFunction(call.name) && !IsDualIntrinsic(call.name)) {
context.messages().Say(
"Cannot use intrinsic function '%s' as a subroutine"_err_en_US,
call.name);
@@ -3218,7 +3240,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
}
if (specificBuffer.empty() && genericBuffer.empty() &&
- IsIntrinsicSubroutine(call.name)) {
+ IsIntrinsicSubroutine(call.name) && !IsDualIntrinsic(call.name)) {
context.messages().Say(
"Cannot use intrinsic subroutine '%s' as a function"_err_en_US,
call.name);