[flang] [llvm] [flang][runtime] Replace recursion with iterative work queue (PR #137727)
Slava Zakharin via llvm-commits
llvm-commits at lists.llvm.org
Tue May 27 12:14:57 PDT 2025
================
@@ -0,0 +1,153 @@
+//===-- lib/runtime/work-queue.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang-rt/runtime/work-queue.h"
+#include "flang-rt/runtime/environment.h"
+#include "flang-rt/runtime/type-info.h"
+#include "flang/Common/visit.h"
+
+namespace Fortran::runtime {
+
+#if !defined(RT_DEVICE_COMPILATION)
+// FLANG_RT_DEBUG code is disabled when false.
+static constexpr bool enableDebugOutput{false};
+#endif
+
+RT_OFFLOAD_API_GROUP_BEGIN
+
+RT_API_ATTRS Componentwise::Componentwise(const typeInfo::DerivedType &derived)
+ : derived_{derived}, components_{derived_.component().Elements()} {
+ GetComponent();
+}
+
+RT_API_ATTRS void Componentwise::GetComponent() {
+ if (componentAt_ >= components_) {
+ component_ = nullptr;
+ } else {
+ const Descriptor &componentDesc{derived_.component()};
+ component_ = componentDesc.ZeroBasedIndexedElement<typeInfo::Component>(
+ componentAt_);
+ }
+}
+
+RT_API_ATTRS int Ticket::Continue(WorkQueue &workQueue) {
+ if (!begun) {
+ begun = true;
+ return common::visit(
+ [&workQueue](
+ auto &specificTicket) { return specificTicket.Begin(workQueue); },
+ u);
+ } else {
+ return common::visit(
+ [&workQueue](auto &specificTicket) {
+ return specificTicket.Continue(workQueue);
+ },
+ u);
+ }
+}
+
+RT_API_ATTRS WorkQueue::~WorkQueue() {
+ if (last_) {
+ if ((last_->next = firstFree_)) {
+ last_->next->previous = last_;
+ }
+ firstFree_ = first_;
+ first_ = last_ = nullptr;
+ }
+ while (firstFree_) {
+ TicketList *next{firstFree_->next};
+ if (!firstFree_->isStatic) {
+ delete firstFree_;
+ }
+ firstFree_ = next;
+ }
+}
+
+RT_API_ATTRS Ticket &WorkQueue::StartTicket() {
+ if (!firstFree_) {
+ firstFree_ = new TicketList;
+ firstFree_->isStatic = false;
+ }
+ TicketList *newTicket{firstFree_};
+ if ((firstFree_ = newTicket->next)) {
+ firstFree_->previous = nullptr;
+ }
+ TicketList *after{insertAfter_ ? insertAfter_->next : nullptr};
+ if ((newTicket->previous = insertAfter_ ? insertAfter_ : last_)) {
+ newTicket->previous->next = newTicket;
+ } else {
+ first_ = newTicket;
+ }
+ if ((newTicket->next = after)) {
+ after->previous = newTicket;
+ } else {
+ last_ = newTicket;
+ }
+ newTicket->ticket.begun = false;
+#if !defined(RT_DEVICE_COMPILATION)
+ if (enableDebugOutput && (executionEnvironment.internalDebugging & 1)) {
----------------
vzakhari wrote:
nit: could you turn literal `1` into a named constant so that it is easier to see which bits of `internalDebugging` are used for what (given that we may add more bits in future)?
https://github.com/llvm/llvm-project/pull/137727
More information about the llvm-commits
mailing list