[OpenMP][FIX] Eliminate race on the IsSPMD global

The `IsSPMD` global can only be read by threads other than the main
thread *after* initialization is complete. To allow usage of
`mapping::getBlockSize` before initialization is done, we can pass the
`IsSPMD` state explicitly. This is similar to other APIs that take
`IsSPMD` explicitly to avoid such a race, e.g.,
`mapping::isInitialThreadInLevel0(IsSPMD)`

Fixes https://github.com/llvm/llvm-project/issues/53857
This commit is contained in:
Johannes Doerfert 2022-02-14 17:19:33 -06:00
parent 6ed1ef0643
commit 57b4c5267b
4 changed files with 12 additions and 4 deletions

View File

@ -79,7 +79,12 @@ uint32_t getNumberOfWarpsInBlock();
uint32_t getBlockId();
/// Return the block size, thus number of threads in the block.
///
/// Note: The version taking \p IsSPMD mode explicitly can be used during the
/// initialization of the target region, that is before `mapping::isSPMDMode()`
/// can be called by any thread other than the main one.
uint32_t getBlockSize();
uint32_t getBlockSize(bool IsSPMD);
/// Return the number of blocks in the kernel.
uint32_t getNumberOfBlocks();

View File

@ -100,7 +100,7 @@ int32_t __kmpc_target_init(IdentTy *Ident, int8_t Mode,
// doing any work. mapping::getBlockSize() does not include any of the main
// thread's warp, so none of its threads can ever be active worker threads.
if (UseGenericStateMachine &&
mapping::getThreadIdInBlock() < mapping::getBlockSize())
mapping::getThreadIdInBlock() < mapping::getBlockSize(IsSPMD))
genericStateMachine(Ident);
return mapping::getThreadIdInBlock();

View File

@ -212,11 +212,14 @@ uint32_t mapping::getThreadIdInBlock() {
uint32_t mapping::getWarpSize() { return impl::getWarpSize(); }
uint32_t mapping::getBlockSize() {
uint32_t mapping::getBlockSize(bool IsSPMD) {
uint32_t BlockSize = mapping::getNumberOfProcessorElements() -
(!mapping::isSPMDMode() * impl::getWarpSize());
(!IsSPMD * impl::getWarpSize());
return BlockSize;
}
uint32_t mapping::getBlockSize() {
return mapping::getBlockSize(mapping::isSPMDMode());
}
uint32_t mapping::getKernelSize() { return impl::getKernelSize(); }

View File

@ -236,7 +236,7 @@ struct TeamStateTy {
TeamStateTy SHARED(TeamState);
void TeamStateTy::init(bool IsSPMD) {
ICVState.NThreadsVar = mapping::getBlockSize();
ICVState.NThreadsVar = mapping::getBlockSize(IsSPMD);
ICVState.LevelVar = 0;
ICVState.ActiveLevelVar = 0;
ICVState.MaxActiveLevelsVar = 1;