Skip to content

Commit

Permalink
[openmp] Support building for armv7 Windows with mingw tools
Browse files Browse the repository at this point in the history
This does things in the same way as
D137168 / a356782 and
D101173 / 4fb0aaf did for aarch64.

This adds a C implementation of __kmp_invoke_microtask in the same
way as the fallback C implementation in z_Linux_util.cpp.

Both the existing C fallback used on arm linux, and this one added here,
fail test/misc_bugs/many-microtask-args.c similarly (which could be
considered as an XFAIL).

Differential Revision: https://reviews.llvm.org/D138689
  • Loading branch information
mstorsjo committed Nov 25, 2022
1 parent d6ab42d commit 97958c9
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 9 deletions.
2 changes: 1 addition & 1 deletion openmp/runtime/src/kmp.h
Expand Up @@ -3616,7 +3616,7 @@ extern void __kmp_check_stack_overlap(kmp_info_t *thr);
extern void __kmp_expand_host_name(char *buffer, size_t size);
extern void __kmp_expand_file_name(char *result, size_t rlen, char *pattern);

#if KMP_ARCH_X86 || KMP_ARCH_X86_64 || (KMP_OS_WINDOWS && KMP_ARCH_AARCH64)
#if KMP_ARCH_X86 || KMP_ARCH_X86_64 || (KMP_OS_WINDOWS && (KMP_ARCH_AARCH64 || KMP_ARCH_ARM))
extern void
__kmp_initialize_system_tick(void); /* Initialize timer tick value */
#endif
Expand Down
4 changes: 2 additions & 2 deletions openmp/runtime/src/kmp_atomic.cpp
Expand Up @@ -832,7 +832,7 @@ static inline kmp_cmplx128_a16_t operator/(kmp_cmplx128_a16_t &lhs,
// end of the first part of the workaround for C78287
#endif // USE_CMPXCHG_FIX

#if KMP_OS_WINDOWS && KMP_ARCH_AARCH64
#if KMP_OS_WINDOWS && (KMP_ARCH_AARCH64 || KMP_ARCH_ARM)
// Undo explicit type casts to get MSVC ARM64 to build. Uses
// OP_CMPXCHG_WORKAROUND definition for OP_CMPXCHG
#undef OP_CMPXCHG
Expand Down Expand Up @@ -863,7 +863,7 @@ static inline kmp_cmplx128_a16_t operator/(kmp_cmplx128_a16_t &lhs,
(*lhs) = (*lhs)OP rhs; \
__kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);

#endif // KMP_OS_WINDOWS && KMP_ARCH_AARCH64
#endif // KMP_OS_WINDOWS && (KMP_ARCH_AARCH64 || KMP_ARCH_ARM)

#if KMP_ARCH_X86 || KMP_ARCH_X86_64

Expand Down
4 changes: 2 additions & 2 deletions openmp/runtime/src/kmp_os.h
Expand Up @@ -184,7 +184,7 @@ typedef unsigned long long kmp_uint64;
#error "Can't determine size_t printf format specifier."
#endif

#if KMP_ARCH_X86
#if KMP_ARCH_X86 || KMP_ARCH_ARM
#define KMP_SIZE_T_MAX (0xFFFFFFFF)
#else
#define KMP_SIZE_T_MAX (0xFFFFFFFFFFFFFFFF)
Expand Down Expand Up @@ -456,7 +456,7 @@ enum kmp_mem_fence_type {

// Synchronization primitives

#if KMP_ASM_INTRINS && KMP_OS_WINDOWS && !(KMP_ARCH_AARCH64 && defined(__GNUC__))
#if KMP_ASM_INTRINS && KMP_OS_WINDOWS && !((KMP_ARCH_AARCH64 || KMP_ARCH_ARM) && defined(__GNUC__))

#if KMP_MSVC_COMPAT && !KMP_COMPILER_CLANG
#pragma intrinsic(InterlockedExchangeAdd)
Expand Down
3 changes: 3 additions & 0 deletions openmp/runtime/src/kmp_platform.h
Expand Up @@ -101,6 +101,9 @@
#elif defined(__aarch64__) || defined(_M_ARM64)
#undef KMP_ARCH_AARCH64
#define KMP_ARCH_AARCH64 1
#elif defined(__arm__) || defined(_M_ARM)
#undef KMP_ARCH_ARMV7
#define KMP_ARCH_ARMV7 1
#else
#undef KMP_ARCH_X86
#define KMP_ARCH_X86 1
Expand Down
95 changes: 93 additions & 2 deletions openmp/runtime/src/z_Windows_NT-586_util.cpp
Expand Up @@ -12,7 +12,7 @@

#include "kmp.h"

#if (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64)
#if (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 || KMP_ARCH_ARM)
/* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
use compare_and_store for these routines */

Expand Down Expand Up @@ -189,4 +189,95 @@ int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
}
#endif

#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 */
#if KMP_ARCH_ARM
// This matches the generic fallback implementation of __kmp_invoke_microtask
// from z_Linux_util.cpp, which is used on Linux on ARM.
int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
void *p_argv[]
#if OMPT_SUPPORT
,
void **exit_frame_ptr
#endif
) {
#if OMPT_SUPPORT
*exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);
#endif

switch (argc) {
default:
fprintf(stderr, "Too many args to microtask: %d!\n", argc);
fflush(stderr);
exit(-1);
case 0:
(*pkfn)(&gtid, &tid);
break;
case 1:
(*pkfn)(&gtid, &tid, p_argv[0]);
break;
case 2:
(*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);
break;
case 3:
(*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);
break;
case 4:
(*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);
break;
case 5:
(*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);
break;
case 6:
(*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],
p_argv[5]);
break;
case 7:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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:
(*pkfn)(&gtid, &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;
}

#if OMPT_SUPPORT
*exit_frame_ptr = 0;
#endif

return 1;
}
#endif

#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 || KMP_ARCH_ARM */
4 changes: 2 additions & 2 deletions openmp/runtime/src/z_Windows_NT_util.cpp
Expand Up @@ -78,7 +78,7 @@ struct SYSTEM_THREAD {
}; // SYSTEM_THREAD

KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, KernelTime) == 0);
#if KMP_ARCH_X86
#if KMP_ARCH_X86 || KMP_ARCH_ARM
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, StartAddress) == 28);
KMP_BUILD_ASSERT(offsetof(SYSTEM_THREAD, State) == 52);
#else
Expand Down Expand Up @@ -108,7 +108,7 @@ typedef SYSTEM_PROCESS_INFORMATION *PSYSTEM_PROCESS_INFORMATION;
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, NextEntryOffset) == 0);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, CreateTime) == 32);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, ImageName) == 56);
#if KMP_ARCH_X86
#if KMP_ARCH_X86 || KMP_ARCH_ARM
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, ProcessId) == 68);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, HandleCount) == 76);
KMP_BUILD_ASSERT(offsetof(SYSTEM_PROCESS_INFORMATION, VMCounters) == 88);
Expand Down

0 comments on commit 97958c9

Please sign in to comment.