OmniSciDB  fe05a0c208
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
 
void reduceOneApproxMedianSlot (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 ( const QueryMemoryDescriptor query_mem_desc,
const std::vector< TargetInfo > &  targets,
const std::vector< int64_t > &  target_init_vals 
)

Definition at line 518 of file ResultSetReductionJIT.cpp.

521  : query_mem_desc_(query_mem_desc)
522  , targets_(targets)
523  , target_init_vals_(target_init_vals) {}
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
const std::vector< TargetInfo > targets_
virtual ResultSetReductionJIT::~ResultSetReductionJIT ( )
virtualdefault

Member Function Documentation

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

Definition at line 1303 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().

1303  {
1304  std::vector<std::string> target_init_vals_strings;
1305  std::transform(target_init_vals_.begin(),
1306  target_init_vals_.end(),
1307  std::back_inserter(target_init_vals_strings),
1308  [](const int64_t v) { return std::to_string(v); });
1309  const auto target_init_vals_key =
1310  boost::algorithm::join(target_init_vals_strings, ", ");
1311  std::vector<std::string> targets_strings;
1312  std::transform(
1313  targets_.begin(),
1314  targets_.end(),
1315  std::back_inserter(targets_strings),
1316  [](const TargetInfo& target_info) { return target_info_key(target_info); });
1317  const auto targets_key = boost::algorithm::join(targets_strings, ", ");
1318  return query_mem_desc_.reductionKey() + "\n" + target_init_vals_key + "\n" +
1319  targets_key;
1320 }
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:

void ResultSetReductionJIT::clearCache ( )
static

Definition at line 637 of file ResultSetReductionJIT.cpp.

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

637  {
638  // Clear stub cache to avoid crash caused by non-deterministic static destructor order
639  // of LLVM context and the cache.
642  g_rt_module = nullptr;
643 }
void clear()
Definition: LruCache.hpp:60
std::unique_ptr< llvm::Module > g_rt_module

+ Here is the call graph for this function:

ReductionCode ResultSetReductionJIT::codegen ( ) const
virtual

Reimplemented in GpuReductionHelperJIT.

Definition at line 556 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(), f, 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().

556  {
557  const auto hash_type = query_mem_desc_.getQueryDescriptionType();
559  return {};
560  }
561  auto reduction_code = setup_functions_ir(hash_type);
562  isEmpty(reduction_code);
566  reduceOneEntryNoCollisions(reduction_code);
567  reduceOneEntryNoCollisionsIdx(reduction_code);
568  break;
569  }
571  reduceOneEntryBaseline(reduction_code);
572  reduceOneEntryBaselineIdx(reduction_code);
573  break;
574  }
575  default: {
576  LOG(FATAL) << "Unexpected query description type";
577  }
578  }
579  reduceLoop(reduction_code);
580  // For small result sets, avoid native code generation and use the interpreter instead.
583  return reduction_code;
584  }
585  std::lock_guard<std::mutex> reduction_guard(ReductionCode::s_reduction_mutex);
586  CodeCacheKey key{cacheKey()};
587  const auto compilation_context = s_code_cache.get(key);
588  if (compilation_context) {
589  auto cpu_context =
590  std::dynamic_pointer_cast<CpuCompilationContext>(compilation_context->first);
591  CHECK(cpu_context);
592  return {reinterpret_cast<ReductionCode::FuncPtr>(cpu_context->func()),
593  nullptr,
594  nullptr,
595  nullptr,
596  std::move(reduction_code.ir_is_empty),
597  std::move(reduction_code.ir_reduce_one_entry),
598  std::move(reduction_code.ir_reduce_one_entry_idx),
599  std::move(reduction_code.ir_reduce_loop)};
600  }
601  reduction_code.cgen_state.reset(new CgenState({}, false));
602  auto cgen_state = reduction_code.cgen_state.get();
603  std::unique_ptr<llvm::Module> module = runtime_module_shallow_copy(cgen_state);
604  cgen_state->module_ = module.get();
605  AUTOMATIC_IR_METADATA(cgen_state);
606  auto ir_is_empty = create_llvm_function(reduction_code.ir_is_empty.get(), cgen_state);
607  auto ir_reduce_one_entry =
608  create_llvm_function(reduction_code.ir_reduce_one_entry.get(), cgen_state);
609  auto ir_reduce_one_entry_idx =
610  create_llvm_function(reduction_code.ir_reduce_one_entry_idx.get(), cgen_state);
611  auto ir_reduce_loop =
612  create_llvm_function(reduction_code.ir_reduce_loop.get(), cgen_state);
613  std::unordered_map<const Function*, llvm::Function*> f;
614  f.emplace(reduction_code.ir_is_empty.get(), ir_is_empty);
615  f.emplace(reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry);
616  f.emplace(reduction_code.ir_reduce_one_entry_idx.get(), ir_reduce_one_entry_idx);
617  f.emplace(reduction_code.ir_reduce_loop.get(), ir_reduce_loop);
618  translate_function(reduction_code.ir_is_empty.get(), ir_is_empty, reduction_code, f);
620  reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry, reduction_code, f);
621  translate_function(reduction_code.ir_reduce_one_entry_idx.get(),
622  ir_reduce_one_entry_idx,
623  reduction_code,
624  f);
626  reduction_code.ir_reduce_loop.get(), ir_reduce_loop, reduction_code, f);
627  reduction_code.llvm_reduce_loop = ir_reduce_loop;
628  reduction_code.module = std::move(module);
630  return finalizeReductionCode(std::move(reduction_code),
631  ir_is_empty,
632  ir_reduce_one_entry,
633  ir_reduce_one_entry_idx,
634  key);
635 }
bool is_aggregate_query(const QueryDescriptionType hash_type)
std::unique_ptr< llvm::Module > runtime_module_shallow_copy(CgenState *cgen_state)
void reduceOneEntryNoCollisions(const ReductionCode &reduction_code) const
void reduceOneEntryBaselineIdx(const ReductionCode &reduction_code) const
#define LOG(tag)
Definition: Logger.h:194
void reduceLoop(const ReductionCode &reduction_code) const
void reduceOneEntryNoCollisionsIdx(const ReductionCode &reduction_code) const
std::vector< std::string > CodeCacheKey
Definition: CodeCache.h:25
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
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_
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)
QueryDescriptionType getQueryDescriptionType() const
#define AUTOMATIC_IR_METADATA_DONE()
void isEmpty(const ReductionCode &reduction_code) const
#define CHECK(condition)
Definition: Logger.h:203
void reduceOneEntryBaseline(const ReductionCode &reduction_code) const
char * f
value_t * get(const key_t &key)
Definition: LruCache.hpp:39
llvm::Function * create_llvm_function(const Function *function, CgenState *cgen_state)
const Executor * getExecutor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 1252 of file ResultSetReductionJIT.cpp.

References ReductionCode::cgen_state, CPU, CodeGenerator::generateNativeCPUCode(), logger::IR, ReductionCode::llvm_reduce_loop, LOG, ReductionCode::module, ReductionJIT, and serialize_llvm_object().

Referenced by codegen().

1257  {
1258  CompilationOptions co{
1260 
1261 #ifdef NDEBUG
1262  LOG(IR) << "Reduction Loop:\n"
1263  << serialize_llvm_object(reduction_code.llvm_reduce_loop);
1264  LOG(IR) << "Reduction Is Empty Func:\n" << serialize_llvm_object(ir_is_empty);
1265  LOG(IR) << "Reduction One Entry Func:\n" << serialize_llvm_object(ir_reduce_one_entry);
1266  LOG(IR) << "Reduction One Entry Idx Func:\n"
1267  << serialize_llvm_object(ir_reduce_one_entry_idx);
1268 #else
1269  LOG(IR) << serialize_llvm_object(reduction_code.cgen_state->module_);
1270 #endif
1271 
1272  reduction_code.module.release();
1274  reduction_code.llvm_reduce_loop, {reduction_code.llvm_reduce_loop}, co);
1275  reduction_code.func_ptr = reinterpret_cast<ReductionCode::FuncPtr>(
1276  ee->getPointerToFunction(reduction_code.llvm_reduce_loop));
1277 
1278  auto cpu_compilation_context = std::make_shared<CpuCompilationContext>(std::move(ee));
1279  cpu_compilation_context->setFunctionPointer(reduction_code.llvm_reduce_loop);
1280  reduction_code.compilation_context = cpu_compilation_context;
1282  reduction_code.compilation_context,
1283  reduction_code.llvm_reduce_loop->getParent(),
1284  s_code_cache);
1285  return reduction_code;
1286 }
std::unique_ptr< CgenState > cgen_state
std::shared_ptr< CompilationContext > compilation_context
#define LOG(tag)
Definition: Logger.h:194
llvm::Function * llvm_reduce_loop
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
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:

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

Definition at line 645 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, result_set::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().

645  {
646  auto ir_is_empty = reduction_code.ir_is_empty.get();
649  Value* key{nullptr};
650  Value* empty_key_val{nullptr};
651  const auto keys_ptr = ir_is_empty->arg(0);
656  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
657  target_init_vals_.size());
658  const int64_t target_slot_off = result_set::get_byteoff_of_slot(
660  const auto slot_ptr = ir_is_empty->add<GetElementPtr>(
661  keys_ptr,
662  ir_is_empty->addConstant<ConstantInt>(target_slot_off, Type::Int32),
663  "is_empty_slot_ptr");
664  const auto compact_sz =
666  key = emit_read_int_from_buff(slot_ptr, compact_sz, ir_is_empty);
667  empty_key_val = ir_is_empty->addConstant<ConstantInt>(
669  } else {
671  case 4: {
674  key = emit_load_i32(keys_ptr, ir_is_empty);
675  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_32, Type::Int32);
676  break;
677  }
678  case 8: {
679  key = emit_load_i64(keys_ptr, ir_is_empty);
680  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_64, Type::Int64);
681  break;
682  }
683  default:
684  LOG(FATAL) << "Invalid key width";
685  }
686  }
687  const auto ret =
688  ir_is_empty->add<ICmp>(ICmp::Predicate::EQ, key, empty_key_val, "is_key_empty");
689  ir_is_empty->add<Ret>(ret);
690 }
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:194
#define CHECK_GE(x, y)
Definition: Logger.h:216
size_t getEffectiveKeyWidth() const
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
Value * emit_load_i32(Value *ptr, Function *function)
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:213
Value * emit_load_i64(Value *ptr, Function *function)
#define CHECK(condition)
Definition: Logger.h:203
#define EMPTY_KEY_32
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1037 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().

1037  {
1038  auto ir_reduce_loop = reduction_code.ir_reduce_loop.get();
1039  const auto this_buff_arg = ir_reduce_loop->arg(0);
1040  const auto that_buff_arg = ir_reduce_loop->arg(1);
1041  const auto start_index_arg = ir_reduce_loop->arg(2);
1042  const auto end_index_arg = ir_reduce_loop->arg(3);
1043  const auto that_entry_count_arg = ir_reduce_loop->arg(4);
1044  const auto this_qmd_handle_arg = ir_reduce_loop->arg(5);
1045  const auto that_qmd_handle_arg = ir_reduce_loop->arg(6);
1046  const auto serialized_varlen_buffer_arg = ir_reduce_loop->arg(7);
1047  For* for_loop =
1048  static_cast<For*>(ir_reduce_loop->add<For>(start_index_arg, end_index_arg, ""));
1049  generate_loop_body(for_loop,
1050  ir_reduce_loop,
1051  reduction_code.ir_reduce_one_entry_idx.get(),
1052  this_buff_arg,
1053  that_buff_arg,
1054  start_index_arg,
1055  that_entry_count_arg,
1056  this_qmd_handle_arg,
1057  that_qmd_handle_arg,
1058  serialized_varlen_buffer_arg);
1059  ir_reduce_loop->add<Ret>(ir_reduce_loop->addConstant<ConstantInt>(0, Type::Int32));
1060 }
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:

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 1137 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, kAPPROX_MEDIAN, kAVG, kCOUNT, kMAX, kMIN, kSUM, LOG, query_mem_desc_, reduceOneApproxMedianSlot(), and reduceOneCountDistinctSlot().

Referenced by reduceOneSlot().

1146  {
1147  switch (target_info.agg_kind) {
1148  case kCOUNT:
1149  case kAPPROX_COUNT_DISTINCT: {
1150  if (is_distinct_target(target_info)) {
1151  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1153  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1154  break;
1155  }
1156  CHECK_EQ(int64_t(0), init_val);
1157  emit_aggregate_one_count(this_ptr1, that_ptr1, chosen_bytes, ir_reduce_one_entry);
1158  break;
1159  }
1160  case kAPPROX_MEDIAN:
1161  CHECK_EQ(chosen_bytes, static_cast<int8_t>(sizeof(int64_t)));
1163  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1164  break;
1165  case kAVG: {
1166  // Ignore float argument compaction for count component for fear of its overflow
1167  emit_aggregate_one_count(this_ptr2,
1168  that_ptr2,
1169  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx),
1170  ir_reduce_one_entry);
1171  }
1172  // fall thru
1173  case kSUM: {
1175  this_ptr1,
1176  that_ptr1,
1177  init_val,
1178  chosen_bytes,
1179  target_info,
1180  ir_reduce_one_entry);
1181  break;
1182  }
1183  case kMIN: {
1185  this_ptr1,
1186  that_ptr1,
1187  init_val,
1188  chosen_bytes,
1189  target_info,
1190  ir_reduce_one_entry);
1191  break;
1192  }
1193  case kMAX: {
1195  this_ptr1,
1196  that_ptr1,
1197  init_val,
1198  chosen_bytes,
1199  target_info,
1200  ir_reduce_one_entry);
1201  break;
1202  }
1203  default:
1204  LOG(FATAL) << "Invalid aggregate type";
1205  }
1206 }
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:211
#define LOG(tag)
Definition: Logger.h:194
const QueryMemoryDescriptor query_mem_desc_
Definition: sqldefs.h:73
void reduceOneCountDistinctSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
Definition: sqldefs.h:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:130
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
SQLAgg agg_kind
Definition: TargetInfo.h:41
void reduceOneApproxMedianSlot(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:

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

Definition at line 1230 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().

1234  {
1236  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1237  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1238  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1239  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1240  ir_reduce_one_entry->add<ExternalCall>(
1241  "approx_median_jit_rt",
1242  Type::Void,
1243  std::vector<const Value*>{
1244  new_set_handle,
1245  old_set_handle,
1246  that_qmd_arg,
1247  this_qmd_arg,
1248  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1249  "");
1250 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:213
Value * emit_load_i64(Value *ptr, Function *function)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 1208 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().

1212  {
1214  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1215  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1216  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1217  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1218  ir_reduce_one_entry->add<ExternalCall>(
1219  "count_distinct_set_union_jit_rt",
1220  Type::Void,
1221  std::vector<const Value*>{
1222  new_set_handle,
1223  old_set_handle,
1224  that_qmd_arg,
1225  this_qmd_arg,
1226  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1227  "");
1228 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:213
Value * emit_load_i64(Value *ptr, Function *function)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 807 of file ResultSetReductionJIT.cpp.

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

Referenced by codegen().

808  {
809  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
810  const auto this_targets_ptr_arg = ir_reduce_one_entry->arg(0);
811  const auto that_targets_ptr_arg = ir_reduce_one_entry->arg(1);
812  Value* this_ptr1 = this_targets_ptr_arg;
813  Value* that_ptr1 = that_targets_ptr_arg;
814  size_t j = 0;
815  size_t init_agg_val_idx = 0;
816  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
817  ++target_logical_idx) {
818  const auto& target_info = targets_[target_logical_idx];
819  Value* this_ptr2{nullptr};
820  Value* that_ptr2{nullptr};
821  if (target_info.is_agg &&
822  (target_info.agg_kind == kAVG ||
823  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
824  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
825  const auto second_slot_rel_off =
826  ir_reduce_one_entry->addConstant<ConstantInt>(sizeof(int64_t), Type::Int32);
827  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
828  this_ptr1, second_slot_rel_off, "this_" + desc);
829  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
830  that_ptr1, second_slot_rel_off, "that_" + desc);
831  }
832  reduceOneSlot(this_ptr1,
833  this_ptr2,
834  that_ptr1,
835  that_ptr2,
836  target_info,
837  target_logical_idx,
838  j,
839  init_agg_val_idx,
840  j,
841  ir_reduce_one_entry);
842  if (target_logical_idx + 1 == targets_.size()) {
843  break;
844  }
846  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
847  } else {
848  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
849  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
850  }
851  }
852  j = advance_slot(j, target_info, false);
853  const auto next_desc =
854  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
855  auto next_slot_rel_off = ir_reduce_one_entry->addConstant<ConstantInt>(
856  init_agg_val_idx * sizeof(int64_t), Type::Int32);
857  this_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
858  this_targets_ptr_arg, next_slot_rel_off, next_desc);
859  that_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
860  that_targets_ptr_arg, next_slot_rel_off, next_desc);
861  }
862  ir_reduce_one_entry->add<Ret>(
863  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
864 }
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
int64_t getTargetGroupbyIndex(const size_t target_idx) 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
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:

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

Definition at line 900 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, BinaryOperator::Mul, query_mem_desc_, Cast::SExt, Cast::Trunc, and Void.

Referenced by codegen().

901  {
902  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
907  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
908  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
909  const auto that_entry_idx = ir_reduce_one_entry_idx->arg(2);
910  const auto that_entry_count = ir_reduce_one_entry_idx->arg(3);
911  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
912  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
913  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
914  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
916  const auto that_entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
917  Cast::CastOp::SExt, that_entry_idx, Type::Int64, "that_entry_idx_64");
918  const auto that_row_off_in_bytes =
919  ir_reduce_one_entry_idx->add<BinaryOperator>(BinaryOperator::BinaryOp::Mul,
920  that_entry_idx_64,
921  row_bytes,
922  "that_row_off_in_bytes");
923  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
924  that_buff, that_row_off_in_bytes, "that_row_ptr");
925  const auto that_is_empty =
926  ir_reduce_one_entry_idx->add<Call>(reduction_code.ir_is_empty.get(),
927  std::vector<const Value*>{that_row_ptr},
928  "that_is_empty");
929  ir_reduce_one_entry_idx->add<ReturnEarly>(
930  that_is_empty,
931  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
932  "");
933  const auto key_count = query_mem_desc_.getGroupbyColCount();
934  const auto one_element =
935  ir_reduce_one_entry_idx->addConstant<ConstantInt>(1, Type::Int32);
936  const auto this_targets_ptr_i64_ptr = ir_reduce_one_entry_idx->add<Alloca>(
937  Type::Int64Ptr, one_element, "this_targets_ptr_out");
938  const auto this_is_empty_ptr =
939  ir_reduce_one_entry_idx->add<Alloca>(Type::Int8, one_element, "this_is_empty_out");
940  ir_reduce_one_entry_idx->add<ExternalCall>(
941  "get_group_value_reduction_rt",
942  Type::Void,
943  std::vector<const Value*>{
944  this_buff,
945  that_row_ptr,
946  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_count, Type::Int32),
947  this_qmd_handle,
948  that_buff,
949  that_entry_idx,
950  that_entry_count,
951  row_bytes,
952  this_targets_ptr_i64_ptr,
953  this_is_empty_ptr},
954  "");
955  const auto this_targets_ptr_i64 = ir_reduce_one_entry_idx->add<Load>(
956  this_targets_ptr_i64_ptr, "this_targets_ptr_i64");
957  auto this_is_empty =
958  ir_reduce_one_entry_idx->add<Load>(this_is_empty_ptr, "this_is_empty");
959  this_is_empty = ir_reduce_one_entry_idx->add<Cast>(
960  Cast::CastOp::Trunc, this_is_empty, Type::Int1, "this_is_empty_bool");
961  ir_reduce_one_entry_idx->add<ReturnEarly>(
962  this_is_empty,
963  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
964  "");
965  const auto key_qw_count = get_slot_off_quad(query_mem_desc_);
966  const auto this_targets_ptr = ir_reduce_one_entry_idx->add<Cast>(
967  Cast::CastOp::BitCast, this_targets_ptr_i64, Type::Int8Ptr, "this_targets_ptr");
968  const auto key_byte_count = key_qw_count * sizeof(int64_t);
969  const auto key_byte_count_lv =
970  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_byte_count, Type::Int32);
971  const auto that_targets_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
972  that_row_ptr, key_byte_count_lv, "that_targets_ptr");
973  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
974  reduction_code.ir_reduce_one_entry.get(),
975  std::vector<const Value*>{this_targets_ptr,
976  that_targets_ptr,
977  this_qmd_handle,
978  that_qmd_handle,
979  serialized_varlen_buffer_arg},
980  "");
981  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
982 }
size_t get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
size_t getGroupbyColCount() const
std::unique_ptr< Function > ir_reduce_one_entry_idx
QueryDescriptionType getQueryDescriptionType() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:203

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 692 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().

693  {
694  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
695  const auto this_row_ptr = ir_reduce_one_entry->arg(0);
696  const auto that_row_ptr = ir_reduce_one_entry->arg(1);
697  const auto that_is_empty =
698  ir_reduce_one_entry->add<Call>(reduction_code.ir_is_empty.get(),
699  std::vector<const Value*>{that_row_ptr},
700  "that_is_empty");
701  ir_reduce_one_entry->add<ReturnEarly>(
702  that_is_empty, ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32), "");
703 
704  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
705  if (key_bytes) { // copy the key from right hand side
706  ir_reduce_one_entry->add<MemCpy>(
707  this_row_ptr,
708  that_row_ptr,
709  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes, Type::Int32));
710  }
711 
712  const auto key_bytes_with_padding = align_to_int64(key_bytes);
713  const auto key_bytes_lv =
714  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes_with_padding, Type::Int32);
715  const auto this_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
716  this_row_ptr, key_bytes_lv, "this_targets_start");
717  const auto that_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
718  that_row_ptr, key_bytes_lv, "that_targets_start");
719 
721  ir_reduce_one_entry, this_targets_start_ptr, that_targets_start_ptr);
722 }
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
void reduceOneEntryTargetsNoCollisions(Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
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:

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

Definition at line 866 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().

867  {
868  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
873  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
874  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
875  const auto entry_idx = ir_reduce_one_entry_idx->arg(2);
876  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
877  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
878  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
879  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
881  const auto entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
882  Cast::CastOp::SExt, entry_idx, Type::Int64, "entry_idx_64");
883  const auto row_off_in_bytes = ir_reduce_one_entry_idx->add<BinaryOperator>(
884  BinaryOperator::BinaryOp::Mul, entry_idx_64, row_bytes, "row_off_in_bytes");
885  const auto this_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
886  this_buff, row_off_in_bytes, "this_row_ptr");
887  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
888  that_buff, row_off_in_bytes, "that_row_ptr");
889  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
890  reduction_code.ir_reduce_one_entry.get(),
891  std::vector<const Value*>{this_row_ptr,
892  that_row_ptr,
893  this_qmd_handle,
894  that_qmd_handle,
895  serialized_varlen_buffer_arg},
896  "");
897  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
898 }
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_reduce_one_entry_idx
QueryDescriptionType getQueryDescriptionType() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:203

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 724 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().

727  {
728  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
729  Value* this_targets_ptr = this_targets_start_ptr;
730  Value* that_targets_ptr = that_targets_start_ptr;
731  size_t init_agg_val_idx = 0;
732  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
733  ++target_logical_idx) {
734  const auto& target_info = targets_[target_logical_idx];
735  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_logical_idx);
736  Value* this_ptr2{nullptr};
737  Value* that_ptr2{nullptr};
738 
739  bool two_slot_target{false};
740  if (target_info.is_agg &&
741  (target_info.agg_kind == kAVG ||
742  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
743  // Note that this assumes if one of the slot pairs in a given target is an array,
744  // all slot pairs are arrays. Currently this is true for all geo targets, but we
745  // should better codify and store this information in the future
746  two_slot_target = true;
747  }
748 
749  for (size_t target_slot_idx = slots_for_col.front();
750  target_slot_idx < slots_for_col.back() + 1;
751  target_slot_idx += 2) {
752  const auto slot_off_val = query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
753  const auto slot_off =
754  ir_reduce_one_entry->addConstant<ConstantInt>(slot_off_val, Type::Int32);
755  if (UNLIKELY(two_slot_target)) {
756  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
757  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
758  this_targets_ptr, slot_off, "this_" + desc);
759  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
760  that_targets_ptr, slot_off, "that_" + desc);
761  }
762  reduceOneSlot(this_targets_ptr,
763  this_ptr2,
764  that_targets_ptr,
765  that_ptr2,
766  target_info,
767  target_logical_idx,
768  target_slot_idx,
769  init_agg_val_idx,
770  slots_for_col.front(),
771  ir_reduce_one_entry);
772  auto increment_agg_val_idx_maybe =
773  [&init_agg_val_idx, &target_logical_idx, this](const int slot_count) {
775  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
776  init_agg_val_idx += slot_count;
777  }
778  };
779  if (target_logical_idx + 1 == targets_.size() &&
780  target_slot_idx + 1 >= slots_for_col.back()) {
781  break;
782  }
783  const auto next_desc =
784  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
785  if (UNLIKELY(two_slot_target)) {
786  increment_agg_val_idx_maybe(2);
787  const auto two_slot_off = ir_reduce_one_entry->addConstant<ConstantInt>(
788  slot_off_val + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1),
789  Type::Int32);
790  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
791  this_targets_ptr, two_slot_off, "this_" + next_desc);
792  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
793  that_targets_ptr, two_slot_off, "that_" + next_desc);
794  } else {
795  increment_agg_val_idx_maybe(1);
796  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
797  this_targets_ptr, slot_off, "this_" + next_desc);
798  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
799  that_targets_ptr, slot_off, "that_" + next_desc);
800  }
801  }
802  }
803  ir_reduce_one_entry->add<Ret>(
804  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
805 }
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
int64_t getTargetGroupbyIndex(const size_t target_idx) const
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
size_t targetGroupbyIndicesSize() const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define UNLIKELY(x)
Definition: likely.h:25
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:

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 1062 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(), result_set::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().

1071  {
1073  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1074  return;
1075  }
1076  }
1077  const bool float_argument_input = takes_float_argument(target_info);
1078  const auto chosen_bytes = result_set::get_width_for_slot(
1079  target_slot_idx, float_argument_input, query_mem_desc_);
1080  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1081  auto init_val = target_init_vals_[init_agg_val_idx];
1082  if (target_info.is_agg &&
1083  (target_info.agg_kind != kSINGLE_VALUE && target_info.agg_kind != kSAMPLE)) {
1084  reduceOneAggregateSlot(this_ptr1,
1085  this_ptr2,
1086  that_ptr1,
1087  that_ptr2,
1088  target_info,
1089  target_logical_idx,
1090  target_slot_idx,
1091  init_val,
1092  chosen_bytes,
1093  ir_reduce_one_entry);
1094  } else if (target_info.agg_kind == kSINGLE_VALUE) {
1095  const auto checked_rc = emit_checked_write_projection(
1096  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1097 
1098  auto checked_rc_bool = ir_reduce_one_entry->add<ICmp>(
1100  checked_rc,
1101  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32),
1102  "");
1103 
1104  ir_reduce_one_entry->add<ReturnEarly>(checked_rc_bool, checked_rc, "");
1105 
1106  } else {
1108  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1109  if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) {
1110  CHECK(this_ptr2 && that_ptr2);
1111  size_t length_to_elems{0};
1112  if (target_info.sql_type.is_geometry()) {
1113  // TODO: Assumes hard-coded sizes for geometry targets
1114  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1115  } else {
1116  const auto& elem_ti = target_info.sql_type.get_elem_type();
1117  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1118  }
1119  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry->arg(4);
1120  ir_reduce_one_entry->add<ExternalCall>(
1121  "serialized_varlen_buffer_sample",
1122  Type::Void,
1123  std::vector<const Value*>{
1124  serialized_varlen_buffer_arg,
1125  this_ptr1,
1126  this_ptr2,
1127  that_ptr1,
1128  that_ptr2,
1129  ir_reduce_one_entry->addConstant<ConstantInt>(init_val, Type::Int64),
1130  ir_reduce_one_entry->addConstant<ConstantInt>(length_to_elems,
1131  Type::Int64)},
1132  "");
1133  }
1134  }
1135 }
int64_t getTargetGroupbyIndex(const size_t target_idx) const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
bool is_varlen() const
Definition: sqltypes.h:514
const std::vector< int64_t > target_init_vals_
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
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:134
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)
const QueryMemoryDescriptor query_mem_desc_
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
bool is_agg
Definition: TargetInfo.h:40
size_t targetGroupbyIndicesSize() const
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)
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define CHECK_LT(x, y)
Definition: Logger.h:213
#define CHECK(condition)
Definition: Logger.h:203
bool is_geometry() const
Definition: sqltypes.h:501
bool is_string() const
Definition: sqltypes.h:489
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:713

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

CodeCache ResultSetReductionJIT::s_code_cache
staticprivate

Definition at line 139 of file ResultSetReductionJIT.h.

Referenced by clearCache(), and codegen().

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

Definition at line 138 of file ResultSetReductionJIT.h.

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

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

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