OmniSciDB  dfae7c3b14
ResultSetReductionJIT Class Reference

#include <ResultSetReductionJIT.h>

+ Inheritance diagram for ResultSetReductionJIT:
+ Collaboration diagram for ResultSetReductionJIT:

Public Member Functions

 ResultSetReductionJIT (const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &target_init_vals)
 
virtual ~ResultSetReductionJIT ()=default
 
virtual ReductionCode codegen () const
 

Static Public Member Functions

static void clearCache ()
 

Protected Member Functions

void isEmpty (const ReductionCode &reduction_code) const
 
void reduceOneEntryNoCollisions (const ReductionCode &reduction_code) const
 
void reduceOneEntryNoCollisionsIdx (const ReductionCode &reduction_code) const
 
void reduceLoop (const ReductionCode &reduction_code) const
 

Private Member Functions

void reduceOneEntryTargetsNoCollisions (Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
 
void reduceOneEntryBaseline (const ReductionCode &reduction_code) const
 
void reduceOneEntryBaselineIdx (const ReductionCode &reduction_code) const
 
void reduceOneSlot (Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
 
void reduceOneAggregateSlot (Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const int64_t init_val, const int8_t chosen_bytes, Function *ir_reduce_one_entry) const
 
void reduceOneCountDistinctSlot (Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
 
ReductionCode finalizeReductionCode (ReductionCode reduction_code, const llvm::Function *ir_is_empty, const llvm::Function *ir_reduce_one_entry, const llvm::Function *ir_reduce_one_entry_idx, const CodeCacheKey &key) const
 
std::string cacheKey () const
 

Private Attributes

const QueryMemoryDescriptor query_mem_desc_
 
const std::vector< TargetInfotargets_
 
const std::vector< int64_t > target_init_vals_
 

Static Private Attributes

static CodeCache s_code_cache
 

Detailed Description

Definition at line 55 of file ResultSetReductionJIT.h.

Constructor & Destructor Documentation

◆ ResultSetReductionJIT()

ResultSetReductionJIT::ResultSetReductionJIT ( const QueryMemoryDescriptor query_mem_desc,
const std::vector< TargetInfo > &  targets,
const std::vector< int64_t > &  target_init_vals 
)

Definition at line 492 of file ResultSetReductionJIT.cpp.

495  : query_mem_desc_(query_mem_desc)
496  , targets_(targets)
497  , target_init_vals_(target_init_vals) {}
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
const std::vector< TargetInfo > targets_

◆ ~ResultSetReductionJIT()

virtual ResultSetReductionJIT::~ResultSetReductionJIT ( )
virtualdefault

Member Function Documentation

◆ cacheKey()

std::string ResultSetReductionJIT::cacheKey ( ) const
private

Definition at line 1248 of file ResultSetReductionJIT.cpp.

References join(), query_mem_desc_, QueryMemoryDescriptor::reductionKey(), anonymous_namespace{ResultSetReductionJIT.cpp}::target_info_key(), target_init_vals_, targets_, and to_string().

Referenced by codegen().

1248  {
1249  std::vector<std::string> target_init_vals_strings;
1250  std::transform(target_init_vals_.begin(),
1251  target_init_vals_.end(),
1252  std::back_inserter(target_init_vals_strings),
1253  [](const int64_t v) { return std::to_string(v); });
1254  const auto target_init_vals_key =
1255  boost::algorithm::join(target_init_vals_strings, ", ");
1256  std::vector<std::string> targets_strings;
1257  std::transform(
1258  targets_.begin(),
1259  targets_.end(),
1260  std::back_inserter(targets_strings),
1261  [](const TargetInfo& target_info) { return target_info_key(target_info); });
1262  const auto targets_key = boost::algorithm::join(targets_strings, ", ");
1263  return query_mem_desc_.reductionKey() + "\n" + target_init_vals_key + "\n" +
1264  targets_key;
1265 }
std::string join(T const &container, std::string const &delim)
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
std::string target_info_key(const TargetInfo &target_info)
std::string reductionKey() const
const std::vector< TargetInfo > targets_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ clearCache()

void ResultSetReductionJIT::clearCache ( )
static

Definition at line 611 of file ResultSetReductionJIT.cpp.

References LruCache< key_t, value_t, hash_t >::clear(), StubGenerator::clearCache(), g_rt_module, and s_code_cache.

611  {
612  // Clear stub cache to avoid crash caused by non-deterministic static destructor order
613  // of LLVM context and the cache.
616  g_rt_module = nullptr;
617 }
void clear()
Definition: LruCache.hpp:60
std::unique_ptr< llvm::Module > g_rt_module
+ Here is the call graph for this function:

◆ codegen()

ReductionCode ResultSetReductionJIT::codegen ( ) const
virtual

Reimplemented in GpuReductionHelperJIT.

Definition at line 530 of file ResultSetReductionJIT.cpp.

References AUTOMATIC_IR_METADATA, AUTOMATIC_IR_METADATA_DONE, QueryMemoryDescriptor::blocksShareMemory(), cacheKey(), CHECK, anonymous_namespace{ResultSetReductionJIT.cpp}::create_llvm_function(), QueryMemoryDescriptor::didOutputColumnar(), logger::FATAL, finalizeReductionCode(), LruCache< key_t, value_t, hash_t >::get(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getExecutor(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, GroupByPerfectHash, anonymous_namespace{ResultSetReductionJIT.cpp}::INTERP_THRESHOLD, anonymous_namespace{ResultSetReductionJIT.cpp}::is_aggregate_query(), isEmpty(), LOG, NonGroupedAggregate, query_mem_desc_, reduceLoop(), reduceOneEntryBaseline(), reduceOneEntryBaselineIdx(), reduceOneEntryNoCollisions(), reduceOneEntryNoCollisionsIdx(), runtime_module_shallow_copy(), s_code_cache, ReductionCode::s_reduction_mutex, anonymous_namespace{ResultSetReductionJIT.cpp}::setup_functions_ir(), and translate_function().

Referenced by anonymous_namespace{Execute.cpp}::get_reduction_code(), and ResultSetManager::reduce().

530  {
531  const auto hash_type = query_mem_desc_.getQueryDescriptionType();
533  return {};
534  }
535  auto reduction_code = setup_functions_ir(hash_type);
536  isEmpty(reduction_code);
540  reduceOneEntryNoCollisions(reduction_code);
541  reduceOneEntryNoCollisionsIdx(reduction_code);
542  break;
543  }
545  reduceOneEntryBaseline(reduction_code);
546  reduceOneEntryBaselineIdx(reduction_code);
547  break;
548  }
549  default: {
550  LOG(FATAL) << "Unexpected query description type";
551  }
552  }
553  reduceLoop(reduction_code);
554  // For small result sets, avoid native code generation and use the interpreter instead.
557  return reduction_code;
558  }
559  std::lock_guard<std::mutex> reduction_guard(ReductionCode::s_reduction_mutex);
560  CodeCacheKey key{cacheKey()};
561  const auto compilation_context = s_code_cache.get(key);
562  if (compilation_context) {
563  auto cpu_context =
564  std::dynamic_pointer_cast<CpuCompilationContext>(compilation_context->first);
565  CHECK(cpu_context);
566  return {reinterpret_cast<ReductionCode::FuncPtr>(cpu_context->func()),
567  nullptr,
568  nullptr,
569  nullptr,
570  std::move(reduction_code.ir_is_empty),
571  std::move(reduction_code.ir_reduce_one_entry),
572  std::move(reduction_code.ir_reduce_one_entry_idx),
573  std::move(reduction_code.ir_reduce_loop)};
574  }
575  reduction_code.cgen_state.reset(new CgenState({}, false));
576  auto cgen_state = reduction_code.cgen_state.get();
577  std::unique_ptr<llvm::Module> module = runtime_module_shallow_copy(cgen_state);
578  cgen_state->module_ = module.get();
579  AUTOMATIC_IR_METADATA(cgen_state);
580  auto ir_is_empty = create_llvm_function(reduction_code.ir_is_empty.get(), cgen_state);
581  auto ir_reduce_one_entry =
582  create_llvm_function(reduction_code.ir_reduce_one_entry.get(), cgen_state);
583  auto ir_reduce_one_entry_idx =
584  create_llvm_function(reduction_code.ir_reduce_one_entry_idx.get(), cgen_state);
585  auto ir_reduce_loop =
586  create_llvm_function(reduction_code.ir_reduce_loop.get(), cgen_state);
587  std::unordered_map<const Function*, llvm::Function*> f;
588  f.emplace(reduction_code.ir_is_empty.get(), ir_is_empty);
589  f.emplace(reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry);
590  f.emplace(reduction_code.ir_reduce_one_entry_idx.get(), ir_reduce_one_entry_idx);
591  f.emplace(reduction_code.ir_reduce_loop.get(), ir_reduce_loop);
592  translate_function(reduction_code.ir_is_empty.get(), ir_is_empty, reduction_code, f);
594  reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry, reduction_code, f);
595  translate_function(reduction_code.ir_reduce_one_entry_idx.get(),
596  ir_reduce_one_entry_idx,
597  reduction_code,
598  f);
600  reduction_code.ir_reduce_loop.get(), ir_reduce_loop, reduction_code, f);
601  reduction_code.llvm_reduce_loop = ir_reduce_loop;
602  reduction_code.module = std::move(module);
604  return finalizeReductionCode(std::move(reduction_code),
605  ir_is_empty,
606  ir_reduce_one_entry,
607  ir_reduce_one_entry_idx,
608  key);
609 }
void reduceOneEntryBaseline(const ReductionCode &reduction_code) const
bool is_aggregate_query(const QueryDescriptionType hash_type)
void isEmpty(const ReductionCode &reduction_code) const
void reduceOneEntryNoCollisionsIdx(const ReductionCode &reduction_code) const
std::unique_ptr< llvm::Module > runtime_module_shallow_copy(CgenState *cgen_state)
#define LOG(tag)
Definition: Logger.h:188
std::vector< std::string > CodeCacheKey
Definition: CodeCache.h:25
int32_t(*)(int8_t *this_buff, const int8_t *that_buff, const int32_t start_entry_index, const int32_t end_entry_index, const int32_t that_entry_count, const void *this_qmd, const void *that_qmd, const void *serialized_varlen_buffer) FuncPtr
const QueryMemoryDescriptor query_mem_desc_
const Executor * getExecutor() const
ReductionCode finalizeReductionCode(ReductionCode reduction_code, const llvm::Function *ir_is_empty, const llvm::Function *ir_reduce_one_entry, const llvm::Function *ir_reduce_one_entry_idx, const CodeCacheKey &key) const
void reduceOneEntryNoCollisions(const ReductionCode &reduction_code) const
void translate_function(const Function *function, llvm::Function *llvm_function, const ReductionCode &reduction_code, const std::unordered_map< const Function *, llvm::Function *> &f)
static std::mutex s_reduction_mutex
ReductionCode setup_functions_ir(const QueryDescriptionType hash_type)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define AUTOMATIC_IR_METADATA_DONE()
void reduceOneEntryBaselineIdx(const ReductionCode &reduction_code) const
#define CHECK(condition)
Definition: Logger.h:197
value_t * get(const key_t &key)
Definition: LruCache.hpp:39
llvm::Function * create_llvm_function(const Function *function, CgenState *cgen_state)
void reduceLoop(const ReductionCode &reduction_code) const
QueryDescriptionType getQueryDescriptionType() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ finalizeReductionCode()

ReductionCode ResultSetReductionJIT::finalizeReductionCode ( ReductionCode  reduction_code,
const llvm::Function *  ir_is_empty,
const llvm::Function *  ir_reduce_one_entry,
const llvm::Function *  ir_reduce_one_entry_idx,
const CodeCacheKey key 
) const
private

Definition at line 1197 of file ResultSetReductionJIT.cpp.

References Executor::addCodeToCache(), ReductionCode::cgen_state, ReductionCode::compilation_context, CPU, ReductionCode::func_ptr, CodeGenerator::generateNativeCPUCode(), logger::IR, ReductionCode::llvm_reduce_loop, LOG, ReductionCode::module, ReductionJIT, s_code_cache, and serialize_llvm_object().

Referenced by codegen().

1202  {
1203  CompilationOptions co{
1205 
1206 #ifdef NDEBUG
1207  LOG(IR) << "Reduction Loop:\n"
1208  << serialize_llvm_object(reduction_code.llvm_reduce_loop);
1209  LOG(IR) << "Reduction Is Empty Func:\n" << serialize_llvm_object(ir_is_empty);
1210  LOG(IR) << "Reduction One Entry Func:\n" << serialize_llvm_object(ir_reduce_one_entry);
1211  LOG(IR) << "Reduction One Entry Idx Func:\n"
1212  << serialize_llvm_object(ir_reduce_one_entry_idx);
1213 #else
1214  LOG(IR) << serialize_llvm_object(reduction_code.cgen_state->module_);
1215 #endif
1216 
1217  reduction_code.module.release();
1219  reduction_code.llvm_reduce_loop, {reduction_code.llvm_reduce_loop}, co);
1220  reduction_code.func_ptr = reinterpret_cast<ReductionCode::FuncPtr>(
1221  ee->getPointerToFunction(reduction_code.llvm_reduce_loop));
1222 
1223  auto cpu_compilation_context = std::make_shared<CpuCompilationContext>(std::move(ee));
1224  cpu_compilation_context->setFunctionPointer(reduction_code.llvm_reduce_loop);
1225  reduction_code.compilation_context = cpu_compilation_context;
1227  reduction_code.compilation_context,
1228  reduction_code.llvm_reduce_loop->getParent(),
1229  s_code_cache);
1230  return reduction_code;
1231 }
std::unique_ptr< CgenState > cgen_state
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function *> &live_funcs, const CompilationOptions &co)
std::shared_ptr< CompilationContext > compilation_context
#define LOG(tag)
Definition: Logger.h:188
llvm::Function * llvm_reduce_loop
int32_t(*)(int8_t *this_buff, const int8_t *that_buff, const int32_t start_entry_index, const int32_t end_entry_index, const int32_t that_entry_count, const void *this_qmd, const void *that_qmd, const void *serialized_varlen_buffer) FuncPtr
static void addCodeToCache(const CodeCacheKey &, std::shared_ptr< CompilationContext >, llvm::Module *, CodeCache &)
std::string serialize_llvm_object(const T *llvm_obj)
std::unique_ptr< llvm::Module > module
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isEmpty()

void ResultSetReductionJIT::isEmpty ( const ReductionCode reduction_code) const
protected

Definition at line 619 of file ResultSetReductionJIT.cpp.

References CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i32(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_read_int_from_buff(), EMPTY_KEY_32, EMPTY_KEY_64, ICmp::EQ, logger::FATAL, get_byteoff_of_slot(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::hasKeylessHash(), Int32, Int64, ReductionCode::ir_is_empty, anonymous_namespace{ResultSetReductionJIT.cpp}::is_aggregate_query(), LOG, query_mem_desc_, and target_init_vals_.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

619  {
620  auto ir_is_empty = reduction_code.ir_is_empty.get();
623  Value* key{nullptr};
624  Value* empty_key_val{nullptr};
625  const auto keys_ptr = ir_is_empty->arg(0);
630  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
631  target_init_vals_.size());
632  const int64_t target_slot_off =
634  const auto slot_ptr = ir_is_empty->add<GetElementPtr>(
635  keys_ptr,
636  ir_is_empty->addConstant<ConstantInt>(target_slot_off, Type::Int32),
637  "is_empty_slot_ptr");
638  const auto compact_sz =
640  key = emit_read_int_from_buff(slot_ptr, compact_sz, ir_is_empty);
641  empty_key_val = ir_is_empty->addConstant<ConstantInt>(
643  } else {
645  case 4: {
648  key = emit_load_i32(keys_ptr, ir_is_empty);
649  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_32, Type::Int32);
650  break;
651  }
652  case 8: {
653  key = emit_load_i64(keys_ptr, ir_is_empty);
654  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_64, Type::Int64);
655  break;
656  }
657  default:
658  LOG(FATAL) << "Invalid key width";
659  }
660  }
661  const auto ret =
662  ir_is_empty->add<ICmp>(ICmp::Predicate::EQ, key, empty_key_val, "is_key_empty");
663  ir_is_empty->add<Ret>(ret);
664 }
bool is_aggregate_query(const QueryDescriptionType hash_type)
#define EMPTY_KEY_64
Value * emit_read_int_from_buff(Value *ptr, const int8_t compact_sz, Function *function)
#define LOG(tag)
Definition: Logger.h:188
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
#define CHECK_GE(x, y)
Definition: Logger.h:210
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Value * emit_load_i32(Value *ptr, Function *function)
int32_t getTargetIdxForKey() const
#define CHECK_LT(x, y)
Definition: Logger.h:207
Value * emit_load_i64(Value *ptr, Function *function)
#define CHECK(condition)
Definition: Logger.h:197
#define EMPTY_KEY_32
QueryDescriptionType getQueryDescriptionType() const
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceLoop()

void ResultSetReductionJIT::reduceLoop ( const ReductionCode reduction_code) const
protected

Definition at line 1009 of file ResultSetReductionJIT.cpp.

References anonymous_namespace{ResultSetReductionJIT.cpp}::generate_loop_body(), Int32, ReductionCode::ir_reduce_loop, and ReductionCode::ir_reduce_one_entry_idx.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

1009  {
1010  auto ir_reduce_loop = reduction_code.ir_reduce_loop.get();
1011  const auto this_buff_arg = ir_reduce_loop->arg(0);
1012  const auto that_buff_arg = ir_reduce_loop->arg(1);
1013  const auto start_index_arg = ir_reduce_loop->arg(2);
1014  const auto end_index_arg = ir_reduce_loop->arg(3);
1015  const auto that_entry_count_arg = ir_reduce_loop->arg(4);
1016  const auto this_qmd_handle_arg = ir_reduce_loop->arg(5);
1017  const auto that_qmd_handle_arg = ir_reduce_loop->arg(6);
1018  const auto serialized_varlen_buffer_arg = ir_reduce_loop->arg(7);
1019  For* for_loop =
1020  static_cast<For*>(ir_reduce_loop->add<For>(start_index_arg, end_index_arg, ""));
1021  generate_loop_body(for_loop,
1022  ir_reduce_loop,
1023  reduction_code.ir_reduce_one_entry_idx.get(),
1024  this_buff_arg,
1025  that_buff_arg,
1026  start_index_arg,
1027  that_entry_count_arg,
1028  this_qmd_handle_arg,
1029  that_qmd_handle_arg,
1030  serialized_varlen_buffer_arg);
1031  ir_reduce_loop->add<Ret>(ir_reduce_loop->addConstant<ConstantInt>(0, Type::Int32));
1032 }
std::unique_ptr< Function > ir_reduce_loop
void generate_loop_body(For *for_loop, Function *ir_reduce_loop, Function *ir_reduce_one_entry_idx, Value *this_buff, Value *that_buff, Value *start_index, Value *that_entry_count, Value *this_qmd_handle, Value *that_qmd_handle, Value *serialized_varlen_buffer)
std::unique_ptr< Function > ir_reduce_one_entry_idx
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneAggregateSlot()

void ResultSetReductionJIT::reduceOneAggregateSlot ( Value this_ptr1,
Value this_ptr2,
Value that_ptr1,
Value that_ptr2,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const int64_t  init_val,
const int8_t  chosen_bytes,
Function ir_reduce_one_entry 
) const
private

Definition at line 1109 of file ResultSetReductionJIT.cpp.

References TargetInfo::agg_kind, CHECK_EQ, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_aggregate_one_count(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_aggregate_one_nullable_value(), logger::FATAL, QueryMemoryDescriptor::getPaddedSlotWidthBytes(), is_distinct_target(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kMAX, kMIN, kSUM, LOG, query_mem_desc_, and reduceOneCountDistinctSlot().

Referenced by reduceOneSlot().

1118  {
1119  switch (target_info.agg_kind) {
1120  case kCOUNT:
1121  case kAPPROX_COUNT_DISTINCT: {
1122  if (is_distinct_target(target_info)) {
1123  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1125  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1126  break;
1127  }
1128  CHECK_EQ(int64_t(0), init_val);
1129  emit_aggregate_one_count(this_ptr1, that_ptr1, chosen_bytes, ir_reduce_one_entry);
1130  break;
1131  }
1132  case kAVG: {
1133  // Ignore float argument compaction for count component for fear of its overflow
1134  emit_aggregate_one_count(this_ptr2,
1135  that_ptr2,
1136  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx),
1137  ir_reduce_one_entry);
1138  }
1139  // fall thru
1140  case kSUM: {
1142  this_ptr1,
1143  that_ptr1,
1144  init_val,
1145  chosen_bytes,
1146  target_info,
1147  ir_reduce_one_entry);
1148  break;
1149  }
1150  case kMIN: {
1152  this_ptr1,
1153  that_ptr1,
1154  init_val,
1155  chosen_bytes,
1156  target_info,
1157  ir_reduce_one_entry);
1158  break;
1159  }
1160  case kMAX: {
1162  this_ptr1,
1163  that_ptr1,
1164  init_val,
1165  chosen_bytes,
1166  target_info,
1167  ir_reduce_one_entry);
1168  break;
1169  }
1170  default:
1171  LOG(FATAL) << "Invalid aggregate type";
1172  }
1173 }
void emit_aggregate_one_nullable_value(const std::string &agg_kind, Value *val_ptr, Value *other_ptr, const int64_t init_val, const size_t chosen_bytes, const TargetInfo &agg_info, Function *ir_reduce_one_entry)
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define LOG(tag)
Definition: Logger.h:188
const QueryMemoryDescriptor query_mem_desc_
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: sqldefs.h:73
Definition: sqldefs.h:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:129
SQLAgg agg_kind
Definition: TargetInfo.h:41
void reduceOneCountDistinctSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
Definition: sqldefs.h:76
void emit_aggregate_one_count(Value *val_ptr, Value *other_ptr, const size_t chosen_bytes, Function *ir_reduce_one_entry)
Definition: sqldefs.h:74
Definition: sqldefs.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneCountDistinctSlot()

void ResultSetReductionJIT::reduceOneCountDistinctSlot ( Value this_ptr1,
Value that_ptr1,
const size_t  target_logical_idx,
Function ir_reduce_one_entry 
) const
private

Definition at line 1175 of file ResultSetReductionJIT.cpp.

References CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Int64, query_mem_desc_, and Void.

Referenced by reduceOneAggregateSlot().

1179  {
1181  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1182  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1183  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1184  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1185  ir_reduce_one_entry->add<ExternalCall>(
1186  "count_distinct_set_union_jit_rt",
1187  Type::Void,
1188  std::vector<const Value*>{
1189  new_set_handle,
1190  old_set_handle,
1191  that_qmd_arg,
1192  this_qmd_arg,
1193  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1194  "");
1195 }
size_t getCountDistinctDescriptorsSize() const
const QueryMemoryDescriptor query_mem_desc_
#define CHECK_LT(x, y)
Definition: Logger.h:207
Value * emit_load_i64(Value *ptr, Function *function)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryBaseline()

void ResultSetReductionJIT::reduceOneEntryBaseline ( const ReductionCode reduction_code) const
private

Definition at line 781 of file ResultSetReductionJIT.cpp.

References advance_slot(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, ReductionCode::ir_reduce_one_entry, kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), targets_, and to_string().

Referenced by codegen().

782  {
783  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
784  const auto this_targets_ptr_arg = ir_reduce_one_entry->arg(0);
785  const auto that_targets_ptr_arg = ir_reduce_one_entry->arg(1);
786  Value* this_ptr1 = this_targets_ptr_arg;
787  Value* that_ptr1 = that_targets_ptr_arg;
788  size_t j = 0;
789  size_t init_agg_val_idx = 0;
790  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
791  ++target_logical_idx) {
792  const auto& target_info = targets_[target_logical_idx];
793  Value* this_ptr2{nullptr};
794  Value* that_ptr2{nullptr};
795  if (target_info.is_agg &&
796  (target_info.agg_kind == kAVG ||
797  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
798  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
799  const auto second_slot_rel_off =
800  ir_reduce_one_entry->addConstant<ConstantInt>(sizeof(int64_t), Type::Int32);
801  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
802  this_ptr1, second_slot_rel_off, "this_" + desc);
803  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
804  that_ptr1, second_slot_rel_off, "that_" + desc);
805  }
806  reduceOneSlot(this_ptr1,
807  this_ptr2,
808  that_ptr1,
809  that_ptr2,
810  target_info,
811  target_logical_idx,
812  j,
813  init_agg_val_idx,
814  j,
815  ir_reduce_one_entry);
816  if (target_logical_idx + 1 == targets_.size()) {
817  break;
818  }
820  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
821  } else {
822  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
823  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
824  }
825  }
826  j = advance_slot(j, target_info, false);
827  const auto next_desc =
828  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
829  auto next_slot_rel_off = ir_reduce_one_entry->addConstant<ConstantInt>(
830  init_agg_val_idx * sizeof(int64_t), Type::Int32);
831  this_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
832  this_targets_ptr_arg, next_slot_rel_off, next_desc);
833  that_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
834  that_targets_ptr_arg, next_slot_rel_off, next_desc);
835  }
836  ir_reduce_one_entry->add<Ret>(
837  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
838 }
void reduceOneSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
size_t targetGroupbyIndicesSize() const
int64_t getTargetGroupbyIndex(const size_t target_idx) const
Definition: sqldefs.h:72
const std::vector< TargetInfo > targets_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryBaselineIdx()

void ResultSetReductionJIT::reduceOneEntryBaselineIdx ( const ReductionCode reduction_code) const
private

Definition at line 874 of file ResultSetReductionJIT.cpp.

References Cast::BitCast, CHECK, QueryMemoryDescriptor::didOutputColumnar(), get_row_bytes(), get_slot_off_quad(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), Int1, Int32, Int64, Int64Ptr, Int8, Int8Ptr, ReductionCode::ir_is_empty, ReductionCode::ir_reduce_one_entry, ReductionCode::ir_reduce_one_entry_idx, key_qw_count, BinaryOperator::Mul, query_mem_desc_, Cast::SExt, Cast::Trunc, and Void.

Referenced by codegen().

875  {
876  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
881  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
882  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
883  const auto that_entry_idx = ir_reduce_one_entry_idx->arg(2);
884  const auto that_entry_count = ir_reduce_one_entry_idx->arg(3);
885  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
886  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
887  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
888  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
890  const auto that_entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
891  Cast::CastOp::SExt, that_entry_idx, Type::Int64, "that_entry_idx_64");
892  const auto that_row_off_in_bytes =
893  ir_reduce_one_entry_idx->add<BinaryOperator>(BinaryOperator::BinaryOp::Mul,
894  that_entry_idx_64,
895  row_bytes,
896  "that_row_off_in_bytes");
897  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
898  that_buff, that_row_off_in_bytes, "that_row_ptr");
899  const auto that_is_empty =
900  ir_reduce_one_entry_idx->add<Call>(reduction_code.ir_is_empty.get(),
901  std::vector<const Value*>{that_row_ptr},
902  "that_is_empty");
903  ir_reduce_one_entry_idx->add<ReturnEarly>(
904  that_is_empty,
905  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
906  "");
907  const auto key_count = query_mem_desc_.getGroupbyColCount();
908  const auto one_element =
909  ir_reduce_one_entry_idx->addConstant<ConstantInt>(1, Type::Int32);
910  const auto this_targets_ptr_i64_ptr = ir_reduce_one_entry_idx->add<Alloca>(
911  Type::Int64Ptr, one_element, "this_targets_ptr_out");
912  const auto this_is_empty_ptr =
913  ir_reduce_one_entry_idx->add<Alloca>(Type::Int8, one_element, "this_is_empty_out");
914  ir_reduce_one_entry_idx->add<ExternalCall>(
915  "get_group_value_reduction_rt",
916  Type::Void,
917  std::vector<const Value*>{
918  this_buff,
919  that_row_ptr,
920  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_count, Type::Int32),
921  this_qmd_handle,
922  that_buff,
923  that_entry_idx,
924  that_entry_count,
925  row_bytes,
926  this_targets_ptr_i64_ptr,
927  this_is_empty_ptr},
928  "");
929  const auto this_targets_ptr_i64 = ir_reduce_one_entry_idx->add<Load>(
930  this_targets_ptr_i64_ptr, "this_targets_ptr_i64");
931  auto this_is_empty =
932  ir_reduce_one_entry_idx->add<Load>(this_is_empty_ptr, "this_is_empty");
933  this_is_empty = ir_reduce_one_entry_idx->add<Cast>(
934  Cast::CastOp::Trunc, this_is_empty, Type::Int1, "this_is_empty_bool");
935  ir_reduce_one_entry_idx->add<ReturnEarly>(
936  this_is_empty,
937  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
938  "");
940  const auto this_targets_ptr = ir_reduce_one_entry_idx->add<Cast>(
941  Cast::CastOp::BitCast, this_targets_ptr_i64, Type::Int8Ptr, "this_targets_ptr");
942  const auto key_byte_count = key_qw_count * sizeof(int64_t);
943  const auto key_byte_count_lv =
944  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_byte_count, Type::Int32);
945  const auto that_targets_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
946  that_row_ptr, key_byte_count_lv, "that_targets_ptr");
947  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
948  reduction_code.ir_reduce_one_entry.get(),
949  std::vector<const Value*>{this_targets_ptr,
950  that_targets_ptr,
951  this_qmd_handle,
952  that_qmd_handle,
953  serialized_varlen_buffer_arg},
954  "");
955  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
956 }
size_t get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
std::unique_ptr< Function > ir_reduce_one_entry
const int64_t const uint32_t const uint32_t key_qw_count
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
std::unique_ptr< Function > ir_reduce_one_entry_idx
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:197
QueryDescriptionType getQueryDescriptionType() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryNoCollisions()

void ResultSetReductionJIT::reduceOneEntryNoCollisions ( const ReductionCode reduction_code) const
protected

Definition at line 666 of file ResultSetReductionJIT.cpp.

References align_to_int64(), get_key_bytes_rowwise(), Int32, ReductionCode::ir_is_empty, ReductionCode::ir_reduce_one_entry, query_mem_desc_, and reduceOneEntryTargetsNoCollisions().

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

667  {
668  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
669  const auto this_row_ptr = ir_reduce_one_entry->arg(0);
670  const auto that_row_ptr = ir_reduce_one_entry->arg(1);
671  const auto that_is_empty =
672  ir_reduce_one_entry->add<Call>(reduction_code.ir_is_empty.get(),
673  std::vector<const Value*>{that_row_ptr},
674  "that_is_empty");
675  ir_reduce_one_entry->add<ReturnEarly>(
676  that_is_empty, ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32), "");
677 
678  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
679  if (key_bytes) { // copy the key from right hand side
680  ir_reduce_one_entry->add<MemCpy>(
681  this_row_ptr,
682  that_row_ptr,
683  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes, Type::Int32));
684  }
685 
686  const auto key_bytes_with_padding = align_to_int64(key_bytes);
687  const auto key_bytes_lv =
688  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes_with_padding, Type::Int32);
689  const auto this_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
690  this_row_ptr, key_bytes_lv, "this_targets_start");
691  const auto that_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
692  that_row_ptr, key_bytes_lv, "that_targets_start");
693 
695  ir_reduce_one_entry, this_targets_start_ptr, that_targets_start_ptr);
696 }
void reduceOneEntryTargetsNoCollisions(Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryNoCollisionsIdx()

void ResultSetReductionJIT::reduceOneEntryNoCollisionsIdx ( const ReductionCode reduction_code) const
protected

Definition at line 840 of file ResultSetReductionJIT.cpp.

References CHECK, get_row_bytes(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByPerfectHash, Int64, ReductionCode::ir_reduce_one_entry, ReductionCode::ir_reduce_one_entry_idx, BinaryOperator::Mul, NonGroupedAggregate, query_mem_desc_, and Cast::SExt.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

841  {
842  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
847  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
848  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
849  const auto entry_idx = ir_reduce_one_entry_idx->arg(2);
850  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
851  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
852  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
853  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
855  const auto entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
856  Cast::CastOp::SExt, entry_idx, Type::Int64, "entry_idx_64");
857  const auto row_off_in_bytes = ir_reduce_one_entry_idx->add<BinaryOperator>(
858  BinaryOperator::BinaryOp::Mul, entry_idx_64, row_bytes, "row_off_in_bytes");
859  const auto this_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
860  this_buff, row_off_in_bytes, "this_row_ptr");
861  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
862  that_buff, row_off_in_bytes, "that_row_ptr");
863  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
864  reduction_code.ir_reduce_one_entry.get(),
865  std::vector<const Value*>{this_row_ptr,
866  that_row_ptr,
867  this_qmd_handle,
868  that_qmd_handle,
869  serialized_varlen_buffer_arg},
870  "");
871  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
872 }
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_reduce_one_entry_idx
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:197
QueryDescriptionType getQueryDescriptionType() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryTargetsNoCollisions()

void ResultSetReductionJIT::reduceOneEntryTargetsNoCollisions ( Function ir_reduce_one_entry,
Value this_targets_start_ptr,
Value that_targets_start_ptr 
) const
private

Definition at line 698 of file ResultSetReductionJIT.cpp.

References QueryMemoryDescriptor::getColSlotContext(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), targets_, to_string(), and UNLIKELY.

Referenced by reduceOneEntryNoCollisions().

701  {
702  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
703  Value* this_targets_ptr = this_targets_start_ptr;
704  Value* that_targets_ptr = that_targets_start_ptr;
705  size_t init_agg_val_idx = 0;
706  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
707  ++target_logical_idx) {
708  const auto& target_info = targets_[target_logical_idx];
709  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_logical_idx);
710  Value* this_ptr2{nullptr};
711  Value* that_ptr2{nullptr};
712 
713  bool two_slot_target{false};
714  if (target_info.is_agg &&
715  (target_info.agg_kind == kAVG ||
716  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
717  // Note that this assumes if one of the slot pairs in a given target is an array,
718  // all slot pairs are arrays. Currently this is true for all geo targets, but we
719  // should better codify and store this information in the future
720  two_slot_target = true;
721  }
722 
723  for (size_t target_slot_idx = slots_for_col.front();
724  target_slot_idx < slots_for_col.back() + 1;
725  target_slot_idx += 2) {
726  const auto slot_off_val = query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
727  const auto slot_off =
728  ir_reduce_one_entry->addConstant<ConstantInt>(slot_off_val, Type::Int32);
729  if (UNLIKELY(two_slot_target)) {
730  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
731  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
732  this_targets_ptr, slot_off, "this_" + desc);
733  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
734  that_targets_ptr, slot_off, "that_" + desc);
735  }
736  reduceOneSlot(this_targets_ptr,
737  this_ptr2,
738  that_targets_ptr,
739  that_ptr2,
740  target_info,
741  target_logical_idx,
742  target_slot_idx,
743  init_agg_val_idx,
744  slots_for_col.front(),
745  ir_reduce_one_entry);
746  auto increment_agg_val_idx_maybe =
747  [&init_agg_val_idx, &target_logical_idx, this](const int slot_count) {
749  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
750  init_agg_val_idx += slot_count;
751  }
752  };
753  if (target_logical_idx + 1 == targets_.size() &&
754  target_slot_idx + 1 >= slots_for_col.back()) {
755  break;
756  }
757  const auto next_desc =
758  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
759  if (UNLIKELY(two_slot_target)) {
760  increment_agg_val_idx_maybe(2);
761  const auto two_slot_off = ir_reduce_one_entry->addConstant<ConstantInt>(
762  slot_off_val + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1),
763  Type::Int32);
764  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
765  this_targets_ptr, two_slot_off, "this_" + next_desc);
766  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
767  that_targets_ptr, two_slot_off, "that_" + next_desc);
768  } else {
769  increment_agg_val_idx_maybe(1);
770  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
771  this_targets_ptr, slot_off, "this_" + next_desc);
772  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
773  that_targets_ptr, slot_off, "that_" + next_desc);
774  }
775  }
776  }
777  ir_reduce_one_entry->add<Ret>(
778  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
779 }
void reduceOneSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
size_t targetGroupbyIndicesSize() const
#define UNLIKELY(x)
Definition: likely.h:25
int64_t getTargetGroupbyIndex(const size_t target_idx) const
const ColSlotContext & getColSlotContext() const
Definition: sqldefs.h:72
const std::vector< TargetInfo > targets_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneSlot()

void ResultSetReductionJIT::reduceOneSlot ( Value this_ptr1,
Value this_ptr2,
Value that_ptr1,
Value that_ptr2,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const size_t  first_slot_idx_for_target,
Function ir_reduce_one_entry 
) const
private

Definition at line 1034 of file ResultSetReductionJIT.cpp.

References TargetInfo::agg_kind, CHECK, CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_checked_write_projection(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_write_projection(), SQLTypeInfo::get_elem_type(), get_width_for_slot(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, Int64, TargetInfo::is_agg, SQLTypeInfo::is_geometry(), SQLTypeInfo::is_string(), SQLTypeInfo::is_varlen(), kSAMPLE, kSINGLE_VALUE, ICmp::NE, query_mem_desc_, reduceOneAggregateSlot(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, QueryMemoryDescriptor::targetGroupbyIndicesSize(), and Void.

Referenced by reduceOneEntryBaseline(), and reduceOneEntryTargetsNoCollisions().

1043  {
1045  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1046  return;
1047  }
1048  }
1049  const bool float_argument_input = takes_float_argument(target_info);
1050  const auto chosen_bytes =
1051  get_width_for_slot(target_slot_idx, float_argument_input, query_mem_desc_);
1052  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1053  auto init_val = target_init_vals_[init_agg_val_idx];
1054  if (target_info.is_agg &&
1055  (target_info.agg_kind != kSINGLE_VALUE && target_info.agg_kind != kSAMPLE)) {
1056  reduceOneAggregateSlot(this_ptr1,
1057  this_ptr2,
1058  that_ptr1,
1059  that_ptr2,
1060  target_info,
1061  target_logical_idx,
1062  target_slot_idx,
1063  init_val,
1064  chosen_bytes,
1065  ir_reduce_one_entry);
1066  } else if (target_info.agg_kind == kSINGLE_VALUE) {
1067  const auto checked_rc = emit_checked_write_projection(
1068  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1069 
1070  auto checked_rc_bool = ir_reduce_one_entry->add<ICmp>(
1072  checked_rc,
1073  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32),
1074  "");
1075 
1076  ir_reduce_one_entry->add<ReturnEarly>(checked_rc_bool, checked_rc, "");
1077 
1078  } else {
1080  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1081  if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) {
1082  CHECK(this_ptr2 && that_ptr2);
1083  size_t length_to_elems{0};
1084  if (target_info.sql_type.is_geometry()) {
1085  // TODO: Assumes hard-coded sizes for geometry targets
1086  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1087  } else {
1088  const auto& elem_ti = target_info.sql_type.get_elem_type();
1089  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1090  }
1091  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry->arg(4);
1092  ir_reduce_one_entry->add<ExternalCall>(
1093  "serialized_varlen_buffer_sample",
1094  Type::Void,
1095  std::vector<const Value*>{
1096  serialized_varlen_buffer_arg,
1097  this_ptr1,
1098  this_ptr2,
1099  that_ptr1,
1100  that_ptr2,
1101  ir_reduce_one_entry->addConstant<ConstantInt>(init_val, Type::Int64),
1102  ir_reduce_one_entry->addConstant<ConstantInt>(length_to_elems,
1103  Type::Int64)},
1104  "");
1105  }
1106  }
1107 }
bool is_string() const
Definition: sqltypes.h:417
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
const std::vector< int64_t > target_init_vals_
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:133
bool is_varlen() const
Definition: sqltypes.h:432
const Value * emit_checked_write_projection(Value *slot_pi8, Value *other_pi8, const int64_t init_val, const size_t chosen_bytes, Function *ir_reduce_one_entry)
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
const QueryMemoryDescriptor query_mem_desc_
bool is_agg
Definition: TargetInfo.h:40
void emit_write_projection(Value *slot_pi8, Value *other_pi8, const int64_t init_val, const size_t chosen_bytes, Function *ir_reduce_one_entry)
size_t targetGroupbyIndicesSize() const
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define CHECK_LT(x, y)
Definition: Logger.h:207
bool is_geometry() const
Definition: sqltypes.h:429
int64_t getTargetGroupbyIndex(const size_t target_idx) const
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:624
#define CHECK(condition)
Definition: Logger.h:197
void reduceOneAggregateSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const int64_t init_val, const int8_t chosen_bytes, Function *ir_reduce_one_entry) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ query_mem_desc_

◆ s_code_cache

CodeCache ResultSetReductionJIT::s_code_cache
staticprivate

Definition at line 134 of file ResultSetReductionJIT.h.

Referenced by clearCache(), codegen(), and finalizeReductionCode().

◆ target_init_vals_

const std::vector<int64_t> ResultSetReductionJIT::target_init_vals_
private

Definition at line 133 of file ResultSetReductionJIT.h.

Referenced by cacheKey(), isEmpty(), and reduceOneSlot().

◆ targets_

const std::vector<TargetInfo> ResultSetReductionJIT::targets_
private

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