OmniSciDB  340b00dbf6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TableFunctionCompilationContext Class Reference

#include <TableFunctionCompilationContext.h>

+ Collaboration diagram for TableFunctionCompilationContext:

Public Types

using FuncPtr = int32_t(*)(const int8_t **input_cols, const int64_t *input_row_count, int64_t **out, int64_t *output_row_count)
 

Public Member Functions

 TableFunctionCompilationContext ()
 
 TableFunctionCompilationContext (const TableFunctionCompilationContext &)=delete
 
TableFunctionCompilationContextoperator= (const TableFunctionCompilationContext &)=delete
 
void compile (const TableFunctionExecutionUnit &exe_unit, const CompilationOptions &co, Executor *executor)
 
TableFunctionCompilationContext::FuncPtr getFuncPtr () const
 
GpuCompilationContextgetGpuCode () const
 

Private Member Functions

void generateEntryPoint (const TableFunctionExecutionUnit &exe_unit)
 
void generateGpuKernel ()
 
void finalize (const CompilationOptions &co, Executor *executor)
 

Private Attributes

std::unique_ptr< CgenStatecgen_state_
 
std::unique_ptr< llvm::Module > module_
 
ExecutionEngineWrapper own_execution_engine_
 
std::shared_ptr
< GpuCompilationContext
gpu_code_
 
llvm::Function * entry_point_func_
 
llvm::Function * kernel_func_
 
FuncPtr func_ptr
 

Detailed Description

Definition at line 29 of file TableFunctionCompilationContext.h.

Member Typedef Documentation

using TableFunctionCompilationContext::FuncPtr = int32_t (*)(const int8_t** input_cols, const int64_t* input_row_count, int64_t** out, int64_t* output_row_count)

Definition at line 45 of file TableFunctionCompilationContext.h.

Constructor & Destructor Documentation

TableFunctionCompilationContext::TableFunctionCompilationContext ( )

Definition at line 153 of file TableFunctionCompilationContext.cpp.

References cgen_state_, CHECK, entry_point_func_, anonymous_namespace{TableFunctionCompilationContext.cpp}::generate_entry_point(), module_, and runtime_module_shallow_copy().

154  : cgen_state_(std::make_unique<CgenState>(/*num_query_infos=*/0,
155  /*contains_left_deep_outer_join=*/false)) {
156  auto cgen_state = cgen_state_.get();
157  CHECK(cgen_state);
158 
159  std::unique_ptr<llvm::Module> module(runtime_module_shallow_copy(cgen_state));
160  cgen_state->module_ = module.get();
161 
163  module_ = std::move(module);
164 }
std::unique_ptr< llvm::Module > runtime_module_shallow_copy(CgenState *cgen_state)
llvm::Function * generate_entry_point(const CgenState *cgen_state)
std::unique_ptr< llvm::Module > module_
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the call graph for this function:

TableFunctionCompilationContext::TableFunctionCompilationContext ( const TableFunctionCompilationContext )
delete

Member Function Documentation

void TableFunctionCompilationContext::compile ( const TableFunctionExecutionUnit exe_unit,
const CompilationOptions co,
Executor executor 
)

Definition at line 166 of file TableFunctionCompilationContext.cpp.

References CompilationOptions::device_type, finalize(), generateEntryPoint(), generateGpuKernel(), and GPU.

Referenced by Executor::executeTableFunction().

168  {
169  generateEntryPoint(exe_unit);
172  }
173  finalize(co, executor);
174 }
void generateEntryPoint(const TableFunctionExecutionUnit &exe_unit)
ExecutorDeviceType device_type
void finalize(const CompilationOptions &co, Executor *executor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void TableFunctionCompilationContext::finalize ( const CompilationOptions co,
Executor executor 
)
private

Definition at line 326 of file TableFunctionCompilationContext.cpp.

References cgen_state_, CHECK, CPU, CompilationOptions::device_type, entry_point_func_, func_ptr, CodeGenerator::generateNativeCPUCode(), CodeGenerator::generateNativeGPUCode(), GPU, gpu_code_, logger::IR, kernel_func_, CodeGenerator::link_udf_module(), LOG, module_, own_execution_engine_, rt_udf_cpu_module, rt_udf_gpu_module, and serialize_llvm_object().

Referenced by compile().

327  {
328  /*
329  TODO 1: eliminate need for OverrideFromSrc
330  TODO 2: detect and link only the udf's that are needed
331  */
332  if (co.device_type == ExecutorDeviceType::GPU && rt_udf_gpu_module != nullptr) {
334  *module_,
335  cgen_state_.get(),
336  llvm::Linker::Flags::OverrideFromSrc);
337  }
338  if (co.device_type == ExecutorDeviceType::CPU && rt_udf_cpu_module != nullptr) {
340  *module_,
341  cgen_state_.get(),
342  llvm::Linker::Flags::OverrideFromSrc);
343  }
344 
345  module_.release();
346  // Add code to cache?
347 
348  LOG(IR) << "Table Function Entry Point IR\n"
350 
352  LOG(IR) << "Table Function Kernel IR\n" << serialize_llvm_object(kernel_func_);
353 
354  CHECK(executor);
355  executor->initializeNVPTXBackend();
356  const auto cuda_mgr = executor->catalog_->getDataMgr().getCudaMgr();
357  CHECK(cuda_mgr);
358 
359  CodeGenerator::GPUTarget gpu_target{executor->nvptx_target_machine_.get(),
360  cuda_mgr,
361  executor->blockSize(),
362  cgen_state_.get(),
363  false};
365  kernel_func_,
367  co,
368  gpu_target);
369  } else {
370  auto ee =
372  func_ptr = reinterpret_cast<FuncPtr>(ee->getPointerToFunction(entry_point_func_));
373  own_execution_engine_ = std::move(ee);
374  }
375 
376  LOG(IR) << "End of IR";
377 }
std::unique_ptr< llvm::Module > rt_udf_cpu_module
#define LOG(tag)
Definition: Logger.h:188
std::unique_ptr< llvm::Module > rt_udf_gpu_module
std::shared_ptr< GpuCompilationContext > gpu_code_
int32_t(*)(const int8_t **input_cols, const int64_t *input_row_count, int64_t **out, int64_t *output_row_count) FuncPtr
std::unique_ptr< llvm::Module > module_
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
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)
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)
ExecutorDeviceType device_type
std::string serialize_llvm_object(const T *llvm_obj)
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void TableFunctionCompilationContext::generateEntryPoint ( const TableFunctionExecutionUnit exe_unit)
private

Definition at line 176 of file TableFunctionCompilationContext.cpp.

References anonymous_namespace{TableFunctionCompilationContext.cpp}::alloc_column(), cgen_state_, CHECK, CHECK_EQ, entry_point_func_, generate_column_heads_load(), get_bit_width(), get_fp_type(), get_int_type(), table_functions::TableFunction::getName(), TableFunctionExecutionUnit::input_exprs, table_functions::TableFunction::isRuntime(), TableFunctionExecutionUnit::table_func, TableFunctionExecutionUnit::target_exprs, to_lower(), to_string(), and verify_function_ir().

Referenced by compile().

177  {
179  auto arg_it = entry_point_func_->arg_begin();
180  const auto input_cols_arg = &*arg_it;
181  const auto input_row_count = &*(++arg_it);
182  const auto output_buffers_arg = &*(++arg_it);
183  const auto output_row_count_ptr = &*(++arg_it);
184 
185  auto cgen_state = cgen_state_.get();
186  CHECK(cgen_state);
187  auto& ctx = cgen_state->context_;
188 
189  const auto bb_entry = llvm::BasicBlock::Create(ctx, ".entry", entry_point_func_, 0);
190  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
191 
192  const auto bb_exit = llvm::BasicBlock::Create(ctx, ".exit", entry_point_func_);
193 
194  const auto func_body_bb = llvm::BasicBlock::Create(
195  ctx, ".func_body", cgen_state->ir_builder_.GetInsertBlock()->getParent());
196  cgen_state->ir_builder_.SetInsertPoint(func_body_bb);
197 
198  auto col_heads = generate_column_heads_load(
199  exe_unit.input_exprs.size(), input_cols_arg, cgen_state->ir_builder_, ctx);
200  CHECK_EQ(exe_unit.input_exprs.size(), col_heads.size());
201 
202  // The column arguments of C++ UDTFs processed by clang must be
203  // passed by reference, see rbc issue 200.
204  auto pass_column_by_value = exe_unit.table_func.isRuntime();
205  std::vector<llvm::Value*> func_args;
206  for (size_t i = 0; i < exe_unit.input_exprs.size(); i++) {
207  const auto& expr = exe_unit.input_exprs[i];
208  const auto& ti = expr->get_type_info();
209  if (ti.is_fp()) {
210  auto r = cgen_state->ir_builder_.CreateBitCast(
211  col_heads[i], llvm::PointerType::get(get_fp_type(get_bit_width(ti), ctx), 0));
212  func_args.push_back(cgen_state->ir_builder_.CreateLoad(r));
213  } else if (ti.is_integer()) {
214  auto r = cgen_state->ir_builder_.CreateBitCast(
215  col_heads[i], llvm::PointerType::get(get_int_type(get_bit_width(ti), ctx), 0));
216  func_args.push_back(cgen_state->ir_builder_.CreateLoad(r));
217  } else if (ti.is_column()) {
218  auto col = alloc_column(std::string("input_col.") + std::to_string(i),
219  ti.get_elem_type(),
220  col_heads[i],
221  input_row_count,
222  ctx,
223  cgen_state_->ir_builder_,
224  pass_column_by_value);
225  func_args.push_back(col);
226  } else {
227  throw std::runtime_error(
228  "Only integer and floating point columns or scalars are supported as inputs to "
229  "table "
230  "functions, got " +
231  ti.get_type_name());
232  }
233  }
234  std::vector<llvm::Value*> output_col_args;
235  for (size_t i = 0; i < exe_unit.target_exprs.size(); i++) {
236  auto output_load = cgen_state->ir_builder_.CreateLoad(
237  cgen_state->ir_builder_.CreateGEP(output_buffers_arg, cgen_state_->llInt(i)));
238  const auto& expr = exe_unit.target_exprs[i];
239  const auto& ti = expr->get_type_info();
240  CHECK(!ti.is_column()); // UDTF output column type is its data type
241  auto col = alloc_column(std::string("output_col.") + std::to_string(i),
242  ti,
243  output_load,
244  output_row_count_ptr,
245  ctx,
246  cgen_state_->ir_builder_,
247  pass_column_by_value);
248  func_args.push_back(col);
249  }
250  auto func_name = exe_unit.table_func.getName();
251  boost::algorithm::to_lower(func_name);
252  const auto table_func_return =
253  cgen_state->emitExternalCall(func_name, get_int_type(32, ctx), func_args);
254  table_func_return->setName("table_func_ret");
255 
256  // If table_func_return is non-negative then store the value in
257  // output_row_count and return zero. Otherwise, return
258  // table_func_return that negative value contains the error code.
259  const auto bb_exit_0 = llvm::BasicBlock::Create(ctx, ".exit0", entry_point_func_);
260 
261  auto const_zero = llvm::ConstantInt::get(table_func_return->getType(), 0, true);
262  auto is_ok = cgen_state_->ir_builder_.CreateICmpSGE(table_func_return, const_zero);
263  cgen_state_->ir_builder_.CreateCondBr(is_ok, bb_exit_0, bb_exit);
264 
265  cgen_state_->ir_builder_.SetInsertPoint(bb_exit_0);
266  auto r = cgen_state->ir_builder_.CreateIntCast(
267  table_func_return, get_int_type(64, ctx), true);
268  cgen_state->ir_builder_.CreateStore(r, output_row_count_ptr);
269  cgen_state->ir_builder_.CreateRet(const_zero);
270 
271  cgen_state->ir_builder_.SetInsertPoint(bb_exit);
272  cgen_state->ir_builder_.CreateRet(table_func_return);
273 
274  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
275  cgen_state->ir_builder_.CreateBr(func_body_bb);
276 
277  /*
278  std::cout << "=================================" << std::endl;
279  entry_point_func_->print(llvm::outs());
280  std::cout << "=================================" << std::endl;
281  */
282 
284 }
std::string to_lower(const std::string &str)
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< Analyzer::Expr * > input_exprs
const table_functions::TableFunction table_func
llvm::Type * get_fp_type(const int width, llvm::LLVMContext &context)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
void verify_function_ir(const llvm::Function *func)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::Value * alloc_column(std::string col_name, const SQLTypeInfo &data_target_info, llvm::Value *data_ptr, llvm::Value *data_size, llvm::LLVMContext &ctx, llvm::IRBuilder<> &ir_builder, bool byval)
std::vector< llvm::Value * > generate_column_heads_load(const int num_columns, llvm::Value *byte_stream_arg, llvm::IRBuilder<> &ir_builder, llvm::LLVMContext &ctx)
#define CHECK(condition)
Definition: Logger.h:197
std::vector< Analyzer::Expr * > target_exprs

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void TableFunctionCompilationContext::generateGpuKernel ( )
private

Definition at line 286 of file TableFunctionCompilationContext.cpp.

References cgen_state_, CHECK, CHECK_EQ, entry_point_func_, get_int_type(), and kernel_func_.

Referenced by compile().

286  {
288  std::vector<llvm::Type*> arg_types;
289  arg_types.reserve(entry_point_func_->arg_size());
290  std::for_each(entry_point_func_->arg_begin(),
291  entry_point_func_->arg_end(),
292  [&arg_types](const auto& arg) { arg_types.push_back(arg.getType()); });
293  CHECK_EQ(arg_types.size(), entry_point_func_->arg_size());
294 
295  auto cgen_state = cgen_state_.get();
296  CHECK(cgen_state);
297  auto& ctx = cgen_state->context_;
298 
299  std::vector<llvm::Type*> wrapper_arg_types(arg_types.size() + 1);
300  wrapper_arg_types[0] = llvm::PointerType::get(get_int_type(32, ctx), 0);
301  wrapper_arg_types[1] = arg_types[0];
302 
303  for (size_t i = 1; i < arg_types.size(); ++i) {
304  wrapper_arg_types[i + 1] = arg_types[i];
305  }
306 
307  auto wrapper_ft =
308  llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), wrapper_arg_types, false);
309  kernel_func_ = llvm::Function::Create(wrapper_ft,
310  llvm::Function::ExternalLinkage,
311  "table_func_kernel",
312  cgen_state->module_);
313 
314  auto wrapper_bb_entry = llvm::BasicBlock::Create(ctx, ".entry", kernel_func_, 0);
315  llvm::IRBuilder<> b(ctx);
316  b.SetInsertPoint(wrapper_bb_entry);
317  std::vector<llvm::Value*> loaded_args = {kernel_func_->arg_begin() + 1};
318  for (size_t i = 2; i < wrapper_arg_types.size(); ++i) {
319  loaded_args.push_back(kernel_func_->arg_begin() + i);
320  }
321  auto error_lv = b.CreateCall(entry_point_func_, loaded_args);
322  b.CreateStore(error_lv, kernel_func_->arg_begin());
323  b.CreateRetVoid();
324 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

TableFunctionCompilationContext::FuncPtr TableFunctionCompilationContext::getFuncPtr ( ) const
inline

Definition at line 46 of file TableFunctionCompilationContext.h.

References func_ptr.

Referenced by TableFunctionExecutionContext::launchCpuCode().

+ Here is the caller graph for this function:

GpuCompilationContext* TableFunctionCompilationContext::getGpuCode ( ) const
inline

Definition at line 48 of file TableFunctionCompilationContext.h.

References gpu_code_.

Referenced by TableFunctionExecutionContext::launchGpuCode().

48 { return gpu_code_.get(); }
std::shared_ptr< GpuCompilationContext > gpu_code_

+ Here is the caller graph for this function:

TableFunctionCompilationContext& TableFunctionCompilationContext::operator= ( const TableFunctionCompilationContext )
delete

Member Data Documentation

std::unique_ptr<CgenState> TableFunctionCompilationContext::cgen_state_
private
llvm::Function* TableFunctionCompilationContext::entry_point_func_
private
FuncPtr TableFunctionCompilationContext::func_ptr
private

Definition at line 61 of file TableFunctionCompilationContext.h.

Referenced by finalize(), and getFuncPtr().

std::shared_ptr<GpuCompilationContext> TableFunctionCompilationContext::gpu_code_
private

Definition at line 58 of file TableFunctionCompilationContext.h.

Referenced by finalize(), and getGpuCode().

llvm::Function* TableFunctionCompilationContext::kernel_func_
private

Definition at line 60 of file TableFunctionCompilationContext.h.

Referenced by finalize(), and generateGpuKernel().

std::unique_ptr<llvm::Module> TableFunctionCompilationContext::module_
private

Definition at line 56 of file TableFunctionCompilationContext.h.

Referenced by finalize(), and TableFunctionCompilationContext().

ExecutionEngineWrapper TableFunctionCompilationContext::own_execution_engine_
private

Definition at line 57 of file TableFunctionCompilationContext.h.

Referenced by finalize().


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