OmniSciDB  94e8789169
 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 506 of file ResultSetReductionJIT.cpp.

509  : query_mem_desc_(query_mem_desc)
510  , targets_(targets)
511  , 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 1289 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().

1289  {
1290  std::vector<std::string> target_init_vals_strings;
1291  std::transform(target_init_vals_.begin(),
1292  target_init_vals_.end(),
1293  std::back_inserter(target_init_vals_strings),
1294  [](const int64_t v) { return std::to_string(v); });
1295  const auto target_init_vals_key =
1296  boost::algorithm::join(target_init_vals_strings, ", ");
1297  std::vector<std::string> targets_strings;
1298  std::transform(
1299  targets_.begin(),
1300  targets_.end(),
1301  std::back_inserter(targets_strings),
1302  [](const TargetInfo& target_info) { return target_info_key(target_info); });
1303  const auto targets_key = boost::algorithm::join(targets_strings, ", ");
1304  return query_mem_desc_.reductionKey() + "\n" + target_init_vals_key + "\n" +
1305  targets_key;
1306 }
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 625 of file ResultSetReductionJIT.cpp.

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

625  {
626  // Clear stub cache to avoid crash caused by non-deterministic static destructor order
627  // of LLVM context and the cache.
630  g_rt_module = nullptr;
631 }
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 544 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(), generate_TableFunctionsFactory_init::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().

544  {
545  const auto hash_type = query_mem_desc_.getQueryDescriptionType();
547  return {};
548  }
549  auto reduction_code = setup_functions_ir(hash_type);
550  isEmpty(reduction_code);
554  reduceOneEntryNoCollisions(reduction_code);
555  reduceOneEntryNoCollisionsIdx(reduction_code);
556  break;
557  }
559  reduceOneEntryBaseline(reduction_code);
560  reduceOneEntryBaselineIdx(reduction_code);
561  break;
562  }
563  default: {
564  LOG(FATAL) << "Unexpected query description type";
565  }
566  }
567  reduceLoop(reduction_code);
568  // For small result sets, avoid native code generation and use the interpreter instead.
571  return reduction_code;
572  }
573  std::lock_guard<std::mutex> reduction_guard(ReductionCode::s_reduction_mutex);
574  CodeCacheKey key{cacheKey()};
575  const auto compilation_context = s_code_cache.get(key);
576  if (compilation_context) {
577  auto cpu_context =
578  std::dynamic_pointer_cast<CpuCompilationContext>(compilation_context->first);
579  CHECK(cpu_context);
580  return {reinterpret_cast<ReductionCode::FuncPtr>(cpu_context->func()),
581  nullptr,
582  nullptr,
583  nullptr,
584  std::move(reduction_code.ir_is_empty),
585  std::move(reduction_code.ir_reduce_one_entry),
586  std::move(reduction_code.ir_reduce_one_entry_idx),
587  std::move(reduction_code.ir_reduce_loop)};
588  }
589  reduction_code.cgen_state.reset(new CgenState({}, false));
590  auto cgen_state = reduction_code.cgen_state.get();
591  std::unique_ptr<llvm::Module> module = runtime_module_shallow_copy(cgen_state);
592  cgen_state->module_ = module.get();
593  AUTOMATIC_IR_METADATA(cgen_state);
594  auto ir_is_empty = create_llvm_function(reduction_code.ir_is_empty.get(), cgen_state);
595  auto ir_reduce_one_entry =
596  create_llvm_function(reduction_code.ir_reduce_one_entry.get(), cgen_state);
597  auto ir_reduce_one_entry_idx =
598  create_llvm_function(reduction_code.ir_reduce_one_entry_idx.get(), cgen_state);
599  auto ir_reduce_loop =
600  create_llvm_function(reduction_code.ir_reduce_loop.get(), cgen_state);
601  std::unordered_map<const Function*, llvm::Function*> f;
602  f.emplace(reduction_code.ir_is_empty.get(), ir_is_empty);
603  f.emplace(reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry);
604  f.emplace(reduction_code.ir_reduce_one_entry_idx.get(), ir_reduce_one_entry_idx);
605  f.emplace(reduction_code.ir_reduce_loop.get(), ir_reduce_loop);
606  translate_function(reduction_code.ir_is_empty.get(), ir_is_empty, reduction_code, f);
608  reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry, reduction_code, f);
609  translate_function(reduction_code.ir_reduce_one_entry_idx.get(),
610  ir_reduce_one_entry_idx,
611  reduction_code,
612  f);
614  reduction_code.ir_reduce_loop.get(), ir_reduce_loop, reduction_code, f);
615  reduction_code.llvm_reduce_loop = ir_reduce_loop;
616  reduction_code.module = std::move(module);
618  return finalizeReductionCode(std::move(reduction_code),
619  ir_is_empty,
620  ir_reduce_one_entry,
621  ir_reduce_one_entry_idx,
622  key);
623 }
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:188
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:197
void reduceOneEntryBaseline(const ReductionCode &reduction_code) const
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 1238 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().

1243  {
1244  CompilationOptions co{
1246 
1247 #ifdef NDEBUG
1248  LOG(IR) << "Reduction Loop:\n"
1249  << serialize_llvm_object(reduction_code.llvm_reduce_loop);
1250  LOG(IR) << "Reduction Is Empty Func:\n" << serialize_llvm_object(ir_is_empty);
1251  LOG(IR) << "Reduction One Entry Func:\n" << serialize_llvm_object(ir_reduce_one_entry);
1252  LOG(IR) << "Reduction One Entry Idx Func:\n"
1253  << serialize_llvm_object(ir_reduce_one_entry_idx);
1254 #else
1255  LOG(IR) << serialize_llvm_object(reduction_code.cgen_state->module_);
1256 #endif
1257 
1258  reduction_code.module.release();
1260  reduction_code.llvm_reduce_loop, {reduction_code.llvm_reduce_loop}, co);
1261  reduction_code.func_ptr = reinterpret_cast<ReductionCode::FuncPtr>(
1262  ee->getPointerToFunction(reduction_code.llvm_reduce_loop));
1263 
1264  auto cpu_compilation_context = std::make_shared<CpuCompilationContext>(std::move(ee));
1265  cpu_compilation_context->setFunctionPointer(reduction_code.llvm_reduce_loop);
1266  reduction_code.compilation_context = cpu_compilation_context;
1268  reduction_code.compilation_context,
1269  reduction_code.llvm_reduce_loop->getParent(),
1270  s_code_cache);
1271  return reduction_code;
1272 }
std::unique_ptr< CgenState > cgen_state
std::shared_ptr< CompilationContext > compilation_context
#define LOG(tag)
Definition: Logger.h:188
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 633 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().

633  {
634  auto ir_is_empty = reduction_code.ir_is_empty.get();
637  Value* key{nullptr};
638  Value* empty_key_val{nullptr};
639  const auto keys_ptr = ir_is_empty->arg(0);
644  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
645  target_init_vals_.size());
646  const int64_t target_slot_off = result_set::get_byteoff_of_slot(
648  const auto slot_ptr = ir_is_empty->add<GetElementPtr>(
649  keys_ptr,
650  ir_is_empty->addConstant<ConstantInt>(target_slot_off, Type::Int32),
651  "is_empty_slot_ptr");
652  const auto compact_sz =
654  key = emit_read_int_from_buff(slot_ptr, compact_sz, ir_is_empty);
655  empty_key_val = ir_is_empty->addConstant<ConstantInt>(
657  } else {
659  case 4: {
662  key = emit_load_i32(keys_ptr, ir_is_empty);
663  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_32, Type::Int32);
664  break;
665  }
666  case 8: {
667  key = emit_load_i64(keys_ptr, ir_is_empty);
668  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_64, Type::Int64);
669  break;
670  }
671  default:
672  LOG(FATAL) << "Invalid key width";
673  }
674  }
675  const auto ret =
676  ir_is_empty->add<ICmp>(ICmp::Predicate::EQ, key, empty_key_val, "is_key_empty");
677  ir_is_empty->add<Ret>(ret);
678 }
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
#define CHECK_GE(x, y)
Definition: Logger.h:210
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:207
Value * emit_load_i64(Value *ptr, Function *function)
#define CHECK(condition)
Definition: Logger.h:197
#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 1023 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().

1023  {
1024  auto ir_reduce_loop = reduction_code.ir_reduce_loop.get();
1025  const auto this_buff_arg = ir_reduce_loop->arg(0);
1026  const auto that_buff_arg = ir_reduce_loop->arg(1);
1027  const auto start_index_arg = ir_reduce_loop->arg(2);
1028  const auto end_index_arg = ir_reduce_loop->arg(3);
1029  const auto that_entry_count_arg = ir_reduce_loop->arg(4);
1030  const auto this_qmd_handle_arg = ir_reduce_loop->arg(5);
1031  const auto that_qmd_handle_arg = ir_reduce_loop->arg(6);
1032  const auto serialized_varlen_buffer_arg = ir_reduce_loop->arg(7);
1033  For* for_loop =
1034  static_cast<For*>(ir_reduce_loop->add<For>(start_index_arg, end_index_arg, ""));
1035  generate_loop_body(for_loop,
1036  ir_reduce_loop,
1037  reduction_code.ir_reduce_one_entry_idx.get(),
1038  this_buff_arg,
1039  that_buff_arg,
1040  start_index_arg,
1041  that_entry_count_arg,
1042  this_qmd_handle_arg,
1043  that_qmd_handle_arg,
1044  serialized_varlen_buffer_arg);
1045  ir_reduce_loop->add<Ret>(ir_reduce_loop->addConstant<ConstantInt>(0, Type::Int32));
1046 }
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 1123 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().

1132  {
1133  switch (target_info.agg_kind) {
1134  case kCOUNT:
1135  case kAPPROX_COUNT_DISTINCT: {
1136  if (is_distinct_target(target_info)) {
1137  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1139  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1140  break;
1141  }
1142  CHECK_EQ(int64_t(0), init_val);
1143  emit_aggregate_one_count(this_ptr1, that_ptr1, chosen_bytes, ir_reduce_one_entry);
1144  break;
1145  }
1146  case kAPPROX_MEDIAN:
1147  CHECK_EQ(chosen_bytes, static_cast<int8_t>(sizeof(int64_t)));
1149  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1150  break;
1151  case kAVG: {
1152  // Ignore float argument compaction for count component for fear of its overflow
1153  emit_aggregate_one_count(this_ptr2,
1154  that_ptr2,
1155  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx),
1156  ir_reduce_one_entry);
1157  }
1158  // fall thru
1159  case kSUM: {
1161  this_ptr1,
1162  that_ptr1,
1163  init_val,
1164  chosen_bytes,
1165  target_info,
1166  ir_reduce_one_entry);
1167  break;
1168  }
1169  case kMIN: {
1171  this_ptr1,
1172  that_ptr1,
1173  init_val,
1174  chosen_bytes,
1175  target_info,
1176  ir_reduce_one_entry);
1177  break;
1178  }
1179  case kMAX: {
1181  this_ptr1,
1182  that_ptr1,
1183  init_val,
1184  chosen_bytes,
1185  target_info,
1186  ir_reduce_one_entry);
1187  break;
1188  }
1189  default:
1190  LOG(FATAL) << "Invalid aggregate type";
1191  }
1192 }
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_
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 1216 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().

1220  {
1222  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1223  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1224  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1225  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1226  ir_reduce_one_entry->add<ExternalCall>(
1227  "approx_median_jit_rt",
1228  Type::Void,
1229  std::vector<const Value*>{
1230  new_set_handle,
1231  old_set_handle,
1232  that_qmd_arg,
1233  this_qmd_arg,
1234  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1235  "");
1236 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#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:

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

1198  {
1200  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1201  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1202  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1203  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1204  ir_reduce_one_entry->add<ExternalCall>(
1205  "count_distinct_set_union_jit_rt",
1206  Type::Void,
1207  std::vector<const Value*>{
1208  new_set_handle,
1209  old_set_handle,
1210  that_qmd_arg,
1211  this_qmd_arg,
1212  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1213  "");
1214 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#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:

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

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

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

889  {
890  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
895  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
896  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
897  const auto that_entry_idx = ir_reduce_one_entry_idx->arg(2);
898  const auto that_entry_count = ir_reduce_one_entry_idx->arg(3);
899  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
900  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
901  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
902  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
904  const auto that_entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
905  Cast::CastOp::SExt, that_entry_idx, Type::Int64, "that_entry_idx_64");
906  const auto that_row_off_in_bytes =
907  ir_reduce_one_entry_idx->add<BinaryOperator>(BinaryOperator::BinaryOp::Mul,
908  that_entry_idx_64,
909  row_bytes,
910  "that_row_off_in_bytes");
911  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
912  that_buff, that_row_off_in_bytes, "that_row_ptr");
913  const auto that_is_empty =
914  ir_reduce_one_entry_idx->add<Call>(reduction_code.ir_is_empty.get(),
915  std::vector<const Value*>{that_row_ptr},
916  "that_is_empty");
917  ir_reduce_one_entry_idx->add<ReturnEarly>(
918  that_is_empty,
919  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
920  "");
921  const auto key_count = query_mem_desc_.getGroupbyColCount();
922  const auto one_element =
923  ir_reduce_one_entry_idx->addConstant<ConstantInt>(1, Type::Int32);
924  const auto this_targets_ptr_i64_ptr = ir_reduce_one_entry_idx->add<Alloca>(
925  Type::Int64Ptr, one_element, "this_targets_ptr_out");
926  const auto this_is_empty_ptr =
927  ir_reduce_one_entry_idx->add<Alloca>(Type::Int8, one_element, "this_is_empty_out");
928  ir_reduce_one_entry_idx->add<ExternalCall>(
929  "get_group_value_reduction_rt",
930  Type::Void,
931  std::vector<const Value*>{
932  this_buff,
933  that_row_ptr,
934  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_count, Type::Int32),
935  this_qmd_handle,
936  that_buff,
937  that_entry_idx,
938  that_entry_count,
939  row_bytes,
940  this_targets_ptr_i64_ptr,
941  this_is_empty_ptr},
942  "");
943  const auto this_targets_ptr_i64 = ir_reduce_one_entry_idx->add<Load>(
944  this_targets_ptr_i64_ptr, "this_targets_ptr_i64");
945  auto this_is_empty =
946  ir_reduce_one_entry_idx->add<Load>(this_is_empty_ptr, "this_is_empty");
947  this_is_empty = ir_reduce_one_entry_idx->add<Cast>(
948  Cast::CastOp::Trunc, this_is_empty, Type::Int1, "this_is_empty_bool");
949  ir_reduce_one_entry_idx->add<ReturnEarly>(
950  this_is_empty,
951  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
952  "");
953  const auto key_qw_count = get_slot_off_quad(query_mem_desc_);
954  const auto this_targets_ptr = ir_reduce_one_entry_idx->add<Cast>(
955  Cast::CastOp::BitCast, this_targets_ptr_i64, Type::Int8Ptr, "this_targets_ptr");
956  const auto key_byte_count = key_qw_count * sizeof(int64_t);
957  const auto key_byte_count_lv =
958  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_byte_count, Type::Int32);
959  const auto that_targets_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
960  that_row_ptr, key_byte_count_lv, "that_targets_ptr");
961  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
962  reduction_code.ir_reduce_one_entry.get(),
963  std::vector<const Value*>{this_targets_ptr,
964  that_targets_ptr,
965  this_qmd_handle,
966  that_qmd_handle,
967  serialized_varlen_buffer_arg},
968  "");
969  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
970 }
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:197

+ 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 680 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().

681  {
682  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
683  const auto this_row_ptr = ir_reduce_one_entry->arg(0);
684  const auto that_row_ptr = ir_reduce_one_entry->arg(1);
685  const auto that_is_empty =
686  ir_reduce_one_entry->add<Call>(reduction_code.ir_is_empty.get(),
687  std::vector<const Value*>{that_row_ptr},
688  "that_is_empty");
689  ir_reduce_one_entry->add<ReturnEarly>(
690  that_is_empty, ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32), "");
691 
692  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
693  if (key_bytes) { // copy the key from right hand side
694  ir_reduce_one_entry->add<MemCpy>(
695  this_row_ptr,
696  that_row_ptr,
697  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes, Type::Int32));
698  }
699 
700  const auto key_bytes_with_padding = align_to_int64(key_bytes);
701  const auto key_bytes_lv =
702  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes_with_padding, Type::Int32);
703  const auto this_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
704  this_row_ptr, key_bytes_lv, "this_targets_start");
705  const auto that_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
706  that_row_ptr, key_bytes_lv, "that_targets_start");
707 
709  ir_reduce_one_entry, this_targets_start_ptr, that_targets_start_ptr);
710 }
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 854 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().

855  {
856  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
861  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
862  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
863  const auto entry_idx = ir_reduce_one_entry_idx->arg(2);
864  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
865  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
866  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
867  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
869  const auto entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
870  Cast::CastOp::SExt, entry_idx, Type::Int64, "entry_idx_64");
871  const auto row_off_in_bytes = ir_reduce_one_entry_idx->add<BinaryOperator>(
872  BinaryOperator::BinaryOp::Mul, entry_idx_64, row_bytes, "row_off_in_bytes");
873  const auto this_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
874  this_buff, row_off_in_bytes, "this_row_ptr");
875  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
876  that_buff, row_off_in_bytes, "that_row_ptr");
877  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
878  reduction_code.ir_reduce_one_entry.get(),
879  std::vector<const Value*>{this_row_ptr,
880  that_row_ptr,
881  this_qmd_handle,
882  that_qmd_handle,
883  serialized_varlen_buffer_arg},
884  "");
885  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
886 }
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:197

+ 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 712 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().

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

1057  {
1059  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1060  return;
1061  }
1062  }
1063  const bool float_argument_input = takes_float_argument(target_info);
1064  const auto chosen_bytes = result_set::get_width_for_slot(
1065  target_slot_idx, float_argument_input, query_mem_desc_);
1066  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1067  auto init_val = target_init_vals_[init_agg_val_idx];
1068  if (target_info.is_agg &&
1069  (target_info.agg_kind != kSINGLE_VALUE && target_info.agg_kind != kSAMPLE)) {
1070  reduceOneAggregateSlot(this_ptr1,
1071  this_ptr2,
1072  that_ptr1,
1073  that_ptr2,
1074  target_info,
1075  target_logical_idx,
1076  target_slot_idx,
1077  init_val,
1078  chosen_bytes,
1079  ir_reduce_one_entry);
1080  } else if (target_info.agg_kind == kSINGLE_VALUE) {
1081  const auto checked_rc = emit_checked_write_projection(
1082  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1083 
1084  auto checked_rc_bool = ir_reduce_one_entry->add<ICmp>(
1086  checked_rc,
1087  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32),
1088  "");
1089 
1090  ir_reduce_one_entry->add<ReturnEarly>(checked_rc_bool, checked_rc, "");
1091 
1092  } else {
1094  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1095  if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) {
1096  CHECK(this_ptr2 && that_ptr2);
1097  size_t length_to_elems{0};
1098  if (target_info.sql_type.is_geometry()) {
1099  // TODO: Assumes hard-coded sizes for geometry targets
1100  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1101  } else {
1102  const auto& elem_ti = target_info.sql_type.get_elem_type();
1103  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1104  }
1105  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry->arg(4);
1106  ir_reduce_one_entry->add<ExternalCall>(
1107  "serialized_varlen_buffer_sample",
1108  Type::Void,
1109  std::vector<const Value*>{
1110  serialized_varlen_buffer_arg,
1111  this_ptr1,
1112  this_ptr2,
1113  that_ptr1,
1114  that_ptr2,
1115  ir_reduce_one_entry->addConstant<ConstantInt>(init_val, Type::Int64),
1116  ir_reduce_one_entry->addConstant<ConstantInt>(length_to_elems,
1117  Type::Int64)},
1118  "");
1119  }
1120  }
1121 }
int64_t getTargetGroupbyIndex(const size_t target_idx) const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
bool is_varlen() const
Definition: sqltypes.h:500
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:207
#define CHECK(condition)
Definition: Logger.h:197
bool is_geometry() const
Definition: sqltypes.h:490
bool is_string() const
Definition: sqltypes.h:478
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:697

+ 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: