This supports lowering parse-tree to MLIR for threadprivate directive
following the OpenMP 5.1 [2.21.2] standard. Take the following as an
example:
program m integer, save :: i !$omp threadprivate(i) call sub(i) !$omp parallel call sub(i) !$omp end parallel end
func.func @_QQmain() { %0 = fir.address_of(@_QFEi) : !fir.ref<i32> %1 = omp.threadprivate %0 : !fir.ref<i32> -> !fir.ref<i32> fir.call @_QPsub(%1) : (!fir.ref<i32>) -> () omp.parallel { %2 = omp.threadprivate %0 : !fir.ref<i32> -> !fir.ref<i32> fir.call @_QPsub(%2) : (!fir.ref<i32>) -> () omp.terminator } return }
A threadprivate operation (omp.threadprivate) is created for all
references to a threadprivate variable. The runtime will appropriately
return a threadprivate var (%1 as above) or its copy (%2 as above)
depending on whether it is outside or inside a parallel region. For
threadprivate access outside the parallel region, the threadprivate
operation is created in instantiateVar. Inside the parallel region, it
is created in createBodyOfOp.
One new utility function collectSymbolSet is created for collecting
all the variables with a property within a evaluation, which may be one
Fortran, or OpenMP, or OpenACC construct.
Nit: Would spelling out be better? getSymbolExtendedValue.