// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// This file contains all of the functions that must be precompiled
// to an LLVM IR format (note: not bitcode to preserve function
// names for retrieval later).
//
// Note namespace scope is just for convenient symbol resolution.
// To preserve function names, extern "C" linkage is used, so these
// functions (1) must not be duplicated in any of the above headers
// and (2) do not belong to namespace kudu.
//
// NOTE: This file may rely on external definitions from any part of Kudu
// because the code generator will resolve external symbols at load time.
// However, the code generator relies on the fact that our Kudu binaries
// are built with unstripped visible symbols, so this style of code generation
// cannot be used in builds with settings that conflict with the required
// visibility (e.g., the client library).
// NOTE: This file is NOT compiled with ASAN annotations, even if Kudu
// is being built with ASAN.

#include <cstdint>
#include <cstring>

#include "kudu/common/rowblock.h"
#include "kudu/gutil/port.h"
#include "kudu/util/bitmap.h"
#include "kudu/util/memory/arena.h"

// Even though this file is only needed for IR purposes, we need to check for
// IR_BUILD because we use a fake static library target to workaround a cmake
// dependencies bug. See 'ir_fake_target' in CMakeLists.txt.
#ifdef IR_BUILD

// This file uses the 'always_inline' attribute on a bunch of functions to force
// the LLVM optimizer at runtime to inline them where it otherwise might not.
// Because the functions themselves aren't marked 'inline', gcc is unhappy with this.
// But, we can't mark them 'inline' or else they'll get optimized away and not even
// included in the .ll file. So, instead, we just mark them as always_inline in
// the IR_BUILD context.
#define IR_ALWAYS_INLINE __attribute__((always_inline))

// Workaround for an MCJIT deficiency where we see a link error when trying
// to load the JITted library. See the following LLVM bug and suggested workaround.
// https://llvm.org/bugs/show_bug.cgi?id=18062
extern "C" void *__dso_handle __attribute__((__visibility__("hidden"))) = NULL;

#else
#define IR_ALWAYS_INLINE
#endif

namespace kudu {

class Slice;

// Returns whether copy was successful (fails iff slice relocation fails,
// which can only occur if is_string is true).
// If arena is NULL, then no relocation occurs.
IR_ALWAYS_INLINE static bool BasicCopyCell(
    uint64_t size, uint8_t* src, uint8_t* dst, bool is_string, Arena* arena) {
  // Relocate indirect data
  if (is_string) {
    if (PREDICT_TRUE(arena != nullptr)) {
      return PREDICT_TRUE(arena->RelocateSlice(*reinterpret_cast<Slice*>(src),
                                               reinterpret_cast<Slice*>(dst)));
    }
    // If arena is NULL, don't relocate, but do copy the pointers to the raw
    // data (callers that pass arena as NULL should be sure that the indirect
    // data will stay alive after the projections)
  }

  // Copy direct data
  memcpy(dst, src, size);
  return true;
}

extern "C" {

// Preface all used functions with _Precompiled to avoid the possibility
// of name clashes. Notice all the nontrivial types must be passed as
// void* parameters, otherwise LLVM will complain that the type does not match
// (and it is not possible to consistently extract the llvm::Type* from a
// parsed module which has the same signature as the one that would be passed
// as a parameter for the below functions if the did not use void* types).
//
// Note that:
//   (1) There is no void* type in LLVM, instead i8* is used.
//   (2) The functions below are all prefixed with _Precompiled to avoid
//       any potential naming conflicts.


// declare i1 @_PrecompiledCopyCellToRowBlock(
//   i64 size, i8* src, RowBlockRow* dst, i64 col, i1 is_string, Arena* arena)
//
//   Performs the same function as CopyCell, copying size bytes of the
//   cell pointed to by src to the cell of column col in the row pointed
//   to by dst, copying indirect data to the parameter arena if is_string
//   is true. Will hard crash if insufficient memory is available for
//   relocation. Copies size bytes directly from the src cell.
//   If arena is NULL then only the direct copy will occur.
//   Returns whether successful. If not, out-of-memory during relocation of
//   slices has occured, which can only happen if is_string is true.
IR_ALWAYS_INLINE bool _PrecompiledCopyCellToRowBlock(
    uint64_t size, uint8_t* src, RowBlockRow* dst,
    uint64_t col, bool is_string, Arena* arena) {

  // We manually compute the destination cell pointer here, rather than
  // using dst->cell_ptr(), since we statically know the size of the column
  // type. Using the normal access path would generate an 'imul' instruction,
  // since it would be loading the column type info from the RowBlock object
  // instead of our static parameter here.
  size_t idx = dst->row_index();
  const RowBlock* block = dst->row_block();
  uint8_t* dst_cell = block->column_data_base_ptr(col) + idx * size;
  return BasicCopyCell(size, src, dst_cell, is_string, arena);
}

// declare i1 @_PrecompiledCopyCellToRowBlockNullable(
//   i64 size, i8* src, RowBlockRow* dst, i64 col, i1 is_string, Arena* arena,
//   i8* src_bitmap, i64 bitmap_idx)
//
//   Performs the same function as _PrecompiledCopyCellToRowBlock but for nullable
//   columns. Checks the parameter bitmap at the specified index and updates
//   The row's bitmap accordingly. Then goes on to copy the cell over if it
//   is not null.
//   If arena is NULL then only the direct copy will occur (if the source
//   bitmap indicates the cell itself is non-null).
//   Returns whether successful. If not, out-of-memory during relocation of
//   slices has occured, which can only happen if is_string is true.
IR_ALWAYS_INLINE bool _PrecompiledCopyCellToRowBlockNullable(
    uint64_t size, uint8_t* src, RowBlockRow* dst, uint64_t col, bool is_string,
    Arena* arena, uint8_t* src_bitmap, uint64_t bitmap_idx) {
  // Using this method implies the nullablity of the column.
  // Write whether the column is nullable to the RowBlock's ColumnBlock's bitmap
  bool is_null = BitmapTest(src_bitmap, bitmap_idx);
  dst->cell(col).set_null(is_null);
  // No more copies necessary if null
  if (is_null) return true;
  return _PrecompiledCopyCellToRowBlock(size, src, dst, col, is_string, arena);
}

// declare void @_PrecompiledSetRowBlockCellSetNull
//   RowBlockRow* %dst, i64 <column index>, i1 %is_null)
//
//   Sets the cell at column 'col' for destination RowBlockRow 'dst'
//   to be marked as 'is_null' (requires the column is nullable).
IR_ALWAYS_INLINE void _PrecompiledCopyCellToRowBlockSetNull(
    RowBlockRow* dst, uint64_t col, bool is_null) {
  dst->cell(col).set_null(is_null);
}

} // extern "C"
} // namespace kudu
