Example #1
0
//===----------------------------------------------------------------------===//
// Here, we discover the layout of every column that will be accessed. A
// column's layout includes three pieces of information:
//
// 1. The starting memory address (where the first value of the column is)
// 2. The stride length
// 3. Whether the column is in columnar layout
//===----------------------------------------------------------------------===//
std::vector<TileGroup::ColumnLayout> TileGroup::GetColumnLayouts(
    CodeGen &codegen, llvm::Value *tile_group_ptr,
    llvm::Value *column_layout_infos) const {
  // Call RuntimeFunctions::GetTileGroupLayout()
  uint32_t num_cols = schema_.GetColumnCount();
  codegen.Call(
      RuntimeFunctionsProxy::GetTileGroupLayout,
      {tile_group_ptr, column_layout_infos, codegen.Const32(num_cols)});

  // Collect <start, stride, is_columnar> triplets of all columns
  std::vector<TileGroup::ColumnLayout> layouts;
  auto *layout_type = ColumnLayoutInfoProxy::GetType(codegen);
  for (uint32_t col_id = 0; col_id < num_cols; col_id++) {
    auto *start = codegen->CreateLoad(codegen->CreateConstInBoundsGEP2_32(
        layout_type, column_layout_infos, col_id, 0));
    auto *stride = codegen->CreateLoad(codegen->CreateConstInBoundsGEP2_32(
        layout_type, column_layout_infos, col_id, 1));
    auto *columnar = codegen->CreateLoad(codegen->CreateConstInBoundsGEP2_32(
        layout_type, column_layout_infos, col_id, 2));
    layouts.push_back(ColumnLayout{col_id, start, stride, columnar});
  }
  return layouts;
}
Example #2
0
codegen::Value Sorter::SorterAccess::LoadRowValue(
    CodeGen &codegen, Sorter::SorterAccess::Row &row,
    uint32_t column_index) const {
  if (row.row_pos_ == nullptr) {
    auto *addr = codegen->CreateInBoundsGEP(codegen.CharPtrType(), start_pos_,
                                            row.row_idx_);
    row.row_pos_ = codegen->CreateLoad(addr);
  }

  const auto &storage_format = sorter_.GetStorageFormat();
  UpdateableStorage::NullBitmap null_bitmap(codegen, storage_format,
                                            row.row_pos_);
  return storage_format.GetValue(codegen, row.row_pos_, column_index,
                                 null_bitmap);
}
Example #3
0
// Load a given column for the row with the given TID
codegen::Value TileGroup::LoadColumn(
    CodeGen &codegen, llvm::Value *tid,
    const TileGroup::ColumnLayout &layout) const {
  // We're calculating: col[tid] = col_start + (tid * col_stride)
  llvm::Value *col_address =
      codegen->CreateInBoundsGEP(codegen.ByteType(), layout.col_start_ptr,
                                 codegen->CreateMul(tid, layout.col_stride));

  // The value, length and is_null check
  llvm::Value *val = nullptr, *length = nullptr, *is_null = nullptr;

  // Column metadata
  bool is_nullable = schema_.AllowNull(layout.col_id);
  const auto &column = schema_.GetColumn(layout.col_id);
  const auto &sql_type = type::SqlType::LookupType(column.GetType());

  // Check if it's a string or numeric value
  if (sql_type.IsVariableLength()) {
    auto *varlen_type = VarlenProxy::GetType(codegen);
    auto *varlen_ptr_ptr = codegen->CreateBitCast(
        col_address, varlen_type->getPointerTo()->getPointerTo());
    if (is_nullable) {
      codegen::Varlen::GetPtrAndLength(
          codegen, codegen->CreateLoad(varlen_ptr_ptr), val, length, is_null);
    } else {
      codegen::Varlen::SafeGetPtrAndLength(
          codegen, codegen->CreateLoad(varlen_ptr_ptr), val, length);
    }
    PL_ASSERT(val != nullptr && length != nullptr);
  } else {
    // Get the LLVM type of the column
    llvm::Type *col_type = nullptr, *col_len_type = nullptr;
    sql_type.GetTypeForMaterialization(codegen, col_type, col_len_type);
    PL_ASSERT(col_type != nullptr && col_len_type == nullptr);

    // val = *(col_type*)col_address;
    val = codegen->CreateLoad(
        col_type,
        codegen->CreateBitCast(col_address, col_type->getPointerTo()));

    if (is_nullable) {
      // To check for NULL, we need to perform a comparison between the value we
      // just read from the table with the NULL value for the column's type. We
      // need to be careful that the runtime type of both values is not NULL to
      // bypass the type system's NULL checking logic.
      if (sql_type.TypeId() == peloton::type::TypeId::BOOLEAN) {
        is_null = type::Boolean::Instance().CheckNull(codegen, col_address);
      } else {
        auto val_tmp = codegen::Value{sql_type, val};
        auto null_val =
            codegen::Value{sql_type, sql_type.GetNullValue(codegen).GetValue()};
        auto val_is_null = val_tmp.CompareEq(codegen, null_val);
        PL_ASSERT(!val_is_null.IsNullable());
        is_null = val_is_null.GetValue();
      }
    }
  }

  // Names
  val->setName(column.GetName());
  if (length != nullptr) length->setName(column.GetName() + ".len");
  if (is_null != nullptr) is_null->setName(column.GetName() + ".null");

  // Return the value
  auto type = type::Type{column.GetType(), is_nullable};
  return codegen::Value{type, val, length, is_null};
}
Example #4
0
// Pull out the 'start_pos_' instance member from the provided Sorter instance
llvm::Value *Sorter::GetStartPosition(CodeGen &codegen,
                                      llvm::Value *sorter_ptr) const {
  auto *sorter_type = SorterProxy::GetType(codegen);
  return codegen->CreateLoad(
      codegen->CreateConstInBoundsGEP2_32(sorter_type, sorter_ptr, 0, 0));
}
Example #5
0
llvm::Value *Sorter::GetNumberOfStoredTuples(CodeGen &codegen,
                                             llvm::Value *sorter_ptr) const {
  auto *sorter_type = SorterProxy::GetType(codegen);
  return codegen->CreateLoad(
      codegen->CreateConstInBoundsGEP2_32(sorter_type, sorter_ptr, 0, 3));
}