/*
 * ompd-specific.cpp -- OpenMP debug support
 */

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ompd-specific.h"

#if OMPD_SUPPORT

/**
 * Declaration of symbols to hold struct size and member offset information
 */

#define ompd_declare_access(t, m) uint64_t ompd_access__##t##__##m;
OMPD_FOREACH_ACCESS(ompd_declare_access)
#undef ompd_declare_access

#define ompd_declare_sizeof_member(t, m) uint64_t ompd_sizeof__##t##__##m;
OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member)
#undef ompd_declare_sizeof_member

#define ompd_declare_bitfield(t, m) uint64_t ompd_bitfield__##t##__##m;
OMPD_FOREACH_BITFIELD(ompd_declare_bitfield)
#undef ompd_declare_bitfield

#define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t;
OMPD_FOREACH_SIZEOF(ompd_declare_sizeof)
#undef ompd_declare_sizeof

volatile const char **ompd_dll_locations = NULL;
uint64_t ompd_state = 0;

char *ompd_env_block = NULL;
ompd_size_t ompd_env_block_size = 0;

void ompd_init() {

  static int ompd_initialized = 0;

  if (ompd_initialized)
    return;

    /**
     * Calculate member offsets for structs and unions
     */

#define ompd_init_access(t, m)                                                 \
  ompd_access__##t##__##m = (uint64_t) & (((t *)0)->m);
  OMPD_FOREACH_ACCESS(ompd_init_access)
#undef ompd_init_access

  /**
   * Create bit mask for bitfield access
   */

#define ompd_init_bitfield(t, m)                                               \
  ompd_bitfield__##t##__##m = 0;                                               \
  ((t *)(&ompd_bitfield__##t##__##m))->m = 1;
  OMPD_FOREACH_BITFIELD(ompd_init_bitfield)
#undef ompd_init_bitfield

  /**
   * Calculate type size information
   */

#define ompd_init_sizeof_member(t, m)                                          \
  ompd_sizeof__##t##__##m = sizeof(((t *)0)->m);
  OMPD_FOREACH_ACCESS(ompd_init_sizeof_member)
#undef ompd_init_sizeof_member

#define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t);
  OMPD_FOREACH_SIZEOF(ompd_init_sizeof)
#undef ompd_init_sizeof

  char *libname = NULL;

#if KMP_OS_UNIX
  // Find the location of libomp.so thru dladdr and replace the libomp with
  // libompd to get the full path of libompd
  Dl_info dl_info;
  int ret = dladdr((void *)ompd_init, &dl_info);
  if (!ret) {
    fprintf(stderr, "%s\n", dlerror());
  } else if (strrchr(dl_info.dli_fname, '/')) {
    int lib_path_length = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname;
    libname =
        (char *)malloc(lib_path_length + 12 /*for '/libompd.so' and '\0'*/);
    strncpy(libname, dl_info.dli_fname, lib_path_length);
    memcpy(libname + lib_path_length, "/libompd.so\0", 12);
  }
#endif

  const char *ompd_env_var = getenv("OMP_DEBUG");
  if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) {
    fprintf(stderr, "OMP_OMPD active\n");
    ompt_enabled.enabled = 1;
    ompd_state |= OMPD_ENABLE_BP;
  }

  ompd_initialized = 1;
  ompd_dll_locations = (volatile const char **)malloc(3 * sizeof(const char *));
  ompd_dll_locations[0] = "libompd.so";
  ompd_dll_locations[1] = libname;
  ompd_dll_locations[2] = NULL;
  ompd_dll_locations_valid();
}

void __attribute__((noinline)) ompd_dll_locations_valid(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}

void ompd_bp_parallel_begin(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}
void ompd_bp_parallel_end(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}
void ompd_bp_task_begin(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}
void ompd_bp_task_end(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}
void ompd_bp_thread_begin(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}
void ompd_bp_thread_end(void) {
  /* naive way of implementing hard to opt-out empty function
     we might want to use a separate object file? */
  asm("");
}

#endif /* OMPD_SUPPORT */
