OmniSciDB  04ee39c94c
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 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 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::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 &)
 
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::ExprhashJoinLhs (const Analyzer::ColumnVar *rhs) const
 
std::shared_ptr< const Analyzer::ColumnVarhashJoinLhsTuple (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 *> &)
 
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() [1/2]

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() const
Executor * executor_
PlanState * plan_state_

◆ CodeGenerator() [2/2]

CodeGenerator::CodeGenerator ( CgenState cgen_state,
PlanState plan_state 
)
inline

Definition at line 34 of file CodeGenerator.h.

References castArrayPointer(), codegen(), codegenCastBetweenIntTypes(), codegenCastBetweenIntTypesOverflowChecks(), codegenHoistedConstants(), codegenIntConst(), generateNativeCPUCode(), generatePTX(), initializeNVPTXBackend(), markDeadRuntimeFuncs(), posArg(), and toBool().

35  : executor_(nullptr), cgen_state_(cgen_state), plan_state_(plan_state) {}
CgenState * cgen_state_
Executor * executor_
PlanState * plan_state_
+ Here is the call graph for this function:

Member Function Documentation

◆ beginArgsNullcheck()

CodeGenerator::ArgNullcheckBBs CodeGenerator::beginArgsNullcheck ( const Analyzer::FunctionOper function_oper,
const std::vector< llvm::Value *> &  orig_arg_lvs 
)
private

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

180  {
181  llvm::BasicBlock* args_null_bb{nullptr};
182  llvm::BasicBlock* args_notnull_bb{nullptr};
183  llvm::BasicBlock* orig_bb = cgen_state_->ir_builder_.GetInsertBlock();
184  // Only generate the check if required (at least one argument must be nullable).
185  if (ext_func_call_requires_nullcheck(function_oper)) {
186  const auto args_notnull_lv = cgen_state_->ir_builder_.CreateNot(
187  codegenFunctionOperNullArg(function_oper, orig_arg_lvs));
188  args_notnull_bb = llvm::BasicBlock::Create(
189  cgen_state_->context_, "args_notnull", cgen_state_->row_func_);
190  args_null_bb = llvm::BasicBlock::Create(
191  cgen_state_->context_, "args_null", cgen_state_->row_func_);
192  cgen_state_->ir_builder_.CreateCondBr(args_notnull_lv, args_notnull_bb, args_null_bb);
193  cgen_state_->ir_builder_.SetInsertPoint(args_notnull_bb);
194  }
195  return {args_null_bb, args_notnull_bb, orig_bb};
196 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Value * codegenFunctionOperNullArg(const Analyzer::FunctionOper *, const std::vector< llvm::Value *> &)
bool ext_func_call_requires_nullcheck(const Analyzer::FunctionOper *function_oper)
llvm::Function * row_func_
Definition: CgenState.h:264
llvm::LLVMContext & context_
Definition: CgenState.h:266
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ castArrayPointer()

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

Definition at line 527 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_integer(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), kDOUBLE, kENCODING_DICT, and kFLOAT.

Referenced by CodeGenerator(), codegenFunctionOperCastArgs(), and OverlapsJoinHashTable::codegenKey().

528  {
529  if (elem_ti.get_type() == kFLOAT) {
530  return cgen_state_->ir_builder_.CreatePointerCast(
531  ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
532  }
533  if (elem_ti.get_type() == kDOUBLE) {
534  return cgen_state_->ir_builder_.CreatePointerCast(
535  ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
536  }
537  CHECK(elem_ti.is_integer() ||
538  (elem_ti.is_string() && elem_ti.get_compression() == kENCODING_DICT));
539  switch (elem_ti.get_size()) {
540  case 1:
541  return cgen_state_->ir_builder_.CreatePointerCast(
542  ptr, llvm::Type::getInt8PtrTy(cgen_state_->context_));
543  case 2:
544  return cgen_state_->ir_builder_.CreatePointerCast(
545  ptr, llvm::Type::getInt16PtrTy(cgen_state_->context_));
546  case 4:
547  return cgen_state_->ir_builder_.CreatePointerCast(
548  ptr, llvm::Type::getInt32PtrTy(cgen_state_->context_));
549  case 8:
550  return cgen_state_->ir_builder_.CreatePointerCast(
551  ptr, llvm::Type::getInt64PtrTy(cgen_state_->context_));
552  default:
553  CHECK(false);
554  }
555  return nullptr;
556 }
HOST DEVICE int get_size() const
Definition: sqltypes.h:333
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:331
bool is_integer() const
Definition: sqltypes.h:452
llvm::LLVMContext & context_
Definition: CgenState.h:266
#define CHECK(condition)
Definition: Logger.h:187
bool is_string() const
Definition: sqltypes.h:450
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkExpressionRanges() [1/2]

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(), codegenUMinus(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:282
CgenState * cgen_state_
Executor * executor() const
bool is_decimal() const
Definition: sqltypes.h:453
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:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkExpressionRanges() [2/2]

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:282
CgenState * cgen_state_
Executor * executor() const
bool is_temporary_column(const Analyzer::Expr *expr)
bool is_decimal() const
Definition: sqltypes.h:453
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:77
const Expr * get_right_operand() const
Definition: Analyzer.h:436
const Expr * get_left_operand() const
Definition: Analyzer.h:435
+ Here is the call graph for this function:

◆ codegen() [1/16]

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(), executor_, Analyzer::Expr::get_type_info(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_fp(), kENCODING_DICT, and posArg().

Referenced by Executor::buildIsDeletedCb(), Executor::buildJoinLoops(), codegen(), GroupByAndAggregate::codegenAggArg(), codegenArith(), codegenArrayAt(), codegenArrayExpr(), codegenCase(), codegenCast(), codegenCmp(), codegenCmpDecimalConst(), codegenDeciDiv(), codegenDictLike(), codegenDictRegexp(), codegenDictStrCmp(), CodeGenerator(), codegenFunctionOper(), codegenFunctionOperWithCustomTypeHandling(), codegenIsNull(), OverlapsJoinHashTable::codegenKey(), BaselineJoinHashTable::codegenKey(), codegenLogical(), codegenLogicalShortCircuit(), GroupByAndAggregate::codegenOutputSlot(), codegenQualifierCmp(), JoinHashTable::codegenSlot(), codegenUMinus(), codegenUnnest(), Executor::codegenWindowFunction(), Executor::codegenWindowFunctionAggregateCalls(), Executor::compileBody(), CodeGenerator::ExecutorRequired::ExecutorRequired(), 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  if (constant->get_is_null()) {
46  const auto& ti = constant->get_type_info();
47  return {ti.is_fp()
48  ? static_cast<llvm::Value*>(executor_->cgen_state_->inlineFpNull(ti))
49  : static_cast<llvm::Value*>(executor_->cgen_state_->inlineIntNull(ti))};
50  }
51  // The dictionary encoding case should be handled by the parent expression
52  // (cast, for now), here is too late to know the dictionary id
53  CHECK_NE(kENCODING_DICT, constant->get_type_info().get_compression());
54  return {codegen(constant, constant->get_type_info().get_compression(), 0, co)};
55  }
56  auto case_expr = dynamic_cast<const Analyzer::CaseExpr*>(expr);
57  if (case_expr) {
58  return {codegen(case_expr, co)};
59  }
60  auto extract_expr = dynamic_cast<const Analyzer::ExtractExpr*>(expr);
61  if (extract_expr) {
62  return {codegen(extract_expr, co)};
63  }
64  auto dateadd_expr = dynamic_cast<const Analyzer::DateaddExpr*>(expr);
65  if (dateadd_expr) {
66  return {codegen(dateadd_expr, co)};
67  }
68  auto datediff_expr = dynamic_cast<const Analyzer::DatediffExpr*>(expr);
69  if (datediff_expr) {
70  return {codegen(datediff_expr, co)};
71  }
72  auto datetrunc_expr = dynamic_cast<const Analyzer::DatetruncExpr*>(expr);
73  if (datetrunc_expr) {
74  return {codegen(datetrunc_expr, co)};
75  }
76  auto charlength_expr = dynamic_cast<const Analyzer::CharLengthExpr*>(expr);
77  if (charlength_expr) {
78  return {codegen(charlength_expr, co)};
79  }
80  auto keyforstring_expr = dynamic_cast<const Analyzer::KeyForStringExpr*>(expr);
81  if (keyforstring_expr) {
82  return {codegen(keyforstring_expr, co)};
83  }
84  auto cardinality_expr = dynamic_cast<const Analyzer::CardinalityExpr*>(expr);
85  if (cardinality_expr) {
86  return {codegen(cardinality_expr, co)};
87  }
88  auto like_expr = dynamic_cast<const Analyzer::LikeExpr*>(expr);
89  if (like_expr) {
90  return {codegen(like_expr, co)};
91  }
92  auto regexp_expr = dynamic_cast<const Analyzer::RegexpExpr*>(expr);
93  if (regexp_expr) {
94  return {codegen(regexp_expr, co)};
95  }
96  auto likelihood_expr = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
97  if (likelihood_expr) {
98  return {codegen(likelihood_expr->get_arg(), fetch_columns, co)};
99  }
100  auto in_expr = dynamic_cast<const Analyzer::InValues*>(expr);
101  if (in_expr) {
102  return {codegen(in_expr, co)};
103  }
104  auto in_integer_set_expr = dynamic_cast<const Analyzer::InIntegerSet*>(expr);
105  if (in_integer_set_expr) {
106  return {codegen(in_integer_set_expr, co)};
107  }
108  auto function_oper_with_custom_type_handling_expr =
109  dynamic_cast<const Analyzer::FunctionOperWithCustomTypeHandling*>(expr);
110  if (function_oper_with_custom_type_handling_expr) {
112  function_oper_with_custom_type_handling_expr, co)};
113  }
114  auto array_oper_expr = dynamic_cast<const Analyzer::ArrayExpr*>(expr);
115  if (array_oper_expr) {
116  return {codegenArrayExpr(array_oper_expr, co)};
117  }
118  auto function_oper_expr = dynamic_cast<const Analyzer::FunctionOper*>(expr);
119  if (function_oper_expr) {
120  return {codegenFunctionOper(function_oper_expr, co)};
121  }
122  if (dynamic_cast<const Analyzer::OffsetInFragment*>(expr)) {
123  return {posArg(nullptr)};
124  }
125  if (dynamic_cast<const Analyzer::WindowFunction*>(expr)) {
126  throw std::runtime_error("Window expression not supported in this context");
127  }
128  abort();
129 }
bool is_fp() const
Definition: sqltypes.h:454
virtual std::vector< llvm::Value * > codegenColumn(const Analyzer::ColumnVar *, const bool fetch_column, const CompilationOptions &)
Definition: ColumnIR.cpp:92
#define CHECK_NE(x, y)
Definition: Logger.h:196
llvm::Value * codegenFunctionOper(const Analyzer::FunctionOper *, const CompilationOptions &)
Executor * executor_
std::vector< llvm::Value * > codegenArrayExpr(const Analyzer::ArrayExpr *, const CompilationOptions &)
Definition: ArrayIR.cpp:88
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * codegenFunctionOperWithCustomTypeHandling(const Analyzer::FunctionOperWithCustomTypeHandling *, const CompilationOptions &)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegen() [2/16]

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_, deviceCount(), 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 }
std::vector< llvm::Value * > codegenHoistedConstants(const std::vector< const Analyzer::Constant *> &constants, const EncodingType enc_type, const int dict_id)
Definition: ConstantIR.cpp:287
Definition: sqltypes.h:51
CgenState * cgen_state_
Executor * executor() const
llvm::Value * addStringConstant(const std::string &str)
Definition: CgenState.h:187
bool boolval
Definition: sqltypes.h:122
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
float floatval
Definition: sqltypes.h:127
Datum get_constval() const
Definition: Analyzer.h:328
llvm::LLVMContext & context_
Definition: CgenState.h:266
ExecutorDeviceType device_type_
std::string * stringval
Definition: sqltypes.h:131
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:268
bool get_is_null() const
Definition: Analyzer.h:327
Definition: sqltypes.h:54
Definition: sqltypes.h:55
Definition: sqltypes.h:43
llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant)
Definition: ConstantIR.cpp:88
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
Definition: sqltypes.h:47
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
double doubleval
Definition: sqltypes.h:128
int deviceCount(const Catalog_Namespace::Catalog *catalog, const ExecutorDeviceType device_type)
+ Here is the call graph for this function:

◆ codegen() [3/16]

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:195
const Expr * get_arg() const
Definition: Analyzer.h:577
CgenState * cgen_state_
Executor * executor() const
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
Definition: sqldefs.h:30
llvm::LLVMContext & context_
Definition: CgenState.h:266
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:196
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:69
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::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
std::unique_ptr< InValuesBitmap > createInValuesBitmap(const Analyzer::InValues *, const CompilationOptions &)
Definition: InValuesIR.cpp:113
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1059
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:579
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [4/16]

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(), CgenState::inlineIntNull(), is_unnest(), kBOOLEAN, 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  if (in_vals_bitmap->isEmpty()) {
104  return in_vals_bitmap->hasNull()
106  : result;
107  }
108  CHECK_EQ(size_t(1), lhs_lvs.size());
109  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
110  ->codegen(lhs_lvs.front(), executor());
111 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
CgenState * cgen_state_
Executor * executor() const
llvm::LLVMContext & context_
Definition: CgenState.h:266
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:196
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1059
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [5/16]

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:195
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const Expr * get_else_expr() const
Definition: Analyzer.h:1044
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:

◆ codegen() [6/16]

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,
56  cgen_state_->llInt(
57  get_extract_timestamp_precision_scale(extract_expr->get_field())),
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 }
constexpr int64_t get_extract_timestamp_precision_scale(const ExtractField field)
Definition: DateTimeUtils.h:78
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Value * codegenExtractHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const ExtractField &)
Definition: DateTimeIR.cpp:155
const Expr * get_from_expr() const
Definition: Analyzer.h:1089
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:55
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
ExtractField get_field() const
Definition: Analyzer.h:1088
constexpr bool is_subsecond_extract_field(const ExtractField &field)
Definition: DateTimeUtils.h:92
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [7/16]

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

Definition at line 71 of file DateTimeIR.cpp.

References CHECK, 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(), kDATE, and kTIMESTAMP.

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 }
const Expr * get_datetime_expr() const
Definition: Analyzer.h:1131
CgenState * cgen_state_
DateaddField get_field() const
Definition: Analyzer.h:1129
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:55
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
const Expr * get_number_expr() const
Definition: Analyzer.h:1130
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [8/16]

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

Definition at line 102 of file DateTimeIR.cpp.

References CHECK, SQLTypeInfoCore< TYPE_FACET_PACK >::get_dimension(), Analyzer::DatediffExpr::get_end_expr(), Analyzer::DatediffExpr::get_field(), get_int_type(), Analyzer::DatediffExpr::get_start_expr(), DateTimeUtils::get_timestamp_precision_scale(), and Analyzer::Expr::get_type_info().

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_
const Expr * get_start_expr() const
Definition: Analyzer.h:1172
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
DatetruncField get_field() const
Definition: Analyzer.h:1171
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
const Expr * get_end_expr() const
Definition: Analyzer.h:1173
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [9/16]

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

Definition at line 135 of file DateTimeIR.cpp.

References CHECK, Analyzer::DatetruncExpr::get_field(), Analyzer::DatetruncExpr::get_from_expr(), get_int_type(), and Analyzer::Expr::get_type_info().

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_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
DatetruncField get_field() const
Definition: Analyzer.h:1213
llvm::LLVMContext & context_
Definition: CgenState.h:266
const Expr * get_from_expr() const
Definition: Analyzer.h:1214
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:203
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
llvm::Value * codegenDateTruncHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
Definition: DateTimeIR.cpp:198
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [10/16]

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

Definition at line 56 of file StringOpsIR.cpp.

References cgen_state_, CHECK_EQ, codegen(), CgenState::context_, CompilationOptions::device_type_, CgenState::emitCall(), CgenState::emitExternalCall(), g_enable_watchdog, Analyzer::CharLengthExpr::get_arg(), Analyzer::CharLengthExpr::get_calc_encoded_length(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), Analyzer::Expr::get_type_info(), GPU, and CgenState::inlineIntNull().

57  {
58  auto str_lv = codegen(expr->get_arg(), true, co);
59  if (str_lv.size() != 3) {
60  CHECK_EQ(size_t(1), str_lv.size());
61  if (g_enable_watchdog) {
62  throw WatchdogException(
63  "LENGTH / CHAR_LENGTH on dictionary-encoded strings would be slow");
64  }
65  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
66  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
68  throw QueryMustRunOnCpu();
69  }
70  }
71  std::vector<llvm::Value*> charlength_args{str_lv[1], str_lv[2]};
72  std::string fn_name("char_length");
73  if (expr->get_calc_encoded_length()) {
74  fn_name += "_encoded";
75  }
76  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
77  if (is_nullable) {
78  fn_name += "_nullable";
79  charlength_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
80  }
81  return expr->get_calc_encoded_length()
83  fn_name, get_int_type(32, cgen_state_->context_), charlength_args)
84  : cgen_state_->emitCall(fn_name, charlength_args);
85 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
bool get_calc_encoded_length() const
Definition: Analyzer.h:651
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
const Expr * get_arg() const
Definition: Analyzer.h:649
bool g_enable_watchdog
Definition: Execute.cpp:69
+ Here is the call graph for this function:

◆ codegen() [11/16]

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

Definition at line 87 of file StringOpsIR.cpp.

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

88  {
89  auto str_lv = codegen(expr->get_arg(), true, co);
90  CHECK_EQ(size_t(1), str_lv.size());
91  return cgen_state_->emitCall("key_for_string_encoded", str_lv);
92 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
CgenState * cgen_state_
const Expr * get_arg() const
Definition: Analyzer.h:698
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
+ Here is the call graph for this function:

◆ codegen() [12/16]

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

Definition at line 94 of file StringOpsIR.cpp.

References cgen_state_, CHECK, CHECK_EQ, codegen(), codegenDictLike(), CompilationOptions::device_type_, 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(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), Analyzer::LikeExpr::get_own_arg(), Analyzer::Expr::get_type_info(), GPU, CgenState::inlineIntNull(), is_unnest(), kENCODING_NONE, and CgenState::llInt().

95  {
96  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
97  throw std::runtime_error("LIKE not supported for unnested expressions");
98  }
99  char escape_char{'\\'};
100  if (expr->get_escape_expr()) {
101  auto escape_char_expr =
102  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
103  CHECK(escape_char_expr);
104  CHECK(escape_char_expr->get_type_info().is_string());
105  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
106  escape_char = (*escape_char_expr->get_constval().stringval)[0];
107  }
108  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_like_expr());
109  CHECK(pattern);
110  auto fast_dict_like_lv = codegenDictLike(expr->get_own_arg(),
111  pattern,
112  expr->get_is_ilike(),
113  expr->get_is_simple(),
114  escape_char,
115  co);
116  if (fast_dict_like_lv) {
117  return fast_dict_like_lv;
118  }
119  const auto& ti = expr->get_arg()->get_type_info();
120  CHECK(ti.is_string());
121  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
122  throw WatchdogException(
123  "Cannot do LIKE / ILIKE on this dictionary encoded column, its cardinality is "
124  "too high");
125  }
126  auto str_lv = codegen(expr->get_arg(), true, co);
127  if (str_lv.size() != 3) {
128  CHECK_EQ(size_t(1), str_lv.size());
129  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
130  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
132  throw QueryMustRunOnCpu();
133  }
134  }
135  auto like_expr_arg_lvs = codegen(expr->get_like_expr(), true, co);
136  CHECK_EQ(size_t(3), like_expr_arg_lvs.size());
137  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
138  std::vector<llvm::Value*> str_like_args{
139  str_lv[1], str_lv[2], like_expr_arg_lvs[1], like_expr_arg_lvs[2]};
140  std::string fn_name{expr->get_is_ilike() ? "string_ilike" : "string_like"};
141  if (expr->get_is_simple()) {
142  fn_name += "_simple";
143  } else {
144  str_like_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
145  }
146  if (is_nullable) {
147  fn_name += "_nullable";
148  str_like_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
149  }
150  return cgen_state_->emitCall(fn_name, str_like_args);
151 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
bool get_is_simple() const
Definition: Analyzer.h:802
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:149
const Expr * get_arg() const
Definition: Analyzer.h:797
const Expr * get_escape_expr() const
Definition: Analyzer.h:800
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
bool g_enable_watchdog
Definition: Execute.cpp:69
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1059
const Expr * get_like_expr() const
Definition: Analyzer.h:799
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:798
bool get_is_ilike() const
Definition: Analyzer.h:801
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
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:

◆ codegen() [13/16]

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

Definition at line 308 of file StringOpsIR.cpp.

References cgen_state_, CHECK, CHECK_EQ, codegen(), codegenDictRegexp(), CgenState::context_, CompilationOptions::device_type_, CgenState::emitCall(), CgenState::emitExternalCall(), extract_cast_arg(), g_enable_watchdog, Analyzer::RegexpExpr::get_arg(), Analyzer::RegexpExpr::get_escape_expr(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), Analyzer::RegexpExpr::get_own_arg(), Analyzer::RegexpExpr::get_pattern_expr(), Analyzer::Expr::get_type_info(), GPU, CgenState::inlineIntNull(), is_unnest(), kENCODING_NONE, and CgenState::llInt().

309  {
310  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
311  throw std::runtime_error("REGEXP not supported for unnested expressions");
312  }
313  char escape_char{'\\'};
314  if (expr->get_escape_expr()) {
315  auto escape_char_expr =
316  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
317  CHECK(escape_char_expr);
318  CHECK(escape_char_expr->get_type_info().is_string());
319  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
320  escape_char = (*escape_char_expr->get_constval().stringval)[0];
321  }
322  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_pattern_expr());
323  CHECK(pattern);
324  auto fast_dict_pattern_lv =
325  codegenDictRegexp(expr->get_own_arg(), pattern, escape_char, co);
326  if (fast_dict_pattern_lv) {
327  return fast_dict_pattern_lv;
328  }
329  const auto& ti = expr->get_arg()->get_type_info();
330  CHECK(ti.is_string());
331  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
332  throw WatchdogException(
333  "Cannot do REGEXP_LIKE on this dictionary encoded column, its cardinality is too "
334  "high");
335  }
336  // Now we know we are working on NONE ENCODED column. So switch back to CPU
338  throw QueryMustRunOnCpu();
339  }
340  auto str_lv = codegen(expr->get_arg(), true, co);
341  if (str_lv.size() != 3) {
342  CHECK_EQ(size_t(1), str_lv.size());
343  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
344  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
345  }
346  auto regexp_expr_arg_lvs = codegen(expr->get_pattern_expr(), true, co);
347  CHECK_EQ(size_t(3), regexp_expr_arg_lvs.size());
348  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
349  std::vector<llvm::Value*> regexp_args{
350  str_lv[1], str_lv[2], regexp_expr_arg_lvs[1], regexp_expr_arg_lvs[2]};
351  std::string fn_name("regexp_like");
352  regexp_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
353  if (is_nullable) {
354  fn_name += "_nullable";
355  regexp_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
357  fn_name, get_int_type(8, cgen_state_->context_), regexp_args);
358  }
360  fn_name, get_int_type(1, cgen_state_->context_), regexp_args);
361 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:149
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
llvm::Value * codegenDictRegexp(const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const char escape_char, const CompilationOptions &)
ExecutorDeviceType device_type_
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:869
const Expr * get_pattern_expr() const
Definition: Analyzer.h:871
const Expr * get_escape_expr() const
Definition: Analyzer.h:872
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:870
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
bool g_enable_watchdog
Definition: Execute.cpp:69
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1059
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [14/16]

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::Type * get_int_type(const int width, llvm::LLVMContext &context)
const Expr * get_arg() const
Definition: Analyzer.h:743
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
#define CHECK(condition)
Definition: Logger.h:187
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:124
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:

◆ codegen() [15/16]

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

Definition at line 131 of file IRCodegen.cpp.

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

132  {
133  const auto optype = bin_oper->get_optype();
134  if (IS_ARITHMETIC(optype)) {
135  return codegenArith(bin_oper, co);
136  }
137  if (IS_COMPARISON(optype)) {
138  return codegenCmp(bin_oper, co);
139  }
140  if (IS_LOGIC(optype)) {
141  return codegenLogical(bin_oper, co);
142  }
143  if (optype == kARRAY_AT) {
144  return codegenArrayAt(bin_oper, co);
145  }
146  abort();
147 }
#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:432
#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:

◆ codegen() [16/16]

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

Definition at line 149 of file IRCodegen.cpp.

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

150  {
151  const auto optype = u_oper->get_optype();
152  switch (optype) {
153  case kNOT: {
154  return codegenLogical(u_oper, co);
155  }
156  case kCAST: {
157  return codegenCast(u_oper, co);
158  }
159  case kUMINUS: {
160  return codegenUMinus(u_oper, co);
161  }
162  case kISNULL: {
163  return codegenIsNull(u_oper, co);
164  }
165  case kUNNEST:
166  return codegenUnnest(u_oper, co);
167  default:
168  abort();
169  }
170 }
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:363
+ Here is the call graph for this function:

◆ codegenAdd()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
HOST DEVICE int get_size() const
Definition: sqltypes.h:333
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Function * row_func_
Definition: CgenState.h:264
bool is_timeinterval() const
Definition: sqltypes.h:461
bool is_integer() const
Definition: sqltypes.h:452
llvm::LLVMContext & context_
Definition: CgenState.h:266
bool is_decimal() const
Definition: sqltypes.h:453
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:1010
bool needs_error_check_
Definition: CgenState.h:283
ExecutorDeviceType device_type_
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
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
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenArith()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
llvm::Value * codegenDeciDiv(const Analyzer::BinOper *, const CompilationOptions &)
SQLOps get_optype() const
Definition: Analyzer.h:432
llvm::Value * codegenFpArith(const Analyzer::BinOper *, llvm::Value *, llvm::Value *)
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:228
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 SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
const Expr * get_right_operand() const
Definition: Analyzer.h:436
const Expr * get_left_operand() const
Definition: Analyzer.h:435
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenArrayAt()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
#define CHECK(condition)
Definition: Logger.h:187
const Expr * get_right_operand() const
Definition: Analyzer.h:436
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:62
const Expr * get_left_operand() const
Definition: Analyzer.h:435
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenArrayExpr()

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(), get_int_array_type(), get_int_type(), Analyzer::Expr::get_type_info(), Analyzer::ArrayExpr::getElement(), Analyzer::ArrayExpr::getElementCount(), GPU, CgenState::ir_builder_, is_member_of_typeset(), Analyzer::ArrayExpr::isLocalAlloc(), kBIGINT, kCHAR, kDATE, kDECIMAL, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kNUMERIC, kSMALLINT, kTEXT, kTIME, kTIMESTAMP, kTINYINT, kVARCHAR, and CgenState::llInt().

Referenced by codegen(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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 =
139  ir_builder.CreateGEP(array_type,
140  casted_allocated_target_buffer,
141  {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:51
size_t getElementCount() const
Definition: Analyzer.h:1380
CgenState * cgen_state_
bool is_member_of_typeset(SQL_INFO_TYPE const &s)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
bool isLocalAlloc() const
Definition: Analyzer.h:1382
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const Analyzer::Expr * getElement(const size_t i) const
Definition: Analyzer.h:1384
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
ExecutorDeviceType device_type_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqltypes.h:54
Definition: sqltypes.h:55
Definition: sqltypes.h:43
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
Definition: sqltypes.h:47
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenBinOpWithOverflowForCPU()

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(func, {lhs_lv, rhs_lv});
732  auto ret = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow, {0});
733  auto overflow = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow, {1});
734  auto val_bb = cgen_state_->ir_builder_.GetInsertBlock();
735 
736  // Return error on overflow
737  cgen_state_->ir_builder_.CreateCondBr(overflow, check_fail, check_ok);
738  cgen_state_->ir_builder_.SetInsertPoint(check_fail);
739  cgen_state_->ir_builder_.CreateRet(
741 
742  cgen_state_->ir_builder_.SetInsertPoint(check_ok);
743 
744  // In case of null check we have to use NULL result on check fail
745  if (null_check) {
746  auto phi = cgen_state_->ir_builder_.CreatePHI(ret->getType(), 2);
747  phi->addIncoming(llvm::ConstantInt::get(ret->getType(), inline_int_null_val(ti)),
748  null_check);
749  phi->addIncoming(ret, val_bb);
750  ret = phi;
751  }
752 
753  return ret;
754 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Function * row_func_
Definition: CgenState.h:264
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:1010
bool needs_error_check_
Definition: CgenState.h:283
llvm::Function * getArithWithOverflowIntrinsic(const Analyzer::BinOper *bin_oper, llvm::Type *type)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCase()

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, CHECK_EQ, codegen(), CgenState::context_, CgenState::emitCall(), Analyzer::CaseExpr::get_else_expr(), Analyzer::CaseExpr::get_expr_pair_list(), CgenState::ir_builder_, CgenState::row_func_, and toBool().

Referenced by codegen(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Function * row_func_
Definition: CgenState.h:264
const Expr * get_else_expr() const
Definition: Analyzer.h:1044
llvm::LLVMContext & context_
Definition: CgenState.h:266
const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr > > > & get_expr_pair_list() const
Definition: Analyzer.h:1041
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
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
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCast() [1/2]

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(), codegenFunctionOperCastArgs(), codegenFunctionOperWithCustomTypeHandling(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
CgenState * cgen_state_
Definition: sqldefs.h:49
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
SQLOps get_optype() const
Definition: Analyzer.h:363
const Expr * get_operand() const
Definition: Analyzer.h:364
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCast() [2/2]

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 }
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
bool is_time() const
Definition: sqltypes.h:456
HOST DEVICE int get_size() const
Definition: sqltypes.h:333
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:325
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:357
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:46
bool is_integer() const
Definition: sqltypes.h:452
llvm::LLVMContext & context_
Definition: CgenState.h:266
bool is_decimal() const
Definition: sqltypes.h:453
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:228
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:107
bool is_boolean() const
Definition: sqltypes.h:457
Definition: sqltypes.h:55
#define CHECK(condition)
Definition: Logger.h:187
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
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_string() const
Definition: sqltypes.h:450
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:

◆ codegenCastBetweenIntTypes()

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(), CodeGenerator(), 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_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE int get_scale() const
Definition: sqltypes.h:328
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_integer() const
Definition: sqltypes.h:452
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:266
bool is_decimal() const
Definition: sqltypes.h:453
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:300
int get_logical_size() const
Definition: sqltypes.h:334
#define CHECK(condition)
Definition: Logger.h:187
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:157
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCastBetweenIntTypesOverflowChecks()

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(), Executor::ERR_OVERFLOW_OR_UNDERFLOW, 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(), and CodeGenerator().

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_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:264
llvm::LLVMContext & context_
Definition: CgenState.h:266
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:1010
bool needs_error_check_
Definition: CgenState.h:283
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
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
int get_logical_size() const
Definition: sqltypes.h:334
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:157
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:74
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCastBetweenTimestamps()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:266
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:203
#define CHECK(condition)
Definition: Logger.h:187
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCastFromFp()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:454
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string get_type_name() const
Definition: sqltypes.h:426
bool is_integer() const
Definition: sqltypes.h:452
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:266
bool is_decimal() const
Definition: sqltypes.h:453
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
bool is_number() const
Definition: sqltypes.h:455
#define CHECK(condition)
Definition: Logger.h:187
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:157
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:

◆ codegenCastFromString()

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(), g_cluster, g_enable_watchdog, 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, and kENCODING_NONE.

Referenced by codegenCast(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:195
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:331
std::string get_type_name() const
Definition: sqltypes.h:426
llvm::LLVMContext & context_
Definition: CgenState.h:266
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:203
ExecutorDeviceType device_type_
#define CHECK(condition)
Definition: Logger.h:187
bool g_cluster
bool g_enable_watchdog
Definition: Execute.cpp:69
bool is_string() const
Definition: sqltypes.h:450
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCastTimestampToDate()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:266
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:203
#define CHECK(condition)
Definition: Logger.h:187
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCastToFp()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:454
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE int get_scale() const
Definition: sqltypes.h:328
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
std::string get_type_name() const
Definition: sqltypes.h:426
llvm::LLVMContext & context_
Definition: CgenState.h:266
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
#define CHECK(condition)
Definition: Logger.h:187
uint64_t exp_to_scale(const unsigned exp)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:157
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:

◆ codegenCmp() [1/2]

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(), codegenCmpDecimalConst(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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 }
SQLQualifier get_qualifier() const
Definition: Analyzer.h:434
#define CHECK_EQ(x, y)
Definition: Logger.h:195
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
std::shared_ptr< Analyzer::BinOper > lower_bw_eq(const Analyzer::BinOper *bw_eq)
Definition: CompareIR.cpp:125
SQLOps get_optype() const
Definition: Analyzer.h:432
llvm::Value * codegenCmpDecimalConst(const SQLOps, const SQLQualifier, const Analyzer::Expr *, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:341
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
const std::shared_ptr< Analyzer::Expr > get_own_left_operand() const
Definition: Analyzer.h:437
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const std::shared_ptr< Analyzer::Expr > get_own_right_operand() const
Definition: Analyzer.h:440
Definition: sqldefs.h:32
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
#define CHECK(condition)
Definition: Logger.h:187
Definition: sqldefs.h:31
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:289
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1059
const Expr * get_right_operand() const
Definition: Analyzer.h:436
const Expr * get_left_operand() const
Definition: Analyzer.h:435
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenCmp() [2/2]

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(), anonymous_namespace{CompareIR.cpp}::icmp_name(), inline_int_null_val(), CgenState::inlineIntNull(), CgenState::ir_builder_, 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(), kBOOLEAN, kDOUBLE, kENCODING_NONE, kEQ, kFLOAT, kNE, kONE, kOVERLAPS, CgenState::llFp(), CgenState::llInt(), anonymous_namespace{CompareIR.cpp}::llvm_fcmp_pred(), anonymous_namespace{CompareIR.cpp}::llvm_icmp_pred(), NULL_DOUBLE, NULL_FLOAT, numeric_type_name(), and anonymous_namespace{CompareIR.cpp}::string_cmp_func().

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 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
#define NULL_DOUBLE
Definition: sqltypes.h:176
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:251
bool is_time() const
Definition: sqltypes.h:456
std::string icmp_name(const SQLOps op_type)
Definition: CompareIR.cpp:45
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:323
Definition: sqldefs.h:30
llvm::CmpInst::Predicate llvm_fcmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:83
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:331
bool is_timeinterval() const
Definition: sqltypes.h:461
bool is_integer() const
Definition: sqltypes.h:452
bool is_decimal() const
Definition: sqltypes.h:453
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
#define NULL_FLOAT
Definition: sqltypes.h:175
std::string get_null_check_suffix(const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
Definition: Execute.h:1043
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
bool is_boolean() const
Definition: sqltypes.h:457
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:69
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
Definition: sqldefs.h:32
llvm::CmpInst::Predicate llvm_icmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:26
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_geometry() const
Definition: sqltypes.h:462
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:157
llvm::Value * codegenQualifierCmp(const SQLOps, const SQLQualifier, std::vector< llvm::Value *>, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:471
bool is_string() const
Definition: sqltypes.h:450
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
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:

◆ codegenCmpDecimalConst()

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(), anonymous_namespace{ImportTest.cpp}::d(), exp_to_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_scale(), Analyzer::Expr::get_type_info(), kCAST, and kDECIMAL.

Referenced by codegenCmp(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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 }
void d(const SQLTypes expected_type, const std::string &str)
Definition: ImportTest.cpp:268
HOST DEVICE int get_scale() const
Definition: sqltypes.h:328
Definition: sqldefs.h:49
int64_t bigintval
Definition: sqltypes.h:126
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
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
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
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:

◆ codegenColumn()

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 Analyzer::ColumnVar::get_rte_idx().

Referenced by codegen(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:279
CgenState * cgen_state_
std::vector< llvm::Value * > codegenOuterJoinNullPlaceholder(const Analyzer::ColumnVar *col_var, const bool fetch_column, const CompilationOptions &co)
Definition: ColumnIR.cpp:412
llvm::Value * foundOuterJoinMatch(const ssize_t nesting_level) const
Definition: ColumnIR.cpp:405
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:195
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenColVar()

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(), CHECK, CHECK_LT, ColumnDescriptor::columnType, get_column_descriptor(), Analyzer::ColumnVar::get_column_id(), Analyzer::ColumnVar::get_table_id(), Analyzer::Expr::get_type_info(), WindowProjectNodeContext::getActiveWindowFunctionContext(), CompilationOptions::hoist_literals_, SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), and kENCODING_NONE.

Referenced by CodeGenerator::ExecutorRequired::ExecutorRequired().

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_column_id() const
Definition: Analyzer.h:194
std::shared_ptr< const Analyzer::Expr > hashJoinLhs(const Analyzer::ColumnVar *rhs) const
Definition: ColumnIR.cpp:539
CgenState * cgen_state_
llvm::Value * codegenRowId(const Analyzer::ColumnVar *col_var, const CompilationOptions &co)
Definition: ColumnIR.cpp:312
Executor * executor() const
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
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
int getLocalColumnId(const Analyzer::ColumnVar *col_var, const bool fetch_column)
Definition: PlanState.cpp:62
std::unordered_map< int, std::vector< llvm::Value * > > fetch_cache_
Definition: CgenState.h:269
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:103
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:197
std::vector< llvm::Value * > frag_offsets_
Definition: CgenState.h:277
int get_table_id() const
Definition: Analyzer.h:193
llvm::Value * codegenFixedLengthColVarInWindow(const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:270
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:503
#define CHECK(condition)
Definition: Logger.h:187
llvm::Value * colByteStream(const Analyzer::ColumnVar *col_var, const bool fetch_column, const bool hoist_literals)
Definition: ColumnIR.cpp:487
bool is_geometry() const
Definition: sqltypes.h:462
llvm::Value * codegenWindowPosition(WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:221
SQLTypeInfo columnType
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:139
llvm::Value * resolveGroupedColumnReference(const Analyzer::ColumnVar *)
Definition: ColumnIR.cpp:468
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenDateTruncHighPrecisionTimestamps()

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

Definition at line 198 of file DateTimeIR.cpp.

References CHECK, DateTimeUtils::get_datetrunc_high_precision_scale(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_dimension(), get_int_type(), SQLTypeInfoCore< TYPE_FACET_PACK >::get_notnull(), DateTimeUtils::get_timestamp_precision_scale(), DateTimeUtils::is_subsecond_datetrunc_field(), and run-benchmark-import::result.

Referenced by CodeGenerator::ExecutorRequired::ExecutorRequired().

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 }
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:325
CgenState * cgen_state_
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:330
llvm::IRBuilder ir_builder_
Definition: CgenState.h:268
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:266
constexpr bool is_subsecond_datetrunc_field(const DatetruncField field)
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:203
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value *> &args)
Definition: CgenState.cpp:134
#define CHECK(condition)
Definition: Logger.h:187
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:48
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:247
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:

◆ codegenDeciDiv()

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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

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:108
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)
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:1043
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
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
uint64_t exp_to_scale(const unsigned exp)
const Expr * get_right_operand() const
Definition: Analyzer.h:436
const Expr * get_left_operand() const
Definition: Analyzer.h:435
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenDictLike()

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 153 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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

159  {
160  const auto cast_oper = std::dynamic_pointer_cast<Analyzer::UOper>(like_arg);
161  if (!cast_oper) {
162  return nullptr;
163  }
164  CHECK(cast_oper);
165  CHECK_EQ(kCAST, cast_oper->get_optype());
166  const auto dict_like_arg = cast_oper->get_own_operand();
167  const auto& dict_like_arg_ti = dict_like_arg->get_type_info();
168  if (!dict_like_arg_ti.is_string()) {
169  throw(std::runtime_error("Cast from " + dict_like_arg_ti.get_type_name() + " to " +
170  cast_oper->get_type_info().get_type_name() +
171  " not supported"));
172  }
173  CHECK_EQ(kENCODING_DICT, dict_like_arg_ti.get_compression());
174  const auto sdp = executor()->getStringDictionaryProxy(
175  dict_like_arg_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true);
176  if (sdp->storageEntryCount() > 200000000) {
177  return nullptr;
178  }
179  const auto& pattern_ti = pattern->get_type_info();
180  CHECK(pattern_ti.is_string());
181  CHECK_EQ(kENCODING_NONE, pattern_ti.get_compression());
182  const auto& pattern_datum = pattern->get_constval();
183  const auto& pattern_str = *pattern_datum.stringval;
184  const auto matching_ids = sdp->getLike(pattern_str, ilike, is_simple, escape_char);
185  // InIntegerSet requires 64-bit values
186  std::vector<int64_t> matching_ids_64(matching_ids.size());
187  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
188  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
189  dict_like_arg, matching_ids_64, dict_like_arg_ti.get_notnull());
190  return codegen(in_values.get(), co);
191 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
Executor * executor() const
Definition: sqldefs.h:49
Datum get_constval() const
Definition: Analyzer.h:328
std::string * stringval
Definition: sqltypes.h:131
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenDictRegexp()

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 363 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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

367  {
368  const auto cast_oper = std::dynamic_pointer_cast<Analyzer::UOper>(pattern_arg);
369  if (!cast_oper) {
370  return nullptr;
371  }
372  CHECK(cast_oper);
373  CHECK_EQ(kCAST, cast_oper->get_optype());
374  const auto dict_regexp_arg = cast_oper->get_own_operand();
375  const auto& dict_regexp_arg_ti = dict_regexp_arg->get_type_info();
376  CHECK(dict_regexp_arg_ti.is_string());
377  CHECK_EQ(kENCODING_DICT, dict_regexp_arg_ti.get_compression());
378  const auto comp_param = dict_regexp_arg_ti.get_comp_param();
379  const auto sdp = executor()->getStringDictionaryProxy(
380  comp_param, executor()->getRowSetMemoryOwner(), true);
381  if (sdp->storageEntryCount() > 15000000) {
382  return nullptr;
383  }
384  const auto& pattern_ti = pattern->get_type_info();
385  CHECK(pattern_ti.is_string());
386  CHECK_EQ(kENCODING_NONE, pattern_ti.get_compression());
387  const auto& pattern_datum = pattern->get_constval();
388  const auto& pattern_str = *pattern_datum.stringval;
389  const auto matching_ids = sdp->getRegexpLike(pattern_str, escape_char);
390  // InIntegerSet requires 64-bit values
391  std::vector<int64_t> matching_ids_64(matching_ids.size());
392  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
393  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
394  dict_regexp_arg, matching_ids_64, dict_regexp_arg_ti.get_notnull());
395  return codegen(in_values.get(), co);
396 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
Executor * executor() const
Definition: sqldefs.h:49
Datum get_constval() const
Definition: Analyzer.h:328
std::string * stringval
Definition: sqltypes.h:131
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenDictStrCmp()

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 226 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(), and CodeGenerator::ExecutorRequired::ExecutorRequired().

229  {
230  auto rhs_cast_oper = std::dynamic_pointer_cast<const Analyzer::UOper>(rhs);
231  auto lhs_cast_oper = std::dynamic_pointer_cast<const Analyzer::UOper>(lhs);
232  auto rhs_col_var = std::dynamic_pointer_cast<const Analyzer::ColumnVar>(rhs);
233  auto lhs_col_var = std::dynamic_pointer_cast<const Analyzer::ColumnVar>(lhs);
234  std::shared_ptr<const Analyzer::UOper> cast_oper;
235  std::shared_ptr<const Analyzer::ColumnVar> col_var;
236  auto compare_opr = compare_operator;
237  if (lhs_col_var && rhs_col_var) {
238  if (lhs_col_var->get_type_info().get_comp_param() ==
239  rhs_col_var->get_type_info().get_comp_param()) {
240  if (compare_operator == kEQ || compare_operator == kNE) {
241  // TODO (vraj): implement compare between two dictionary encoded columns which
242  // share a dictionary
243  return nullptr;
244  }
245  }
246  // TODO (vraj): implement compare between two dictionary encoded columns which don't
247  // shared dictionary
248  throw std::runtime_error("Decoding two Dictionary encoded columns will be slow");
249  } else if (lhs_col_var && rhs_cast_oper) {
250  cast_oper.swap(rhs_cast_oper);
251  col_var.swap(lhs_col_var);
252  } else if (lhs_cast_oper && rhs_col_var) {
253  cast_oper.swap(lhs_cast_oper);
254  col_var.swap(rhs_col_var);
255  switch (compare_operator) {
256  case kLT:
257  compare_opr = kGT;
258  break;
259  case kLE:
260  compare_opr = kGE;
261  break;
262  case kGT:
263  compare_opr = kLT;
264  break;
265  case kGE:
266  compare_opr = kLE;
267  default:
268  break;
269  }
270  }
271  if (!cast_oper || !col_var) {
272  return nullptr;
273  }
274  CHECK_EQ(kCAST, cast_oper->get_optype());
275 
276  const auto const_expr =
277  dynamic_cast<Analyzer::Constant*>(cast_oper->get_own_operand().get());
278  if (!const_expr) {
279  // Analyzer casts dictionary encoded columns to none encoded if there is a comparison
280  // between two encoded columns. Which we currently do not handle.
281  return nullptr;
282  }
283  const auto& const_val = const_expr->get_constval();
284 
285  const auto col_ti = col_var->get_type_info();
286  CHECK(col_ti.is_string());
287  CHECK_EQ(kENCODING_DICT, col_ti.get_compression());
288  const auto sdp = executor()->getStringDictionaryProxy(
289  col_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true);
290 
291  if (sdp->storageEntryCount() > 200000000) {
292  std::runtime_error("Cardinality for string dictionary is too high");
293  return nullptr;
294  }
295 
296  const auto& pattern_str = *const_val.stringval;
297  const auto matching_ids = get_compared_ids(sdp, compare_opr, pattern_str);
298 
299  // InIntegerSet requires 64-bit values
300  std::vector<int64_t> matching_ids_64(matching_ids.size());
301  std::copy(matching_ids.begin(), matching_ids.end(), matching_ids_64.begin());
302 
303  const auto in_values = std::make_shared<Analyzer::InIntegerSet>(
304  col_var, matching_ids_64, col_ti.get_notnull());
305  return codegen(in_values.get(), co);
306 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::vector< int32_t > get_compared_ids(const StringDictionaryProxy *dict, const SQLOps compare_operator, const std::string &pattern)
Executor * executor() const
Definition: sqldefs.h:35
Definition: sqldefs.h:36
Definition: sqldefs.h:49
Definition: sqldefs.h:30
Datum get_constval() const
Definition: Analyzer.h:328
Definition: sqldefs.h:34
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:25
Definition: sqldefs.h:32
#define CHECK(condition)
Definition: Logger.h:187
Definition: sqldefs.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ codegenDiv()

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