OmniSciDB  471d68cefb
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TableFunctionCompilationContext.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <llvm/IR/Verifier.h>
20 #include <llvm/Support/raw_os_ostream.h>
21 #include <algorithm>
22 #include <boost/algorithm/string.hpp>
23 
25 
26 extern std::unique_ptr<llvm::Module> rt_udf_cpu_module;
27 extern std::unique_ptr<llvm::Module> rt_udf_gpu_module;
28 
29 namespace {
30 
31 llvm::Function* generate_entry_point(const CgenState* cgen_state) {
32  auto& ctx = cgen_state->context_;
33  const auto pi8_type = llvm::PointerType::get(get_int_type(8, ctx), 0);
34  const auto ppi8_type = llvm::PointerType::get(pi8_type, 0);
35  const auto pi64_type = llvm::PointerType::get(get_int_type(64, ctx), 0);
36  const auto ppi64_type = llvm::PointerType::get(pi64_type, 0);
37  const auto i32_type = get_int_type(32, ctx);
38 
39  const auto func_type = llvm::FunctionType::get(
40  i32_type, {pi8_type, ppi8_type, pi64_type, ppi64_type, pi64_type}, false);
41 
42  auto func = llvm::Function::Create(func_type,
43  llvm::Function::ExternalLinkage,
44  "call_table_function",
45  cgen_state->module_);
46  auto arg_it = func->arg_begin();
47  const auto mgr_arg = &*arg_it;
48  mgr_arg->setName("mgr_ptr");
49  const auto input_cols_arg = &*(++arg_it);
50  input_cols_arg->setName("input_col_buffers");
51  const auto input_row_counts = &*(++arg_it);
52  input_row_counts->setName("input_row_counts");
53  const auto output_buffers = &*(++arg_it);
54  output_buffers->setName("output_buffers");
55  const auto output_row_count = &*(++arg_it);
56  output_row_count->setName("output_row_count");
57  return func;
58 }
59 
61  llvm::LLVMContext& ctx) {
62  if (elem_ti.is_fp()) {
63  return get_fp_ptr_type(elem_ti.get_size() * 8, ctx);
64  } else if (elem_ti.is_boolean()) {
65  return get_int_ptr_type(8, ctx);
66  } else if (elem_ti.is_integer()) {
67  return get_int_ptr_type(elem_ti.get_size() * 8, ctx);
68  } else if (elem_ti.is_string()) {
69  if (elem_ti.get_compression() == kENCODING_DICT) {
70  return get_int_ptr_type(elem_ti.get_size() * 8, ctx);
71  }
72  CHECK(elem_ti.is_bytes()); // None encoded string
73  return get_int_ptr_type(8, ctx);
74  }
75  LOG(FATAL) << "get_llvm_type_from_sql_column_type: not implemented for "
76  << ::toString(elem_ti);
77  return nullptr;
78 }
79 
80 std::tuple<llvm::Value*, llvm::Value*> alloc_column(std::string col_name,
81  const size_t index,
82  const SQLTypeInfo& data_target_info,
83  llvm::Value* data_ptr,
84  llvm::Value* data_size,
85  llvm::LLVMContext& ctx,
86  llvm::IRBuilder<>& ir_builder) {
87  /*
88  Creates a new Column instance of given element type and initialize
89  its data ptr and sz members when specified. If data ptr or sz are
90  unspecified (have nullptr values) then the corresponding members
91  are initialized with NULL and -1, respectively.
92 
93  Return a pair of Column allocation (caller should apply
94  builder.CreateLoad to it in order to construct a Column instance
95  as a value) and a pointer to the Column instance.
96  */
97  llvm::Type* data_ptr_llvm_type =
98  get_llvm_type_from_sql_column_type(data_target_info, ctx);
99  llvm::StructType* col_struct_type =
100  llvm::StructType::get(ctx,
101  {
102  data_ptr_llvm_type, /* T* ptr */
103  llvm::Type::getInt64Ty(ctx) /* int64_t sz */
104  });
105  auto col = ir_builder.CreateAlloca(col_struct_type);
106  col->setName(col_name);
107  auto col_ptr_ptr = ir_builder.CreateStructGEP(col_struct_type, col, 0);
108  auto col_sz_ptr = ir_builder.CreateStructGEP(col_struct_type, col, 1);
109  col_ptr_ptr->setName(col_name + ".ptr");
110  col_sz_ptr->setName(col_name + ".sz");
111 
112  if (data_ptr != nullptr) {
113  if (data_ptr->getType() == data_ptr_llvm_type->getPointerElementType()) {
114  ir_builder.CreateStore(data_ptr, col_ptr_ptr);
115  } else {
116  auto tmp = ir_builder.CreateBitCast(data_ptr, data_ptr_llvm_type);
117  ir_builder.CreateStore(tmp, col_ptr_ptr);
118  }
119  } else {
120  ir_builder.CreateStore(llvm::Constant::getNullValue(data_ptr_llvm_type), col_ptr_ptr);
121  }
122  if (data_size != nullptr) {
123  auto data_size_type = data_size->getType();
124  llvm::Value* size_val = nullptr;
125  if (data_size_type->isPointerTy()) {
126  CHECK(data_size_type->getPointerElementType()->isIntegerTy(64));
127  size_val = ir_builder.CreateLoad(data_size);
128  } else {
129  CHECK(data_size_type->isIntegerTy(64));
130  size_val = data_size;
131  }
132  ir_builder.CreateStore(size_val, col_sz_ptr);
133  } else {
134  auto const_minus1 = llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx), -1, true);
135  ir_builder.CreateStore(const_minus1, col_sz_ptr);
136  }
137  auto col_ptr = ir_builder.CreatePointerCast(
138  col_ptr_ptr, llvm::PointerType::get(llvm::Type::getInt8Ty(ctx), 0));
139  col_ptr->setName(col_name + "_ptr");
140  return {col, col_ptr};
141 }
142 
143 llvm::Value* alloc_column_list(std::string col_list_name,
144  const SQLTypeInfo& data_target_info,
145  llvm::Value* data_ptrs,
146  int length,
147  llvm::Value* data_size,
148  llvm::LLVMContext& ctx,
149  llvm::IRBuilder<>& ir_builder) {
150  /*
151  Creates a new ColumnList instance of given element type and initialize
152  its members. If data ptr or size are unspecified (have nullptr
153  values) then the corresponding members are initialized with NULL
154  and -1, respectively.
155  */
156  llvm::Type* data_ptrs_llvm_type = llvm::Type::getInt8PtrTy(ctx);
157 
158  llvm::StructType* col_list_struct_type =
159  llvm::StructType::get(ctx,
160  {
161  data_ptrs_llvm_type, /* int8_t* ptrs */
162  llvm::Type::getInt64Ty(ctx), /* int64_t length */
163  llvm::Type::getInt64Ty(ctx) /* int64_t size */
164  });
165  auto col_list = ir_builder.CreateAlloca(col_list_struct_type);
166  col_list->setName(col_list_name);
167  auto col_list_ptr_ptr = ir_builder.CreateStructGEP(col_list_struct_type, col_list, 0);
168  auto col_list_length_ptr =
169  ir_builder.CreateStructGEP(col_list_struct_type, col_list, 1);
170  auto col_list_size_ptr = ir_builder.CreateStructGEP(col_list_struct_type, col_list, 2);
171 
172  col_list_ptr_ptr->setName(col_list_name + ".ptrs");
173  col_list_length_ptr->setName(col_list_name + ".length");
174  col_list_size_ptr->setName(col_list_name + ".size");
175 
176  CHECK(length >= 0);
177  auto const_length = llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx), length, true);
178 
179  if (data_ptrs != nullptr) {
180  if (data_ptrs->getType() == data_ptrs_llvm_type->getPointerElementType()) {
181  ir_builder.CreateStore(data_ptrs, col_list_ptr_ptr);
182  } else {
183  auto tmp = ir_builder.CreateBitCast(data_ptrs, data_ptrs_llvm_type);
184  ir_builder.CreateStore(tmp, col_list_ptr_ptr);
185  }
186  } else {
187  ir_builder.CreateStore(llvm::Constant::getNullValue(data_ptrs_llvm_type),
188  col_list_ptr_ptr);
189  }
190 
191  ir_builder.CreateStore(const_length, col_list_length_ptr);
192 
193  if (data_size != nullptr) {
194  auto data_size_type = data_size->getType();
195  llvm::Value* size_val = nullptr;
196  if (data_size_type->isPointerTy()) {
197  CHECK(data_size_type->getPointerElementType()->isIntegerTy(64));
198  size_val = ir_builder.CreateLoad(data_size);
199  } else {
200  CHECK(data_size_type->isIntegerTy(64));
201  size_val = data_size;
202  }
203  ir_builder.CreateStore(size_val, col_list_size_ptr);
204  } else {
205  auto const_minus1 = llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx), -1, true);
206  ir_builder.CreateStore(const_minus1, col_list_size_ptr);
207  }
208 
209  auto col_list_ptr = ir_builder.CreatePointerCast(
210  col_list_ptr_ptr, llvm::PointerType::get(llvm::Type::getInt8Ty(ctx), 0));
211  col_list_ptr->setName(col_list_name + "_ptrs");
212  return col_list_ptr;
213 }
214 
215 } // namespace
216 
218  : cgen_state_(std::make_unique<CgenState>(/*num_query_infos=*/0,
219  /*contains_left_deep_outer_join=*/false)) {}
220 
222  const CompilationOptions& co,
223  Executor* executor) {
224  auto timer = DEBUG_TIMER(__func__);
225  auto cgen_state = cgen_state_.get();
226  CHECK(cgen_state);
227  std::unique_ptr<llvm::Module> module(runtime_module_shallow_copy(cgen_state));
228  cgen_state->module_ = module.get();
230  module_ = std::move(module);
231  generateEntryPoint(exe_unit, /*is_gpu=*/co.device_type == ExecutorDeviceType::GPU);
234  }
235  finalize(co, executor);
236 }
237 
239  const TableFunctionExecutionUnit& exe_unit,
240  bool is_gpu) {
241  llvm::Module* mod = (is_gpu ? rt_udf_gpu_module.get() : rt_udf_cpu_module.get());
242  if (mod != nullptr) {
243  auto* flag = mod->getModuleFlag("pass_column_arguments_by_value");
244  if (auto* cnt = llvm::mdconst::extract_or_null<llvm::ConstantInt>(flag)) {
245  return cnt->getZExtValue();
246  }
247  }
248 
249  // fallback to original behavior
250  return exe_unit.table_func.isRuntime();
251 }
252 
254  const TableFunctionExecutionUnit& exe_unit,
255  const std::vector<llvm::Value*>& func_args) {
256  // call require check function
257  llvm::LLVMContext& ctx = cgen_state_->context_;
258 
259  std::string require_check_fn = exe_unit.table_func.getRequireCheckName();
260  boost::algorithm::to_lower(require_check_fn);
261  llvm::Value* require_check_fn_return =
262  cgen_state_->emitExternalCall(require_check_fn, get_int_type(32, ctx), func_args);
263  require_check_fn_return->setName("require_check_fn_return");
264 
265  // if require_chec_fn_return != 0, return its value
266  llvm::BasicBlock* bb_exit_1 =
267  llvm::BasicBlock::Create(ctx, ".exit1", entry_point_func_);
268  llvm::BasicBlock* bb_ok =
269  llvm::BasicBlock::Create(ctx, ".func_body1", entry_point_func_);
270 
271  llvm::ConstantInt* zero = cgen_state_->llInt(0);
272  auto is_ok = cgen_state_->ir_builder_.CreateICmpEQ(require_check_fn_return, zero);
273  cgen_state_->ir_builder_.CreateCondBr(is_ok, bb_ok, bb_exit_1);
274 
275  cgen_state_->ir_builder_.SetInsertPoint(bb_exit_1);
276  cgen_state_->ir_builder_.CreateRet(require_check_fn_return);
277  cgen_state_->ir_builder_.SetInsertPoint(bb_ok);
278 }
279 
281  const TableFunctionExecutionUnit& exe_unit,
282  bool is_gpu) {
284  CHECK_EQ(entry_point_func_->arg_size(), 5);
285  auto arg_it = entry_point_func_->arg_begin();
286  const auto mgr_ptr = &*arg_it;
287  const auto input_cols_arg = &*(++arg_it);
288  const auto input_row_counts_arg = &*(++arg_it);
289  const auto output_buffers_arg = &*(++arg_it);
290  const auto output_row_count_ptr = &*(++arg_it);
291  auto cgen_state = cgen_state_.get();
292  CHECK(cgen_state);
293  auto& ctx = cgen_state->context_;
294 
295  const auto bb_entry = llvm::BasicBlock::Create(ctx, ".entry", entry_point_func_, 0);
296  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
297 
298  const auto bb_exit = llvm::BasicBlock::Create(ctx, ".exit", entry_point_func_);
299 
300  const auto func_body_bb = llvm::BasicBlock::Create(
301  ctx, ".func_body0", cgen_state->ir_builder_.GetInsertBlock()->getParent());
302 
303  cgen_state->ir_builder_.SetInsertPoint(func_body_bb);
304  auto col_heads = generate_column_heads_load(
305  exe_unit.input_exprs.size(), input_cols_arg, cgen_state->ir_builder_, ctx);
306  CHECK_EQ(exe_unit.input_exprs.size(), col_heads.size());
307  auto row_count_heads = generate_column_heads_load(
308  exe_unit.input_exprs.size(), input_row_counts_arg, cgen_state->ir_builder_, ctx);
309  // The column arguments of C++ UDTFs processed by clang must be
310  // passed by reference, see rbc issues 200 and 289.
311  auto pass_column_by_value = passColumnsByValue(exe_unit, is_gpu);
312  std::vector<llvm::Value*> func_args;
313  size_t func_arg_index = 0;
314  if (exe_unit.table_func.usesManager()) {
315  func_args.push_back(mgr_ptr);
316  func_arg_index++;
317  }
318  int col_index = -1;
319  for (size_t i = 0; i < exe_unit.input_exprs.size(); i++) {
320  const auto& expr = exe_unit.input_exprs[i];
321  const auto& ti = expr->get_type_info();
322  if (col_index == -1) {
323  func_arg_index += 1;
324  }
325  if (ti.is_fp()) {
326  auto r = cgen_state->ir_builder_.CreateBitCast(
327  col_heads[i], get_fp_ptr_type(get_bit_width(ti), ctx));
328  func_args.push_back(cgen_state->ir_builder_.CreateLoad(r));
329  CHECK_EQ(col_index, -1);
330  } else if (ti.is_integer() || ti.is_boolean()) {
331  auto r = cgen_state->ir_builder_.CreateBitCast(
332  col_heads[i], get_int_ptr_type(get_bit_width(ti), ctx));
333  func_args.push_back(cgen_state->ir_builder_.CreateLoad(r));
334  CHECK_EQ(col_index, -1);
335  } else if (ti.is_bytes()) {
336  auto varchar_size =
337  cgen_state->ir_builder_.CreateBitCast(col_heads[i], get_int_ptr_type(64, ctx));
338  auto varchar_ptr =
339  cgen_state->ir_builder_.CreateGEP(col_heads[i], cgen_state_->llInt(8));
340  auto [varchar_struct, varchar_struct_ptr] =
341  alloc_column(std::string("varchar_literal.") + std::to_string(func_arg_index),
342  i,
343  ti,
344  varchar_ptr,
345  varchar_size,
346  ctx,
347  cgen_state_->ir_builder_);
348  func_args.push_back((pass_column_by_value
349  ? cgen_state_->ir_builder_.CreateLoad(varchar_struct)
350  : varchar_struct_ptr));
351  CHECK_EQ(col_index, -1);
352  } else if (ti.is_column()) {
353  auto [col, col_ptr] =
354  alloc_column(std::string("input_col.") + std::to_string(func_arg_index),
355  i,
356  ti.get_elem_type(),
357  col_heads[i],
358  row_count_heads[i],
359  ctx,
360  cgen_state_->ir_builder_);
361  func_args.push_back(
362  (pass_column_by_value ? cgen_state_->ir_builder_.CreateLoad(col) : col_ptr));
363  CHECK_EQ(col_index, -1);
364  } else if (ti.is_column_list()) {
365  if (col_index == -1) {
366  auto col_list = alloc_column_list(
367  std::string("input_col_list.") + std::to_string(func_arg_index),
368  ti.get_elem_type(),
369  col_heads[i],
370  ti.get_dimension(),
371  row_count_heads[i],
372  ctx,
373  cgen_state_->ir_builder_);
374  func_args.push_back(col_list);
375  }
376  col_index++;
377  if (col_index + 1 == ti.get_dimension()) {
378  col_index = -1;
379  }
380  } else {
381  throw std::runtime_error(
382  "Only integer and floating point columns or scalars are supported as inputs to "
383  "table "
384  "functions, got " +
385  ti.get_type_name());
386  }
387  }
388  std::vector<llvm::Value*> output_col_args;
389  for (size_t i = 0; i < exe_unit.target_exprs.size(); i++) {
390  auto output_load = cgen_state->ir_builder_.CreateLoad(
391  cgen_state->ir_builder_.CreateGEP(output_buffers_arg, cgen_state_->llInt(i)));
392  const auto& expr = exe_unit.target_exprs[i];
393  const auto& ti = expr->get_type_info();
394  CHECK(!ti.is_column()); // UDTF output column type is its data type
395  CHECK(!ti.is_column_list()); // TODO: when UDTF outputs column_list, convert it to
396  // output columns
397  auto [col, col_ptr] = alloc_column(
398  std::string("output_col.") + std::to_string(i),
399  i,
400  ti,
401  (is_gpu ? output_load : nullptr), // CPU: set_output_row_size will set the output
402  // Column ptr member
403  output_row_count_ptr,
404  ctx,
405  cgen_state_->ir_builder_);
406  if (!is_gpu) {
407  cgen_state->emitExternalCall(
408  "TableFunctionManager_register_output_column",
409  llvm::Type::getVoidTy(ctx),
410  {mgr_ptr, llvm::ConstantInt::get(get_int_type(32, ctx), i, true), col_ptr});
411  }
412  output_col_args.push_back((pass_column_by_value ? col : col_ptr));
413  }
414 
415  // output column members must be set before loading column when
416  // column instances are passed by value
417  if (exe_unit.table_func.hasOutputSizeKnownPreLaunch() && !is_gpu) {
418  cgen_state->emitExternalCall(
419  "TableFunctionManager_set_output_row_size",
420  llvm::Type::getVoidTy(ctx),
421  {mgr_ptr, cgen_state_->ir_builder_.CreateLoad(output_row_count_ptr)});
422  }
423 
424  for (auto& col : output_col_args) {
425  func_args.push_back(
426  (pass_column_by_value ? cgen_state_->ir_builder_.CreateLoad(col) : col));
427  }
428 
429  if (exe_unit.table_func.requireInAnnotations()) {
430  generateRequireCheckCall(exe_unit, func_args);
431  }
432 
433  auto func_name = exe_unit.table_func.getName();
434  boost::algorithm::to_lower(func_name);
435  const auto table_func_return =
436  cgen_state->emitExternalCall(func_name, get_int_type(32, ctx), func_args);
437  table_func_return->setName("table_func_ret");
438 
439  // If table_func_return is non-negative then store the value in
440  // output_row_count and return zero. Otherwise, return
441  // table_func_return that negative value contains the error code.
442  const auto bb_exit_0 = llvm::BasicBlock::Create(ctx, ".exit0", entry_point_func_);
443 
444  auto const_zero = llvm::ConstantInt::get(table_func_return->getType(), 0, true);
445  auto is_ok = cgen_state_->ir_builder_.CreateICmpSGE(table_func_return, const_zero);
446  cgen_state_->ir_builder_.CreateCondBr(is_ok, bb_exit_0, bb_exit);
447 
448  cgen_state_->ir_builder_.SetInsertPoint(bb_exit_0);
449  auto r = cgen_state->ir_builder_.CreateIntCast(
450  table_func_return, get_int_type(64, ctx), true);
451  cgen_state->ir_builder_.CreateStore(r, output_row_count_ptr);
452  cgen_state->ir_builder_.CreateRet(const_zero);
453 
454  cgen_state->ir_builder_.SetInsertPoint(bb_exit);
455  cgen_state->ir_builder_.CreateRet(table_func_return);
456 
457  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
458  cgen_state->ir_builder_.CreateBr(func_body_bb);
459 
460  // std::cout << "=================================" << std::endl;
461  // entry_point_func_->print(llvm::outs());
462  // std::cout << "=================================" << std::endl;
463 
465 }
466 
469  std::vector<llvm::Type*> arg_types;
470  arg_types.reserve(entry_point_func_->arg_size());
471  std::for_each(entry_point_func_->arg_begin(),
472  entry_point_func_->arg_end(),
473  [&arg_types](const auto& arg) { arg_types.push_back(arg.getType()); });
474  CHECK_EQ(arg_types.size(), entry_point_func_->arg_size());
475 
476  auto cgen_state = cgen_state_.get();
477  CHECK(cgen_state);
478  auto& ctx = cgen_state->context_;
479 
480  std::vector<llvm::Type*> wrapper_arg_types(arg_types.size() + 1);
481  wrapper_arg_types[0] = llvm::PointerType::get(get_int_type(32, ctx), 0);
482  wrapper_arg_types[1] = arg_types[0];
483 
484  for (size_t i = 1; i < arg_types.size(); ++i) {
485  wrapper_arg_types[i + 1] = arg_types[i];
486  }
487 
488  auto wrapper_ft =
489  llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), wrapper_arg_types, false);
490  kernel_func_ = llvm::Function::Create(wrapper_ft,
491  llvm::Function::ExternalLinkage,
492  "table_func_kernel",
493  cgen_state->module_);
494 
495  auto wrapper_bb_entry = llvm::BasicBlock::Create(ctx, ".entry", kernel_func_, 0);
496  llvm::IRBuilder<> b(ctx);
497  b.SetInsertPoint(wrapper_bb_entry);
498  std::vector<llvm::Value*> loaded_args = {kernel_func_->arg_begin() + 1};
499  for (size_t i = 2; i < wrapper_arg_types.size(); ++i) {
500  loaded_args.push_back(kernel_func_->arg_begin() + i);
501  }
502  auto error_lv = b.CreateCall(entry_point_func_, loaded_args);
503  b.CreateStore(error_lv, kernel_func_->arg_begin());
504  b.CreateRetVoid();
505 }
506 
508  Executor* executor) {
509  /*
510  TODO 1: eliminate need for OverrideFromSrc
511  TODO 2: detect and link only the udf's that are needed
512  */
513  if (co.device_type == ExecutorDeviceType::GPU && rt_udf_gpu_module != nullptr) {
515  *module_,
516  cgen_state_.get(),
517  llvm::Linker::Flags::OverrideFromSrc);
518  }
519  if (co.device_type == ExecutorDeviceType::CPU && rt_udf_cpu_module != nullptr) {
521  *module_,
522  cgen_state_.get(),
523  llvm::Linker::Flags::OverrideFromSrc);
524  }
525 
526  module_.release();
527  // Add code to cache?
528 
529  LOG(IR) << "Table Function Entry Point IR\n"
532  LOG(IR) << "Table Function Kernel IR\n" << serialize_llvm_object(kernel_func_);
533 
534  CHECK(executor);
535  executor->initializeNVPTXBackend();
536 
537  CodeGenerator::GPUTarget gpu_target{executor->nvptx_target_machine_.get(),
538  executor->cudaMgr(),
539  executor->blockSize(),
540  cgen_state_.get(),
541  false};
543  kernel_func_,
545  co,
546  gpu_target);
547  } else {
548  auto ee =
550  func_ptr = reinterpret_cast<FuncPtr>(ee->getPointerToFunction(entry_point_func_));
551  own_execution_engine_ = std::move(ee);
552  }
553  LOG(IR) << "End of IR";
554 }
llvm::Type * get_fp_ptr_type(const int width, llvm::LLVMContext &context)
std::string to_lower(const std::string &str)
#define CHECK_EQ(x, y)
Definition: Logger.h:217
std::unique_ptr< llvm::Module > rt_udf_cpu_module
HOST DEVICE int get_size() const
Definition: sqltypes.h:339
std::string toString(const ExtArgumentType &sig_type)
std::unique_ptr< llvm::Module > runtime_module_shallow_copy(CgenState *cgen_state)
std::tuple< llvm::Value *, llvm::Value * > alloc_column(std::string col_name, const size_t index, const SQLTypeInfo &data_target_info, llvm::Value *data_ptr, llvm::Value *data_size, llvm::LLVMContext &ctx, llvm::IRBuilder<> &ir_builder)
std::vector< Analyzer::Expr * > input_exprs
void generateEntryPoint(const TableFunctionExecutionUnit &exe_unit, bool is_gpu)
const table_functions::TableFunction table_func
#define LOG(tag)
Definition: Logger.h:203
std::unique_ptr< llvm::Module > rt_udf_gpu_module
bool is_fp() const
Definition: sqltypes.h:513
void generateRequireCheckCall(const TableFunctionExecutionUnit &exe_unit, const std::vector< llvm::Value * > &args)
std::shared_ptr< GpuCompilationContext > gpu_code_
llvm::Function * generate_entry_point(const CgenState *cgen_state)
std::unique_ptr< llvm::Module > module_
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
static std::shared_ptr< GpuCompilationContext > generateNativeGPUCode(llvm::Function *func, llvm::Function *wrapper_func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co, const GPUTarget &gpu_target)
llvm::Module * module_
Definition: CgenState.h:329
void verify_function_ir(const llvm::Function *func)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:338
bool is_integer() const
Definition: sqltypes.h:511
bool is_boolean() const
Definition: sqltypes.h:516
static void link_udf_module(const std::unique_ptr< llvm::Module > &udf_module, llvm::Module &module, CgenState *cgen_state, llvm::Linker::Flags flags=llvm::Linker::Flags::None)
std::string getName(const bool drop_suffix=false, const bool lower=false) const
ExecutorDeviceType device_type
void finalize(const CompilationOptions &co, Executor *executor)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:337
std::string serialize_llvm_object(const T *llvm_obj)
std::vector< llvm::Value * > generate_column_heads_load(const int num_columns, llvm::Value *byte_stream_arg, llvm::IRBuilder<> &ir_builder, llvm::LLVMContext &ctx)
llvm::Value * alloc_column_list(std::string col_list_name, const SQLTypeInfo &data_target_info, llvm::Value *data_ptrs, int length, llvm::Value *data_size, llvm::LLVMContext &ctx, llvm::IRBuilder<> &ir_builder)
llvm::Type * get_llvm_type_from_sql_column_type(const SQLTypeInfo elem_ti, llvm::LLVMContext &ctx)
bool is_bytes() const
Definition: sqltypes.h:524
bool g_enable_watchdog false
Definition: Execute.cpp:76
#define CHECK(condition)
Definition: Logger.h:209
#define DEBUG_TIMER(name)
Definition: Logger.h:352
bool passColumnsByValue(const TableFunctionExecutionUnit &exe_unit, bool is_gpu)
std::vector< Analyzer::Expr * > target_exprs
bool is_string() const
Definition: sqltypes.h:509
int32_t(*)(const int8_t *mgr_ptr, const int8_t **input_cols, const int64_t *input_row_count, int64_t **out, int64_t *output_row_count) FuncPtr
llvm::Type * get_int_ptr_type(const int width, llvm::LLVMContext &context)
void compile(const TableFunctionExecutionUnit &exe_unit, const CompilationOptions &co, Executor *executor)