[Openmp-commits] [openmp] af14456 - [OpenMP] Simplify generic microtask dispatch (#214004)
via Openmp-commits
openmp-commits at lists.llvm.org
Tue Aug 4 10:52:48 PDT 2026
Author: arsnyder16
Date: 2026-08-04T10:52:44-07:00
New Revision: af14456a2bac55026b2d57cbf14b3905c452b8a4
URL: https://github.com/llvm/llvm-project/commit/af14456a2bac55026b2d57cbf14b3905c452b8a4
DIFF: https://github.com/llvm/llvm-project/commit/af14456a2bac55026b2d57cbf14b3905c452b8a4.diff
LOG: [OpenMP] Simplify generic microtask dispatch (#214004)
Replace the generic microtask dispatcher's handwritten function-pointer
types and calls with a variadic-template helper and a macro for each
supported argument count.
The dispatcher still casts each microtask to the exact fixed-arity
signature required by platforms such as WebAssembly. This is intended as
a refactor only: the existing limit of 15 microtask arguments and the
diagnostic for larger argument counts remain unchanged.
This reduces the repetitive code and makes future changes to the
supported argument range easier to review.
Split out from #211071
Added:
Modified:
openmp/runtime/src/kmp_invoke_microtask.cpp
Removed:
################################################################################
diff --git a/openmp/runtime/src/kmp_invoke_microtask.cpp b/openmp/runtime/src/kmp_invoke_microtask.cpp
index f14f27cc06ee3..e3cae9938bcd3 100644
--- a/openmp/runtime/src/kmp_invoke_microtask.cpp
+++ b/openmp/runtime/src/kmp_invoke_microtask.cpp
@@ -1,49 +1,27 @@
#include "kmp.h"
+#include <utility>
+
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || KMP_ARCH_AARCH64 || \
KMP_ARCH_PPC64 || KMP_ARCH_RISCV64 || KMP_ARCH_LOONGARCH64 || \
KMP_ARCH_ARM || KMP_ARCH_VE || KMP_ARCH_S390X || KMP_ARCH_PPC_XCOFF || \
KMP_ARCH_AARCH64_32)
-// Because WebAssembly will use `call_indirect` to invoke the microtask and
-// WebAssembly indirect calls check that the called signature is a precise
-// match, we need to cast each microtask function pointer back from `void *` to
-// its original type.
-typedef void (*microtask_t0)(int *, int *);
-typedef void (*microtask_t1)(int *, int *, void *);
-typedef void (*microtask_t2)(int *, int *, void *, void *);
-typedef void (*microtask_t3)(int *, int *, void *, void *, void *);
-typedef void (*microtask_t4)(int *, int *, void *, void *, void *, void *);
-typedef void (*microtask_t5)(int *, int *, void *, void *, void *, void *,
- void *);
-typedef void (*microtask_t6)(int *, int *, void *, void *, void *, void *,
- void *, void *);
-typedef void (*microtask_t7)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *);
-typedef void (*microtask_t8)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *);
-typedef void (*microtask_t9)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *);
-typedef void (*microtask_t10)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *);
-typedef void (*microtask_t11)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *,
- void *);
-typedef void (*microtask_t12)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *,
- void *, void *);
-typedef void (*microtask_t13)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *,
- void *, void *, void *);
-typedef void (*microtask_t14)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *,
- void *, void *, void *, void *);
-typedef void (*microtask_t15)(int *, int *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *, void *,
- void *, void *, void *, void *, void *);
+template <size_t> using microtask_argument_t = void *;
+
+template <size_t... Indices>
+static void invokeMicrotask(microtask_t pkfn, int *gtid, int *tid,
+ void *p_argv[], std::index_sequence<Indices...>) {
+ // WebAssembly's `call_indirect` requires the callee type to exactly match the
+ // call site. Cast the variadic microtask_t to the fixed-arity signature that
+ // matches argc before invoking it.
+ using typed_microtask_t =
+ void (*)(int *, int *, microtask_argument_t<Indices>...);
+ (*(typed_microtask_t)pkfn)(gtid, tid, p_argv[Indices]...);
+}
-// we really only need the case with 1 argument, because CLANG always build
-// a struct of pointers to shared variables referenced in the outlined function
+// Keep a bounded set of exact signatures for targets that cannot dynamically
+// construct a variable-argument microtask call.
int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
void *p_argv[]
#if OMPT_SUPPORT
@@ -55,85 +33,36 @@ int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
*exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);
#endif
+#define KMP_INVOKE_MICROTASK_CASE(N) \
+ case N: \
+ invokeMicrotask(pkfn, >id, &tid, p_argv, std::make_index_sequence<N>{}); \
+ break
+
switch (argc) {
+ KMP_INVOKE_MICROTASK_CASE(0);
+ KMP_INVOKE_MICROTASK_CASE(1);
+ KMP_INVOKE_MICROTASK_CASE(2);
+ KMP_INVOKE_MICROTASK_CASE(3);
+ KMP_INVOKE_MICROTASK_CASE(4);
+ KMP_INVOKE_MICROTASK_CASE(5);
+ KMP_INVOKE_MICROTASK_CASE(6);
+ KMP_INVOKE_MICROTASK_CASE(7);
+ KMP_INVOKE_MICROTASK_CASE(8);
+ KMP_INVOKE_MICROTASK_CASE(9);
+ KMP_INVOKE_MICROTASK_CASE(10);
+ KMP_INVOKE_MICROTASK_CASE(11);
+ KMP_INVOKE_MICROTASK_CASE(12);
+ KMP_INVOKE_MICROTASK_CASE(13);
+ KMP_INVOKE_MICROTASK_CASE(14);
+ KMP_INVOKE_MICROTASK_CASE(15);
default:
fprintf(stderr, "Too many args to microtask: %d!\n", argc);
fflush(stderr);
exit(-1);
- case 0:
- (*(microtask_t0)pkfn)(>id, &tid);
- break;
- case 1:
- (*(microtask_t1)pkfn)(>id, &tid, p_argv[0]);
- break;
- case 2:
- (*(microtask_t2)pkfn)(>id, &tid, p_argv[0], p_argv[1]);
- break;
- case 3:
- (*(microtask_t3)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2]);
- break;
- case 4:
- (*(microtask_t4)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3]);
- break;
- case 5:
- (*(microtask_t5)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4]);
- break;
- case 6:
- (*(microtask_t6)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5]);
- break;
- case 7:
- (*(microtask_t7)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6]);
- break;
- case 8:
- (*(microtask_t8)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7]);
- break;
- case 9:
- (*(microtask_t9)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6], p_argv[7],
- p_argv[8]);
- break;
- case 10:
- (*(microtask_t10)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9]);
- break;
- case 11:
- (*(microtask_t11)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9], p_argv[10]);
- break;
- case 12:
- (*(microtask_t12)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9], p_argv[10],
- p_argv[11]);
- break;
- case 13:
- (*(microtask_t13)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9], p_argv[10],
- p_argv[11], p_argv[12]);
- break;
- case 14:
- (*(microtask_t14)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9], p_argv[10],
- p_argv[11], p_argv[12], p_argv[13]);
- break;
- case 15:
- (*(microtask_t15)pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2],
- p_argv[3], p_argv[4], p_argv[5], p_argv[6],
- p_argv[7], p_argv[8], p_argv[9], p_argv[10],
- p_argv[11], p_argv[12], p_argv[13], p_argv[14]);
- break;
}
+#undef KMP_INVOKE_MICROTASK_CASE
+
return 1;
}
More information about the Openmp-commits
mailing list