OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScalarCodeGenerator Class Reference

#include <CodeGenerator.h>

+ Inheritance diagram for ScalarCodeGenerator:
+ Collaboration diagram for ScalarCodeGenerator:

Classes

struct  CompiledExpression
 

Public Types

using ColumnMap = std::unordered_map< InputColDescriptor, std::shared_ptr< Analyzer::ColumnVar >>
 

Public Member Functions

 ScalarCodeGenerator (std::unique_ptr< llvm::Module > llvm_module)
 
CompiledExpression compile (const Analyzer::Expr *expr, const bool fetch_columns, const CompilationOptions &co)
 
std::vector< void * > generateNativeCode (Executor *executor, const CompiledExpression &compiled_expression, const CompilationOptions &co)
 
CudaMgr_Namespace::CudaMgrgetCudaMgr () const
 
- Public Member Functions inherited from CodeGenerator
 CodeGenerator (Executor *executor)
 
 CodeGenerator (CgenState *cgen_state, PlanState *plan_state)
 
std::vector< llvm::Value * > codegen (const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
 
llvm::Value * codegenPerRowStringOper (const Analyzer::StringOper *string_oper, const CompilationOptions &co)
 
llvm::Value * codegenPseudoStringOper (const Analyzer::ColumnVar *, const std::vector< StringOps_Namespace::StringOpInfo > &string_op_infos, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenHoistedConstants (const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const shared::StringDictKey &dict_id)
 
llvm::Value * codegenCastBetweenIntTypes (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
 
void codegenCastBetweenIntTypesOverflowChecks (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
 
llvm::Value * posArg (const Analyzer::Expr *) const
 
llvm::Value * toBool (llvm::Value *)
 
llvm::Value * castArrayPointer (llvm::Value *ptr, const SQLTypeInfo &elem_ti)
 
llvm::Value * codegenCastBetweenTimestamps (llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
 
llvm::Value * codegenWindowPosition (const WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
 

Private Member Functions

std::vector< llvm::Value * > codegenColumn (const Analyzer::ColumnVar *, const bool fetch_column, const CompilationOptions &) override
 
ColumnMap prepare (const Analyzer::Expr *)
 
std::vector< void * > generateNativeGPUCode (Executor *executor, llvm::Function *func, llvm::Function *wrapper_func, const CompilationOptions &co)
 

Private Attributes

std::unique_ptr< llvm::Module > module_
 
ExecutionEngineWrapper execution_engine_
 
std::unique_ptr< CgenStateown_cgen_state_
 
std::unique_ptr< PlanStateown_plan_state_
 
std::unique_ptr
< CudaMgr_Namespace::CudaMgr
cuda_mgr_
 
std::shared_ptr
< GpuCompilationContext
gpu_compilation_context_
 
std::unique_ptr
< llvm::TargetMachine > 
nvptx_target_machine_
 

Additional Inherited Members

- Static Public Member Functions inherited from CodeGenerator
static llvm::ConstantInt * codegenIntConst (const Analyzer::Constant *constant, CgenState *cgen_state)
 
static std::unordered_set
< llvm::Function * > 
markDeadRuntimeFuncs (llvm::Module &module, const std::vector< llvm::Function * > &roots, const std::vector< llvm::Function * > &leaves)
 
static ExecutionEngineWrapper generateNativeCPUCode (llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
 
static std::string generatePTX (const std::string &cuda_llir, llvm::TargetMachine *nvptx_target_machine, llvm::LLVMContext &context)
 
static std::unique_ptr
< llvm::TargetMachine > 
initializeNVPTXBackend (const CudaMgr_Namespace::NvidiaDeviceArch arch)
 
static bool alwaysCloneRuntimeFunction (const llvm::Function *func)
 
static void linkModuleWithLibdevice (Executor *executor, llvm::Module &module, llvm::PassManagerBuilder &pass_manager_builder, const GPUTarget &gpu_target)
 
static std::shared_ptr
< GpuCompilationContext
generateNativeGPUCode (Executor *executor, llvm::Function *func, llvm::Function *wrapper_func, const std::unordered_set< llvm::Function * > &live_funcs, const bool is_gpu_smem_used, 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)
 
static bool prioritizeQuals (const RelAlgExecutionUnit &ra_exe_unit, std::vector< Analyzer::Expr * > &primary_quals, std::vector< Analyzer::Expr * > &deferred_quals, const PlanState::HoistedFiltersSet &hoisted_quals)
 
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck (llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
 
- Protected Member Functions inherited from CodeGenerator
Executorexecutor () const
 
- Protected Attributes inherited from CodeGenerator
CgenStatecgen_state_
 
PlanStateplan_state_
 

Detailed Description

Definition at line 680 of file CodeGenerator.h.

Member Typedef Documentation

using ScalarCodeGenerator::ColumnMap = std::unordered_map<InputColDescriptor, std::shared_ptr<Analyzer::ColumnVar>>

Definition at line 713 of file CodeGenerator.h.

Constructor & Destructor Documentation

ScalarCodeGenerator::ScalarCodeGenerator ( std::unique_ptr< llvm::Module >  llvm_module)
inline

Definition at line 683 of file CodeGenerator.h.

684  : CodeGenerator(nullptr, nullptr), module_(std::move(llvm_module)) {}
CodeGenerator(Executor *executor)
Definition: CodeGenerator.h:30
std::unique_ptr< llvm::Module > module_

Member Function Documentation

std::vector< llvm::Value * > ScalarCodeGenerator::codegenColumn ( const Analyzer::ColumnVar column,
const bool  fetch_column,
const CompilationOptions co 
)
overrideprivatevirtual

Reimplemented from CodeGenerator.

Definition at line 170 of file ScalarCodeGenerator.cpp.

References CodeGenerator::cgen_state_, CHECK_LT, PlanState::getLocalColumnId(), CodeGenerator::plan_state_, and CgenState::row_func_.

173  {
174  int arg_idx = plan_state_->getLocalColumnId(column, fetch_column);
175  CHECK_LT(static_cast<size_t>(arg_idx), cgen_state_->row_func_->arg_size());
176  llvm::Value* arg = cgen_state_->row_func_->arg_begin() + arg_idx + 1;
177  return {arg};
178 }
CgenState * cgen_state_
llvm::Function * row_func_
Definition: CgenState.h:374
int getLocalColumnId(const Analyzer::ColumnVar *col_var, const bool fetch_column)
Definition: PlanState.cpp:52
PlanState * plan_state_
#define CHECK_LT(x, y)
Definition: Logger.h:303

+ Here is the call graph for this function:

ScalarCodeGenerator::CompiledExpression ScalarCodeGenerator::compile ( const Analyzer::Expr expr,
const bool  fetch_columns,
const CompilationOptions co 
)

Definition at line 78 of file ScalarCodeGenerator.cpp.

References AUTOMATIC_IR_METADATA, CodeGenerator::cgen_state_, CHECK_EQ, CHECK_LT, CodeGenerator::codegen(), CompilationOptions::device_type, anonymous_namespace{ScalarCodeGenerator.cpp}::g_table_infos, get_int_type(), Analyzer::Expr::get_type_info(), GPU, CgenState::ir_builder_, anonymous_namespace{ScalarCodeGenerator.cpp}::llvm_type_from_sql(), module_, own_cgen_state_, own_plan_state_, CodeGenerator::plan_state_, prepare(), and CgenState::row_func_.

81  {
82  own_plan_state_ = std::make_unique<PlanState>(
83  false, std::vector<InputTableInfo>{}, PlanState::DeletedColumnsMap{}, nullptr);
85  const auto used_columns = prepare(expr);
86  std::vector<llvm::Type*> arg_types(plan_state_->global_to_local_col_ids_.size() + 1);
87  std::vector<std::shared_ptr<Analyzer::ColumnVar>> inputs(arg_types.size() - 1);
88  auto& ctx = module_->getContext();
89  for (const auto& kv : plan_state_->global_to_local_col_ids_) {
90  size_t arg_idx = kv.second;
91  CHECK_LT(arg_idx, arg_types.size());
92  const auto it = used_columns.find(kv.first);
93  const auto col_expr = it->second;
94  inputs[arg_idx] = col_expr;
95  const auto& ti = col_expr->get_type_info();
96  arg_types[arg_idx + 1] = llvm_type_from_sql(ti, ctx);
97  }
98  arg_types[0] =
99  llvm::PointerType::get(llvm_type_from_sql(expr->get_type_info(), ctx), 0);
100  auto ft = llvm::FunctionType::get(get_int_type(32, ctx), arg_types, false);
101  auto scalar_expr_func = llvm::Function::Create(
102  ft, llvm::Function::ExternalLinkage, "scalar_expr", module_.get());
103  auto bb_entry = llvm::BasicBlock::Create(ctx, ".entry", scalar_expr_func, 0);
104  own_cgen_state_ = std::make_unique<CgenState>(g_table_infos.size(), false);
105  own_cgen_state_->module_ = module_.get();
106  own_cgen_state_->row_func_ = own_cgen_state_->current_func_ = scalar_expr_func;
107  own_cgen_state_->ir_builder_.SetInsertPoint(bb_entry);
110  const auto expr_lvs = codegen(expr, fetch_columns, co);
111  CHECK_EQ(expr_lvs.size(), size_t(1));
112  cgen_state_->ir_builder_.CreateStore(expr_lvs.front(),
113  cgen_state_->row_func_->arg_begin());
114  cgen_state_->ir_builder_.CreateRet(ll_int<int32_t>(0, ctx));
116  std::vector<llvm::Type*> wrapper_arg_types(arg_types.size() + 1);
117  wrapper_arg_types[0] = llvm::PointerType::get(get_int_type(32, ctx), 0);
118  wrapper_arg_types[1] = arg_types[0];
119  for (size_t i = 1; i < arg_types.size(); ++i) {
120  wrapper_arg_types[i + 1] = llvm::PointerType::get(arg_types[i], 0);
121  }
122  auto wrapper_ft =
123  llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), wrapper_arg_types, false);
124  auto wrapper_scalar_expr_func =
125  llvm::Function::Create(wrapper_ft,
126  llvm::Function::ExternalLinkage,
127  "wrapper_scalar_expr",
128  module_.get());
129  auto wrapper_bb_entry =
130  llvm::BasicBlock::Create(ctx, ".entry", wrapper_scalar_expr_func, 0);
131  llvm::IRBuilder<> b(ctx);
132  b.SetInsertPoint(wrapper_bb_entry);
133  std::vector<llvm::Value*> loaded_args = {wrapper_scalar_expr_func->arg_begin() + 1};
134  for (size_t i = 2; i < wrapper_arg_types.size(); ++i) {
135  auto* value = wrapper_scalar_expr_func->arg_begin() + i;
136  loaded_args.push_back(
137  b.CreateLoad(value->getType()->getPointerElementType(), value));
138  }
139  auto error_lv = b.CreateCall(scalar_expr_func, loaded_args);
140  b.CreateStore(error_lv, wrapper_scalar_expr_func->arg_begin());
141  b.CreateRetVoid();
142  return {scalar_expr_func, wrapper_scalar_expr_func, inputs};
143  }
144  return {scalar_expr_func, nullptr, inputs};
145 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
llvm::Type * llvm_type_from_sql(const SQLTypeInfo &ti, llvm::LLVMContext &ctx)
std::unordered_map< shared::TableKey, const ColumnDescriptor * > DeletedColumnsMap
Definition: PlanState.h:44
std::unique_ptr< PlanState > own_plan_state_
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:374
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
ExecutorDeviceType device_type
PlanState * plan_state_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
#define CHECK_LT(x, y)
Definition: Logger.h:303
ColumnMap prepare(const Analyzer::Expr *)
std::unique_ptr< CgenState > own_cgen_state_
std::unique_ptr< llvm::Module > module_

+ Here is the call graph for this function:

std::vector< void * > ScalarCodeGenerator::generateNativeCode ( Executor executor,
const CompiledExpression compiled_expression,
const CompilationOptions co 
)

Definition at line 147 of file ScalarCodeGenerator.cpp.

References CHECK, CPU, CompilationOptions::device_type, execution_engine_, logger::FATAL, ScalarCodeGenerator::CompiledExpression::func, CodeGenerator::generateNativeCPUCode(), generateNativeGPUCode(), ExecutionEngineWrapper::get(), GPU, LOG, module_, and ScalarCodeGenerator::CompiledExpression::wrapper_func.

150  {
151  CHECK(module_ && !execution_engine_.get()) << "Invalid code generator state";
152  module_.release();
153  switch (co.device_type) {
156  generateNativeCPUCode(compiled_expression.func, {compiled_expression.func}, co);
157  return {execution_engine_->getPointerToFunction(compiled_expression.func)};
158  }
160  return generateNativeGPUCode(
161  executor, compiled_expression.func, compiled_expression.wrapper_func, co);
162  }
163  default: {
164  LOG(FATAL) << "Invalid device type";
165  return {}; // satisfy -Wreturn-type
166  }
167  }
168 }
ExecutionEngineWrapper execution_engine_
#define LOG(tag)
Definition: Logger.h:285
llvm::ExecutionEngine * get()
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
ExecutorDeviceType device_type
std::vector< void * > generateNativeGPUCode(Executor *executor, llvm::Function *func, llvm::Function *wrapper_func, const CompilationOptions &co)
#define CHECK(condition)
Definition: Logger.h:291
std::unique_ptr< llvm::Module > module_
Executor * executor() const

+ Here is the call graph for this function:

std::vector< void * > ScalarCodeGenerator::generateNativeGPUCode ( Executor executor,
llvm::Function *  func,
llvm::Function *  wrapper_func,
const CompilationOptions co 
)
private

Definition at line 180 of file ScalarCodeGenerator.cpp.

References CodeGenerator::GPUTarget::cgen_state, CodeGenerator::cgen_state_, CodeGenerator::GPUTarget::cuda_mgr, cuda_mgr_, CodeGenerator::generateNativeGPUCode(), gpu_compilation_context_, CodeGenerator::initializeNVPTXBackend(), CudaMgr_Namespace::Kepler, CodeGenerator::GPUTarget::nvptx_target_machine, nvptx_target_machine_, and CodeGenerator::GPUTarget::row_func_not_inlined.

Referenced by generateNativeCode().

184  {
185  if (!nvptx_target_machine_) {
188  }
189  if (!cuda_mgr_) {
190  cuda_mgr_ = std::make_unique<CudaMgr_Namespace::CudaMgr>(0);
191  }
192  GPUTarget gpu_target;
193  gpu_target.nvptx_target_machine = nvptx_target_machine_.get();
194  gpu_target.cuda_mgr = cuda_mgr_.get();
195  gpu_target.cgen_state = cgen_state_;
196  gpu_target.row_func_not_inlined = false;
199  func,
200  wrapper_func,
201  {func, wrapper_func},
202  /*is_gpu_smem_used=*/false,
203  co,
204  gpu_target);
205  return gpu_compilation_context_->getNativeFunctionPointers();
206 }
CgenState * cgen_state_
std::unique_ptr< llvm::TargetMachine > nvptx_target_machine_
std::shared_ptr< GpuCompilationContext > gpu_compilation_context_
std::unique_ptr< CudaMgr_Namespace::CudaMgr > cuda_mgr_
static std::shared_ptr< GpuCompilationContext > generateNativeGPUCode(Executor *executor, llvm::Function *func, llvm::Function *wrapper_func, const std::unordered_set< llvm::Function * > &live_funcs, const bool is_gpu_smem_used, const CompilationOptions &co, const GPUTarget &gpu_target)
static std::unique_ptr< llvm::TargetMachine > initializeNVPTXBackend(const CudaMgr_Namespace::NvidiaDeviceArch arch)
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

CudaMgr_Namespace::CudaMgr* ScalarCodeGenerator::getCudaMgr ( ) const
inline

Definition at line 710 of file CodeGenerator.h.

References cuda_mgr_.

710 { return cuda_mgr_.get(); }
std::unique_ptr< CudaMgr_Namespace::CudaMgr > cuda_mgr_
ScalarCodeGenerator::ColumnMap ScalarCodeGenerator::prepare ( const Analyzer::Expr expr)
private

Definition at line 62 of file ScalarCodeGenerator.cpp.

References PlanState::allocateLocalColumnIds(), and CodeGenerator::plan_state_.

Referenced by compile().

62  {
63  UsedColumnExpressions visitor;
64  const auto used_columns = visitor.visit(expr);
65  std::list<std::shared_ptr<const InputColDescriptor>> global_col_ids;
66  for (const auto& used_column : used_columns) {
67  const auto& table_key = used_column.first.getScanDesc().getTableKey();
68  global_col_ids.push_back(std::make_shared<InputColDescriptor>(
69  used_column.first.getColId(),
70  table_key.table_id,
71  table_key.db_id,
72  used_column.first.getScanDesc().getNestLevel()));
73  }
74  plan_state_->allocateLocalColumnIds(global_col_ids);
75  return used_columns;
76 }
void allocateLocalColumnIds(const std::list< std::shared_ptr< const InputColDescriptor >> &global_col_ids)
Definition: PlanState.cpp:40
PlanState * plan_state_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

std::unique_ptr<CudaMgr_Namespace::CudaMgr> ScalarCodeGenerator::cuda_mgr_
private

Definition at line 733 of file CodeGenerator.h.

Referenced by generateNativeGPUCode(), and getCudaMgr().

ExecutionEngineWrapper ScalarCodeGenerator::execution_engine_
private

Definition at line 730 of file CodeGenerator.h.

Referenced by generateNativeCode().

std::shared_ptr<GpuCompilationContext> ScalarCodeGenerator::gpu_compilation_context_
private

Definition at line 734 of file CodeGenerator.h.

Referenced by generateNativeGPUCode().

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

Definition at line 729 of file CodeGenerator.h.

Referenced by compile(), and generateNativeCode().

std::unique_ptr<llvm::TargetMachine> ScalarCodeGenerator::nvptx_target_machine_
private

Definition at line 735 of file CodeGenerator.h.

Referenced by generateNativeGPUCode().

std::unique_ptr<CgenState> ScalarCodeGenerator::own_cgen_state_
private

Definition at line 731 of file CodeGenerator.h.

Referenced by compile().

std::unique_ptr<PlanState> ScalarCodeGenerator::own_plan_state_
private

Definition at line 732 of file CodeGenerator.h.

Referenced by compile().


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