[OpenMP] Introduce ompx.h and 3D wrappers (threadId, threadDim, ...)

The new ompx.h header will give us a place to put extensions. The first
are 3D getters for the common cuda values:
  `{threadId,threadDim,blockId,blockDim}.{x,y,z}`

Differential Revision: https://reviews.llvm.org/D156501
diff --git a/openmp/libomptarget/DeviceRTL/src/Mapping.cpp b/openmp/libomptarget/DeviceRTL/src/Mapping.cpp
index 8f26af0..2f50530 100644
--- a/openmp/libomptarget/DeviceRTL/src/Mapping.cpp
+++ b/openmp/libomptarget/DeviceRTL/src/Mapping.cpp
@@ -372,4 +372,12 @@
 }
 }
 
+#define _TGT_KERNEL_LANGUAGE(NAME, MAPPER_NAME)                                \
+  extern "C" int ompx_##NAME(int Dim) { return mapping::MAPPER_NAME(Dim); }
+
+_TGT_KERNEL_LANGUAGE(thread_id, getThreadIdInBlock)
+_TGT_KERNEL_LANGUAGE(thread_dim, getNumberOfThreadsInBlock)
+_TGT_KERNEL_LANGUAGE(block_id, getBlockIdInKernel)
+_TGT_KERNEL_LANGUAGE(block_dim, getNumberOfBlocksInKernel)
+
 #pragma omp end declare target
diff --git a/openmp/libomptarget/DeviceRTL/src/exports b/openmp/libomptarget/DeviceRTL/src/exports
index 85fd459..2d13195 100644
--- a/openmp/libomptarget/DeviceRTL/src/exports
+++ b/openmp/libomptarget/DeviceRTL/src/exports
@@ -1,4 +1,5 @@
 omp_*
+ompx_*
 *llvm_*
 __kmpc_*
 
diff --git a/openmp/libomptarget/test/api/ompx_3d.c b/openmp/libomptarget/test/api/ompx_3d.c
new file mode 100644
index 0000000..a67ad01
--- /dev/null
+++ b/openmp/libomptarget/test/api/ompx_3d.c
@@ -0,0 +1,41 @@
+// RUN: %libomptarget-compile-run-and-check-generic
+
+#include <omp.h>
+#include <ompx.h>
+#include <stdio.h>
+
+void foo(int device) {
+  int tid = 0, bid = 0, bdim = 0;
+#pragma omp target teams distribute parallel for map(from                      \
+                                                     : tid, bid, bdim)         \
+    device(device) thread_limit(2) num_teams(5)
+  for (int i = 0; i < 1000; ++i) {
+    if (i == 42) {
+      tid = ompx_thread_dim_x();
+      bid = ompx_block_id_x();
+      bdim = ompx_block_dim_x();
+    }
+  }
+  // CHECK: tid: 2, bid: 1, bdim: 5
+  // CHECK: tid: 2, bid: 0, bdim: 1
+  printf("tid: %i, bid: %i, bdim: %i\n", tid, bid, bdim);
+}
+
+int isGPU() { return 0; }
+#pragma omp declare variant(isGPU) match(device = {arch(gpu)})
+int isGPUvariant() { return 1; }
+
+int defaultIsGPU() {
+  int r = 0;
+#pragma omp target map(from : r)
+  r = isGPU();
+  return r;
+}
+
+int main() {
+  if (defaultIsGPU())
+    foo(omp_get_default_device());
+  else
+    printf("tid: 2, bid: 1, bdim: 5\n");
+  foo(omp_get_initial_device());
+}
diff --git a/openmp/libomptarget/test/api/ompx_3d.cpp b/openmp/libomptarget/test/api/ompx_3d.cpp
new file mode 100644
index 0000000..8b2f622
--- /dev/null
+++ b/openmp/libomptarget/test/api/ompx_3d.cpp
@@ -0,0 +1,41 @@
+// RUN: %libomptarget-compilexx-run-and-check-generic
+
+#include <omp.h>
+#include <ompx.h>
+#include <stdio.h>
+
+void foo(int device) {
+  int tid = 0, bid = 0, bdim = 0;
+#pragma omp target teams distribute parallel for map(from                      \
+                                                     : tid, bid, bdim)         \
+    device(device) thread_limit(2) num_teams(5)
+  for (int i = 0; i < 1000; ++i) {
+    if (i == 42) {
+      tid = ompx::thread_dim_x();
+      bid = ompx::block_id_x();
+      bdim = ompx::block_dim_x();
+    }
+  }
+  // CHECK: tid: 2, bid: 1, bdim: 5
+  // CHECK: tid: 2, bid: 0, bdim: 1
+  printf("tid: %i, bid: %i, bdim: %i\n", tid, bid, bdim);
+}
+
+int isGPU() { return 0; }
+#pragma omp declare variant(isGPU) match(device = {arch(gpu)})
+int isGPUvariant() { return 1; }
+
+int defaultIsGPU() {
+  int r = 0;
+#pragma omp target map(from : r)
+  r = isGPU();
+  return r;
+}
+
+int main() {
+  if (defaultIsGPU())
+    foo(omp_get_default_device());
+  else
+    printf("tid: 2, bid: 1, bdim: 5\n");
+  foo(omp_get_initial_device());
+}