OmniSciDB  b24e664e58
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CodeGenerator Class Reference

#include <CodeGenerator.h>

+ Inheritance diagram for CodeGenerator:
+ Collaboration diagram for CodeGenerator:

Classes

struct  ArgNullcheckBBs
 
struct  ExecutorRequired
 
struct  GPUCode
 
struct  GPUTarget
 

Public Member Functions

 CodeGenerator (Executor *executor)
 
 CodeGenerator (CgenState *cgen_state, PlanState *plan_state)
 
std::vector< llvm::Value * > codegen (const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenHoistedConstants (const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const int dict_id)
 
llvm::ConstantInt * codegenIntConst (const Analyzer::Constant *constant)
 
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)
 

Static Public Member Functions

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, CgenState *cgen_state)
 
static std::unique_ptr
< llvm::TargetMachine > 
initializeNVPTXBackend ()
 
static bool alwaysCloneRuntimeFunction (const llvm::Function *func)
 
static GPUCode 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)
 
static bool prioritizeQuals (const RelAlgExecutionUnit &ra_exe_unit, std::vector< Analyzer::Expr * > &primary_quals, std::vector< Analyzer::Expr * > &deferred_quals)
 

Protected Member Functions

Executorexecutor () const
 

Protected Attributes

CgenStatecgen_state_
 
PlanStateplan_state_
 

Private Member Functions

std::vector< llvm::Value * > codegen (const Analyzer::Constant *, const EncodingType enc_type, const int dict_id, const CompilationOptions &)
 
virtual std::vector
< llvm::Value * > 
codegenColumn (const Analyzer::ColumnVar *, const bool fetch_column, const CompilationOptions &)
 
llvm::Value * codegenArith (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenUMinus (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenCmp (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenCmp (const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
 
llvm::Value * codegenIsNull (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenIsNullNumber (llvm::Value *, const SQLTypeInfo &)
 
llvm::Value * codegenLogical (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenLogical (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenCast (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenCast (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
 
llvm::Value * codegen (const Analyzer::InValues *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::InIntegerSet *expr, const CompilationOptions &co)
 
std::vector< llvm::Value * > codegen (const Analyzer::CaseExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::ExtractExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::DateaddExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::DatediffExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::DatetruncExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::CharLengthExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::KeyForStringExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::LowerExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::LikeExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::RegexpExpr *, const CompilationOptions &)
 
llvm::Value * codegenUnnest (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenArrayAt (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::CardinalityExpr *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenArrayExpr (const Analyzer::ArrayExpr *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoExpr (const Analyzer::GeoExpr *, const CompilationOptions &)
 
llvm::Value * codegenFunctionOper (const Analyzer::FunctionOper *, const CompilationOptions &)
 
llvm::Value * codegenFunctionOperWithCustomTypeHandling (const Analyzer::FunctionOperWithCustomTypeHandling *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::UOper *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenHoistedConstantsLoads (const SQLTypeInfo &type_info, const EncodingType enc_type, const int dict_id, const int16_t lit_off)
 
std::vector< llvm::Value * > codegenHoistedConstantsPlaceholders (const SQLTypeInfo &type_info, const EncodingType enc_type, const int16_t lit_off, const std::vector< llvm::Value * > &literal_loads)
 
std::vector< llvm::Value * > codegenColVar (const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
 
llvm::Value * codegenFixedLengthColVar (const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
 
llvm::Value * codegenFixedLengthColVarInWindow (const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
 
llvm::Value * codegenWindowPosition (WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
 
std::vector< llvm::Value * > codegenVariableLengthStringColVar (llvm::Value *col_byte_stream, llvm::Value *pos_arg)
 
llvm::Value * codegenRowId (const Analyzer::ColumnVar *col_var, const CompilationOptions &co)
 
llvm::Value * codgenAdjustFixedEncNull (llvm::Value *, const SQLTypeInfo &)
 
std::vector< llvm::Value * > codegenOuterJoinNullPlaceholder (const Analyzer::ColumnVar *col_var, const bool fetch_column, const CompilationOptions &co)
 
llvm::Value * codegenIntArith (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const CompilationOptions &)
 
llvm::Value * codegenFpArith (const Analyzer::BinOper *, llvm::Value *, llvm::Value *)
 
llvm::Value * codegenCastTimestampToDate (llvm::Value *ts_lv, const int dimen, const bool nullable)
 
llvm::Value * codegenCastBetweenTimestamps (llvm::Value *ts_lv, const int operand_dimen, const int target_dimen, const bool nullable)
 
llvm::Value * codegenCastFromString (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
 
llvm::Value * codegenCastToFp (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
 
llvm::Value * codegenCastFromFp (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
 
llvm::Value * codegenAdd (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &)
 
llvm::Value * codegenSub (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &)
 
void codegenSkipOverflowCheckForNull (llvm::Value *lhs_lv, llvm::Value *rhs_lv, llvm::BasicBlock *no_overflow_bb, const SQLTypeInfo &ti)
 
llvm::Value * codegenMul (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &, bool downscale=true)
 
llvm::Value * codegenDiv (llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, bool upscale=true)
 
llvm::Value * codegenDeciDiv (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenMod (llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &)
 
llvm::Value * codegenCase (const Analyzer::CaseExpr *, llvm::Type *case_llvm_type, const bool is_real_str, const CompilationOptions &)
 
llvm::Value * codegenExtractHighPrecisionTimestamps (llvm::Value *, const SQLTypeInfo &, const ExtractField &)
 
llvm::Value * codegenDateTruncHighPrecisionTimestamps (llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
 
llvm::Value * codegenCmpDecimalConst (const SQLOps, const SQLQualifier, const Analyzer::Expr *, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
 
llvm::Value * codegenOverlaps (const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
 
llvm::Value * codegenStrCmp (const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
 
llvm::Value * codegenQualifierCmp (const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const Analyzer::Expr *, const CompilationOptions &)
 
llvm::Value * codegenLogicalShortCircuit (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenDictLike (const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const bool ilike, const bool is_simple, const char escape_char, const CompilationOptions &)
 
llvm::Value * codegenDictStrCmp (const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const SQLOps, const CompilationOptions &co)
 
llvm::Value * codegenDictRegexp (const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const char escape_char, const CompilationOptions &)
 
llvm::Value * foundOuterJoinMatch (const ssize_t nesting_level) const
 
llvm::Value * resolveGroupedColumnReference (const Analyzer::ColumnVar *)
 
llvm::Value * colByteStream (const Analyzer::ColumnVar *col_var, const bool fetch_column, const bool hoist_literals)
 
std::shared_ptr< const
Analyzer::Expr
hashJoinLhs (const Analyzer::ColumnVar *rhs) const
 
std::shared_ptr< const
Analyzer::ColumnVar
hashJoinLhsTuple (const Analyzer::ColumnVar *rhs, const Analyzer::BinOper *tautological_eq) const
 
std::unique_ptr< InValuesBitmapcreateInValuesBitmap (const Analyzer::InValues *, const CompilationOptions &)
 
bool checkExpressionRanges (const Analyzer::UOper *, int64_t, int64_t)
 
bool checkExpressionRanges (const Analyzer::BinOper *, int64_t, int64_t)
 
ArgNullcheckBBs beginArgsNullcheck (const Analyzer::FunctionOper *function_oper, const std::vector< llvm::Value * > &orig_arg_lvs)
 
llvm::Value * endArgsNullcheck (const ArgNullcheckBBs &, llvm::Value *, const Analyzer::FunctionOper *)
 
llvm::Value * codegenFunctionOperNullArg (const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
 
llvm::StructType * createArrayStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenArrayArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *array_buf, llvm::Value *array_size, llvm::Value *array_is_null, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createPointStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoPointArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *point_buf, llvm::Value *point_size, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createLineStringStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoLineStringArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *line_string_buf, llvm::Value *line_string_size, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createPolygonStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoPolygonArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *polygon_buf, llvm::Value *polygon_size, llvm::Value *ring_sizes_buf, llvm::Value *num_rings, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
std::vector< llvm::Value * > codegenFunctionOperCastArgs (const Analyzer::FunctionOper *, const ExtensionFunction *, const std::vector< llvm::Value * > &, const std::unordered_map< llvm::Value *, llvm::Value * > &, const CompilationOptions &)
 
llvm::Function * getArithWithOverflowIntrinsic (const Analyzer::BinOper *bin_oper, llvm::Type *type)
 
llvm::Value * codegenBinOpWithOverflowForCPU (const Analyzer::BinOper *bin_oper, llvm::Value *lhs_lv, llvm::Value *rhs_lv, const std::string &null_check_suffix, const SQLTypeInfo &ti)
 

Private Attributes

Executorexecutor_
 

Detailed Description

Definition at line 25 of file CodeGenerator.h.

Constructor & Destructor Documentation

CodeGenerator::CodeGenerator ( Executor executor)
inline

Definition at line 27 of file CodeGenerator.h.

29  , cgen_state_(executor->cgen_state_.get())
30  , plan_state_(executor->plan_state_.get()) {}
CgenState * cgen_state_
Executor * executor_
PlanState * plan_state_
Executor * executor() const
CodeGenerator::CodeGenerator ( CgenState cgen_state,
PlanState plan_state 
)
inline

Definition at line 34 of file CodeGenerator.h.

35  : executor_(nullptr), cgen_state_(cgen_state), plan_state_(plan_state) {}
CgenState * cgen_state_
Executor * executor_
PlanState * plan_state_

Member Function Documentation

bool CodeGenerator::alwaysCloneRuntimeFunction ( const llvm::Function *  func)
static

Definition at line 913 of file NativeCodegen.cpp.

913  {
914  return func->getName() == "query_stub_hoisted_literals" ||
915  func->getName() == "multifrag_query_hoisted_literals" ||
916  func->getName() == "query_stub" || func->getName() == "multifrag_query" ||
917  func->getName() == "fixed_width_int_decode" ||
918  func->getName() == "fixed_width_unsigned_decode" ||
919  func->getName() == "diff_fixed_width_int_decode" ||
920  func->getName() == "fixed_width_double_decode" ||
921  func->getName() == "fixed_width_float_decode" ||
922  func->getName() == "fixed_width_small_date_decode" ||
923  func->getName() == "record_error_code";
924 }
CodeGenerator::ArgNullcheckBBs CodeGenerator::beginArgsNullcheck ( const Analyzer::FunctionOper function_oper,
const std::vector< llvm::Value * > &  orig_arg_lvs 
)
private

Definition at line 185 of file ExtensionsIR.cpp.

References cgen_state_, codegenFunctionOperNullArg(), CgenState::context_, anonymous_namespace{ExtensionsIR.cpp}::ext_func_call_requires_nullcheck(), CgenState::ir_builder_, and CgenState::row_func_.

Referenced by codegenFunctionOper(), and codegenFunctionOperWithCustomTypeHandling().

187  {
188  llvm::BasicBlock* args_null_bb{nullptr};
189  llvm::BasicBlock* args_notnull_bb{nullptr};
190  llvm::BasicBlock* orig_bb = cgen_state_->ir_builder_.GetInsertBlock();
191  // Only generate the check if required (at least one argument must be nullable).
192  if (ext_func_call_requires_nullcheck(function_oper)) {
193  const auto args_notnull_lv = cgen_state_->ir_builder_.CreateNot(
194  codegenFunctionOperNullArg(function_oper, orig_arg_lvs));
195  args_notnull_bb = llvm::BasicBlock::Create(
196  cgen_state_->context_, "args_notnull", cgen_state_->row_func_);
197  args_null_bb = llvm::BasicBlock::Create(
198  cgen_state_->context_, "args_null", cgen_state_->row_func_);
199  cgen_state_->ir_builder_.CreateCondBr(args_notnull_lv, args_notnull_bb, args_null_bb);
200  cgen_state_->ir_builder_.SetInsertPoint(args_notnull_bb);
201  }
202  return {args_null_bb, args_notnull_bb, orig_bb};
203 }
CgenState * cgen_state_
llvm::Value * codegenFunctionOperNullArg(const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
bool ext_func_call_requires_nullcheck(const Analyzer::FunctionOper *function_oper)
llvm::Function * row_func_
Definition: CgenState.h:265
llvm::LLVMContext & context_
Definition: CgenState.h:267

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::castArrayPointer ( llvm::Value *  ptr,
const SQLTypeInfo elem_ti 
)

Definition at line 900 of file ExtensionsIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, SQLTypeInfoCore< TYPE_FACET_PACK >::get_compression(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_size(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_boolean(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), kDOUBLE, kENCODING_DICT, and kFLOAT.

Referenced by codegenFunctionOperCastArgs().

901  {
902  if (elem_ti.get_type() == kFLOAT) {
903  return cgen_state_->ir_builder_.CreatePointerCast(
904  ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
905  }
906  if (elem_ti.get_type() == kDOUBLE) {
907  return cgen_state_->ir_builder_.CreatePointerCast(
908  ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
909  }
910  CHECK(elem_ti.is_integer() || elem_ti.is_boolean() ||
911  (elem_ti.is_string() && elem_ti.get_compression() == kENCODING_DICT));
912  switch (elem_ti.get_size()) {
913  case 1:
914  return cgen_state_->ir_builder_.CreatePointerCast(
915  ptr, llvm::Type::getInt8PtrTy(cgen_state_->context_));
916  case 2:
917  return cgen_state_->ir_builder_.CreatePointerCast(
918  ptr, llvm::Type::getInt16PtrTy(cgen_state_->context_));
919  case 4:
920  return cgen_state_->ir_builder_.CreatePointerCast(
921  ptr, llvm::Type::getInt32PtrTy(cgen_state_->context_));
922  case 8:
923  return cgen_state_->ir_builder_.CreatePointerCast(
924  ptr, llvm::Type::getInt64PtrTy(cgen_state_->context_));
925  default:
926  CHECK(false);
927  }
928  return nullptr;
929 }
bool is_boolean() const
Definition: sqltypes.h:484
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:334
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
HOST DEVICE int get_size() const
Definition: sqltypes.h:336
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
bool is_integer() const
Definition: sqltypes.h:479
bool is_string() const
Definition: sqltypes.h:477

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool CodeGenerator::checkExpressionRanges ( const Analyzer::UOper uoper,
int64_t  min,
int64_t  max 
)
private

Definition at line 616 of file ArithmeticIR.cpp.

References cgen_state_, executor(), Analyzer::Expr::get_type_info(), getExpressionRange(), Integer, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), ExpressionRange::makeInvalidRange(), and CgenState::query_infos_.

Referenced by codegenAdd(), codegenMul(), codegenSub(), and codegenUMinus().

618  {
619  if (uoper->get_type_info().is_decimal()) {
620  return false;
621  }
622 
623  auto expr_range_info =
624  cgen_state_->query_infos_.size() > 0
626  : ExpressionRange::makeInvalidRange();
627  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
628  return false;
629  }
630  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
631  return true;
632  }
633 
634  return false;
635 }
const std::vector< InputTableInfo > & query_infos_
Definition: CgenState.h:283
CgenState * cgen_state_
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
bool is_decimal() const
Definition: sqltypes.h:480
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool CodeGenerator::checkExpressionRanges ( const Analyzer::BinOper bin_oper,
int64_t  min,
int64_t  max 
)
private

Definition at line 184 of file ArithmeticIR.cpp.

References cgen_state_, executor(), Analyzer::BinOper::get_left_operand(), Analyzer::BinOper::get_right_operand(), Analyzer::Expr::get_type_info(), getExpressionRange(), Integer, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), anonymous_namespace{ArithmeticIR.cpp}::is_temporary_column(), ExpressionRange::makeInvalidRange(), and CgenState::query_infos_.

186  {
187  if (is_temporary_column(bin_oper->get_left_operand()) ||
188  is_temporary_column(bin_oper->get_right_operand())) {
189  // Computing the range for temporary columns is a lot more expensive than the overflow
190  // check.
191  return false;
192  }
193  if (bin_oper->get_type_info().is_decimal()) {
194  return false;
195  }
196 
197  auto expr_range_info =
198  cgen_state_->query_infos_.size() > 0
200  : ExpressionRange::makeInvalidRange();
201  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
202  return false;
203  }
204  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
205  return true;
206  }
207 
208  return false;
209 }
const std::vector< InputTableInfo > & query_infos_
Definition: CgenState.h:283
CgenState * cgen_state_
const Expr * get_right_operand() const
Definition: Analyzer.h:437
bool is_temporary_column(const Analyzer::Expr *expr)
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
const Expr * get_left_operand() const
Definition: Analyzer.h:436
bool is_decimal() const
Definition: sqltypes.h:480
Executor * executor() const

+ Here is the call graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegen ( const Analyzer::Expr expr,
const bool  fetch_columns,
const CompilationOptions co 
)

Definition at line 25 of file IRCodegen.cpp.

References CHECK_NE, codegenArrayExpr(), codegenColumn(), codegenFunctionOper(), codegenFunctionOperWithCustomTypeHandling(), codegenGeoExpr(), executor_, Analyzer::Expr::get_type_info(), kENCODING_DICT, kNULLT, and posArg().

Referenced by Executor::buildIsDeletedCb(), codegen(), GroupByAndAggregate::codegenAggArg(), codegenArith(), codegenArrayAt(), codegenArrayExpr(), codegenCase(), codegenCast(), codegenCmp(), codegenCmpDecimalConst(), codegenColVar(), codegenDeciDiv(), codegenDictLike(), codegenDictRegexp(), codegenDictStrCmp(), codegenFunctionOper(), codegenFunctionOperWithCustomTypeHandling(), codegenGeoExpr(), codegenIsNull(), OverlapsJoinHashTable::codegenKey(), BaselineJoinHashTable::codegenKey(), codegenLogical(), codegenLogicalShortCircuit(), codegenOuterJoinNullPlaceholder(), GroupByAndAggregate::codegenOutputSlot(), codegenQualifierCmp(), codegenRowId(), JoinHashTable::codegenSlot(), codegenUMinus(), codegenUnnest(), Executor::codegenWindowFunction(), Executor::codegenWindowFunctionAggregateCalls(), ScalarCodeGenerator::compile(), JoinHashTable::getHashJoinArgs(), and Executor::groupByColumnCodegen().

27  {
28  if (!expr) {
29  return {posArg(expr)};
30  }
31  auto bin_oper = dynamic_cast<const Analyzer::BinOper*>(expr);
32  if (bin_oper) {
33  return {codegen(bin_oper, co)};
34  }
35  auto u_oper = dynamic_cast<const Analyzer::UOper*>(expr);
36  if (u_oper) {
37  return {codegen(u_oper, co)};
38  }
39  auto col_var = dynamic_cast<const Analyzer::ColumnVar*>(expr);
40  if (col_var) {
41  return codegenColumn(col_var, fetch_columns, co);
42  }
43  auto constant = dynamic_cast<const Analyzer::Constant*>(expr);
44  if (constant) {
45  const auto& ti = constant->get_type_info();
46  if (ti.get_type() == kNULLT) {
47  throw std::runtime_error(
48  "NULL type literals are not currently supported in this context.");
49  }
50  if (constant->get_is_null()) {
51  return {ti.is_fp()
52  ? static_cast<llvm::Value*>(executor_->cgen_state_->inlineFpNull(ti))
53  : static_cast<llvm::Value*>(executor_->cgen_state_->inlineIntNull(ti))};
54  }
55  // The dictionary encoding case should be handled by the parent expression
56  // (cast, for now), here is too late to know the dictionary id
57  CHECK_NE(kENCODING_DICT, ti.get_compression());
58  return {codegen(constant, ti.get_compression(), 0, co)};
59  }
60  auto case_expr = dynamic_cast<const Analyzer::CaseExpr*>(expr);
61  if (case_expr) {
62  return {codegen(case_expr, co)};
63  }
64  auto extract_expr = dynamic_cast<const Analyzer::ExtractExpr*>(expr);
65  if (extract_expr) {
66  return {codegen(extract_expr, co)};
67  }
68  auto dateadd_expr = dynamic_cast<const Analyzer::DateaddExpr*>(expr);
69  if (dateadd_expr) {
70  return {codegen(dateadd_expr, co)};
71  }
72  auto datediff_expr = dynamic_cast<const Analyzer::DatediffExpr*>(expr);
73  if (datediff_expr) {
74  return {codegen(datediff_expr, co)};
75  }
76  auto datetrunc_expr = dynamic_cast<const Analyzer::DatetruncExpr*>(expr);
77  if (datetrunc_expr) {
78  return {codegen(datetrunc_expr, co)};
79  }
80  auto charlength_expr = dynamic_cast<const Analyzer::CharLengthExpr*>(expr);
81  if (charlength_expr) {
82  return {codegen(charlength_expr, co)};
83  }
84  auto keyforstring_expr = dynamic_cast<const Analyzer::KeyForStringExpr*>(expr);
85  if (keyforstring_expr) {
86  return {codegen(keyforstring_expr, co)};
87  }
88  auto lower_expr = dynamic_cast<const Analyzer::LowerExpr*>(expr);
89  if (lower_expr) {
90  return {codegen(lower_expr, co)};
91  }
92  auto cardinality_expr = dynamic_cast<const Analyzer::CardinalityExpr*>(expr);
93  if (cardinality_expr) {
94  return {codegen(cardinality_expr, co)};
95  }
96  auto like_expr = dynamic_cast<const Analyzer::LikeExpr*>(expr);
97  if (like_expr) {
98  return {codegen(like_expr, co)};
99  }
100  auto regexp_expr = dynamic_cast<const Analyzer::RegexpExpr*>(expr);
101  if (regexp_expr) {
102  return {codegen(regexp_expr, co)};
103  }
104  auto likelihood_expr = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
105  if (likelihood_expr) {
106  return {codegen(likelihood_expr->get_arg(), fetch_columns, co)};
107  }
108  auto in_expr = dynamic_cast<const Analyzer::InValues*>(expr);
109  if (in_expr) {
110  return {codegen(in_expr, co)};
111  }
112  auto in_integer_set_expr = dynamic_cast<const Analyzer::InIntegerSet*>(expr);
113  if (in_integer_set_expr) {
114  return {codegen(in_integer_set_expr, co)};
115  }
116  auto function_oper_with_custom_type_handling_expr =
117  dynamic_cast<const Analyzer::FunctionOperWithCustomTypeHandling*>(expr);
118  if (function_oper_with_custom_type_handling_expr) {
120  function_oper_with_custom_type_handling_expr, co)};
121  }
122  auto array_oper_expr = dynamic_cast<const Analyzer::ArrayExpr*>(expr);
123  if (array_oper_expr) {
124  return {codegenArrayExpr(array_oper_expr, co)};
125  }
126  auto geo_expr = dynamic_cast<const Analyzer::GeoExpr*>(expr);
127  if (geo_expr) {
128  return {codegenGeoExpr(geo_expr, co)};
129  }
130  auto function_oper_expr = dynamic_cast<const Analyzer::FunctionOper*>(expr);
131  if (function_oper_expr) {
132  return {codegenFunctionOper(function_oper_expr, co)};
133  }
134  if (dynamic_cast<const Analyzer::OffsetInFragment*>(expr)) {
135  return {posArg(nullptr)};
136  }
137  if (dynamic_cast<const Analyzer::WindowFunction*>(expr)) {
138  throw std::runtime_error("Window expression not supported in this context");
139  }
140  abort();
141 }
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
virtual std::vector< llvm::Value * > codegenColumn(const Analyzer::ColumnVar *, const bool fetch_column, const CompilationOptions &)
Definition: ColumnIR.cpp:92
std::vector< llvm::Value * > codegenGeoExpr(const Analyzer::GeoExpr *, const CompilationOptions &)
Definition: GeoIR.cpp:20
#define CHECK_NE(x, y)
Definition: Logger.h:199
llvm::Value * codegenFunctionOper(const Analyzer::FunctionOper *, const CompilationOptions &)
Executor * executor_
std::vector< llvm::Value * > codegenArrayExpr(const Analyzer::ArrayExpr *, const CompilationOptions &)
Definition: ArrayIR.cpp:88
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Expression class for the LOWER (lowercase) string function. The &quot;arg&quot; constructor parameter must be a...
Definition: Analyzer.h:740
llvm::Value * codegenFunctionOperWithCustomTypeHandling(const Analyzer::FunctionOperWithCustomTypeHandling *, const CompilationOptions &)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegen ( const Analyzer::Constant constant,
const EncodingType  enc_type,
const int  dict_id,
const CompilationOptions co 
)
private

Definition at line 20 of file ConstantIR.cpp.

References CgenState::addStringConstant(), Datum::boolval, cgen_state_, CHECK(), codegenHoistedConstants(), codegenIntConst(), CgenState::context_, decimal_to_int_type(), CompilationOptions::device_type_, Datum::doubleval, executor(), Datum::floatval, Analyzer::Constant::get_constval(), get_int_type(), Analyzer::Constant::get_is_null(), Analyzer::Expr::get_type_info(), CompilationOptions::hoist_literals_, inline_int_null_val(), kBIGINT, kBOOLEAN, kCHAR, kDATE, kDOUBLE, kENCODING_DICT, kFLOAT, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kSMALLINT, kTEXT, kTIME, kTIMESTAMP, kTINYINT, kVARCHAR, CgenState::llInt(), Datum::stringval, and run_benchmark_import::type.

23  {
24  if (co.hoist_literals_) {
25  std::vector<const Analyzer::Constant*> constants(
26  executor()->deviceCount(co.device_type_), constant);
27  return codegenHoistedConstants(constants, enc_type, dict_id);
28  }
29  const auto& type_info = constant->get_type_info();
30  const auto type =
31  type_info.is_decimal() ? decimal_to_int_type(type_info) : type_info.get_type();
32  switch (type) {
33  case kBOOLEAN:
34  return type_info.get_notnull() ? std::vector<llvm::Value*>{llvm::ConstantInt::get(
36  constant->get_constval().boolval)}
37  : std::vector<llvm::Value*>{llvm::ConstantInt::get(
39  constant->get_constval().boolval)};
40  case kTINYINT:
41  case kSMALLINT:
42  case kINT:
43  case kBIGINT:
44  case kTIME:
45  case kTIMESTAMP:
46  case kDATE:
47  case kINTERVAL_DAY_TIME:
49  return {codegenIntConst(constant)};
50  case kFLOAT:
51  return {llvm::ConstantFP::get(llvm::Type::getFloatTy(cgen_state_->context_),
52  constant->get_constval().floatval)};
53  case kDOUBLE:
54  return {llvm::ConstantFP::get(llvm::Type::getDoubleTy(cgen_state_->context_),
55  constant->get_constval().doubleval)};
56  case kVARCHAR:
57  case kCHAR:
58  case kTEXT: {
59  CHECK(constant->get_constval().stringval || constant->get_is_null());
60  if (constant->get_is_null()) {
61  if (enc_type == kENCODING_DICT) {
62  return {
63  cgen_state_->llInt(static_cast<int32_t>(inline_int_null_val(type_info)))};
64  }
65  return {cgen_state_->llInt(int64_t(0)),
66  llvm::Constant::getNullValue(
67  llvm::PointerType::get(get_int_type(8, cgen_state_->context_), 0)),
68  cgen_state_->llInt(int32_t(0))};
69  }
70  const auto& str_const = *constant->get_constval().stringval;
71  if (enc_type == kENCODING_DICT) {
72  return {
74  ->getStringDictionaryProxy(
75  dict_id, executor()->getRowSetMemoryOwner(), true)
76  ->getIdOfString(str_const))};
77  }
78  return {cgen_state_->llInt(int64_t(0)),
79  cgen_state_->addStringConstant(str_const),
80  cgen_state_->llInt(static_cast<int32_t>(str_const.size()))};
81  }
82  default:
83  CHECK(false);
84  }
85  abort();
86 }
Definition: sqltypes.h:52
CgenState * cgen_state_
llvm::Value * addStringConstant(const std::string &str)
Definition: CgenState.h:186
bool boolval
Definition: sqltypes.h:125
bool get_is_null() const
Definition: Analyzer.h:328
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
float floatval
Definition: sqltypes.h:130
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
std::vector< llvm::Value * > codegenHoistedConstants(const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const int dict_id)
Definition: ConstantIR.cpp:287
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
std::string * stringval
Definition: sqltypes.h:134
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:268
Definition: sqltypes.h:55
Definition: sqltypes.h:56
Datum get_constval() const
Definition: Analyzer.h:329
Definition: sqltypes.h:44
llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant)
Definition: ConstantIR.cpp:88
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
Definition: sqltypes.h:48
double doubleval
Definition: sqltypes.h:131
Executor * executor() const

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::InValues expr,
const CompilationOptions co 
)
private

Definition at line 22 of file InValuesIR.cpp.

References CgenState::addInValuesBitmap(), cgen_state_, CHECK(), CHECK_EQ, codegen(), InValuesBitmap::codegen(), codegenCmp(), CgenState::context_, createInValuesBitmap(), CgenState::emitCall(), executor(), Analyzer::InValues::get_arg(), Analyzer::Expr::get_type_info(), Analyzer::InValues::get_value_list(), CompilationOptions::hoist_literals_, CgenState::inlineIntNull(), CgenState::ir_builder_, is_unnest(), kBOOLEAN, kEQ, kONE, CgenState::llInt(), run_benchmark_import::result, and toBool().

23  {
24  const auto in_arg = expr->get_arg();
25  if (is_unnest(in_arg)) {
26  throw std::runtime_error("IN not supported for unnested expressions");
27  }
28  const auto& expr_ti = expr->get_type_info();
29  CHECK(expr_ti.is_boolean());
30  const auto lhs_lvs = codegen(in_arg, true, co);
31  llvm::Value* result{nullptr};
32  if (expr_ti.get_notnull()) {
33  result = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(cgen_state_->context_),
34  false);
35  } else {
36  result = cgen_state_->llInt(int8_t(0));
37  }
38  CHECK(result);
39  if (co.hoist_literals_) { // TODO(alex): remove this constraint
40  auto in_vals_bitmap = createInValuesBitmap(expr, co);
41  if (in_vals_bitmap) {
42  if (in_vals_bitmap->isEmpty()) {
43  return in_vals_bitmap->hasNull()
45  : result;
46  }
47  CHECK_EQ(size_t(1), lhs_lvs.size());
48  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
49  ->codegen(lhs_lvs.front(), executor());
50  }
51  }
52  if (expr_ti.get_notnull()) {
53  for (auto in_val : expr->get_value_list()) {
54  result = cgen_state_->ir_builder_.CreateOr(
55  result,
56  toBool(
57  codegenCmp(kEQ, kONE, lhs_lvs, in_arg->get_type_info(), in_val.get(), co)));
58  }
59  } else {
60  for (auto in_val : expr->get_value_list()) {
61  const auto crt =
62  codegenCmp(kEQ, kONE, lhs_lvs, in_arg->get_type_info(), in_val.get(), co);
63  result = cgen_state_->emitCall("logical_or",
64  {result, crt, cgen_state_->inlineIntNull(expr_ti)});
65  }
66  }
67  return result;
68 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
Definition: sqldefs.h:30
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:195
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:69
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:580
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:333
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
std::unique_ptr< InValuesBitmap > createInValuesBitmap(const Analyzer::InValues *, const CompilationOptions &)
Definition: InValuesIR.cpp:108
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1090
const Expr * get_arg() const
Definition: Analyzer.h:578
Executor * executor() const

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::InIntegerSet expr,
const CompilationOptions co 
)
private

Definition at line 70 of file InValuesIR.cpp.

References CgenState::addInValuesBitmap(), cgen_state_, CHECK(), CHECK_EQ, codegen(), InValuesBitmap::codegen(), CgenState::context_, Data_Namespace::CPU_LEVEL, CompilationOptions::device_type_, executor(), Analyzer::InIntegerSet::get_arg(), Analyzer::Expr::get_type_info(), Analyzer::InIntegerSet::get_value_list(), GPU, Data_Namespace::GPU_LEVEL, CompilationOptions::hoist_literals_, inline_int_null_val(), is_unnest(), CgenState::llInt(), and run_benchmark_import::result.

71  {
72  const auto in_arg = in_integer_set->get_arg();
73  if (is_unnest(in_arg)) {
74  throw std::runtime_error("IN not supported for unnested expressions");
75  }
76  const auto& ti = in_integer_set->get_arg()->get_type_info();
77  const auto needle_null_val = inline_int_null_val(ti);
78  if (!co.hoist_literals_) {
79  // We never run without literal hoisting in real world scenarios, this avoids a crash
80  // when testing.
81  throw std::runtime_error(
82  "IN subquery with many right-hand side values not supported when literal "
83  "hoisting is disabled");
84  }
85  auto in_vals_bitmap = boost::make_unique<InValuesBitmap>(
86  in_integer_set->get_value_list(),
87  needle_null_val,
90  executor()->deviceCount(co.device_type_),
91  &executor()->getCatalog()->getDataMgr());
92  const auto& in_integer_set_ti = in_integer_set->get_type_info();
93  CHECK(in_integer_set_ti.is_boolean());
94  const auto lhs_lvs = codegen(in_arg, true, co);
95  llvm::Value* result{nullptr};
96  if (in_integer_set_ti.get_notnull()) {
97  result = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(cgen_state_->context_),
98  false);
99  } else {
100  result = cgen_state_->llInt(int8_t(0));
101  }
102  CHECK(result);
103  CHECK_EQ(size_t(1), lhs_lvs.size());
104  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
105  ->codegen(lhs_lvs.front(), executor());
106 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:195
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1090
Executor * executor() const

+ Here is the call graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegen ( const Analyzer::CaseExpr case_expr,
const CompilationOptions co 
)
private

Definition at line 20 of file CaseIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegenCase(), CgenState::context_, CgenState::emitCall(), get_bit_width(), Analyzer::CaseExpr::get_else_expr(), get_int_type(), Analyzer::Expr::get_type_info(), kENCODING_DICT, and kFLOAT.

21  {
22  const auto case_ti = case_expr->get_type_info();
23  llvm::Type* case_llvm_type = nullptr;
24  bool is_real_str = false;
25  if (case_ti.is_integer() || case_ti.is_time() || case_ti.is_decimal()) {
26  case_llvm_type = get_int_type(get_bit_width(case_ti), cgen_state_->context_);
27  } else if (case_ti.is_fp()) {
28  case_llvm_type = case_ti.get_type() == kFLOAT
29  ? llvm::Type::getFloatTy(cgen_state_->context_)
30  : llvm::Type::getDoubleTy(cgen_state_->context_);
31  } else if (case_ti.is_string()) {
32  if (case_ti.get_compression() == kENCODING_DICT) {
33  case_llvm_type =
34  get_int_type(8 * case_ti.get_logical_size(), cgen_state_->context_);
35  } else {
36  is_real_str = true;
37  case_llvm_type = get_int_type(64, cgen_state_->context_);
38  }
39  } else if (case_ti.is_boolean()) {
40  case_llvm_type = get_int_type(8 * case_ti.get_logical_size(), cgen_state_->context_);
41  }
42  CHECK(case_llvm_type);
43  const auto& else_ti = case_expr->get_else_expr()->get_type_info();
44  CHECK_EQ(else_ti.get_type(), case_ti.get_type());
45  llvm::Value* case_val = codegenCase(case_expr, case_llvm_type, is_real_str, co);
46  std::vector<llvm::Value*> ret_vals{case_val};
47  if (is_real_str) {
48  ret_vals.push_back(cgen_state_->emitCall("extract_str_ptr", {case_val}));
49  ret_vals.push_back(cgen_state_->emitCall("extract_str_len", {case_val}));
50  }
51  return ret_vals;
52 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
const Expr * get_else_expr() const
Definition: Analyzer.h:1101
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
llvm::Value * codegenCase(const Analyzer::CaseExpr *, llvm::Type *case_llvm_type, const bool is_real_str, const CompilationOptions &)
Definition: CaseIR.cpp:54

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::ExtractExpr extract_expr,
const CompilationOptions co 
)
private

Definition at line 24 of file DateTimeIR.cpp.

References CHECK(), DateTimeUtils::get_extract_timestamp_precision_scale(), Analyzer::ExtractExpr::get_field(), Analyzer::ExtractExpr::get_from_expr(), get_int_type(), Analyzer::Expr::get_type_info(), DateTimeUtils::is_subsecond_extract_field(), kDATE, kEPOCH, and kTIMESTAMP.

25  {
26  auto from_expr = codegen(extract_expr->get_from_expr(), true, co).front();
27  const int32_t extract_field{extract_expr->get_field()};
28  const auto& extract_expr_ti = extract_expr->get_from_expr()->get_type_info();
29  if (extract_field == kEPOCH) {
30  CHECK(extract_expr_ti.get_type() == kTIMESTAMP ||
31  extract_expr_ti.get_type() == kDATE);
32  if (from_expr->getType()->isIntegerTy(32)) {
33  from_expr =
34  cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
35  from_expr,
37  }
38  return from_expr;
39  }
40  CHECK(from_expr->getType()->isIntegerTy(64));
41  if (extract_expr_ti.is_high_precision_timestamp()) {
43  from_expr, extract_expr_ti, extract_expr->get_field());
44  }
45  if (!extract_expr_ti.is_high_precision_timestamp() &&
46  is_subsecond_extract_field(extract_expr->get_field())) {
47  from_expr =
48  extract_expr_ti.get_notnull()
49  ? cgen_state_->ir_builder_.CreateMul(
50  from_expr,
54  "mul_int64_t_nullable_lhs",
55  {from_expr,
58  cgen_state_->inlineIntNull(extract_expr_ti)});
59  }
60  std::vector<llvm::Value*> extract_args{
61  cgen_state_->llInt(static_cast<int32_t>(extract_expr->get_field())), from_expr};
62  std::string extract_fname{"ExtractFromTime"};
63  if (!extract_expr_ti.get_notnull()) {
64  extract_args.push_back(cgen_state_->inlineIntNull(extract_expr_ti));
65  extract_fname += "Nullable";
66  }
68  extract_fname, get_int_type(64, cgen_state_->context_), extract_args);
69 }
const Expr * get_from_expr() const
Definition: Analyzer.h:1146
constexpr int64_t get_extract_timestamp_precision_scale(const ExtractField field)
Definition: DateTimeUtils.h:78
CgenState * cgen_state_
ExtractField get_field() const
Definition: Analyzer.h:1145
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Value * codegenExtractHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const ExtractField &)
Definition: DateTimeIR.cpp:155
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:56
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
constexpr bool is_subsecond_extract_field(const ExtractField &field)
Definition: DateTimeUtils.h:92

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::DateaddExpr dateadd_expr,
const CompilationOptions co 
)
private

Definition at line 71 of file DateTimeIR.cpp.

References cgen_state_, CHECK(), codegen(), CgenState::context_, CgenState::emitExternalCall(), Analyzer::DateaddExpr::get_datetime_expr(), Analyzer::DateaddExpr::get_field(), get_int_type(), Analyzer::DateaddExpr::get_number_expr(), DateTimeUtils::get_timestamp_precision_scale(), Analyzer::Expr::get_type_info(), CgenState::inlineIntNull(), kDATE, kTIMESTAMP, and CgenState::llInt().

72  {
73  const auto& dateadd_expr_ti = dateadd_expr->get_type_info();
74  CHECK(dateadd_expr_ti.get_type() == kTIMESTAMP || dateadd_expr_ti.get_type() == kDATE);
75  auto datetime = codegen(dateadd_expr->get_datetime_expr(), true, co).front();
76  CHECK(datetime->getType()->isIntegerTy(64));
77  auto number = codegen(dateadd_expr->get_number_expr(), true, co).front();
78 
79  const auto& datetime_ti = dateadd_expr->get_datetime_expr()->get_type_info();
80  std::vector<llvm::Value*> dateadd_args{
81  cgen_state_->llInt(static_cast<int32_t>(dateadd_expr->get_field())),
82  number,
83  datetime};
84  std::string dateadd_fname{"DateAdd"};
85  if (dateadd_expr_ti.is_high_precision_timestamp()) {
86  dateadd_fname += "HighPrecision";
87  dateadd_args.push_back(cgen_state_->llInt(static_cast<int64_t>(
88  get_timestamp_precision_scale(dateadd_expr_ti.get_dimension()))));
89  }
90  if (!datetime_ti.get_notnull()) {
91  dateadd_args.push_back(cgen_state_->inlineIntNull(datetime_ti));
92  dateadd_fname += "Nullable";
93  }
94  return cgen_state_->emitExternalCall(dateadd_fname,
96  dateadd_args,
97  {llvm::Attribute::NoUnwind,
98  llvm::Attribute::ReadNone,
99  llvm::Attribute::Speculatable});
100 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:56
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
const Expr * get_datetime_expr() const
Definition: Analyzer.h:1188
DateaddField get_field() const
Definition: Analyzer.h:1186
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
const Expr * get_number_expr() const
Definition: Analyzer.h:1187

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::DatediffExpr datediff_expr,
const CompilationOptions co 
)
private

Definition at line 102 of file DateTimeIR.cpp.

References cgen_state_, CHECK(), codegen(), CgenState::context_, CgenState::emitExternalCall(), Analyzer::DatediffExpr::get_end_expr(), Analyzer::DatediffExpr::get_field(), get_int_type(), Analyzer::DatediffExpr::get_start_expr(), DateTimeUtils::get_timestamp_precision_scale(), Analyzer::Expr::get_type_info(), CgenState::inlineIntNull(), and CgenState::llInt().

103  {
104  auto start = codegen(datediff_expr->get_start_expr(), true, co).front();
105  CHECK(start->getType()->isIntegerTy(64));
106  auto end = codegen(datediff_expr->get_end_expr(), true, co).front();
107  CHECK(end->getType()->isIntegerTy(32) || end->getType()->isIntegerTy(64));
108  const auto& start_ti = datediff_expr->get_start_expr()->get_type_info();
109  const auto& end_ti = datediff_expr->get_end_expr()->get_type_info();
110  std::vector<llvm::Value*> datediff_args{
111  cgen_state_->llInt(static_cast<int32_t>(datediff_expr->get_field())), start, end};
112  std::string datediff_fname{"DateDiff"};
113  if (start_ti.is_high_precision_timestamp() || end_ti.is_high_precision_timestamp()) {
114  const auto adj_dimen = end_ti.get_dimension() - start_ti.get_dimension();
115  datediff_fname += "HighPrecision";
116  datediff_args.push_back(cgen_state_->llInt(static_cast<int32_t>(adj_dimen)));
117  datediff_args.push_back(cgen_state_->llInt(
118  static_cast<int64_t>(get_timestamp_precision_scale(abs(adj_dimen)))));
119  datediff_args.push_back(
120  cgen_state_->llInt(static_cast<int64_t>(get_timestamp_precision_scale(
121  adj_dimen < 0 ? end_ti.get_dimension() : start_ti.get_dimension()))));
122  datediff_args.push_back(
123  cgen_state_->llInt(static_cast<int64_t>(get_timestamp_precision_scale(
124  adj_dimen > 0 ? end_ti.get_dimension() : start_ti.get_dimension()))));
125  }
126  const auto& ret_ti = datediff_expr->get_type_info();
127  if (!start_ti.get_notnull() || !end_ti.get_notnull()) {
128  datediff_args.push_back(cgen_state_->inlineIntNull(ret_ti));
129  datediff_fname += "Nullable";
130  }
132  datediff_fname, get_int_type(64, cgen_state_->context_), datediff_args);
133 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const Expr * get_start_expr() const
Definition: Analyzer.h:1229
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
const Expr * get_end_expr() const
Definition: Analyzer.h:1230
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
DatetruncField get_field() const
Definition: Analyzer.h:1228

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::DatetruncExpr datetrunc_expr,
const CompilationOptions co 
)
private

Definition at line 135 of file DateTimeIR.cpp.

References cgen_state_, CHECK(), codegen(), codegenDateTruncHighPrecisionTimestamps(), CgenState::context_, CgenState::emitExternalCall(), Analyzer::DatetruncExpr::get_field(), Analyzer::DatetruncExpr::get_from_expr(), get_int_type(), Analyzer::Expr::get_type_info(), CgenState::inlineIntNull(), and CgenState::llInt().

136  {
137  auto from_expr = codegen(datetrunc_expr->get_from_expr(), true, co).front();
138  const auto& datetrunc_expr_ti = datetrunc_expr->get_from_expr()->get_type_info();
139  CHECK(from_expr->getType()->isIntegerTy(64));
140  if (datetrunc_expr_ti.is_high_precision_timestamp()) {
142  from_expr, datetrunc_expr_ti, datetrunc_expr->get_field());
143  }
144  std::vector<llvm::Value*> datetrunc_args{
145  cgen_state_->llInt(static_cast<int32_t>(datetrunc_expr->get_field())), from_expr};
146  std::string datetrunc_fname{"DateTruncate"};
147  if (!datetrunc_expr_ti.get_notnull()) {
148  datetrunc_args.push_back(cgen_state_->inlineIntNull(datetrunc_expr_ti));
149  datetrunc_fname += "Nullable";
150  }
152  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
153 }
CgenState * cgen_state_
DatetruncField get_field() const
Definition: Analyzer.h:1270
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
const Expr * get_from_expr() const
Definition: Analyzer.h:1271
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
llvm::Value * codegenDateTruncHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
Definition: DateTimeIR.cpp:198

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::CharLengthExpr expr,
const CompilationOptions co 
)
private

Definition at line 65 of file StringOpsIR.cpp.

References cgen_state_, CHECK_EQ, codegen(), CgenState::emitCall(), g_enable_watchdog, and Analyzer::CharLengthExpr::get_arg().

66  {
67  auto str_lv = codegen(expr->get_arg(), true, co);
68  if (str_lv.size() != 3) {
69  CHECK_EQ(size_t(1), str_lv.size());
70  if (g_enable_watchdog) {
71  throw WatchdogException(
72  "LENGTH / CHAR_LENGTH on dictionary-encoded strings would be slow");
73  }
74  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
75  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
77  throw QueryMustRunOnCpu();
78  }
79  }
80  std::vector<llvm::Value*> charlength_args{str_lv[1], str_lv[2]};
81  std::string fn_name("char_length");
82  if (expr->get_calc_encoded_length()) {
83  fn_name += "_encoded";
84  }
85  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
86  if (is_nullable) {
87  fn_name += "_nullable";
88  charlength_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
89  }
90  return expr->get_calc_encoded_length()
92  fn_name, get_int_type(32, cgen_state_->context_), charlength_args)
93  : cgen_state_->emitCall(fn_name, charlength_args);
94 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool g_enable_watchdog
bool get_calc_encoded_length() const
Definition: Analyzer.h:652
llvm::LLVMContext & context_
Definition: CgenState.h:267
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
const Expr * get_arg() const
Definition: Analyzer.h:650

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::KeyForStringExpr expr,
const CompilationOptions co 
)
private

Definition at line 96 of file StringOpsIR.cpp.

References cgen_state_, CHECK_EQ, codegen(), CgenState::emitCall(), and Analyzer::KeyForStringExpr::get_arg().

97  {
98  auto str_lv = codegen(expr->get_arg(), true, co);
99  CHECK_EQ(size_t(1), str_lv.size());
100  return cgen_state_->emitCall("key_for_string_encoded", str_lv);
101 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const Expr * get_arg() const
Definition: Analyzer.h:699

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::LowerExpr expr,
const CompilationOptions co 
)
private

Definition at line 103 of file StringOpsIR.cpp.

References run_benchmark_import::args, cgen_state_, CHECK(), CHECK_EQ, codegen(), CgenState::context_, CompilationOptions::device_type_, CgenState::emitExternalCall(), executor(), Analyzer::LowerExpr::get_arg(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_comp_param(), get_int_type(), Analyzer::Expr::get_type_info(), GPU, and CgenState::llInt().

104  {
106  throw QueryMustRunOnCpu();
107  }
108 
109  auto str_id_lv = codegen(expr->get_arg(), true, co);
110  CHECK_EQ(size_t(1), str_id_lv.size());
111 
112  const auto string_dictionary_proxy = executor()->getStringDictionaryProxy(
113  expr->get_type_info().get_comp_param(), executor()->getRowSetMemoryOwner(), true);
114  CHECK(string_dictionary_proxy);
115 
116  std::vector<llvm::Value*> args{
117  str_id_lv[0],
118  cgen_state_->llInt(reinterpret_cast<int64_t>(string_dictionary_proxy))};
119 
121  "lower_encoded", get_int_type(32, cgen_state_->context_), args);
122 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:335
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
const Expr * get_arg() const
Definition: Analyzer.h:744
Executor * executor() const

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::LikeExpr expr,
const CompilationOptions co 
)
private

Definition at line 124 of file StringOpsIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegen(), codegenDictLike(), CgenState::emitCall(), extract_cast_arg(), g_enable_watchdog, Analyzer::LikeExpr::get_arg(), Analyzer::LikeExpr::get_escape_expr(), Analyzer::LikeExpr::get_is_ilike(), Analyzer::LikeExpr::get_is_simple(), Analyzer::LikeExpr::get_like_expr(), Analyzer::LikeExpr::get_own_arg(), Analyzer::Expr::get_type_info(), is_unnest(), and kENCODING_NONE.

125  {
126  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
127  throw std::runtime_error("LIKE not supported for unnested expressions");
128  }
129  char escape_char{'\\'};
130  if (expr->get_escape_expr()) {
131  auto escape_char_expr =
132  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
133  CHECK(escape_char_expr);
134  CHECK(escape_char_expr->get_type_info().is_string());
135  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
136  escape_char = (*escape_char_expr->get_constval().stringval)[0];
137  }
138  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_like_expr());
139  CHECK(pattern);
140  auto fast_dict_like_lv = codegenDictLike(expr->get_own_arg(),
141  pattern,
142  expr->get_is_ilike(),
143  expr->get_is_simple(),
144  escape_char,
145  co);
146  if (fast_dict_like_lv) {
147  return fast_dict_like_lv;
148  }
149  const auto& ti = expr->get_arg()->get_type_info();
150  CHECK(ti.is_string());
151  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
152  throw WatchdogException(
153  "Cannot do LIKE / ILIKE on this dictionary encoded column, its cardinality is "
154  "too high");
155  }
156  auto str_lv = codegen(expr->get_arg(), true, co);
157  if (str_lv.size() != 3) {
158  CHECK_EQ(size_t(1), str_lv.size());
159  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
160  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
162  throw QueryMustRunOnCpu();
163  }
164  }
165  auto like_expr_arg_lvs = codegen(expr->get_like_expr(), true, co);
166  CHECK_EQ(size_t(3), like_expr_arg_lvs.size());
167  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
168  std::vector<llvm::Value*> str_like_args{
169  str_lv[1], str_lv[2], like_expr_arg_lvs[1], like_expr_arg_lvs[2]};
170  std::string fn_name{expr->get_is_ilike() ? "string_ilike" : "string_like"};
171  if (expr->get_is_simple()) {
172  fn_name += "_simple";
173  } else {
174  str_like_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
175  }
176  if (is_nullable) {
177  fn_name += "_nullable";
178  str_like_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
179  }
180  return cgen_state_->emitCall(fn_name, str_like_args);
181 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
const Expr * get_escape_expr() const
Definition: Analyzer.h:857
CgenState * cgen_state_
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:152
const Expr * get_arg() const
Definition: Analyzer.h:854
bool g_enable_watchdog
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
bool get_is_simple() const
Definition: Analyzer.h:859
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const Expr * get_like_expr() const
Definition: Analyzer.h:856
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:855
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1090
bool get_is_ilike() const
Definition: Analyzer.h:858
llvm::Value * codegenDictLike(const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const bool ilike, const bool is_simple, const char escape_char, const CompilationOptions &)

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::RegexpExpr expr,
const CompilationOptions co 
)
private

Definition at line 338 of file StringOpsIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegen(), codegenDictRegexp(), CompilationOptions::device_type_, CgenState::emitCall(), extract_cast_arg(), g_enable_watchdog, Analyzer::RegexpExpr::get_arg(), Analyzer::RegexpExpr::get_escape_expr(), Analyzer::RegexpExpr::get_own_arg(), Analyzer::RegexpExpr::get_pattern_expr(), Analyzer::Expr::get_type_info(), GPU, is_unnest(), and kENCODING_NONE.

339  {
340  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
341  throw std::runtime_error("REGEXP not supported for unnested expressions");
342  }
343  char escape_char{'\\'};
344  if (expr->get_escape_expr()) {
345  auto escape_char_expr =
346  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
347  CHECK(escape_char_expr);
348  CHECK(escape_char_expr->get_type_info().is_string());
349  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
350  escape_char = (*escape_char_expr->get_constval().stringval)[0];
351  }
352  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_pattern_expr());
353  CHECK(pattern);
354  auto fast_dict_pattern_lv =
355  codegenDictRegexp(expr->get_own_arg(), pattern, escape_char, co);
356  if (fast_dict_pattern_lv) {
357  return fast_dict_pattern_lv;
358  }
359  const auto& ti = expr->get_arg()->get_type_info();
360  CHECK(ti.is_string());
361  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
362  throw WatchdogException(
363  "Cannot do REGEXP_LIKE on this dictionary encoded column, its cardinality is too "
364  "high");
365  }
366  // Now we know we are working on NONE ENCODED column. So switch back to CPU
368  throw QueryMustRunOnCpu();
369  }
370  auto str_lv = codegen(expr->get_arg(), true, co);
371  if (str_lv.size() != 3) {
372  CHECK_EQ(size_t(1), str_lv.size());
373  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
374  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
375  }
376  auto regexp_expr_arg_lvs = codegen(expr->get_pattern_expr(), true, co);
377  CHECK_EQ(size_t(3), regexp_expr_arg_lvs.size());
378  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
379  std::vector<llvm::Value*> regexp_args{
380  str_lv[1], str_lv[2], regexp_expr_arg_lvs[1], regexp_expr_arg_lvs[2]};
381  std::string fn_name("regexp_like");
382  regexp_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
383  if (is_nullable) {
384  fn_name += "_nullable";
385  regexp_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
387  fn_name, get_int_type(8, cgen_state_->context_), regexp_args);
388  }
390  fn_name, get_int_type(1, cgen_state_->context_), regexp_args);
391 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:927
CgenState * cgen_state_
const Expr * get_escape_expr() const
Definition: Analyzer.h:929
const Expr * get_arg() const
Definition: Analyzer.h:926
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:152
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool g_enable_watchdog
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
llvm::Value * codegenDictRegexp(const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const char escape_char, const CompilationOptions &)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const Expr * get_pattern_expr() const
Definition: Analyzer.h:928
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1090

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::CardinalityExpr expr,
const CompilationOptions co 
)
private

Definition at line 66 of file ArrayIR.cpp.

References cgen_state_, CHECK(), codegen(), CgenState::context_, CgenState::emitExternalCall(), Analyzer::CardinalityExpr::get_arg(), get_int_type(), Analyzer::Expr::get_type_info(), CgenState::inlineIntNull(), CgenState::llInt(), log2_bytes(), and posArg().

67  {
68  const auto arr_expr = expr->get_arg();
69  const auto& array_ti = arr_expr->get_type_info();
70  CHECK(array_ti.is_array());
71  const auto& elem_ti = array_ti.get_elem_type();
72  auto arr_lv = codegen(arr_expr, true, co);
73  std::string fn_name("array_size");
74 
75  std::vector<llvm::Value*> array_size_args{
76  arr_lv.front(),
77  posArg(arr_expr),
78  cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))};
79  const bool is_nullable{!arr_expr->get_type_info().get_notnull()};
80  if (is_nullable) {
81  fn_name += "_nullable";
82  array_size_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
83  }
85  fn_name, get_int_type(32, cgen_state_->context_), array_size_args);
86 }
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:127
const Expr * get_arg() const
Definition: Analyzer.h:800

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::BinOper bin_oper,
const CompilationOptions co 
)
private

Definition at line 143 of file IRCodegen.cpp.

References codegenArith(), codegenArrayAt(), codegenCmp(), codegenLogical(), Analyzer::BinOper::get_optype(), IS_ARITHMETIC, IS_COMPARISON, IS_LOGIC, and kARRAY_AT.

144  {
145  const auto optype = bin_oper->get_optype();
146  if (IS_ARITHMETIC(optype)) {
147  return codegenArith(bin_oper, co);
148  }
149  if (IS_COMPARISON(optype)) {
150  return codegenCmp(bin_oper, co);
151  }
152  if (IS_LOGIC(optype)) {
153  return codegenLogical(bin_oper, co);
154  }
155  if (optype == kARRAY_AT) {
156  return codegenArrayAt(bin_oper, co);
157  }
158  abort();
159 }
#define IS_LOGIC(X)
Definition: sqldefs.h:60
llvm::Value * codegenArith(const Analyzer::BinOper *, const CompilationOptions &)
llvm::Value * codegenArrayAt(const Analyzer::BinOper *, const CompilationOptions &)
Definition: ArrayIR.cpp:25
SQLOps get_optype() const
Definition: Analyzer.h:433
#define IS_ARITHMETIC(X)
Definition: sqldefs.h:61
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:289
#define IS_COMPARISON(X)
Definition: sqldefs.h:57

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegen ( const Analyzer::UOper u_oper,
const CompilationOptions co 
)
private

Definition at line 161 of file IRCodegen.cpp.

References codegenCast(), codegenIsNull(), codegenLogical(), codegenUMinus(), codegenUnnest(), Analyzer::UOper::get_optype(), kCAST, kISNULL, kNOT, kUMINUS, and kUNNEST.

162  {
163  const auto optype = u_oper->get_optype();
164  switch (optype) {
165  case kNOT: {
166  return codegenLogical(u_oper, co);
167  }
168  case kCAST: {
169  return codegenCast(u_oper, co);
170  }
171  case kUMINUS: {
172  return codegenUMinus(u_oper, co);
173  }
174  case kISNULL: {
175  return codegenIsNull(u_oper, co);
176  }
177  case kUNNEST:
178  return codegenUnnest(u_oper, co);
179  default:
180  abort();
181  }
182 }
Definition: sqldefs.h:49
llvm::Value * codegenIsNull(const Analyzer::UOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:368
llvm::Value * codegenUMinus(const Analyzer::UOper *, const CompilationOptions &)
llvm::Value * codegenUnnest(const Analyzer::UOper *, const CompilationOptions &)
Definition: ArrayIR.cpp:20
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:289
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
Definition: sqldefs.h:39
SQLOps get_optype() const
Definition: Analyzer.h:364

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegenAdd ( const Analyzer::BinOper bin_oper,
llvm::Value *  lhs_lv,
llvm::Value *  rhs_lv,
const std::string &  null_typename,
const std::string &  null_check_suffix,
const SQLTypeInfo ti,
const CompilationOptions co 
)
private

Definition at line 211 of file ArithmeticIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, checkExpressionRanges(), codegenBinOpWithOverflowForCPU(), codegenSkipOverflowCheckForNull(), CgenState::context_, CPU, CompilationOptions::device_type_, CgenState::emitCall(), Executor::ERR_OVERFLOW_OR_UNDERFLOW, SQLTypeInfoCore< TYPE_FACET_PACK >::get_size(), inline_int_null_val(), CgenState::inlineIntMaxMin(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_timeinterval(), CgenState::llInt(), CgenState::needs_error_check_, and CgenState::row_func_.

Referenced by codegenIntArith().

217  {
218  CHECK_EQ(lhs_lv->getType(), rhs_lv->getType());
219  CHECK(ti.is_integer() || ti.is_decimal() || ti.is_timeinterval());
220  llvm::Value* chosen_max{nullptr};
221  llvm::Value* chosen_min{nullptr};
222  std::tie(chosen_max, chosen_min) = cgen_state_->inlineIntMaxMin(ti.get_size(), true);
223  auto need_overflow_check =
224  !checkExpressionRanges(bin_oper,
225  static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue(),
226  static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue());
227 
228  if (need_overflow_check && co.device_type_ == ExecutorDeviceType::CPU) {
230  bin_oper, lhs_lv, rhs_lv, null_check_suffix, ti);
231  }
232 
233  llvm::BasicBlock* add_ok{nullptr};
234  llvm::BasicBlock* add_fail{nullptr};
235  if (need_overflow_check) {
237  add_ok =
238  llvm::BasicBlock::Create(cgen_state_->context_, "add_ok", cgen_state_->row_func_);
239  if (!null_check_suffix.empty()) {
240  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, add_ok, ti);
241  }
242  add_fail = llvm::BasicBlock::Create(
243  cgen_state_->context_, "add_fail", cgen_state_->row_func_);
244  llvm::Value* detected{nullptr};
245  auto const_zero = llvm::ConstantInt::get(lhs_lv->getType(), 0, true);
246  auto overflow = cgen_state_->ir_builder_.CreateAnd(
247  cgen_state_->ir_builder_.CreateICmpSGT(lhs_lv, const_zero),
248  cgen_state_->ir_builder_.CreateICmpSGT(
249  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_max, lhs_lv)));
250  auto underflow = cgen_state_->ir_builder_.CreateAnd(
251  cgen_state_->ir_builder_.CreateICmpSLT(lhs_lv, const_zero),
252  cgen_state_->ir_builder_.CreateICmpSLT(
253  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_min, lhs_lv)));
254  detected = cgen_state_->ir_builder_.CreateOr(overflow, underflow);
255  cgen_state_->ir_builder_.CreateCondBr(detected, add_fail, add_ok);
256  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
257  }
258  auto ret = null_check_suffix.empty()
259  ? cgen_state_->ir_builder_.CreateAdd(lhs_lv, rhs_lv)
261  "add_" + null_typename + null_check_suffix,
262  {lhs_lv, rhs_lv, cgen_state_->llInt(inline_int_null_val(ti))});
263  if (need_overflow_check) {
264  cgen_state_->ir_builder_.SetInsertPoint(add_fail);
265  cgen_state_->ir_builder_.CreateRet(
267  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
268  }
269  return ret;
270 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
HOST DEVICE int get_size() const
Definition: sqltypes.h:336
llvm::Function * row_func_
Definition: CgenState.h:265
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
void codegenSkipOverflowCheckForNull(llvm::Value *lhs_lv, llvm::Value *rhs_lv, llvm::BasicBlock *no_overflow_bb, const SQLTypeInfo &ti)
llvm::Value * codegenBinOpWithOverflowForCPU(const Analyzer::BinOper *bin_oper, llvm::Value *lhs_lv, llvm::Value *rhs_lv, const std::string &null_check_suffix, const SQLTypeInfo &ti)
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1039
bool needs_error_check_
Definition: CgenState.h:284
ExecutorDeviceType device_type_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
bool is_integer() const
Definition: sqltypes.h:479
bool is_timeinterval() const
Definition: sqltypes.h:488
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_decimal() const
Definition: sqltypes.h:480
bool checkExpressionRanges(const Analyzer::UOper *, int64_t, int64_t)
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenArith ( const Analyzer::BinOper bin_oper,
const CompilationOptions co 
)
private

Definition at line 36 of file ArithmeticIR.cpp.

References CHECK(), CHECK_EQ, codegen(), codegenCastBetweenIntTypes(), codegenDeciDiv(), codegenFpArith(), codegenIntArith(), Analyzer::BinOper::get_left_operand(), Analyzer::BinOper::get_optype(), Analyzer::BinOper::get_right_operand(), Analyzer::Expr::get_type_info(), IS_ARITHMETIC, and kDIVIDE.

Referenced by codegen().

37  {
38  const auto optype = bin_oper->get_optype();
39  CHECK(IS_ARITHMETIC(optype));
40  const auto lhs = bin_oper->get_left_operand();
41  const auto rhs = bin_oper->get_right_operand();
42  const auto& lhs_type = lhs->get_type_info();
43  const auto& rhs_type = rhs->get_type_info();
44 
45  if (lhs_type.is_decimal() && rhs_type.is_decimal() && optype == kDIVIDE) {
46  const auto ret = codegenDeciDiv(bin_oper, co);
47  if (ret) {
48  return ret;
49  }
50  }
51 
52  auto lhs_lv = codegen(lhs, true, co).front();
53  auto rhs_lv = codegen(rhs, true, co).front();
54  // Handle operations when a time interval operand is involved, an operation
55  // between an integer and a time interval isn't normalized by the analyzer.
56  if (lhs_type.is_timeinterval()) {
57  rhs_lv = codegenCastBetweenIntTypes(rhs_lv, rhs_type, lhs_type);
58  } else if (rhs_type.is_timeinterval()) {
59  lhs_lv = codegenCastBetweenIntTypes(lhs_lv, lhs_type, rhs_type);
60  } else {
61  CHECK_EQ(lhs_type.get_type(), rhs_type.get_type());
62  }
63  if (lhs_type.is_integer() || lhs_type.is_decimal() || lhs_type.is_timeinterval()) {
64  return codegenIntArith(bin_oper, lhs_lv, rhs_lv, co);
65  }
66  if (lhs_type.is_fp()) {
67  return codegenFpArith(bin_oper, lhs_lv, rhs_lv);
68  }
69  CHECK(false);
70  return nullptr;
71 }
llvm::Value * codegenIntArith(const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const CompilationOptions &)
#define CHECK_EQ(x, y)
Definition: Logger.h:198
const Expr * get_right_operand() const
Definition: Analyzer.h:437
llvm::Value * codegenDeciDiv(const Analyzer::BinOper *, const CompilationOptions &)
llvm::Value * codegenFpArith(const Analyzer::BinOper *, llvm::Value *, llvm::Value *)
SQLOps get_optype() const
Definition: Analyzer.h:433
CHECK(cgen_state)
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:228
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
#define IS_ARITHMETIC(X)
Definition: sqldefs.h:61
const Expr * get_left_operand() const
Definition: Analyzer.h:436

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void CodeGenerator::codegenArrayArgs ( const std::string &  udf_func_name,
size_t  param_num,
llvm::Value *  array_buf,
llvm::Value *  array_size,
llvm::Value *  array_is_null,
std::vector< llvm::Value * > &  output_args 
)
private

Definition at line 364 of file ExtensionsIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, createArrayStructType(), and CgenState::ir_builder_.

Referenced by codegenFunctionOperCastArgs().

369  {
370  CHECK(array_buf);
371  CHECK(array_size);
372  CHECK(array_null);
373 
374  auto array_abstraction = createArrayStructType(udf_func_name, param_num);
375  auto alloc_mem = cgen_state_->ir_builder_.CreateAlloca(array_abstraction, nullptr);
376 
377  auto array_buf_ptr =
378  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 0);
379  cgen_state_->ir_builder_.CreateStore(array_buf, array_buf_ptr);
380 
381  auto array_size_ptr =
382  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 1);
383  cgen_state_->ir_builder_.CreateStore(array_size, array_size_ptr);
384 
385  auto bool_extended_type = llvm::Type::getInt8Ty(cgen_state_->context_);
386  auto array_null_extended =
387  cgen_state_->ir_builder_.CreateZExt(array_null, bool_extended_type);
388  auto array_is_null_ptr =
389  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 2);
390  cgen_state_->ir_builder_.CreateStore(array_null_extended, array_is_null_ptr);
391  output_args.push_back(alloc_mem);
392 }
CgenState * cgen_state_
llvm::StructType * createArrayStructType(const std::string &udf_func_name, size_t param_num)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenArrayAt ( const Analyzer::BinOper array_at,
const CompilationOptions co 
)
private

Definition at line 25 of file ArrayIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegen(), CgenState::context_, CgenState::emitExternalCall(), get_int_type(), Analyzer::BinOper::get_left_operand(), Analyzer::BinOper::get_right_operand(), Analyzer::Expr::get_type_info(), CgenState::inlineFpNull(), CgenState::inlineIntNull(), CgenState::ir_builder_, kDOUBLE, posArg(), and to_string().

Referenced by codegen().

26  {
27  const auto arr_expr = array_at->get_left_operand();
28  const auto idx_expr = array_at->get_right_operand();
29  const auto& idx_ti = idx_expr->get_type_info();
30  CHECK(idx_ti.is_integer());
31  auto idx_lvs = codegen(idx_expr, true, co);
32  CHECK_EQ(size_t(1), idx_lvs.size());
33  auto idx_lv = idx_lvs.front();
34  if (idx_ti.get_logical_size() < 8) {
35  idx_lv = cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
36  idx_lv,
38  }
39  const auto& array_ti = arr_expr->get_type_info();
40  CHECK(array_ti.is_array());
41  const auto& elem_ti = array_ti.get_elem_type();
42  const std::string array_at_fname{
43  elem_ti.is_fp()
44  ? "array_at_" + std::string(elem_ti.get_type() == kDOUBLE ? "double_checked"
45  : "float_checked")
46  : "array_at_int" + std::to_string(elem_ti.get_logical_size() * 8) +
47  "_t_checked"};
48  const auto ret_ty =
49  elem_ti.is_fp()
50  ? (elem_ti.get_type() == kDOUBLE
51  ? llvm::Type::getDoubleTy(cgen_state_->context_)
52  : llvm::Type::getFloatTy(cgen_state_->context_))
53  : get_int_type(elem_ti.get_logical_size() * 8, cgen_state_->context_);
54  const auto arr_lvs = codegen(arr_expr, true, co);
55  CHECK_EQ(size_t(1), arr_lvs.size());
57  array_at_fname,
58  ret_ty,
59  {arr_lvs.front(),
60  posArg(arr_expr),
61  idx_lv,
62  elem_ti.is_fp() ? static_cast<llvm::Value*>(cgen_state_->inlineFpNull(elem_ti))
63  : static_cast<llvm::Value*>(cgen_state_->inlineIntNull(elem_ti))});
64 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
const Expr * get_right_operand() const
Definition: Analyzer.h:437
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
const Expr * get_left_operand() const
Definition: Analyzer.h:436
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:62

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegenArrayExpr ( const Analyzer::ArrayExpr array_expr,
const CompilationOptions co 
)
private

Definition at line 88 of file ArrayIR.cpp.

References cgen_state_, codegen(), CgenState::context_, CompilationOptions::device_type_, CgenState::emitExternalCall(), executor(), get_int_array_type(), get_int_type(), Analyzer::Expr::get_type_info(), Analyzer::ArrayExpr::getElement(), Analyzer::ArrayExpr::getElementCount(), GPU, CgenState::ir_builder_, Analyzer::ArrayExpr::isLocalAlloc(), and CgenState::llInt().

Referenced by codegen().

90  {
91  using ValueVector = std::vector<llvm::Value*>;
92  ValueVector argument_list;
93  auto& ir_builder(cgen_state_->ir_builder_);
94 
95  const auto& return_type = array_expr->get_type_info();
96  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
97  const auto arg = array_expr->getElement(i);
98  const auto arg_lvs = codegen(arg, true, co);
99  if (arg_lvs.size() == 1) {
100  argument_list.push_back(arg_lvs.front());
101  } else {
102  throw std::runtime_error(
103  "Unexpected argument count during array[] code generation.");
104  }
105  }
106 
107  auto array_element_size_bytes =
108  return_type.get_elem_type().get_array_context_logical_size();
109  auto* array_index_type =
110  get_int_type(array_element_size_bytes * 8, cgen_state_->context_);
111  auto* array_type = get_int_array_type(
112  array_element_size_bytes * 8, array_expr->getElementCount(), cgen_state_->context_);
113 
114  llvm::Value* allocated_target_buffer;
115  if (array_expr->isLocalAlloc()) {
116  allocated_target_buffer = ir_builder.CreateAlloca(array_type);
117  } else {
119  throw QueryMustRunOnCpu();
120  }
121 
122  allocated_target_buffer =
123  cgen_state_->emitExternalCall("allocate_varlen_buffer",
124  llvm::Type::getInt8PtrTy(cgen_state_->context_),
125  {cgen_state_->llInt(array_expr->getElementCount()),
126  cgen_state_->llInt(array_element_size_bytes)});
128  "register_buffer_with_executor_rsm",
129  llvm::Type::getVoidTy(cgen_state_->context_),
130  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
131  allocated_target_buffer});
132  }
133  llvm::Value* casted_allocated_target_buffer =
134  ir_builder.CreatePointerCast(allocated_target_buffer, array_type->getPointerTo());
135 
136  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
137  auto* element = argument_list[i];
138  auto* element_ptr = ir_builder.CreateGEP(
139  array_type,
140  casted_allocated_target_buffer,
141  std::vector<llvm::Value*>{cgen_state_->llInt(0), cgen_state_->llInt(i)});
142 
144  kSMALLINT,
145  kINT,
146  kBIGINT,
147  kTIMESTAMP,
148  kDATE,
149  kTIME,
150  kNUMERIC,
151  kDECIMAL,
154  kVARCHAR,
155  kTEXT,
156  kCHAR>(return_type.get_elem_type())) {
157  auto sign_extended_element = ir_builder.CreateSExt(element, array_index_type);
158  ir_builder.CreateStore(sign_extended_element, element_ptr);
159  } else if (is_member_of_typeset<kBOOLEAN>(return_type.get_elem_type())) {
160  auto byte_casted_bit = ir_builder.CreateIntCast(element, array_index_type, true);
161  ir_builder.CreateStore(byte_casted_bit, element_ptr);
162  } else if (is_member_of_typeset<kFLOAT>(return_type.get_elem_type())) {
163  auto float_element_ptr = ir_builder.CreatePointerCast(
164  element_ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
165  ir_builder.CreateStore(element, float_element_ptr);
166  } else if (is_member_of_typeset<kDOUBLE>(return_type.get_elem_type())) {
167  auto double_element_ptr = ir_builder.CreatePointerCast(
168  element_ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
169  ir_builder.CreateStore(element, double_element_ptr);
170  } else {
171  throw std::runtime_error("Unsupported type used in ARRAY construction.");
172  }
173  }
174 
175  return {ir_builder.CreateGEP(
176  array_type, casted_allocated_target_buffer, cgen_state_->llInt(0)),
177  cgen_state_->llInt(array_expr->getElementCount())};
178 }
Definition: sqltypes.h:52
CgenState * cgen_state_
bool is_member_of_typeset(SQL_INFO_TYPE const &s)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type_
size_t getElementCount() const
Definition: Analyzer.h:1437
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:55
Definition: sqltypes.h:56
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
bool isLocalAlloc() const
Definition: Analyzer.h:1439
Definition: sqltypes.h:44
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
Definition: sqltypes.h:48
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
const Analyzer::Expr * getElement(const size_t i) const
Definition: Analyzer.h:1441
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenBinOpWithOverflowForCPU ( const Analyzer::BinOper bin_oper,
llvm::Value *  lhs_lv,
llvm::Value *  rhs_lv,
const std::string &  null_check_suffix,
const SQLTypeInfo ti 
)
private

Definition at line 710 of file ArithmeticIR.cpp.

References cgen_state_, codegenSkipOverflowCheckForNull(), CgenState::context_, Executor::ERR_OVERFLOW_OR_UNDERFLOW, getArithWithOverflowIntrinsic(), inline_int_null_val(), CgenState::ir_builder_, CgenState::llInt(), CgenState::needs_error_check_, and CgenState::row_func_.

Referenced by codegenAdd(), codegenMul(), and codegenSub().

715  {
717 
718  llvm::BasicBlock* check_ok =
719  llvm::BasicBlock::Create(cgen_state_->context_, "ovf_ok", cgen_state_->row_func_);
720  llvm::BasicBlock* check_fail = llvm::BasicBlock::Create(
721  cgen_state_->context_, "ovf_detected", cgen_state_->row_func_);
722  llvm::BasicBlock* null_check{nullptr};
723 
724  if (!null_check_suffix.empty()) {
725  null_check = cgen_state_->ir_builder_.GetInsertBlock();
726  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, check_ok, ti);
727  }
728 
729  // Compute result and overflow flag
730  auto func = getArithWithOverflowIntrinsic(bin_oper, lhs_lv->getType());
731  auto ret_and_overflow = cgen_state_->ir_builder_.CreateCall(
732  func, std::vector<llvm::Value*>{lhs_lv, rhs_lv});
733  auto ret = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
734  std::vector<unsigned>{0});
735  auto overflow = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
736  std::vector<unsigned>{1});
737  auto val_bb = cgen_state_->ir_builder_.GetInsertBlock();
738 
739  // Return error on overflow
740  cgen_state_->ir_builder_.CreateCondBr(overflow, check_fail, check_ok);
741  cgen_state_->ir_builder_.SetInsertPoint(check_fail);
742  cgen_state_->ir_builder_.CreateRet(
744 
745  cgen_state_->ir_builder_.SetInsertPoint(check_ok);
746 
747  // In case of null check we have to use NULL result on check fail
748  if (null_check) {
749  auto phi = cgen_state_->ir_builder_.CreatePHI(ret->getType(), 2);
750  phi->addIncoming(llvm::ConstantInt::get(ret->getType(), inline_int_null_val(ti)),
751  null_check);
752  phi->addIncoming(ret, val_bb);
753  ret = phi;
754  }
755 
756  return ret;
757 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Function * row_func_
Definition: CgenState.h:265
llvm::LLVMContext & context_
Definition: CgenState.h:267
void codegenSkipOverflowCheckForNull(llvm::Value *lhs_lv, llvm::Value *rhs_lv, llvm::BasicBlock *no_overflow_bb, const SQLTypeInfo &ti)
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1039
bool needs_error_check_
Definition: CgenState.h:284
llvm::Function * getArithWithOverflowIntrinsic(const Analyzer::BinOper *bin_oper, llvm::Type *type)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCase ( const Analyzer::CaseExpr case_expr,
llvm::Type case_llvm_type,
const bool  is_real_str,
const CompilationOptions co 
)
private

Definition at line 54 of file CaseIR.cpp.

References cgen_state_, CHECK_EQ, codegen(), CgenState::context_, CgenState::emitCall(), Analyzer::CaseExpr::get_expr_pair_list(), CgenState::ir_builder_, CgenState::row_func_, and toBool().

Referenced by codegen().

57  {
58  // Here the linear control flow will diverge and expressions cached during the
59  // code branch code generation (currently just column decoding) are not going
60  // to be available once we're done generating the case. Take a snapshot of
61  // the cache with FetchCacheAnchor and restore it once we're done with CASE.
63  const auto& expr_pair_list = case_expr->get_expr_pair_list();
64  std::vector<llvm::Value*> then_lvs;
65  std::vector<llvm::BasicBlock*> then_bbs;
66  const auto end_bb =
67  llvm::BasicBlock::Create(cgen_state_->context_, "end_case", cgen_state_->row_func_);
68  for (const auto& expr_pair : expr_pair_list) {
70  const auto when_lv = toBool(codegen(expr_pair.first.get(), true, co).front());
71  const auto cmp_bb = cgen_state_->ir_builder_.GetInsertBlock();
72  const auto then_bb = llvm::BasicBlock::Create(
73  cgen_state_->context_, "then_case", cgen_state_->row_func_);
74  cgen_state_->ir_builder_.SetInsertPoint(then_bb);
75  auto then_bb_lvs = codegen(expr_pair.second.get(), true, co);
76  if (is_real_str) {
77  if (then_bb_lvs.size() == 3) {
78  then_lvs.push_back(
79  cgen_state_->emitCall("string_pack", {then_bb_lvs[1], then_bb_lvs[2]}));
80  } else {
81  then_lvs.push_back(then_bb_lvs.front());
82  }
83  } else {
84  CHECK_EQ(size_t(1), then_bb_lvs.size());
85  then_lvs.push_back(then_bb_lvs.front());
86  }
87  then_bbs.push_back(cgen_state_->ir_builder_.GetInsertBlock());
88  cgen_state_->ir_builder_.CreateBr(end_bb);
89  const auto when_bb = llvm::BasicBlock::Create(
90  cgen_state_->context_, "when_case", cgen_state_->row_func_);
91  cgen_state_->ir_builder_.SetInsertPoint(cmp_bb);
92  cgen_state_->ir_builder_.CreateCondBr(when_lv, then_bb, when_bb);
93  cgen_state_->ir_builder_.SetInsertPoint(when_bb);
94  }
95  const auto else_expr = case_expr->get_else_expr();
96  CHECK(else_expr);
97  auto else_lvs = codegen(else_expr, true, co);
98  llvm::Value* else_lv{nullptr};
99  if (else_lvs.size() == 3) {
100  else_lv = cgen_state_->emitCall("string_pack", {else_lvs[1], else_lvs[2]});
101  } else {
102  else_lv = else_lvs.front();
103  }
104  CHECK(else_lv);
105  auto else_bb = cgen_state_->ir_builder_.GetInsertBlock();
106  cgen_state_->ir_builder_.CreateBr(end_bb);
107  cgen_state_->ir_builder_.SetInsertPoint(end_bb);
108  auto then_phi =
109  cgen_state_->ir_builder_.CreatePHI(case_llvm_type, expr_pair_list.size() + 1);
110  CHECK_EQ(then_bbs.size(), then_lvs.size());
111  for (size_t i = 0; i < then_bbs.size(); ++i) {
112  then_phi->addIncoming(then_lvs[i], then_bbs[i]);
113  }
114  then_phi->addIncoming(else_lv, else_bb);
115  return then_phi;
116 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
const Expr * get_else_expr() const
Definition: Analyzer.h:1101
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Function * row_func_
Definition: CgenState.h:265
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:333
const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr > > > & get_expr_pair_list() const
Definition: Analyzer.h:1098

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCast ( const Analyzer::UOper uoper,
const CompilationOptions co 
)
private

Definition at line 20 of file CastIR.cpp.

References cgen_state_, CHECK_EQ, codegen(), CgenState::emitCall(), Analyzer::UOper::get_operand(), Analyzer::UOper::get_optype(), Analyzer::Expr::get_type_info(), and kCAST.

Referenced by codegen(), codegenCmpDecimalConst(), codegenFunctionOper(), and codegenFunctionOperWithCustomTypeHandling().

21  {
22  CHECK_EQ(uoper->get_optype(), kCAST);
23  const auto& ti = uoper->get_type_info();
24  const auto operand = uoper->get_operand();
25  const auto operand_as_const = dynamic_cast<const Analyzer::Constant*>(operand);
26  // For dictionary encoded constants, the cast holds the dictionary id
27  // information as the compression parameter; handle this case separately.
28  llvm::Value* operand_lv{nullptr};
29  if (operand_as_const) {
30  const auto operand_lvs =
31  codegen(operand_as_const, ti.get_compression(), ti.get_comp_param(), co);
32  if (operand_lvs.size() == 3) {
33  operand_lv = cgen_state_->emitCall("string_pack", {operand_lvs[1], operand_lvs[2]});
34  } else {
35  operand_lv = operand_lvs.front();
36  }
37  } else {
38  operand_lv = codegen(operand, true, co).front();
39  }
40  const auto& operand_ti = operand->get_type_info();
41  return codegenCast(operand_lv, operand_ti, ti, operand_as_const, co);
42 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
CgenState * cgen_state_
Definition: sqldefs.h:49
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const Expr * get_operand() const
Definition: Analyzer.h:365
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
SQLOps get_optype() const
Definition: Analyzer.h:364

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCast ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti,
const bool  operand_is_const,
const CompilationOptions co 
)
private

Definition at line 53 of file CastIR.cpp.

References anonymous_namespace{CastIR.cpp}::byte_array_cast(), CgenState::castToTypeIn(), cgen_state_, CHECK(), codegenCastBetweenIntTypes(), codegenCastBetweenTimestamps(), codegenCastFromFp(), codegenCastFromString(), codegenCastTimestampToDate(), codegenCastToFp(), CgenState::context_, SQLTypeInfoCore< TYPE_FACET_PACK >::get_dimension(), get_int_array_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_size(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_boolean(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_time(), kDATE, and kTIMESTAMP.

57  {
58  if (byte_array_cast(operand_ti, ti)) {
59  auto* byte_array_type = get_int_array_type(8, ti.get_size(), cgen_state_->context_);
60  return cgen_state_->ir_builder_.CreatePointerCast(operand_lv,
61  byte_array_type->getPointerTo());
62  }
63  if (operand_lv->getType()->isIntegerTy()) {
64  if (operand_ti.is_string()) {
65  return codegenCastFromString(operand_lv, operand_ti, ti, operand_is_const, co);
66  }
67  CHECK(operand_ti.is_integer() || operand_ti.is_decimal() || operand_ti.is_time() ||
68  operand_ti.is_boolean());
69  if (operand_ti.is_boolean()) {
70  CHECK(operand_lv->getType()->isIntegerTy(1) ||
71  operand_lv->getType()->isIntegerTy(8));
72  if (operand_lv->getType()->isIntegerTy(1)) {
73  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
74  }
75  }
76  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
77  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
78  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
79  // whereas this cast returns a date. The underlying type for both is still the same,
80  // but it still doesn't look like a good idea to misuse DatetruncExpr.
81  // Date will have default precision of day, but TIMESTAMP dimension would
82  // matter but while converting date through seconds
84  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
85  }
86  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
87  ti.get_type() == kTIMESTAMP) {
88  const auto operand_dimen =
89  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
90  if (operand_dimen != ti.get_dimension()) {
92  operand_lv, operand_dimen, ti.get_dimension(), !ti.get_notnull());
93  }
94  }
95  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
96  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
97  } else {
98  return codegenCastToFp(operand_lv, operand_ti, ti);
99  }
100  } else {
101  return codegenCastFromFp(operand_lv, operand_ti, ti);
102  }
103  CHECK(false);
104  return nullptr;
105 }
bool is_boolean() const
Definition: sqltypes.h:484
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:103
llvm::Value * codegenCastFromFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:388
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:357
HOST DEVICE int get_size() const
Definition: sqltypes.h:336
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:46
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
bool is_time() const
Definition: sqltypes.h:483
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:228
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:107
Definition: sqltypes.h:56
bool is_integer() const
Definition: sqltypes.h:479
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:328
bool is_string() const
Definition: sqltypes.h:477
llvm::Value * codegenCastFromString(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
Definition: CastIR.cpp:164
bool is_decimal() const
Definition: sqltypes.h:480
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const int operand_dimen, const int target_dimen, const bool nullable)
Definition: CastIR.cpp:136

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegenCastBetweenIntTypes ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti,
bool  upscale = true 
)

Definition at line 228 of file CastIR.cpp.

References cgen_state_, CHECK(), codegenCastBetweenIntTypesOverflowChecks(), CgenState::context_, CgenState::emitCall(), exp_to_scale(), get_bit_width(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_logical_size(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_scale(), inline_int_null_val(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), kBIGINT, CgenState::llInt(), and numeric_type_name().

Referenced by codegenArith(), codegenCast(), codegenDeciDiv(), and Executor::codegenWindowFunctionAggregateCalls().

231  {
232  if (ti.is_decimal() &&
233  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
234  if (upscale) {
235  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
236  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
237  const auto scale_lv =
238  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
239  operand_lv = cgen_state_->ir_builder_.CreateSExt(
240  operand_lv, get_int_type(64, cgen_state_->context_));
241 
242  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
243 
244  if (operand_ti.get_notnull()) {
245  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
246  } else {
247  operand_lv = cgen_state_->emitCall(
248  "scale_decimal_up",
249  {operand_lv,
250  scale_lv,
251  cgen_state_->llInt(inline_int_null_val(operand_ti)),
253  }
254  }
255  }
256  } else if (operand_ti.is_decimal()) {
257  // rounded scale down
258  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
259  const auto scale_lv =
260  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
261 
262  const auto operand_width =
263  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
264 
265  std::string method_name = "scale_decimal_down_nullable";
266  if (operand_ti.get_notnull()) {
267  method_name = "scale_decimal_down_not_nullable";
268  }
269 
270  CHECK(operand_width == 64);
271  operand_lv = cgen_state_->emitCall(
272  method_name,
273  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
274  }
275  if (ti.is_integer() && operand_ti.is_integer() &&
276  operand_ti.get_logical_size() > ti.get_logical_size()) {
277  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
278  }
279 
280  const auto operand_width =
281  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
282  const auto target_width = get_bit_width(ti);
283  if (target_width == operand_width) {
284  return operand_lv;
285  }
286  if (operand_ti.get_notnull()) {
287  return cgen_state_->ir_builder_.CreateCast(
288  target_width > operand_width ? llvm::Instruction::CastOps::SExt
289  : llvm::Instruction::CastOps::Trunc,
290  operand_lv,
291  get_int_type(target_width, cgen_state_->context_));
292  }
293  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
294  numeric_type_name(ti) + "_nullable",
295  {operand_lv,
296  cgen_state_->inlineIntNull(operand_ti),
297  cgen_state_->inlineIntNull(ti)});
298 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
HOST DEVICE int get_scale() const
Definition: sqltypes.h:331
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
int get_logical_size() const
Definition: sqltypes.h:337
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
bool is_integer() const
Definition: sqltypes.h:479
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:300
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
uint64_t exp_to_scale(const unsigned exp)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:160
bool is_decimal() const
Definition: sqltypes.h:480

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void CodeGenerator::codegenCastBetweenIntTypesOverflowChecks ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti,
const int64_t  scale 
)

Definition at line 300 of file CastIR.cpp.

References cgen_state_, CgenState::context_, CgenState::emitCall(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_logical_size(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), inline_int_null_val(), CgenState::inlineIntMaxMin(), CgenState::inlineIntNull(), CgenState::ir_builder_, kBOOLEAN, CgenState::llInt(), CgenState::needs_error_check_, numeric_type_name(), CgenState::row_func_, and toBool().

Referenced by codegenCastBetweenIntTypes().

304  {
305  llvm::Value* chosen_max{nullptr};
306  llvm::Value* chosen_min{nullptr};
307  std::tie(chosen_max, chosen_min) =
309 
311  auto cast_ok =
312  llvm::BasicBlock::Create(cgen_state_->context_, "cast_ok", cgen_state_->row_func_);
313  auto cast_fail = llvm::BasicBlock::Create(
314  cgen_state_->context_, "cast_fail", cgen_state_->row_func_);
315  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
316  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
317  const auto ti_llvm_type =
319  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
320  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
321  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
322  if (is_narrowing) {
323  const auto operand_ti_llvm_type =
325  operand_max_lv =
326  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
327  operand_min_lv =
328  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
329  }
330  llvm::Value* over{nullptr};
331  llvm::Value* under{nullptr};
332  if (operand_ti.get_notnull()) {
333  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
334  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
335  } else {
336  const auto type_name =
337  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
338  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
339  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
340  over = toBool(cgen_state_->emitCall(
341  "gt_" + type_name + "_nullable_lhs",
342  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
343  under = toBool(cgen_state_->emitCall(
344  "le_" + type_name + "_nullable_lhs",
345  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
346  }
347  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
348  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
349 
350  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
351  cgen_state_->ir_builder_.CreateRet(
353 
354  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
355 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:265
llvm::LLVMContext & context_
Definition: CgenState.h:267
int get_logical_size() const
Definition: sqltypes.h:337
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1039
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
bool needs_error_check_
Definition: CgenState.h:284
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:333
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:160
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCastBetweenTimestamps ( llvm::Value *  ts_lv,
const int  operand_dimen,
const int  target_dimen,
const bool  nullable 
)
private

Definition at line 136 of file CastIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, CgenState::emitExternalCall(), get_int_type(), DateTimeUtils::get_timestamp_precision_scale(), CgenState::inlineIntNull(), kBIGINT, and CgenState::llInt().

Referenced by codegenCast().

139  {
140  if (operand_dimen == target_dimen) {
141  return ts_lv;
142  }
143  CHECK(ts_lv->getType()->isIntegerTy(64));
144  static const std::string sup_fname{"DateTruncateAlterPrecisionScaleUp"};
145  static const std::string sdn_fname{"DateTruncateAlterPrecisionScaleDown"};
146  static const std::string sup_null_fname{"DateTruncateAlterPrecisionScaleUpNullable"};
147  static const std::string sdn_null_fname{"DateTruncateAlterPrecisionScaleDownNullable"};
148  std::vector<llvm::Value*> f_args{ts_lv,
149  cgen_state_->llInt(static_cast<int64_t>(
151  abs(operand_dimen - target_dimen))))};
152  if (nullable) {
153  f_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
154  }
155  return operand_dimen < target_dimen
156  ? cgen_state_->emitExternalCall(nullable ? sup_null_fname : sup_fname,
158  f_args)
159  : cgen_state_->emitExternalCall(nullable ? sdn_null_fname : sdn_fname,
161  f_args);
162 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCastFromFp ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti 
)
private

Definition at line 388 of file CastIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, CgenState::emitCall(), get_bit_width(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type_name(), CgenState::inlineFpNull(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_fp(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_number(), kDOUBLE, kFLOAT, and numeric_type_name().

Referenced by codegenCast().

390  {
391  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
392  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
393  ti.get_type_name() + " not supported");
394  }
395  if (operand_ti.get_type() == ti.get_type()) {
396  // Should not have been called when both dimensions are same.
397  return operand_lv;
398  }
399  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
400  if (operand_ti.get_notnull()) {
401  if (ti.get_type() == kDOUBLE) {
402  return cgen_state_->ir_builder_.CreateFPExt(
403  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
404  } else if (ti.get_type() == kFLOAT) {
405  return cgen_state_->ir_builder_.CreateFPTrunc(
406  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
407  } else if (ti.is_integer()) {
408  return cgen_state_->ir_builder_.CreateFPToSI(
409  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
410  } else {
411  CHECK(false);
412  }
413  } else {
414  const auto from_tname = numeric_type_name(operand_ti);
415  const auto to_tname = numeric_type_name(ti);
416  if (ti.is_fp()) {
417  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
418  {operand_lv,
419  cgen_state_->inlineFpNull(operand_ti),
420  cgen_state_->inlineFpNull(ti)});
421  } else if (ti.is_integer()) {
422  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
423  {operand_lv,
424  cgen_state_->inlineFpNull(operand_ti),
425  cgen_state_->inlineIntNull(ti)});
426  } else {
427  CHECK(false);
428  }
429  }
430  CHECK(false);
431  return nullptr;
432 }
bool is_fp() const
Definition: sqltypes.h:481
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:482
std::string get_type_name() const
Definition: sqltypes.h:429
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
bool is_integer() const
Definition: sqltypes.h:479
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:160
bool is_decimal() const
Definition: sqltypes.h:480
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:62

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCastFromString ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti,
const bool  operand_is_const,
const CompilationOptions co 
)
private

Definition at line 164 of file CastIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, CgenState::context_, CompilationOptions::device_type_, CgenState::emitExternalCall(), executor(), g_cluster, g_enable_watchdog, SQLTypeInfoCore< TYPE_FACET_PACK >::get_comp_param(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_compression(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type_name(), GPU, SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), kENCODING_DICT, kENCODING_NONE, and CgenState::llInt().

Referenced by codegenCast().

168  {
169  if (!ti.is_string()) {
170  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
171  ti.get_type_name() + " not supported");
172  }
173  if (operand_ti.get_compression() == kENCODING_NONE &&
175  return operand_lv;
176  }
177  // dictionary encode non-constant
178  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
179  if (g_cluster) {
180  throw std::runtime_error(
181  "Cast from none-encoded string to dictionary-encoded not supported for "
182  "distributed queries");
183  }
184  if (g_enable_watchdog) {
185  throw WatchdogException(
186  "Cast from none-encoded string to dictionary-encoded would be slow");
187  }
188  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
190  CHECK(operand_lv->getType()->isIntegerTy(64));
192  throw QueryMustRunOnCpu();
193  }
195  "string_compress",
197  {operand_lv,
198  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
199  ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
200  }
201  CHECK(operand_lv->getType()->isIntegerTy(32));
202  if (ti.get_compression() == kENCODING_NONE) {
203  if (g_cluster) {
204  throw std::runtime_error(
205  "Cast from dictionary-encoded string to none-encoded not supported for "
206  "distributed queries");
207  }
208  if (g_enable_watchdog) {
209  throw WatchdogException(
210  "Cast from dictionary-encoded string to none-encoded would be slow");
211  }
212  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
214  throw QueryMustRunOnCpu();
215  }
217  "string_decompress",
219  {operand_lv,
220  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
221  operand_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
222  }
223  CHECK(operand_is_const);
225  return operand_lv;
226 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:334
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:335
bool g_cluster
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool g_enable_watchdog
std::string get_type_name() const
Definition: sqltypes.h:429
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
ExecutorDeviceType device_type_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
bool is_string() const
Definition: sqltypes.h:477
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCastTimestampToDate ( llvm::Value *  ts_lv,
const int  dimen,
const bool  nullable 
)
private

Definition at line 107 of file CastIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, dtDAY, CgenState::emitExternalCall(), get_int_type(), DateTimeUtils::get_timestamp_precision_scale(), CgenState::inlineIntNull(), kBIGINT, and CgenState::llInt().

Referenced by codegenCast().

109  {
110  CHECK(ts_lv->getType()->isIntegerTy(64));
111  std::vector<llvm::Value*> datetrunc_args{ts_lv};
112  if (dimen > 0) {
113  static const std::string hptodate_fname = "DateTruncateHighPrecisionToDate";
114  static const std::string hptodate_null_fname =
115  "DateTruncateHighPrecisionToDateNullable";
116  datetrunc_args.push_back(
118  if (nullable) {
119  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
120  }
121  return cgen_state_->emitExternalCall(nullable ? hptodate_null_fname : hptodate_fname,
123  datetrunc_args);
124  }
125  std::string datetrunc_fname{"DateTruncate"};
126  datetrunc_args.insert(datetrunc_args.begin(),
127  cgen_state_->llInt(static_cast<int32_t>(dtDAY)));
128  if (nullable) {
129  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
130  datetrunc_fname += "Nullable";
131  }
133  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
134 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCastToFp ( llvm::Value *  operand_lv,
const SQLTypeInfo operand_ti,
const SQLTypeInfo ti 
)
private

Definition at line 357 of file CastIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, CgenState::emitCall(), exp_to_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type_name(), CgenState::inlineFpNull(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_fp(), kFLOAT, and numeric_type_name().

Referenced by codegenCast().

359  {
360  if (!ti.is_fp()) {
361  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
362  ti.get_type_name() + " not supported");
363  }
364  const auto to_tname = numeric_type_name(ti);
365  llvm::Value* result_lv{nullptr};
366  if (operand_ti.get_notnull()) {
367  result_lv = cgen_state_->ir_builder_.CreateSIToFP(
368  operand_lv,
369  ti.get_type() == kFLOAT ? llvm::Type::getFloatTy(cgen_state_->context_)
370  : llvm::Type::getDoubleTy(cgen_state_->context_));
371  } else {
372  result_lv = cgen_state_->emitCall(
373  "cast_" + numeric_type_name(operand_ti) + "_to_" + to_tname + "_nullable",
374  {operand_lv,
375  cgen_state_->inlineIntNull(operand_ti),
376  cgen_state_->inlineFpNull(ti)});
377  }
378  CHECK(result_lv);
379  if (operand_ti.get_scale()) {
380  result_lv = cgen_state_->ir_builder_.CreateFDiv(
381  result_lv,
382  llvm::ConstantFP::get(result_lv->getType(),
383  exp_to_scale(operand_ti.get_scale())));
384  }
385  return result_lv;
386 }
bool is_fp() const
Definition: sqltypes.h:481
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
HOST DEVICE int get_scale() const
Definition: sqltypes.h:331
std::string get_type_name() const
Definition: sqltypes.h:429
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
uint64_t exp_to_scale(const unsigned exp)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:160
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:62

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCmp ( const Analyzer::BinOper bin_oper,
const CompilationOptions co 
)
private

Definition at line 184 of file CompareIR.cpp.

References CHECK(), CHECK_EQ, codegen(), codegenCmpDecimalConst(), codegenLogical(), codegenOverlaps(), codegenStrCmp(), Analyzer::BinOper::get_left_operand(), Analyzer::BinOper::get_optype(), Analyzer::BinOper::get_own_left_operand(), Analyzer::BinOper::get_own_right_operand(), Analyzer::BinOper::get_qualifier(), Analyzer::BinOper::get_right_operand(), IS_EQUIVALENCE, is_unnest(), kBW_EQ, kNE, kOVERLAPS, anonymous_namespace{CompareIR.cpp}::lower_bw_eq(), and anonymous_namespace{CompareIR.cpp}::lower_multicol_compare().

Referenced by codegen(), and codegenCmpDecimalConst().

185  {
186  const auto qualifier = bin_oper->get_qualifier();
187  const auto lhs = bin_oper->get_left_operand();
188  const auto rhs = bin_oper->get_right_operand();
189  if (dynamic_cast<const Analyzer::ExpressionTuple*>(lhs)) {
190  CHECK(dynamic_cast<const Analyzer::ExpressionTuple*>(rhs));
191  const auto lowered = lower_multicol_compare(bin_oper);
192  const auto lowered_lvs = codegen(lowered.get(), true, co);
193  CHECK_EQ(size_t(1), lowered_lvs.size());
194  return lowered_lvs.front();
195  }
196  const auto optype = bin_oper->get_optype();
197  if (optype == kBW_EQ) {
198  const auto bw_eq_oper = lower_bw_eq(bin_oper);
199  return codegenLogical(bw_eq_oper.get(), co);
200  }
201  if (optype == kOVERLAPS) {
202  return codegenOverlaps(optype,
203  qualifier,
204  bin_oper->get_own_left_operand(),
205  bin_oper->get_own_right_operand(),
206  co);
207  }
208  if (is_unnest(lhs) || is_unnest(rhs)) {
209  throw std::runtime_error("Unnest not supported in comparisons");
210  }
211  const auto& lhs_ti = lhs->get_type_info();
212  const auto& rhs_ti = rhs->get_type_info();
213 
214  if (lhs_ti.is_string() && rhs_ti.is_string() &&
215  !(IS_EQUIVALENCE(optype) || optype == kNE)) {
216  auto cmp_str = codegenStrCmp(optype,
217  qualifier,
218  bin_oper->get_own_left_operand(),
219  bin_oper->get_own_right_operand(),
220  co);
221  if (cmp_str) {
222  return cmp_str;
223  }
224  }
225 
226  if (lhs_ti.is_decimal()) {
227  auto cmp_decimal_const =
228  codegenCmpDecimalConst(optype, qualifier, lhs, lhs_ti, rhs, co);
229  if (cmp_decimal_const) {
230  return cmp_decimal_const;
231  }
232  }
233 
234  auto lhs_lvs = codegen(lhs, true, co);
235  return codegenCmp(optype, qualifier, lhs_lvs, lhs_ti, rhs, co);
236 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
llvm::Value * codegenStrCmp(const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
Definition: CompareIR.cpp:311
#define IS_EQUIVALENCE(X)
Definition: sqldefs.h:67
std::shared_ptr< Analyzer::BinOper > lower_multicol_compare(const Analyzer::BinOper *multicol_compare)
Definition: CompareIR.cpp:159
const Expr * get_right_operand() const
Definition: Analyzer.h:437
std::shared_ptr< Analyzer::BinOper > lower_bw_eq(const Analyzer::BinOper *bw_eq)
Definition: CompareIR.cpp:125
SQLOps get_optype() const
Definition: Analyzer.h:433
llvm::Value * codegenCmpDecimalConst(const SQLOps, const SQLQualifier, const Analyzer::Expr *, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:341
CHECK(cgen_state)
llvm::Value * codegenOverlaps(const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
Definition: CompareIR.cpp:238
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:32
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
Definition: sqldefs.h:31
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:289
const Expr * get_left_operand() const
Definition: Analyzer.h:436
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1090
const std::shared_ptr< Analyzer::Expr > get_own_right_operand() const
Definition: Analyzer.h:441
const std::shared_ptr< Analyzer::Expr > get_own_left_operand() const
Definition: Analyzer.h:438
SQLQualifier get_qualifier() const
Definition: Analyzer.h:435

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCmp ( const SQLOps  optype,
const SQLQualifier  qualifier,
std::vector< llvm::Value * >  lhs_lvs,
const SQLTypeInfo lhs_ti,
const Analyzer::Expr rhs,
const CompilationOptions co 
)
private

Definition at line 391 of file CompareIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegen(), codegenQualifierCmp(), CgenState::emitCall(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_compression(), get_null_check_suffix(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), Analyzer::Expr::get_type_info(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_boolean(), IS_COMPARISON, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_time(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_timeinterval(), kENCODING_NONE, kONE, and kOVERLAPS.

396  {
397  CHECK(IS_COMPARISON(optype));
398  const auto& rhs_ti = rhs->get_type_info();
399  if (rhs_ti.is_array()) {
400  return codegenQualifierCmp(optype, qualifier, lhs_lvs, rhs, co);
401  }
402  auto rhs_lvs = codegen(rhs, true, co);
403  CHECK_EQ(kONE, qualifier);
404  if (optype == kOVERLAPS) {
405  CHECK(lhs_ti.is_geometry());
406  CHECK(rhs_ti.is_array() ||
407  rhs_ti.is_geometry()); // allow geo col or bounds col to pass
408  } else {
409  CHECK((lhs_ti.get_type() == rhs_ti.get_type()) ||
410  (lhs_ti.is_string() && rhs_ti.is_string()));
411  }
412  const auto null_check_suffix = get_null_check_suffix(lhs_ti, rhs_ti);
413  if (lhs_ti.is_integer() || lhs_ti.is_decimal() || lhs_ti.is_time() ||
414  lhs_ti.is_boolean() || lhs_ti.is_string() || lhs_ti.is_timeinterval()) {
415  if (lhs_ti.is_string()) {
416  CHECK(rhs_ti.is_string());
417  CHECK_EQ(lhs_ti.get_compression(), rhs_ti.get_compression());
418  if (lhs_ti.get_compression() == kENCODING_NONE) {
419  // unpack pointer + length if necessary
420  if (lhs_lvs.size() != 3) {
421  CHECK_EQ(size_t(1), lhs_lvs.size());
422  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {lhs_lvs.front()}));
423  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {lhs_lvs.front()}));
424  }
425  if (rhs_lvs.size() != 3) {
426  CHECK_EQ(size_t(1), rhs_lvs.size());
427  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {rhs_lvs.front()}));
428  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {rhs_lvs.front()}));
429  }
430  std::vector<llvm::Value*> str_cmp_args{
431  lhs_lvs[1], lhs_lvs[2], rhs_lvs[1], rhs_lvs[2]};
432  if (!null_check_suffix.empty()) {
433  str_cmp_args.push_back(
435  }
436  return cgen_state_->emitCall(
437  string_cmp_func(optype) + (null_check_suffix.empty() ? "" : "_nullable"),
438  str_cmp_args);
439  } else {
440  CHECK(optype == kEQ || optype == kNE);
441  }
442  }
443  return null_check_suffix.empty()
444  ? cgen_state_->ir_builder_.CreateICmp(
445  llvm_icmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
447  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
448  null_check_suffix,
449  {lhs_lvs.front(),
450  rhs_lvs.front(),
453  }
454  if (lhs_ti.get_type() == kFLOAT || lhs_ti.get_type() == kDOUBLE) {
455  return null_check_suffix.empty()
456  ? cgen_state_->ir_builder_.CreateFCmp(
457  llvm_fcmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
459  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
460  null_check_suffix,
461  {lhs_lvs.front(),
462  rhs_lvs.front(),
463  lhs_ti.get_type() == kFLOAT ? cgen_state_->llFp(NULL_FLOAT)
466  }
467  CHECK(false);
468  return nullptr;
469 }
bool is_boolean() const
Definition: sqltypes.h:484
#define CHECK_EQ(x, y)
Definition: Logger.h:198
#define NULL_DOUBLE
Definition: sqltypes.h:179
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:334
std::string icmp_name(const SQLOps op_type)
Definition: CompareIR.cpp:45
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
Definition: sqldefs.h:30
llvm::CmpInst::Predicate llvm_fcmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:83
CHECK(cgen_state)
bool is_time() const
Definition: sqltypes.h:483
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
#define NULL_FLOAT
Definition: sqltypes.h:178
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:252
std::string get_null_check_suffix(const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
Definition: Execute.h:1074
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
bool is_geometry() const
Definition: sqltypes.h:489
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:69
llvm::Value * codegenQualifierCmp(const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:471
bool is_integer() const
Definition: sqltypes.h:479
Definition: sqldefs.h:32
bool is_timeinterval() const
Definition: sqltypes.h:488
llvm::CmpInst::Predicate llvm_icmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:26
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
bool is_string() const
Definition: sqltypes.h:477
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:160
bool is_decimal() const
Definition: sqltypes.h:480
std::string string_cmp_func(const SQLOps optype)
Definition: CompareIR.cpp:106
#define IS_COMPARISON(X)
Definition: sqldefs.h:57

+ Here is the call graph for this function:

llvm::Value * CodeGenerator::codegenCmpDecimalConst ( const SQLOps  optype,
const SQLQualifier  qualifier,
const Analyzer::Expr lhs,
const SQLTypeInfo lhs_ti,
const Analyzer::Expr rhs,
const CompilationOptions co 
)
private

Definition at line 341 of file CompareIR.cpp.

References Datum::bigintval, codegen(), codegenCast(), codegenCmp(), exp_to_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_scale(), Analyzer::Expr::get_type_info(), kCAST, and kDECIMAL.

Referenced by codegenCmp().

346  {
347  auto u_oper = dynamic_cast<const Analyzer::UOper*>(lhs);
348  if (!u_oper || u_oper->get_optype() != kCAST) {
349  return nullptr;
350  }
351  auto rhs_constant = dynamic_cast<const Analyzer::Constant*>(rhs);
352  if (!rhs_constant) {
353  return nullptr;
354  }
355  const auto operand = u_oper->get_operand();
356  const auto& operand_ti = operand->get_type_info();
357  if (operand_ti.is_decimal() && operand_ti.get_scale() < lhs_ti.get_scale()) {
358  // lhs decimal type has smaller scale
359  } else if (operand_ti.is_integer() && 0 < lhs_ti.get_scale()) {
360  // lhs is integer, no need to scale it all the way up to the cmp expr scale
361  } else {
362  return nullptr;
363  }
364 
365  auto scale_diff = lhs_ti.get_scale() - operand_ti.get_scale() - 1;
366  int64_t bigintval = rhs_constant->get_constval().bigintval;
367  bool negative = false;
368  if (bigintval < 0) {
369  negative = true;
370  bigintval = -bigintval;
371  }
372  int64_t truncated_decimal = bigintval / exp_to_scale(scale_diff);
373  int64_t decimal_tail = bigintval % exp_to_scale(scale_diff);
374  if (truncated_decimal % 10 == 0 && decimal_tail > 0) {
375  truncated_decimal += 1;
376  }
377  SQLTypeInfo new_ti = SQLTypeInfo(
378  kDECIMAL, 19, lhs_ti.get_scale() - scale_diff, operand_ti.get_notnull());
379  if (negative) {
380  truncated_decimal = -truncated_decimal;
381  }
382  Datum d;
383  d.bigintval = truncated_decimal;
384  const auto new_rhs_lit =
385  makeExpr<Analyzer::Constant>(new_ti, rhs_constant->get_is_null(), d);
386  const auto operand_lv = codegen(operand, true, co).front();
387  const auto lhs_lv = codegenCast(operand_lv, operand_ti, new_ti, false, co);
388  return codegenCmp(optype, qualifier, {lhs_lv}, new_ti, new_rhs_lit.get(), co);
389 }
HOST DEVICE int get_scale() const
Definition: sqltypes.h:331
Definition: sqldefs.h:49
int64_t bigintval
Definition: sqltypes.h:129
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
uint64_t exp_to_scale(const unsigned exp)
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegenColumn ( const Analyzer::ColumnVar col_var,
const bool  fetch_column,
const CompilationOptions co 
)
privatevirtual

Reimplemented in ScalarCodeGenerator.

Definition at line 92 of file ColumnIR.cpp.

References cgen_state_, codegenColVar(), codegenOuterJoinNullPlaceholder(), foundOuterJoinMatch(), Analyzer::ColumnVar::get_rte_idx(), and CgenState::outer_join_match_found_per_level_.

Referenced by codegen().

94  {
95  if (col_var->get_rte_idx() <= 0 ||
97  !foundOuterJoinMatch(col_var->get_rte_idx())) {
98  return codegenColVar(col_var, fetch_column, true, co);
99  }
100  return codegenOuterJoinNullPlaceholder(col_var, fetch_column, co);
101 }
std::vector< llvm::Value * > outer_join_match_found_per_level_
Definition: CgenState.h:280
CgenState * cgen_state_
std::vector< llvm::Value * > codegenOuterJoinNullPlaceholder(const Analyzer::ColumnVar *col_var, const bool fetch_column, const CompilationOptions &co)
Definition: ColumnIR.cpp:412
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:103
int get_rte_idx() const
Definition: Analyzer.h:196
llvm::Value * foundOuterJoinMatch(const ssize_t nesting_level) const
Definition: ColumnIR.cpp:405

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector< llvm::Value * > CodeGenerator::codegenColVar ( const Analyzer::ColumnVar col_var,
const bool  fetch_column,
const bool  update_query_plan,
const CompilationOptions co 
)
private

Definition at line 103 of file ColumnIR.cpp.

References anonymous_namespace{ColumnIR.cpp}::adjusted_range_table_index(), cgen_state_, CHECK(), CHECK_LT, codegen(), codegenFixedLengthColVar(), codegenFixedLengthColVarInWindow(), codegenRowId(), codegenVariableLengthStringColVar(), codegenWindowPosition(), colByteStream(), PlanState::columns_to_fetch_, PlanState::columns_to_not_fetch_, ColumnDescriptor::columnType, executor(), CgenState::fetch_cache_, CgenState::frag_offsets_, get_column_descriptor(), Analyzer::ColumnVar::get_column_id(), Analyzer::ColumnVar::get_table_id(), Analyzer::Expr::get_type_info(), WindowProjectNodeContext::getActiveWindowFunctionContext(), PlanState::getLocalColumnId(), hashJoinLhs(), CompilationOptions::hoist_literals_, CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), PlanState::isLazyFetchColumn(), kENCODING_NONE, plan_state_, posArg(), and resolveGroupedColumnReference().

Referenced by codegenColumn(), and codegenOuterJoinNullPlaceholder().

106  {
107  const bool hoist_literals = co.hoist_literals_;
108  auto col_id = col_var->get_column_id();
109  const int rte_idx = adjusted_range_table_index(col_var);
110  CHECK_LT(static_cast<size_t>(rte_idx), cgen_state_->frag_offsets_.size());
111  const auto catalog = executor()->getCatalog();
112  CHECK(catalog);
113  if (col_var->get_table_id() > 0) {
114  auto cd = get_column_descriptor(col_id, col_var->get_table_id(), *catalog);
115  if (cd->isVirtualCol) {
116  CHECK(cd->columnName == "rowid");
117  return {codegenRowId(col_var, co)};
118  }
119  auto col_ti = cd->columnType;
120  if (col_ti.get_physical_coord_cols() > 0) {
121  std::vector<llvm::Value*> cols;
122  for (auto i = 0; i < col_ti.get_physical_coord_cols(); i++) {
123  auto cd0 =
124  get_column_descriptor(col_id + i + 1, col_var->get_table_id(), *catalog);
125  auto col0_ti = cd0->columnType;
126  CHECK(!cd0->isVirtualCol);
127  auto col0_var = makeExpr<Analyzer::ColumnVar>(
128  col0_ti, col_var->get_table_id(), cd0->columnId, rte_idx);
129  auto col = codegenColVar(col0_var.get(), fetch_column, false, co);
130  cols.insert(cols.end(), col.begin(), col.end());
131  if (!fetch_column && plan_state_->isLazyFetchColumn(col_var)) {
133  std::make_pair(col_var->get_table_id(), col0_var->get_column_id()));
134  }
135  }
136  if (!fetch_column && plan_state_->isLazyFetchColumn(col_var)) {
138  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
139  } else {
141  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
142  }
143  return cols;
144  }
145  } else {
146  if (col_var->get_type_info().is_geometry()) {
147  throw std::runtime_error(
148  "Geospatial columns not supported in temporary tables yet");
149  }
150  }
151  const auto grouped_col_lv = resolveGroupedColumnReference(col_var);
152  if (grouped_col_lv) {
153  return {grouped_col_lv};
154  }
155  const int local_col_id = plan_state_->getLocalColumnId(col_var, fetch_column);
156  const auto window_func_context =
158  // only generate the decoding code once; if a column has been previously
159  // fetched in the generated IR, we'll reuse it
160  if (!window_func_context) {
161  auto it = cgen_state_->fetch_cache_.find(local_col_id);
162  if (it != cgen_state_->fetch_cache_.end()) {
163  return {it->second};
164  }
165  }
166  const auto hash_join_lhs = hashJoinLhs(col_var);
167  // Use the already fetched left-hand side of an equi-join if the types are identical.
168  // Currently, types can only be different because of different underlying dictionaries.
169  if (hash_join_lhs && hash_join_lhs->get_type_info() == col_var->get_type_info()) {
170  if (plan_state_->isLazyFetchColumn(col_var)) {
172  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
173  }
174  return codegen(hash_join_lhs.get(), fetch_column, co);
175  }
176  auto pos_arg = posArg(col_var);
177  if (window_func_context) {
178  pos_arg = codegenWindowPosition(window_func_context, pos_arg);
179  }
180  auto col_byte_stream = colByteStream(col_var, fetch_column, hoist_literals);
181  if (plan_state_->isLazyFetchColumn(col_var)) {
182  if (update_query_plan) {
184  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
185  }
186  if (rte_idx > 0) {
187  const auto offset = cgen_state_->frag_offsets_[rte_idx];
188  if (offset) {
189  return {cgen_state_->ir_builder_.CreateAdd(pos_arg, offset)};
190  } else {
191  return {pos_arg};
192  }
193  }
194  return {pos_arg};
195  }
196  const auto& col_ti = col_var->get_type_info();
197  if (col_ti.is_string() && col_ti.get_compression() == kENCODING_NONE) {
198  const auto varlen_str_column_lvs =
199  codegenVariableLengthStringColVar(col_byte_stream, pos_arg);
200  if (!window_func_context) {
201  auto it_ok = cgen_state_->fetch_cache_.insert(
202  std::make_pair(local_col_id, varlen_str_column_lvs));
203  CHECK(it_ok.second);
204  }
205  return varlen_str_column_lvs;
206  }
207  if (col_ti.is_array()) {
208  return {col_byte_stream};
209  }
210  if (window_func_context) {
211  return {codegenFixedLengthColVarInWindow(col_var, col_byte_stream, pos_arg)};
212  }
213  const auto fixed_length_column_lv =
214  codegenFixedLengthColVar(col_var, col_byte_stream, pos_arg);
215  auto it_ok = cgen_state_->fetch_cache_.insert(
216  std::make_pair(local_col_id, std::vector<llvm::Value*>{fixed_length_column_lv}));
217  CHECK(it_ok.second);
218  return {it_ok.first->second};
219 }
int get_table_id() const
Definition: Analyzer.h:194
CgenState * cgen_state_
llvm::Value * codegenRowId(const Analyzer::ColumnVar *col_var, const CompilationOptions &co)
Definition: ColumnIR.cpp:312
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
std::set< std::pair< TableId, ColumnId > > columns_to_fetch_
Definition: PlanState.h:53
std::set< std::pair< TableId, ColumnId > > columns_to_not_fetch_
Definition: PlanState.h:54
std::shared_ptr< const Analyzer::Expr > hashJoinLhs(const Analyzer::ColumnVar *rhs) const
Definition: ColumnIR.cpp:539
int getLocalColumnId(const Analyzer::ColumnVar *col_var, const bool fetch_column)
Definition: PlanState.cpp:62
CHECK(cgen_state)
std::unordered_map< int, std::vector< llvm::Value * > > fetch_cache_
Definition: CgenState.h:270
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:103
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
bool is_geometry() const
Definition: sqltypes.h:489
PlanState * plan_state_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
#define CHECK_LT(x, y)
Definition: Logger.h:200
std::vector< llvm::Value * > frag_offsets_
Definition: CgenState.h:278
llvm::Value * codegenFixedLengthColVarInWindow(const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:270
llvm::Value * colByteStream(const Analyzer::ColumnVar *col_var, const bool fetch_column, const bool hoist_literals)
Definition: ColumnIR.cpp:487
llvm::Value * codegenWindowPosition(WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:221
SQLTypeInfo columnType
int get_column_id() const
Definition: Analyzer.h:195
bool isLazyFetchColumn(const Analyzer::Expr *target_expr)
Definition: PlanState.cpp:20
std::vector< llvm::Value * > codegenVariableLengthStringColVar(llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:298
llvm::Value * codegenFixedLengthColVar(const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:234
int adjusted_range_table_index(const Analyzer::ColumnVar *col_var)
Definition: ColumnIR.cpp:86
static WindowFunctionContext * getActiveWindowFunctionContext()
const ColumnDescriptor * get_column_descriptor(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:142
llvm::Value * resolveGroupedColumnReference(const Analyzer::ColumnVar *)
Definition: ColumnIR.cpp:468
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDateTruncHighPrecisionTimestamps ( llvm::Value *  ts_lv,
const SQLTypeInfo ti,
const DatetruncField field 
)
private

Definition at line 198 of file DateTimeIR.cpp.

References cgen_state_, CHECK(), CgenState::emitCall(), DateTimeUtils::get_datetrunc_high_precision_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_dimension(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), CgenState::inlineIntNull(), CgenState::ir_builder_, DateTimeUtils::is_subsecond_datetrunc_field(), CgenState::llInt(), and run_benchmark_import::result.

Referenced by codegen().

201  {
202  CHECK(ti.is_high_precision_timestamp());
203  CHECK(ts_lv->getType()->isIntegerTy(64));
206  if (result != -1) {
207  ts_lv =
208  ti.get_notnull()
209  ? cgen_state_->ir_builder_.CreateSDiv(
210  ts_lv, cgen_state_->llInt(static_cast<int64_t>(result)))
211  : cgen_state_->emitCall("div_int64_t_nullable_lhs",
212  {ts_lv,
213  cgen_state_->llInt(static_cast<int64_t>(result)),
214  cgen_state_->inlineIntNull(ti)});
215  return ti.get_notnull()
216  ? cgen_state_->ir_builder_.CreateMul(
217  ts_lv, cgen_state_->llInt(static_cast<int64_t>(result)))
219  "mul_int64_t_nullable_lhs",
220  {ts_lv,
221  cgen_state_->llInt(static_cast<int64_t>(result)),
222  cgen_state_->inlineIntNull(ti)});
223  } else {
224  return ts_lv;
225  }
226  }
227  std::string datetrunc_fname = "DateTruncate";
228  const int64_t scale = get_timestamp_precision_scale(ti.get_dimension());
229  ts_lv = ti.get_notnull()
230  ? cgen_state_->ir_builder_.CreateSDiv(
231  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)))
232  : cgen_state_->emitCall("div_int64_t_nullable_lhs",
233  {ts_lv,
234  cgen_state_->llInt(static_cast<int64_t>(scale)),
235  cgen_state_->inlineIntNull(ti)});
236  std::vector<llvm::Value*> datetrunc_args{
237  cgen_state_->llInt(static_cast<int32_t>(field)), ts_lv};
238  if (!ti.get_notnull()) {
239  datetrunc_fname += "Nullable";
240  datetrunc_args.push_back(cgen_state_->inlineIntNull(ti));
241  }
242  ts_lv = cgen_state_->emitExternalCall(
243  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
244  return ti.get_notnull()
245  ? cgen_state_->ir_builder_.CreateMul(
246  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)))
247  : cgen_state_->emitCall("mul_int64_t_nullable_lhs",
248  {ts_lv,
249  cgen_state_->llInt(static_cast<int64_t>(scale)),
250  cgen_state_->inlineIntNull(ti)});
251 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
constexpr bool is_subsecond_datetrunc_field(const DatetruncField field)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:333
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={})
Definition: CgenState.h:205
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:328
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
const int64_t get_datetrunc_high_precision_scale(const DatetruncField &field, const int32_t dimen)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDeciDiv ( const Analyzer::BinOper bin_oper,
const CompilationOptions co 
)
private

Definition at line 534 of file ArithmeticIR.cpp.

References Parser::IntLiteral::analyzeValue(), CHECK(), codegen(), codegenCastBetweenIntTypes(), codegenDiv(), codegenIntConst(), exp_to_scale(), Analyzer::BinOper::get_left_operand(), get_null_check_suffix(), Analyzer::BinOper::get_right_operand(), Analyzer::Expr::get_type_info(), kCAST, and anonymous_namespace{ArithmeticIR.cpp}::numeric_or_time_interval_type_name().

Referenced by codegenArith().

535  {
536  auto lhs = bin_oper->get_left_operand();
537  auto rhs = bin_oper->get_right_operand();
538  const auto& lhs_type = lhs->get_type_info();
539  const auto& rhs_type = rhs->get_type_info();
540  CHECK(lhs_type.is_decimal() && rhs_type.is_decimal() &&
541  lhs_type.get_scale() == rhs_type.get_scale());
542 
543  auto rhs_constant = dynamic_cast<const Analyzer::Constant*>(rhs);
544  auto rhs_cast = dynamic_cast<const Analyzer::UOper*>(rhs);
545  if (rhs_constant && !rhs_constant->get_is_null() &&
546  rhs_constant->get_constval().bigintval != 0LL &&
547  (rhs_constant->get_constval().bigintval % exp_to_scale(rhs_type.get_scale())) ==
548  0LL) {
549  // can safely downscale a scaled constant
550  } else if (rhs_cast && rhs_cast->get_optype() == kCAST &&
551  rhs_cast->get_operand()->get_type_info().is_integer()) {
552  // can skip upscale in the int to dec cast
553  } else {
554  return nullptr;
555  }
556 
557  auto lhs_lv = codegen(lhs, true, co).front();
558  llvm::Value* rhs_lv{nullptr};
559  if (rhs_constant) {
560  const auto rhs_lit = Parser::IntLiteral::analyzeValue(
561  rhs_constant->get_constval().bigintval / exp_to_scale(rhs_type.get_scale()));
562  auto rhs_lit_lv =
563  codegenIntConst(dynamic_cast<const Analyzer::Constant*>(rhs_lit.get()));
565  rhs_lit_lv, rhs_lit->get_type_info(), lhs_type, /*upscale*/ false);
566  } else if (rhs_cast) {
567  auto rhs_cast_oper = rhs_cast->get_operand();
568  const auto& rhs_cast_oper_ti = rhs_cast_oper->get_type_info();
569  auto rhs_cast_oper_lv = codegen(rhs_cast_oper, true, co).front();
571  rhs_cast_oper_lv, rhs_cast_oper_ti, lhs_type, /*upscale*/ false);
572  } else {
573  CHECK(false);
574  }
575  const auto int_typename = numeric_or_time_interval_type_name(lhs_type, rhs_type);
576  const auto null_check_suffix = get_null_check_suffix(lhs_type, rhs_type);
577  return codegenDiv(lhs_lv,
578  rhs_lv,
579  null_check_suffix.empty() ? "" : int_typename,
580  null_check_suffix,
581  lhs_type,
582  /*upscale*/ false);
583 }
static std::shared_ptr< Analyzer::Expr > analyzeValue(const int64_t intval)
Definition: ParserNode.cpp:112
const Expr * get_right_operand() const
Definition: Analyzer.h:437
Definition: sqldefs.h:49
llvm::Value * codegenDiv(llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, bool upscale=true)
std::string numeric_or_time_interval_type_name(const SQLTypeInfo &ti1, const SQLTypeInfo &ti2)
CHECK(cgen_state)
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:228
std::string get_null_check_suffix(const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
Definition: Execute.h:1074
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant)
Definition: ConstantIR.cpp:88
uint64_t exp_to_scale(const unsigned exp)
const Expr * get_left_operand() const
Definition: Analyzer.h:436

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDictLike ( const std::shared_ptr< Analyzer::Expr arg,
const Analyzer::Constant pattern,
const bool  ilike,
const bool  is_simple,
const char  escape_char,
const CompilationOptions co 
)
private

Definition at line 183 of file StringOpsIR.cpp.

References CHECK(), CHECK_EQ, codegen(), executor(), Analyzer::Constant::get_constval(), Analyzer::Expr::get_type_info(), kCAST, kENCODING_DICT, kENCODING_NONE, and Datum::stringval.

Referenced by codegen().

189  {
190  const auto cast_oper = std::dynamic_pointer_cast<Analyzer::UOper>(like_arg);
191  if (!cast_oper) {
192  return nullptr;
193  }
194  CHECK(cast_oper);
195  CHECK_EQ(kCAST, cast_oper->get_optype());
196  const auto dict_like_arg = cast_oper->get_own_operand();
197  const auto& dict_like_arg_ti = dict_like_arg->get_type_info();
198  if (!dict_like_arg_ti.is_string()) {
199  throw(std::runtime_error("Cast from " + dict_like_arg_ti.get_type_name() + " to " +
200  cast_oper->get_type_info().get_type_name() +
201  " not supported"));
202  }
203  CHECK_EQ(kENCODING_DICT, dict_like_arg_ti.get_compression());
204  const auto sdp = executor()->getStringDictionaryProxy(
205  dict_like_arg_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true);
206  if (sdp->storageEntryCount() > 200000000) {
207  return nullptr;
208  }
209  const auto& pattern_ti = pattern->get_type_info();
210  CHECK(pattern_ti.is_string());
211  CHECK_EQ(kENCODING_NONE, pattern_ti.get_compression());
212  const auto& pattern_datum = pattern->get_constval();
213  const auto& pattern_str = *pattern_datum.stringval;
214  const auto matching_ids = sdp->getLike(pattern_str, ilike, is_simple, escape_char);
215  // InIntegerSet requires 64-bit values
216  std::vector<int64_t> matching_ids_64(matching_ids.size());
217  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
218  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
219  dict_like_arg, matching_ids_64, dict_like_arg_ti.get_notnull());
220  return codegen(in_values.get(), co);
221 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
Definition: sqldefs.h:49
CHECK(cgen_state)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::string * stringval
Definition: sqltypes.h:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Datum get_constval() const
Definition: Analyzer.h:329
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDictRegexp ( const std::shared_ptr< Analyzer::Expr arg,
const Analyzer::Constant pattern,
const char  escape_char,
const CompilationOptions co 
)
private

Definition at line 393 of file StringOpsIR.cpp.

References CHECK(), CHECK_EQ, codegen(), executor(), Analyzer::Constant::get_constval(), Analyzer::Expr::get_type_info(), kCAST, kENCODING_DICT, kENCODING_NONE, and Datum::stringval.

Referenced by codegen().

397  {
398  const auto cast_oper = std::dynamic_pointer_cast<Analyzer::UOper>(pattern_arg);
399  if (!cast_oper) {
400  return nullptr;
401  }
402  CHECK(cast_oper);
403  CHECK_EQ(kCAST, cast_oper->get_optype());
404  const auto dict_regexp_arg = cast_oper->get_own_operand();
405  const auto& dict_regexp_arg_ti = dict_regexp_arg->get_type_info();
406  CHECK(dict_regexp_arg_ti.is_string());
407  CHECK_EQ(kENCODING_DICT, dict_regexp_arg_ti.get_compression());
408  const auto comp_param = dict_regexp_arg_ti.get_comp_param();
409  const auto sdp = executor()->getStringDictionaryProxy(
410  comp_param, executor()->getRowSetMemoryOwner(), true);
411  if (sdp->storageEntryCount() > 15000000) {
412  return nullptr;
413  }
414  const auto& pattern_ti = pattern->get_type_info();
415  CHECK(pattern_ti.is_string());
416  CHECK_EQ(kENCODING_NONE, pattern_ti.get_compression());
417  const auto& pattern_datum = pattern->get_constval();
418  const auto& pattern_str = *pattern_datum.stringval;
419  const auto matching_ids = sdp->getRegexpLike(pattern_str, escape_char);
420  // InIntegerSet requires 64-bit values
421  std::vector<int64_t> matching_ids_64(matching_ids.size());
422  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
423  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
424  dict_regexp_arg, matching_ids_64, dict_regexp_arg_ti.get_notnull());
425  return codegen(in_values.get(), co);
426 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
Definition: sqldefs.h:49
CHECK(cgen_state)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::string * stringval
Definition: sqltypes.h:134
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Datum get_constval() const
Definition: Analyzer.h:329
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDictStrCmp ( const std::shared_ptr< Analyzer::Expr lhs,
const std::shared_ptr< Analyzer::Expr rhs,
const SQLOps  compare_operator,
const CompilationOptions co 
)
private

Definition at line 256 of file StringOpsIR.cpp.

References CHECK(), CHECK_EQ, codegen(), executor(), anonymous_namespace{StringOpsIR.cpp}::get_compared_ids(), Analyzer::Constant::get_constval(), kCAST, kENCODING_DICT, kEQ, kGE, kGT, kLE, kLT, and kNE.

Referenced by codegenStrCmp().

259  {
260  auto rhs_cast_oper = std::dynamic_pointer_cast<const Analyzer::UOper>(rhs);
261  auto lhs_cast_oper = std::dynamic_pointer_cast<const Analyzer::UOper>(lhs);
262  auto rhs_col_var = std::dynamic_pointer_cast<const Analyzer::ColumnVar>(rhs);
263  auto lhs_col_var = std::dynamic_pointer_cast<const Analyzer::ColumnVar>(lhs);
264  std::shared_ptr<const Analyzer::UOper> cast_oper;
265  std::shared_ptr<const Analyzer::ColumnVar> col_var;
266  auto compare_opr = compare_operator;
267  if (lhs_col_var && rhs_col_var) {
268  if (lhs_col_var->get_type_info().get_comp_param() ==
269  rhs_col_var->get_type_info().get_comp_param()) {
270  if (compare_operator == kEQ || compare_operator == kNE) {
271  // TODO (vraj): implement compare between two dictionary encoded columns which
272  // share a dictionary
273  return nullptr;
274  }
275  }
276  // TODO (vraj): implement compare between two dictionary encoded columns which don't
277  // shared dictionary
278  throw std::runtime_error("Decoding two Dictionary encoded columns will be slow");
279  } else if (lhs_col_var && rhs_cast_oper) {
280  cast_oper.swap(rhs_cast_oper);
281  col_var.swap(lhs_col_var);
282  } else if (lhs_cast_oper && rhs_col_var) {
283  cast_oper.swap(lhs_cast_oper);
284  col_var.swap(rhs_col_var);
285  switch (compare_operator) {
286  case kLT:
287  compare_opr = kGT;
288  break;
289  case kLE:
290  compare_opr = kGE;
291  break;
292  case kGT:
293  compare_opr = kLT;
294  break;
295  case kGE:
296  compare_opr = kLE;
297  default:
298  break;
299  }
300  }
301  if (!cast_oper || !col_var) {
302  return nullptr;
303  }
304  CHECK_EQ(kCAST, cast_oper->get_optype());
305 
306  const auto const_expr =
307  dynamic_cast<Analyzer::Constant*>(cast_oper->get_own_operand().get());
308  if (!const_expr) {
309  // Analyzer casts dictionary encoded columns to none encoded if there is a comparison
310  // between two encoded columns. Which we currently do not handle.
311  return nullptr;
312  }
313  const auto& const_val = const_expr->get_constval();
314 
315  const auto col_ti = col_var->get_type_info();
316  CHECK(col_ti.is_string());
317  CHECK_EQ(kENCODING_DICT, col_ti.get_compression());
318  const auto sdp = executor()->getStringDictionaryProxy(
319  col_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true);
320 
321  if (sdp->storageEntryCount() > 200000000) {
322  std::runtime_error("Cardinality for string dictionary is too high");
323  return nullptr;
324  }
325 
326  const auto& pattern_str = *const_val.stringval;
327  const auto matching_ids = get_compared_ids(sdp, compare_opr, pattern_str);
328 
329  // InIntegerSet requires 64-bit values
330  std::vector<int64_t> matching_ids_64(matching_ids.size());
331  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
332 
333  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
334  col_var, matching_ids_64, col_ti.get_notnull());
335  return codegen(in_values.get(), co);
336 }
#define CHECK_EQ(x, y)
Definition: Logger.h:198
std::vector< int32_t > get_compared_ids(const StringDictionaryProxy *dict, const SQLOps compare_operator, const std::string &pattern)
Definition: sqldefs.h:35
Definition: sqldefs.h:36
Definition: sqldefs.h:49
Definition: sqldefs.h:30
CHECK(cgen_state)
Definition: sqldefs.h:34
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Datum get_constval() const
Definition: Analyzer.h:329
Definition: sqldefs.h:32
Definition: sqldefs.h:33
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenDiv ( llvm::Value *  lhs_lv,
llvm::Value *  rhs_lv,
const std::string &  null_typename,
const std::string &  null_check_suffix,
const SQLTypeInfo ti,
bool  upscale = true 
)
private

Definition at line 422 of file ArithmeticIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, codegenSkipOverflowCheckForNull(), CgenState::context_, CgenState::emitCall(), Executor::ERR_DIV_BY_ZERO, Executor::ERR_OVERFLOW_OR_UNDERFLOW, exp_to_scale(), g_null_div_by_zero, get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_type(), inline_int_null_val(), CgenState::inlineIntMaxMin(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_decimal(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_fp(), kBOOLEAN, kFLOAT, CgenState::llFp(), CgenState::llInt(), CgenState::needs_error_check_, NULL_DOUBLE, NULL_FLOAT, numeric_type_name(), CgenState::row_func_, and toBool().

Referenced by codegenDeciDiv(), codegenFpArith(), and codegenIntArith().

427  {
428  CHECK_EQ(lhs_lv->getType(), rhs_lv->getType());
429  if (ti.is_decimal()) {
430  if (upscale) {
431  CHECK(lhs_lv->getType()->isIntegerTy());
432  const auto scale_lv =
433  llvm::ConstantInt::get(lhs_lv->getType(), exp_to_scale(ti.get_scale()));
434 
435  lhs_lv = cgen_state_->ir_builder_.CreateSExt(
436  lhs_lv, get_int_type(64, cgen_state_->context_));
437  llvm::Value* chosen_max{nullptr};
438  llvm::Value* chosen_min{nullptr};
439  std::tie(chosen_max, chosen_min) = cgen_state_->inlineIntMaxMin(8, true);
440  auto decimal_div_ok = llvm::BasicBlock::Create(
441  cgen_state_->context_, "decimal_div_ok", cgen_state_->row_func_);
442  if (!null_check_suffix.empty()) {
443  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, decimal_div_ok, ti);
444  }
445  auto decimal_div_fail = llvm::BasicBlock::Create(
446  cgen_state_->context_, "decimal_div_fail", cgen_state_->row_func_);
447  auto lhs_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() /
448  exp_to_scale(ti.get_scale());
449  auto lhs_max_lv =
450  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), lhs_max);
451  llvm::Value* detected{nullptr};
452  if (ti.get_notnull()) {
453  detected = cgen_state_->ir_builder_.CreateICmpSGT(lhs_lv, lhs_max_lv);
454  } else {
455  detected = toBool(cgen_state_->emitCall(
456  "gt_" + numeric_type_name(ti) + "_nullable",
457  {lhs_lv,
458  lhs_max_lv,
461  }
462  cgen_state_->ir_builder_.CreateCondBr(detected, decimal_div_fail, decimal_div_ok);
463 
464  cgen_state_->ir_builder_.SetInsertPoint(decimal_div_fail);
465  cgen_state_->ir_builder_.CreateRet(
467 
468  cgen_state_->ir_builder_.SetInsertPoint(decimal_div_ok);
469 
470  lhs_lv = null_typename.empty()
471  ? cgen_state_->ir_builder_.CreateMul(lhs_lv, scale_lv)
473  "mul_" + numeric_type_name(ti) + null_check_suffix,
474  {lhs_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(ti))});
475  }
476  }
477  if (g_null_div_by_zero) {
478  llvm::Value* null_lv{nullptr};
479  if (ti.is_fp()) {
480  null_lv = ti.get_type() == kFLOAT ? cgen_state_->llFp(NULL_FLOAT)
482  } else {
483  null_lv = cgen_state_->llInt(inline_int_null_val(ti));
484  }
485  return cgen_state_->emitCall("safe_div_" + numeric_type_name(ti),
486  {lhs_lv, rhs_lv, null_lv});
487  }
489  auto div_ok =
490  llvm::BasicBlock::Create(cgen_state_->context_, "div_ok", cgen_state_->row_func_);
491  if (!null_check_suffix.empty()) {
492  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, div_ok, ti);
493  }
494  auto div_zero =
495  llvm::BasicBlock::Create(cgen_state_->context_, "div_zero", cgen_state_->row_func_);
496  auto zero_const = rhs_lv->getType()->isIntegerTy()
497  ? llvm::ConstantInt::get(rhs_lv->getType(), 0, true)
498  : llvm::ConstantFP::get(rhs_lv->getType(), 0.);
499  cgen_state_->ir_builder_.CreateCondBr(
500  zero_const->getType()->isFloatingPointTy()
501  ? cgen_state_->ir_builder_.CreateFCmp(
502  llvm::FCmpInst::FCMP_ONE, rhs_lv, zero_const)
503  : cgen_state_->ir_builder_.CreateICmp(
504  llvm::ICmpInst::ICMP_NE, rhs_lv, zero_const),
505  div_ok,
506  div_zero);
507  cgen_state_->ir_builder_.SetInsertPoint(div_ok);
508  auto ret =
509  zero_const->getType()->isIntegerTy()
510  ? (null_typename.empty()
511  ? cgen_state_->ir_builder_.CreateSDiv(lhs_lv, rhs_lv)
513  "div_" + null_typename + null_check_suffix,
514  {lhs_lv, rhs_lv, cgen_state_->llInt(inline_int_null_val(ti))}))
515  : (null_typename.empty()
516  ? cgen_state_->ir_builder_.CreateFDiv(lhs_lv, rhs_lv)
518  "div_" + null_typename + null_check_suffix,
519  {lhs_lv,
520  rhs_lv,
521  ti.get_type() == kFLOAT ? cgen_state_->llFp(