OmniSciDB  8a228a1076
TargetExprCodegenBuilder Struct Reference

#include <TargetExprBuilder.h>

+ Collaboration diagram for TargetExprCodegenBuilder:

Public Member Functions

 TargetExprCodegenBuilder (const QueryMemoryDescriptor &query_mem_desc, const RelAlgExecutionUnit &ra_exe_unit, const bool is_group_by)
 
void operator() (const Analyzer::Expr *target_expr, const Executor *executor, const CompilationOptions &co)
 
void codegen (GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const GpuSharedMemoryContext &gpu_smem_context, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
 
void codegenSampleExpressions (GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
 
void codegenSingleSlotSampleExpression (GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
 
void codegenMultiSlotSampleExpressions (GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
 
llvm::Value * codegenSlotEmptyKey (llvm::Value *agg_col_ptr, std::vector< llvm::Value *> &target_lvs, Executor *executor, const int64_t init_val) const
 

Public Attributes

size_t target_index_counter {0}
 
size_t slot_index_counter {0}
 
const QueryMemoryDescriptorquery_mem_desc
 
const RelAlgExecutionUnitra_exe_unit
 
std::vector< TargetExprCodegentarget_exprs_to_codegen
 
std::vector< TargetExprCodegensample_exprs_to_codegen
 
bool is_group_by
 

Detailed Description

Definition at line 76 of file TargetExprBuilder.h.

Constructor & Destructor Documentation

◆ TargetExprCodegenBuilder()

TargetExprCodegenBuilder::TargetExprCodegenBuilder ( const QueryMemoryDescriptor query_mem_desc,
const RelAlgExecutionUnit ra_exe_unit,
const bool  is_group_by 
)
inline

Definition at line 77 of file TargetExprBuilder.h.

References TargetExprCodegen::codegen(), and TargetExprCodegen::target_expr.

80  : query_mem_desc(query_mem_desc)
81  , ra_exe_unit(ra_exe_unit)
const RelAlgExecutionUnit & ra_exe_unit
const QueryMemoryDescriptor & query_mem_desc
+ Here is the call graph for this function:

Member Function Documentation

◆ codegen()

void TargetExprCodegenBuilder::codegen ( GroupByAndAggregate group_by_and_agg,
Executor executor,
const QueryMemoryDescriptor query_mem_desc,
const CompilationOptions co,
const GpuSharedMemoryContext gpu_smem_context,
const std::tuple< llvm::Value *, llvm::Value *> &  agg_out_ptr_w_idx,
const std::vector< llvm::Value *> &  agg_out_vec,
llvm::Value *  output_buffer_byte_stream,
llvm::Value *  out_row_idx,
GroupByAndAggregate::DiamondCodegen diamond_codegen 
) const

Definition at line 574 of file TargetExprBuilder.cpp.

References AUTOMATIC_IR_METADATA, and CHECK.

Referenced by GroupByAndAggregate::codegenAggCalls().

584  {
585  CHECK(group_by_and_agg);
586  CHECK(executor);
587  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
588 
589  for (const auto& target_expr_codegen : target_exprs_to_codegen) {
590  target_expr_codegen.codegen(group_by_and_agg,
591  executor,
592  query_mem_desc,
593  co,
594  gpu_smem_context,
595  agg_out_ptr_w_idx,
596  agg_out_vec,
597  output_buffer_byte_stream,
598  out_row_idx,
599  diamond_codegen);
600  }
601  if (!sample_exprs_to_codegen.empty()) {
602  codegenSampleExpressions(group_by_and_agg,
603  executor,
604  query_mem_desc,
605  co,
606  agg_out_ptr_w_idx,
607  agg_out_vec,
608  output_buffer_byte_stream,
609  out_row_idx,
610  diamond_codegen);
611  }
612 }
std::vector< TargetExprCodegen > target_exprs_to_codegen
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define AUTOMATIC_IR_METADATA(CGENSTATE)
void codegenSampleExpressions(GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ codegenMultiSlotSampleExpressions()

void TargetExprCodegenBuilder::codegenMultiSlotSampleExpressions ( GroupByAndAggregate group_by_and_agg,
Executor executor,
const QueryMemoryDescriptor query_mem_desc,
const CompilationOptions co,
const std::tuple< llvm::Value *, llvm::Value *> &  agg_out_ptr_w_idx,
const std::vector< llvm::Value *> &  agg_out_vec,
llvm::Value *  output_buffer_byte_stream,
llvm::Value *  out_row_idx,
GroupByAndAggregate::DiamondCodegen diamond_codegen 
) const

Definition at line 678 of file TargetExprBuilder.cpp.

References AUTOMATIC_IR_METADATA, CHECK, CHECK_GE, CHECK_LT, GroupByAndAggregate::codegenAggArg(), GroupByAndAggregate::codegenAggColumnPtr(), CompilationOptions::device_type, anonymous_namespace{TargetExprBuilder.cpp}::get_initial_agg_val(), GPU, TargetExprCodegen::is_group_by, and QueryMemoryDescriptor::isLogicalSizedColumnsAllowed().

687  {
688  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
689  CHECK(sample_exprs_to_codegen.size() > 1 ||
690  sample_exprs_to_codegen.front().target_info.sql_type.is_varlen());
692  const auto& first_sample_expr = sample_exprs_to_codegen.front();
693  auto target_lvs = group_by_and_agg->codegenAggArg(first_sample_expr.target_expr, co);
694  CHECK_GE(target_lvs.size(), size_t(1));
695 
696  const auto init_val =
697  get_initial_agg_val(first_sample_expr.target_info, query_mem_desc);
698 
699  llvm::Value* agg_col_ptr{nullptr};
700  if (is_group_by) {
701  const auto agg_column_size_bytes =
702  query_mem_desc.isLogicalSizedColumnsAllowed() &&
703  !first_sample_expr.target_info.sql_type.is_varlen()
704  ? first_sample_expr.target_info.sql_type.get_size()
705  : sizeof(int64_t);
706  agg_col_ptr = group_by_and_agg->codegenAggColumnPtr(output_buffer_byte_stream,
707  out_row_idx,
708  agg_out_ptr_w_idx,
709  query_mem_desc,
710  agg_column_size_bytes,
711  first_sample_expr.base_slot_index,
712  first_sample_expr.target_idx);
713  } else {
714  CHECK_LT(static_cast<size_t>(first_sample_expr.base_slot_index), agg_out_vec.size());
715  agg_col_ptr =
716  executor->castToIntPtrTyIn(agg_out_vec[first_sample_expr.base_slot_index], 64);
717  }
718 
719  auto sample_cas_lv = codegenSlotEmptyKey(agg_col_ptr, target_lvs, executor, init_val);
720 
722  sample_cas_lv, executor, false, "sample_valcheck", &diamond_codegen, false);
723 
724  for (const auto& target_expr_codegen : sample_exprs_to_codegen) {
725  target_expr_codegen.codegen(group_by_and_agg,
726  executor,
727  query_mem_desc,
728  co,
729  {},
730  agg_out_ptr_w_idx,
731  agg_out_vec,
732  output_buffer_byte_stream,
733  out_row_idx,
734  diamond_codegen,
735  &sample_cfg);
736  }
737 }
#define CHECK_GE(x, y)
Definition: Logger.h:210
llvm::Value * codegenAggColumnPtr(llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const QueryMemoryDescriptor &query_mem_desc, const size_t chosen_bytes, const size_t agg_out_off, const size_t target_idx)
: returns the pointer to where the aggregation should be stored.
llvm::Value * codegenSlotEmptyKey(llvm::Value *agg_col_ptr, std::vector< llvm::Value *> &target_lvs, Executor *executor, const int64_t init_val) const
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
#define CHECK_LT(x, y)
Definition: Logger.h:207
std::vector< llvm::Value * > codegenAggArg(const Analyzer::Expr *target_expr, const CompilationOptions &co)
#define CHECK(condition)
Definition: Logger.h:197
int64_t get_initial_agg_val(const TargetInfo &target_info, const QueryMemoryDescriptor &query_mem_desc)
+ Here is the call graph for this function:

◆ codegenSampleExpressions()

void TargetExprCodegenBuilder::codegenSampleExpressions ( GroupByAndAggregate group_by_and_agg,
Executor executor,
const QueryMemoryDescriptor query_mem_desc,
const CompilationOptions co,
const std::tuple< llvm::Value *, llvm::Value *> &  agg_out_ptr_w_idx,
const std::vector< llvm::Value *> &  agg_out_vec,
llvm::Value *  output_buffer_byte_stream,
llvm::Value *  out_row_idx,
GroupByAndAggregate::DiamondCodegen diamond_codegen 
) const

Definition at line 614 of file TargetExprBuilder.cpp.

References AUTOMATIC_IR_METADATA, CHECK, CompilationOptions::device_type, and GPU.

623  {
624  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
625  CHECK(!sample_exprs_to_codegen.empty());
627  if (sample_exprs_to_codegen.size() == 1 &&
628  !sample_exprs_to_codegen.front().target_info.sql_type.is_varlen()) {
629  codegenSingleSlotSampleExpression(group_by_and_agg,
630  executor,
631  query_mem_desc,
632  co,
633  agg_out_ptr_w_idx,
634  agg_out_vec,
635  output_buffer_byte_stream,
636  out_row_idx,
637  diamond_codegen);
638  } else {
639  codegenMultiSlotSampleExpressions(group_by_and_agg,
640  executor,
641  query_mem_desc,
642  co,
643  agg_out_ptr_w_idx,
644  agg_out_vec,
645  output_buffer_byte_stream,
646  out_row_idx,
647  diamond_codegen);
648  }
649 }
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
void codegenSingleSlotSampleExpression(GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const
#define CHECK(condition)
Definition: Logger.h:197
void codegenMultiSlotSampleExpressions(GroupByAndAggregate *group_by_and_agg, Executor *executor, const QueryMemoryDescriptor &query_mem_desc, const CompilationOptions &co, const std::tuple< llvm::Value *, llvm::Value *> &agg_out_ptr_w_idx, const std::vector< llvm::Value *> &agg_out_vec, llvm::Value *output_buffer_byte_stream, llvm::Value *out_row_idx, GroupByAndAggregate::DiamondCodegen &diamond_codegen) const

◆ codegenSingleSlotSampleExpression()

void TargetExprCodegenBuilder::codegenSingleSlotSampleExpression ( GroupByAndAggregate group_by_and_agg,
Executor executor,
const QueryMemoryDescriptor query_mem_desc,
const CompilationOptions co,
const std::tuple< llvm::Value *, llvm::Value *> &  agg_out_ptr_w_idx,
const std::vector< llvm::Value *> &  agg_out_vec,
llvm::Value *  output_buffer_byte_stream,
llvm::Value *  out_row_idx,
GroupByAndAggregate::DiamondCodegen diamond_codegen 
) const

Definition at line 651 of file TargetExprBuilder.cpp.

References AUTOMATIC_IR_METADATA, CHECK, CHECK_EQ, CompilationOptions::device_type, and GPU.

660  {
661  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
662  CHECK_EQ(size_t(1), sample_exprs_to_codegen.size());
663  CHECK(!sample_exprs_to_codegen.front().target_info.sql_type.is_varlen());
665  // no need for the atomic if we only have one SAMPLE target
666  sample_exprs_to_codegen.front().codegen(group_by_and_agg,
667  executor,
668  query_mem_desc,
669  co,
670  {},
671  agg_out_ptr_w_idx,
672  agg_out_vec,
673  output_buffer_byte_stream,
674  out_row_idx,
675  diamond_codegen);
676 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
#define CHECK(condition)
Definition: Logger.h:197

◆ codegenSlotEmptyKey()

llvm::Value * TargetExprCodegenBuilder::codegenSlotEmptyKey ( llvm::Value *  agg_col_ptr,
std::vector< llvm::Value *> &  target_lvs,
Executor executor,
const int64_t  init_val 
) const

Definition at line 739 of file TargetExprBuilder.cpp.

References AUTOMATIC_IR_METADATA, CHECK_EQ, get_int_type(), LL_BUILDER, LL_CONTEXT, LL_INT, and UNREACHABLE.

743  {
744  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
745  const auto& first_sample_expr = sample_exprs_to_codegen.front();
746  const auto first_sample_slot_bytes =
747  first_sample_expr.target_info.sql_type.is_varlen()
748  ? sizeof(int64_t)
749  : first_sample_expr.target_info.sql_type.get_size();
750  llvm::Value* target_lv_casted{nullptr};
751  // deciding whether proper casting is required for the first sample's slot:
752  if (first_sample_expr.target_info.sql_type.is_varlen()) {
753  target_lv_casted =
754  LL_BUILDER.CreatePtrToInt(target_lvs.front(), llvm::Type::getInt64Ty(LL_CONTEXT));
755  } else if (first_sample_expr.target_info.sql_type.is_fp()) {
756  // Initialization value for SAMPLE on a float column should be 0
757  CHECK_EQ(init_val, 0);
759  target_lv_casted = executor->cgen_state_->ir_builder_.CreateFPToSI(
760  target_lvs.front(),
761  first_sample_slot_bytes == sizeof(float) ? llvm::Type::getInt32Ty(LL_CONTEXT)
762  : llvm::Type::getInt64Ty(LL_CONTEXT));
763  } else {
764  target_lv_casted = executor->cgen_state_->ir_builder_.CreateFPToSI(
765  target_lvs.front(), llvm::Type::getInt64Ty(LL_CONTEXT));
766  }
767  } else if (first_sample_slot_bytes != sizeof(int64_t) &&
769  target_lv_casted =
770  executor->cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
771  target_lvs.front(),
772  llvm::Type::getInt64Ty(LL_CONTEXT));
773  } else {
774  target_lv_casted = target_lvs.front();
775  }
776 
777  std::string slot_empty_cas_func_name("slotEmptyKeyCAS");
778  llvm::Value* init_val_lv{LL_INT(init_val)};
780  !first_sample_expr.target_info.sql_type.is_varlen()) {
781  // add proper suffix to the function name:
782  switch (first_sample_slot_bytes) {
783  case 1:
784  slot_empty_cas_func_name += "_int8";
785  break;
786  case 2:
787  slot_empty_cas_func_name += "_int16";
788  break;
789  case 4:
790  slot_empty_cas_func_name += "_int32";
791  break;
792  case 8:
793  break;
794  default:
795  UNREACHABLE() << "Invalid slot size for slotEmptyKeyCAS function.";
796  break;
797  }
798  if (first_sample_slot_bytes != sizeof(int64_t)) {
799  init_val_lv = llvm::ConstantInt::get(
800  get_int_type(first_sample_slot_bytes * 8, LL_CONTEXT), init_val);
801  }
802  }
803 
804  auto sample_cas_lv = executor->cgen_state_->emitExternalCall(
805  slot_empty_cas_func_name,
806  llvm::Type::getInt1Ty(executor->cgen_state_->context_),
807  {agg_col_ptr, target_lv_casted, init_val_lv});
808  return sample_cas_lv;
809 }
#define LL_BUILDER
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define UNREACHABLE()
Definition: Logger.h:241
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const QueryMemoryDescriptor & query_mem_desc
#define LL_INT(v)
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define LL_CONTEXT
#define AUTOMATIC_IR_METADATA(CGENSTATE)
+ Here is the call graph for this function:

◆ operator()()

void TargetExprCodegenBuilder::operator() ( const Analyzer::Expr target_expr,
const Executor executor,
const CompilationOptions co 
)

Definition at line 498 of file TargetExprBuilder.cpp.

References agg_arg(), anonymous_namespace{TargetExprBuilder.cpp}::agg_fn_base_names(), TargetInfo::agg_kind, AUTOMATIC_IR_METADATA, CHECK, constrained_not_null(), CompilationOptions::device_type, g_bigint_count, get_target_info(), GPU, TargetInfo::is_agg, anonymous_namespace{TargetExprBuilder.cpp}::is_columnar_projection(), TargetExprCodegen::is_group_by, kSAMPLE, kSINGLE_VALUE, kUNNEST, NonGroupedAggregate, TargetInfo::skip_null_val, and TargetExprCodegen::target_info.

500  {
501  AUTOMATIC_IR_METADATA(executor->cgen_state_.get());
503  CHECK(!dynamic_cast<const Analyzer::AggExpr*>(target_expr));
506  return;
507  }
508  if (dynamic_cast<const Analyzer::UOper*>(target_expr) &&
509  static_cast<const Analyzer::UOper*>(target_expr)->get_optype() == kUNNEST) {
510  throw std::runtime_error("UNNEST not supported in the projection list yet.");
511  }
512  if ((executor->plan_state_->isLazyFetchColumn(target_expr) || !is_group_by) &&
514  sizeof(int64_t)) &&
516  // TODO(miyu): enable different byte width in the layout w/o padding
518  }
519 
520  auto target_info = get_target_info(target_expr, g_bigint_count);
521  auto arg_expr = agg_arg(target_expr);
522  if (arg_expr) {
523  if (target_info.agg_kind == kSINGLE_VALUE || target_info.agg_kind == kSAMPLE) {
524  target_info.skip_null_val = false;
527  !arg_expr->get_type_info().is_varlen()) {
528  // TODO: COUNT is currently not null-aware for varlen types. Need to add proper code
529  // generation for handling varlen nulls.
530  target_info.skip_null_val = true;
531  } else if (constrained_not_null(arg_expr, ra_exe_unit.quals)) {
532  target_info.skip_null_val = false;
533  }
534  }
535 
538  (co.device_type == ExecutorDeviceType::GPU) && target_info.is_agg &&
539  (target_info.agg_kind == kSAMPLE)) {
540  sample_exprs_to_codegen.emplace_back(target_expr,
541  target_info,
544  is_group_by);
545  } else {
546  target_exprs_to_codegen.emplace_back(target_expr,
547  target_info,
550  is_group_by);
551  }
552 
553  const auto agg_fn_names = agg_fn_base_names(target_info);
554  slot_index_counter += agg_fn_names.size();
555 }
const RelAlgExecutionUnit & ra_exe_unit
const Analyzer::Expr * agg_arg(const Analyzer::Expr *expr)
bool constrained_not_null(const Analyzer::Expr *expr, const std::list< std::shared_ptr< Analyzer::Expr >> &quals)
std::vector< std::string > agg_fn_base_names(const TargetInfo &target_info)
TargetInfo get_target_info(const PointerType target_expr, const bool bigint_count)
Definition: TargetInfo.h:78
std::vector< TargetExprCodegen > target_exprs_to_codegen
const QueryMemoryDescriptor & query_mem_desc
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
bool g_bigint_count
std::vector< TargetExprCodegen > sample_exprs_to_codegen
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
std::list< std::shared_ptr< Analyzer::Expr > > quals
#define CHECK(condition)
Definition: Logger.h:197
QueryDescriptionType getQueryDescriptionType() const
bool is_columnar_projection(const QueryMemoryDescriptor &query_mem_desc)
+ Here is the call graph for this function:

Member Data Documentation

◆ is_group_by

bool TargetExprCodegenBuilder::is_group_by

Definition at line 146 of file TargetExprBuilder.h.

◆ query_mem_desc

const QueryMemoryDescriptor& TargetExprCodegenBuilder::query_mem_desc

Definition at line 140 of file TargetExprBuilder.h.

◆ ra_exe_unit

const RelAlgExecutionUnit& TargetExprCodegenBuilder::ra_exe_unit

Definition at line 141 of file TargetExprBuilder.h.

◆ sample_exprs_to_codegen

std::vector<TargetExprCodegen> TargetExprCodegenBuilder::sample_exprs_to_codegen

Definition at line 144 of file TargetExprBuilder.h.

◆ slot_index_counter

size_t TargetExprCodegenBuilder::slot_index_counter {0}

Definition at line 138 of file TargetExprBuilder.h.

◆ target_exprs_to_codegen

std::vector<TargetExprCodegen> TargetExprCodegenBuilder::target_exprs_to_codegen

Definition at line 143 of file TargetExprBuilder.h.

◆ target_index_counter

size_t TargetExprCodegenBuilder::target_index_counter {0}

Definition at line 137 of file TargetExprBuilder.h.


The documentation for this struct was generated from the following files: