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

#include <CodeGenerator.h>

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

Classes

struct  ArgNullcheckBBs
 
struct  ExecutorRequired
 
struct  GPUTarget
 
struct  NullCheckCodegen
 

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, llvm::LLVMContext &context)
 
static std::unique_ptr
< llvm::TargetMachine > 
initializeNVPTXBackend (const CudaMgr_Namespace::NvidiaDeviceArch arch)
 
static bool alwaysCloneRuntimeFunction (const llvm::Function *func)
 
static std::shared_ptr
< GpuCompilationContext
generateNativeGPUCode (llvm::Function *func, llvm::Function *wrapper_func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co, const GPUTarget &gpu_target)
 
static void link_udf_module (const std::unique_ptr< llvm::Module > &udf_module, llvm::Module &module, CgenState *cgen_state, llvm::Linker::Flags flags=llvm::Linker::Flags::None)
 
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::SampleRatioExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::LowerExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::LikeExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::RegexpExpr *, const CompilationOptions &)
 
llvm::Value * codegenUnnest (const Analyzer::UOper *, const CompilationOptions &)
 
llvm::Value * codegenArrayAt (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::CardinalityExpr *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenArrayExpr (const Analyzer::ArrayExpr *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoUOper (const Analyzer::GeoUOper *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoBinOper (const Analyzer::GeoBinOper *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeosPredicateCall (const std::string &, std::vector< llvm::Value * >, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeosConstructorCall (const std::string &, std::vector< llvm::Value * >, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoArgs (const std::vector< std::shared_ptr< Analyzer::Expr >> &, 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 SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
 
llvm::Value * codegenCastFromString (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
 
llvm::Value * codegenCastToFp (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
 
llvm::Value * codegenCastFromFp (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
 
llvm::Value * codegenAdd (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &)
 
llvm::Value * codegenSub (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &)
 
void codegenSkipOverflowCheckForNull (llvm::Value *lhs_lv, llvm::Value *rhs_lv, llvm::BasicBlock *no_overflow_bb, const SQLTypeInfo &ti)
 
llvm::Value * codegenMul (const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, const CompilationOptions &, bool downscale=true)
 
llvm::Value * codegenDiv (llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &, bool upscale=true)
 
llvm::Value * codegenDeciDiv (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenMod (llvm::Value *, llvm::Value *, const std::string &null_typename, const std::string &null_check_suffix, const SQLTypeInfo &)
 
llvm::Value * codegenCase (const Analyzer::CaseExpr *, llvm::Type *case_llvm_type, const bool is_real_str, const CompilationOptions &)
 
llvm::Value * codegenExtractHighPrecisionTimestamps (llvm::Value *, const SQLTypeInfo &, const ExtractField &)
 
llvm::Value * codegenDateTruncHighPrecisionTimestamps (llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
 
llvm::Value * codegenCmpDecimalConst (const SQLOps, const SQLQualifier, const Analyzer::Expr *, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
 
llvm::Value * codegenOverlaps (const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
 
llvm::Value * codegenStrCmp (const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
 
llvm::Value * codegenQualifierCmp (const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const Analyzer::Expr *, const CompilationOptions &)
 
llvm::Value * codegenLogicalShortCircuit (const Analyzer::BinOper *, const CompilationOptions &)
 
llvm::Value * codegenDictLike (const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const bool ilike, const bool is_simple, const char escape_char, const CompilationOptions &)
 
llvm::Value * codegenDictStrCmp (const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const SQLOps, const CompilationOptions &co)
 
llvm::Value * codegenDictRegexp (const std::shared_ptr< Analyzer::Expr > arg, const Analyzer::Constant *pattern, const char escape_char, const CompilationOptions &)
 
llvm::Value * foundOuterJoinMatch (const ssize_t nesting_level) const
 
llvm::Value * resolveGroupedColumnReference (const Analyzer::ColumnVar *)
 
llvm::Value * colByteStream (const Analyzer::ColumnVar *col_var, const bool fetch_column, const bool hoist_literals)
 
std::shared_ptr< const
Analyzer::Expr
hashJoinLhs (const Analyzer::ColumnVar *rhs) const
 
std::shared_ptr< const
Analyzer::ColumnVar
hashJoinLhsTuple (const Analyzer::ColumnVar *rhs, const Analyzer::BinOper *tautological_eq) const
 
std::unique_ptr< InValuesBitmapcreateInValuesBitmap (const Analyzer::InValues *, const CompilationOptions &)
 
bool checkExpressionRanges (const Analyzer::UOper *, int64_t, int64_t)
 
bool checkExpressionRanges (const Analyzer::BinOper *, int64_t, int64_t)
 
std::tuple< ArgNullcheckBBs,
llvm::Value * > 
beginArgsNullcheck (const Analyzer::FunctionOper *function_oper, const std::vector< llvm::Value * > &orig_arg_lvs)
 
llvm::Value * endArgsNullcheck (const ArgNullcheckBBs &, llvm::Value *, llvm::Value *, const Analyzer::FunctionOper *)
 
llvm::Value * codegenFunctionOperNullArg (const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
 
llvm::Value * codegenCompression (const SQLTypeInfo &type_info)
 
std::pair< llvm::Value
*, llvm::Value * > 
codegenArrayBuff (llvm::Value *chunk, llvm::Value *row_pos, SQLTypes array_type, bool cast_and_extend)
 
void codegenArrayArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *array_buf, llvm::Value *array_size, llvm::Value *array_is_null, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createPointStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoPointArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *point_buf, llvm::Value *point_size, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createLineStringStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoLineStringArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *line_string_buf, llvm::Value *line_string_size, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createPolygonStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoPolygonArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *polygon_buf, llvm::Value *polygon_size, llvm::Value *ring_sizes_buf, llvm::Value *num_rings, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
llvm::StructType * createMultiPolygonStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoMultiPolygonArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *polygon_coords, llvm::Value *polygon_coords_size, llvm::Value *ring_sizes_buf, llvm::Value *ring_sizes, llvm::Value *polygon_bounds, llvm::Value *polygon_bounds_sizes, llvm::Value *compression, llvm::Value *input_srid, llvm::Value *output_srid, std::vector< llvm::Value * > &output_args)
 
std::vector< llvm::Value * > codegenFunctionOperCastArgs (const Analyzer::FunctionOper *, const ExtensionFunction *, const std::vector< llvm::Value * > &, const std::unordered_map< llvm::Value *, llvm::Value * > &, const CompilationOptions &)
 
llvm::Function * getArithWithOverflowIntrinsic (const Analyzer::BinOper *bin_oper, llvm::Type *type)
 
llvm::Value * codegenBinOpWithOverflowForCPU (const Analyzer::BinOper *bin_oper, llvm::Value *lhs_lv, llvm::Value *rhs_lv, const std::string &null_check_suffix, const SQLTypeInfo &ti)
 

Private Attributes

Executorexecutor_
 

Detailed Description

Definition at line 25 of file CodeGenerator.h.

Constructor & Destructor Documentation

CodeGenerator::CodeGenerator ( Executor executor)
inline

Definition at line 27 of file CodeGenerator.h.

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

Definition at line 34 of file CodeGenerator.h.

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

Member Function Documentation

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

Definition at line 993 of file NativeCodegen.cpp.

993  {
994  return func->getName() == "query_stub_hoisted_literals" ||
995  func->getName() == "multifrag_query_hoisted_literals" ||
996  func->getName() == "query_stub" || func->getName() == "multifrag_query" ||
997  func->getName() == "fixed_width_int_decode" ||
998  func->getName() == "fixed_width_unsigned_decode" ||
999  func->getName() == "diff_fixed_width_int_decode" ||
1000  func->getName() == "fixed_width_double_decode" ||
1001  func->getName() == "fixed_width_float_decode" ||
1002  func->getName() == "fixed_width_small_date_decode" ||
1003  func->getName() == "record_error_code";
1004 }
std::tuple< CodeGenerator::ArgNullcheckBBs, llvm::Value * > CodeGenerator::beginArgsNullcheck ( const Analyzer::FunctionOper function_oper,
const std::vector< llvm::Value * > &  orig_arg_lvs 
)
private

Definition at line 326 of file ExtensionsIR.cpp.

References cgen_state_, codegenFunctionOperNullArg(), CgenState::context_, anonymous_namespace{ExtensionsIR.cpp}::ext_func_call_requires_nullcheck(), anonymous_namespace{ExtensionsIR.cpp}::get_arr_struct_type(), anonymous_namespace{ExtensionsIR.cpp}::get_llvm_type_from_sql_array_type(), Analyzer::Expr::get_type_info(), Analyzer::FunctionOper::getName(), CgenState::ir_builder_, SQLTypeInfo::is_array(), and CgenState::row_func_.

Referenced by codegenFunctionOper(), and codegenFunctionOperWithCustomTypeHandling().

327  {
328  llvm::BasicBlock* args_null_bb{nullptr};
329  llvm::BasicBlock* args_notnull_bb{nullptr};
330  llvm::BasicBlock* orig_bb = cgen_state_->ir_builder_.GetInsertBlock();
331  llvm::Value* null_array_alloca{nullptr};
332  // Only generate the check if required (at least one argument must be nullable).
333  if (ext_func_call_requires_nullcheck(function_oper)) {
334  if (function_oper->get_type_info().is_array()) {
335  const auto arr_struct_ty =
337  function_oper->getName(),
339  function_oper->get_type_info(), cgen_state_->context_),
340  0);
341  null_array_alloca = cgen_state_->ir_builder_.CreateAlloca(arr_struct_ty);
342  }
343  const auto args_notnull_lv = cgen_state_->ir_builder_.CreateNot(
344  codegenFunctionOperNullArg(function_oper, orig_arg_lvs));
345  args_notnull_bb = llvm::BasicBlock::Create(
346  cgen_state_->context_, "args_notnull", cgen_state_->row_func_);
347  args_null_bb = llvm::BasicBlock::Create(
348  cgen_state_->context_, "args_null", cgen_state_->row_func_);
349  cgen_state_->ir_builder_.CreateCondBr(args_notnull_lv, args_notnull_bb, args_null_bb);
350  cgen_state_->ir_builder_.SetInsertPoint(args_notnull_bb);
351  }
352  return std::make_tuple(
353  CodeGenerator::ArgNullcheckBBs{args_null_bb, args_notnull_bb, orig_bb},
354  null_array_alloca);
355 }
CgenState * cgen_state_
llvm::Value * codegenFunctionOperNullArg(const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
bool ext_func_call_requires_nullcheck(const Analyzer::FunctionOper *function_oper)
llvm::StructType * get_arr_struct_type(CgenState *cgen_state, const std::string &ext_func_name, llvm::Type *array_type, size_t param_num)
llvm::Function * row_func_
Definition: CgenState.h:315
llvm::LLVMContext & context_
Definition: CgenState.h:317
llvm::Type * get_llvm_type_from_sql_array_type(const SQLTypeInfo ti, llvm::LLVMContext &ctx)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::string getName() const
Definition: Analyzer.h:1359
bool is_array() const
Definition: sqltypes.h:423

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1170 of file ExtensionsIR.cpp.

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

Referenced by codegenFunctionOperCastArgs().

1171  {
1172  if (elem_ti.get_type() == kFLOAT) {
1173  return cgen_state_->ir_builder_.CreatePointerCast(
1174  ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
1175  }
1176  if (elem_ti.get_type() == kDOUBLE) {
1177  return cgen_state_->ir_builder_.CreatePointerCast(
1178  ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
1179  }
1180  CHECK(elem_ti.is_integer() || elem_ti.is_boolean() ||
1181  (elem_ti.is_string() && elem_ti.get_compression() == kENCODING_DICT));
1182  switch (elem_ti.get_size()) {
1183  case 1:
1184  return cgen_state_->ir_builder_.CreatePointerCast(
1185  ptr, llvm::Type::getInt8PtrTy(cgen_state_->context_));
1186  case 2:
1187  return cgen_state_->ir_builder_.CreatePointerCast(
1188  ptr, llvm::Type::getInt16PtrTy(cgen_state_->context_));
1189  case 4:
1190  return cgen_state_->ir_builder_.CreatePointerCast(
1191  ptr, llvm::Type::getInt32PtrTy(cgen_state_->context_));
1192  case 8:
1193  return cgen_state_->ir_builder_.CreatePointerCast(
1194  ptr, llvm::Type::getInt64PtrTy(cgen_state_->context_));
1195  default:
1196  CHECK(false);
1197  }
1198  return nullptr;
1199 }
HOST DEVICE int get_size() const
Definition: sqltypes.h:268
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
bool is_integer() const
Definition: sqltypes.h:417
bool is_boolean() const
Definition: sqltypes.h:422
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:266
bool is_string() const
Definition: sqltypes.h:415

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 616 of file ArithmeticIR.cpp.

References cgen_state_, executor(), Analyzer::Expr::get_type_info(), getExpressionRange(), Integer, SQLTypeInfo::is_decimal(), ExpressionRange::makeInvalidRange(), and CgenState::query_infos_.

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

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 184 of file ArithmeticIR.cpp.

References cgen_state_, executor(), Analyzer::BinOper::get_left_operand(), Analyzer::BinOper::get_right_operand(), Analyzer::Expr::get_type_info(), getExpressionRange(), Integer, SQLTypeInfo::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:333
CgenState * cgen_state_
const Expr * get_right_operand() const
Definition: Analyzer.h:444
bool is_temporary_column(const Analyzer::Expr *expr)
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
const Expr * get_left_operand() const
Definition: Analyzer.h:443
bool is_decimal() const
Definition: sqltypes.h:418
Executor * executor() const

+ Here is the call graph for this function:

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

Definition at line 26 of file IRCodegen.cpp.

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

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

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 20 of file ConstantIR.cpp.

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

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

+ Here is the call graph for this function:

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

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

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

+ Here is the call graph for this function:

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

Definition at line 71 of file InValuesIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 20 of file CaseIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 69 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.

70  {
71  auto from_expr = codegen(extract_expr->get_from_expr(), true, co).front();
72  const int32_t extract_field{extract_expr->get_field()};
73  const auto& extract_expr_ti = extract_expr->get_from_expr()->get_type_info();
74  if (extract_field == kEPOCH) {
75  CHECK(extract_expr_ti.get_type() == kTIMESTAMP ||
76  extract_expr_ti.get_type() == kDATE);
77  if (from_expr->getType()->isIntegerTy(32)) {
78  from_expr =
79  cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
80  from_expr,
82  return from_expr;
83  }
84  }
85  CHECK(from_expr->getType()->isIntegerTy(64));
86  if (extract_expr_ti.is_high_precision_timestamp()) {
88  from_expr, extract_expr_ti, extract_expr->get_field());
89  }
90  if (!extract_expr_ti.is_high_precision_timestamp() &&
91  is_subsecond_extract_field(extract_expr->get_field())) {
92  from_expr =
93  extract_expr_ti.get_notnull()
94  ? cgen_state_->ir_builder_.CreateMul(
95  from_expr,
99  "mul_int64_t_nullable_lhs",
100  {from_expr,
103  cgen_state_->inlineIntNull(extract_expr_ti)});
104  }
105  const auto extract_fname = get_extract_function_name(extract_expr->get_field());
106  if (!extract_expr_ti.get_notnull()) {
107  llvm::BasicBlock* extract_nullcheck_bb{nullptr};
108  llvm::PHINode* extract_nullcheck_value{nullptr};
109  {
111  cgen_state_->ir_builder_.CreateICmp(
112  llvm::ICmpInst::ICMP_EQ,
113  from_expr,
114  cgen_state_->inlineIntNull(extract_expr_ti)),
115  executor(),
116  false,
117  "extract_nullcheck",
118  nullptr,
119  false);
120  // generate a phi node depending on whether we got a null or not
121  extract_nullcheck_bb = llvm::BasicBlock::Create(
122  cgen_state_->context_, "extract_nullcheck_bb", cgen_state_->row_func_);
123 
124  // update the blocks created by diamond codegen to point to the newly created phi
125  // block
126  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_true_);
127  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
128  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_false_);
129  auto extract_call =
130  cgen_state_->emitExternalCall(extract_fname,
132  std::vector<llvm::Value*>{from_expr});
133  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
134 
135  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
136  extract_nullcheck_value = cgen_state_->ir_builder_.CreatePHI(
137  get_int_type(64, cgen_state_->context_), 2, "extract_value");
138  extract_nullcheck_value->addIncoming(extract_call, null_check.cond_false_);
139  extract_nullcheck_value->addIncoming(cgen_state_->inlineIntNull(extract_expr_ti),
140  null_check.cond_true_);
141  }
142 
143  // diamond codegen will set the insert point in its destructor. override it to
144  // continue using the extract nullcheck bb
145  CHECK(extract_nullcheck_bb);
146  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
147  CHECK(extract_nullcheck_value);
148  return extract_nullcheck_value;
149  } else {
150  return cgen_state_->emitExternalCall(extract_fname,
152  std::vector<llvm::Value*>{from_expr});
153  }
154 }
const Expr * get_from_expr() const
Definition: Analyzer.h:1198
constexpr int64_t get_extract_timestamp_precision_scale(const ExtractField field)
Definition: DateTimeUtils.h:81
CgenState * cgen_state_
ExtractField get_field() const
Definition: Analyzer.h:1197
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
const char * get_extract_function_name(ExtractField field)
Definition: DateTimeIR.cpp:26
llvm::Value * codegenExtractHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const ExtractField &)
Definition: DateTimeIR.cpp:234
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:315
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqltypes.h:54
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr bool is_subsecond_extract_field(const ExtractField &field)
Definition: DateTimeUtils.h:95
Executor * executor() const

+ Here is the call graph for this function:

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

Definition at line 156 of file DateTimeIR.cpp.

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

157  {
158  const auto& dateadd_expr_ti = dateadd_expr->get_type_info();
159  CHECK(dateadd_expr_ti.get_type() == kTIMESTAMP || dateadd_expr_ti.get_type() == kDATE);
160  auto datetime = codegen(dateadd_expr->get_datetime_expr(), true, co).front();
161  CHECK(datetime->getType()->isIntegerTy(64));
162  auto number = codegen(dateadd_expr->get_number_expr(), true, co).front();
163 
164  const auto& datetime_ti = dateadd_expr->get_datetime_expr()->get_type_info();
165  std::vector<llvm::Value*> dateadd_args{
166  cgen_state_->llInt(static_cast<int32_t>(dateadd_expr->get_field())),
167  number,
168  datetime};
169  std::string dateadd_fname{"DateAdd"};
170  if (dateadd_expr_ti.is_high_precision_timestamp()) {
171  dateadd_fname += "HighPrecision";
172  dateadd_args.push_back(cgen_state_->llInt(static_cast<int64_t>(
173  get_timestamp_precision_scale(dateadd_expr_ti.get_dimension()))));
174  }
175  if (!datetime_ti.get_notnull()) {
176  dateadd_args.push_back(cgen_state_->inlineIntNull(datetime_ti));
177  dateadd_fname += "Nullable";
178  }
179  return cgen_state_->emitExternalCall(dateadd_fname,
181  dateadd_args,
182  {llvm::Attribute::NoUnwind,
183  llvm::Attribute::ReadNone,
184  llvm::Attribute::Speculatable});
185 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqltypes.h:54
const Expr * get_datetime_expr() const
Definition: Analyzer.h:1240
DateaddField get_field() const
Definition: Analyzer.h:1238
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51
const Expr * get_number_expr() const
Definition: Analyzer.h:1239

+ Here is the call graph for this function:

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

Definition at line 187 of file DateTimeIR.cpp.

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

188  {
189  auto start = codegen(datediff_expr->get_start_expr(), true, co).front();
190  CHECK(start->getType()->isIntegerTy(64));
191  auto end = codegen(datediff_expr->get_end_expr(), true, co).front();
192  CHECK(end->getType()->isIntegerTy(32) || end->getType()->isIntegerTy(64));
193  const auto& start_ti = datediff_expr->get_start_expr()->get_type_info();
194  const auto& end_ti = datediff_expr->get_end_expr()->get_type_info();
195  std::vector<llvm::Value*> datediff_args{
196  cgen_state_->llInt(static_cast<int32_t>(datediff_expr->get_field())), start, end};
197  std::string datediff_fname{"DateDiff"};
198  if (start_ti.is_high_precision_timestamp() || end_ti.is_high_precision_timestamp()) {
199  datediff_fname += "HighPrecision";
200  datediff_args.push_back(
201  cgen_state_->llInt(static_cast<int32_t>(start_ti.get_dimension())));
202  datediff_args.push_back(
203  cgen_state_->llInt(static_cast<int32_t>(end_ti.get_dimension())));
204  }
205  const auto& ret_ti = datediff_expr->get_type_info();
206  if (!start_ti.get_notnull() || !end_ti.get_notnull()) {
207  datediff_args.push_back(cgen_state_->inlineIntNull(ret_ti));
208  datediff_fname += "Nullable";
209  }
211  datediff_fname, get_int_type(64, cgen_state_->context_), datediff_args);
212 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
const Expr * get_start_expr() const
Definition: Analyzer.h:1281
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
const Expr * get_end_expr() const
Definition: Analyzer.h:1282
DatetruncField get_field() const
Definition: Analyzer.h:1280

+ Here is the call graph for this function:

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

Definition at line 214 of file DateTimeIR.cpp.

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

215  {
216  auto from_expr = codegen(datetrunc_expr->get_from_expr(), true, co).front();
217  const auto& datetrunc_expr_ti = datetrunc_expr->get_from_expr()->get_type_info();
218  CHECK(from_expr->getType()->isIntegerTy(64));
219  if (datetrunc_expr_ti.is_high_precision_timestamp()) {
221  from_expr, datetrunc_expr_ti, datetrunc_expr->get_field());
222  }
223  std::vector<llvm::Value*> datetrunc_args{
224  cgen_state_->llInt(static_cast<int32_t>(datetrunc_expr->get_field())), from_expr};
225  std::string datetrunc_fname{"DateTruncate"};
226  if (!datetrunc_expr_ti.get_notnull()) {
227  datetrunc_args.push_back(cgen_state_->inlineIntNull(datetrunc_expr_ti));
228  datetrunc_fname += "Nullable";
229  }
231  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
232 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
DatetruncField get_field() const
Definition: Analyzer.h:1322
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
const Expr * get_from_expr() const
Definition: Analyzer.h:1323
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
llvm::Value * codegenDateTruncHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
Definition: DateTimeIR.cpp:277

+ Here is the call graph for this function:

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

Definition at line 65 of file StringOpsIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 96 of file StringOpsIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 196 of file IRCodegen.cpp.

References run_benchmark_import::args, cgen_state_, CHECK(), CHECK_EQ, codegen(), CgenState::context_, CgenState::emitCall(), executor(), Analyzer::SampleRatioExpr::get_arg(), kDOUBLE, ll_bool(), and posArg().

197  {
198  auto input_expr = expr->get_arg();
199  CHECK(input_expr);
200 
201  auto double_lv = codegen(input_expr, true, co);
202  CHECK_EQ(size_t(1), double_lv.size());
203 
204  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
205  const bool is_nullable = !input_expr->get_type_info().get_notnull();
206  if (is_nullable) {
207  nullcheck_codegen = std::make_unique<NullCheckCodegen>(cgen_state_,
208  executor(),
209  double_lv.front(),
210  input_expr->get_type_info(),
211  "sample_ratio_nullcheck");
212  }
213  CHECK_EQ(input_expr->get_type_info().get_type(), kDOUBLE);
214  std::vector<llvm::Value*> args{double_lv[0], posArg(nullptr)};
215  auto ret = cgen_state_->emitCall("sample_ratio", args);
216  if (nullcheck_codegen) {
217  ret = nullcheck_codegen->finalize(ll_bool(false, cgen_state_->context_), ret);
218  }
219  return ret;
220 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:509
CHECK(cgen_state)
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
const Expr * get_arg() const
Definition: Analyzer.h:751
llvm::ConstantInt * ll_bool(const bool v, llvm::LLVMContext &context)
Executor * executor() const

+ Here is the call graph for this function:

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

Definition at line 103 of file StringOpsIR.cpp.

References run_benchmark_import::args, cgen_state_, CHECK(), CHECK_EQ, codegen(), CgenState::context_, CompilationOptions::device_type, CgenState::emitExternalCall(), executor(), Analyzer::LowerExpr::get_arg(), SQLTypeInfo::get_comp_param(), get_int_type(), Analyzer::Expr::get_type_info(), GPU, and CgenState::llInt().

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

+ Here is the call graph for this function:

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

Definition at line 124 of file StringOpsIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 338 of file StringOpsIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 66 of file ArrayIR.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 155 of file IRCodegen.cpp.

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

156  {
157  const auto optype = bin_oper->get_optype();
158  if (IS_ARITHMETIC(optype)) {
159  return codegenArith(bin_oper, co);
160  }
161  if (IS_COMPARISON(optype)) {
162  return codegenCmp(bin_oper, co);
163  }
164  if (IS_LOGIC(optype)) {
165  return codegenLogical(bin_oper, co);
166  }
167  if (optype == kARRAY_AT) {
168  return codegenArrayAt(bin_oper, co);
169  }
170  abort();
171 }
#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:440
#define IS_ARITHMETIC(X)
Definition: sqldefs.h:61
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:289
#define IS_COMPARISON(X)
Definition: sqldefs.h:57

+ Here is the call graph for this function:

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

Definition at line 173 of file IRCodegen.cpp.

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

174  {
175  const auto optype = u_oper->get_optype();
176  switch (optype) {
177  case kNOT: {
178  return codegenLogical(u_oper, co);
179  }
180  case kCAST: {
181  return codegenCast(u_oper, co);
182  }
183  case kUMINUS: {
184  return codegenUMinus(u_oper, co);
185  }
186  case kISNULL: {
187  return codegenIsNull(u_oper, co);
188  }
189  case kUNNEST:
190  return codegenUnnest(u_oper, co);
191  default:
192  abort();
193  }
194 }
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:371

+ Here is the call graph for this function:

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

Definition at line 211 of file ArithmeticIR.cpp.

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

Referenced by codegenIntArith().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 36 of file ArithmeticIR.cpp.

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

Referenced by codegen().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 579 of file ExtensionsIR.cpp.

References cgen_state_, CHECK(), CgenState::context_, anonymous_namespace{ExtensionsIR.cpp}::get_arr_struct_type(), and CgenState::ir_builder_.

Referenced by codegenFunctionOperCastArgs().

584  {
585  CHECK(array_buf);
586  CHECK(array_size);
587  CHECK(array_null);
588 
589  auto array_abstraction =
590  get_arr_struct_type(cgen_state_, ext_func_name, array_buf->getType(), param_num);
591  auto alloc_mem = cgen_state_->ir_builder_.CreateAlloca(array_abstraction);
592 
593  auto array_buf_ptr =
594  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 0);
595  cgen_state_->ir_builder_.CreateStore(array_buf, array_buf_ptr);
596 
597  auto array_size_ptr =
598  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 1);
599  cgen_state_->ir_builder_.CreateStore(array_size, array_size_ptr);
600 
601  auto bool_extended_type = llvm::Type::getInt8Ty(cgen_state_->context_);
602  auto array_null_extended =
603  cgen_state_->ir_builder_.CreateZExt(array_null, bool_extended_type);
604  auto array_is_null_ptr =
605  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 2);
606  cgen_state_->ir_builder_.CreateStore(array_null_extended, array_is_null_ptr);
607  output_args.push_back(alloc_mem);
608 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::StructType * get_arr_struct_type(CgenState *cgen_state, const std::string &ext_func_name, llvm::Type *array_type, size_t param_num)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 25 of file ArrayIR.cpp.

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

Referenced by codegen().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::pair< llvm::Value *, llvm::Value * > CodeGenerator::codegenArrayBuff ( llvm::Value *  chunk,
llvm::Value *  row_pos,
SQLTypes  array_type,
bool  cast_and_extend 
)
private

Definition at line 552 of file ExtensionsIR.cpp.

References cgen_state_, CgenState::context_, CgenState::emitExternalCall(), SQLTypeInfo::get_elem_type(), kARRAY, and kENCODING_NONE.

Referenced by codegenFunctionOperCastArgs().

556  {
557  const auto elem_ti =
558  SQLTypeInfo(
559  SQLTypes::kARRAY, 0, 0, false, EncodingType::kENCODING_NONE, 0, array_type)
560  .get_elem_type();
561 
562  auto buff = cgen_state_->emitExternalCall(
563  "array_buff", llvm::Type::getInt32PtrTy(cgen_state_->context_), {chunk, row_pos});
564 
565  auto len = cgen_state_->emitExternalCall(
566  "array_size",
568  {chunk, row_pos, cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))});
569 
570  if (cast_and_extend) {
571  buff = castArrayPointer(buff, elem_ti);
572  len =
573  cgen_state_->ir_builder_.CreateZExt(len, get_int_type(64, cgen_state_->context_));
574  }
575 
576  return std::make_pair(buff, len);
577 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Value * castArrayPointer(llvm::Value *ptr, const SQLTypeInfo &elem_ti)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:105
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:622

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 88 of file ArrayIR.cpp.

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

Referenced by codegen().

90  {
91  using ValueVector = std::vector<llvm::Value*>;
92  ValueVector argument_list;
93  auto& ir_builder(cgen_state_->ir_builder_);
94 
95  const auto& return_type = array_expr->get_type_info();
96  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
97  const auto arg = array_expr->getElement(i);
98  const auto arg_lvs = codegen(arg, true, co);
99  if (arg_lvs.size() == 1) {
100  argument_list.push_back(arg_lvs.front());
101  } else {
102  throw std::runtime_error(
103  "Unexpected argument count during array[] code generation.");
104  }
105  }
106 
107  auto array_element_size_bytes =
108  return_type.get_elem_type().get_array_context_logical_size();
109  auto* array_index_type =
110  get_int_type(array_element_size_bytes * 8, cgen_state_->context_);
111  auto* array_type = get_int_array_type(
112  array_element_size_bytes * 8, array_expr->getElementCount(), cgen_state_->context_);
113 
114  if (array_expr->isNull()) {
115  return {llvm::ConstantPointerNull::get(
116  llvm::PointerType::get(get_int_type(64, cgen_state_->context_), 0)),
117  cgen_state_->llInt(0)};
118  }
119 
120  if (0 == array_expr->getElementCount()) {
121  llvm::Constant* dead_const = cgen_state_->llInt(0xdead);
122  llvm::Value* dead_pointer = llvm::ConstantExpr::getIntToPtr(
123  dead_const, llvm::PointerType::get(get_int_type(64, cgen_state_->context_), 0));
124  return {dead_pointer, cgen_state_->llInt(0)};
125  }
126 
127  llvm::Value* allocated_target_buffer;
128  if (array_expr->isLocalAlloc()) {
129  allocated_target_buffer = ir_builder.CreateAlloca(array_type);
130  } else {
132  throw QueryMustRunOnCpu();
133  }
134 
135  allocated_target_buffer =
136  cgen_state_->emitExternalCall("allocate_varlen_buffer",
137  llvm::Type::getInt8PtrTy(cgen_state_->context_),
138  {cgen_state_->llInt(array_expr->getElementCount()),
139  cgen_state_->llInt(array_element_size_bytes)});
141  "register_buffer_with_executor_rsm",
142  llvm::Type::getVoidTy(cgen_state_->context_),
143  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
144  allocated_target_buffer});
145  }
146  llvm::Value* casted_allocated_target_buffer =
147  ir_builder.CreatePointerCast(allocated_target_buffer, array_type->getPointerTo());
148 
149  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
150  auto* element = argument_list[i];
151  auto* element_ptr = ir_builder.CreateGEP(
152  array_type,
153  casted_allocated_target_buffer,
154  std::vector<llvm::Value*>{cgen_state_->llInt(0), cgen_state_->llInt(i)});
155 
156  const auto& elem_ti = return_type.get_elem_type();
157  if (elem_ti.is_boolean()) {
158  const auto byte_casted_bit =
159  ir_builder.CreateIntCast(element, array_index_type, true);
160  ir_builder.CreateStore(byte_casted_bit, element_ptr);
161  } else if (elem_ti.is_fp()) {
162  switch (elem_ti.get_size()) {
163  case sizeof(double): {
164  const auto double_element_ptr = ir_builder.CreatePointerCast(
165  element_ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
166  ir_builder.CreateStore(element, double_element_ptr);
167  break;
168  }
169  case sizeof(float): {
170  const auto float_element_ptr = ir_builder.CreatePointerCast(
171  element_ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
172  ir_builder.CreateStore(element, float_element_ptr);
173  break;
174  }
175  default:
176  UNREACHABLE();
177  }
178  } else if (elem_ti.is_integer() || elem_ti.is_decimal() || elem_ti.is_date() ||
179  elem_ti.is_timestamp() || elem_ti.is_time() || elem_ti.is_timeinterval() ||
180  elem_ti.is_dict_encoded_string()) {
181  // TODO(adb): this validation and handling should be done elsewhere
182  const auto sign_extended_element = ir_builder.CreateSExt(element, array_index_type);
183  ir_builder.CreateStore(sign_extended_element, element_ptr);
184  } else {
185  throw std::runtime_error("Unsupported type used in ARRAY construction.");
186  }
187  }
188 
189  return {ir_builder.CreateGEP(
190  array_type, casted_allocated_target_buffer, cgen_state_->llInt(0)),
191  cgen_state_->llInt(array_expr->getElementCount())};
192 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
#define UNREACHABLE()
Definition: Logger.h:241
bool isNull() const
Definition: Analyzer.h:1491
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
size_t getElementCount() const
Definition: Analyzer.h:1489
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
bool isLocalAlloc() const
Definition: Analyzer.h:1490
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
const Analyzer::Expr * getElement(const size_t i) const
Definition: Analyzer.h:1493
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 710 of file ArithmeticIR.cpp.

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

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

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 54 of file CaseIR.cpp.

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

Referenced by codegen().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 20 of file CastIR.cpp.

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

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

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 53 of file CastIR.cpp.

References anonymous_namespace{CastIR.cpp}::byte_array_cast(), CgenState::castToTypeIn(), cgen_state_, CHECK(), codegenCastBetweenIntTypes(), codegenCastBetweenTimestamps(), codegenCastFromFp(), codegenCastFromString(), codegenCastTimestampToDate(), codegenCastToFp(), CgenState::context_, SQLTypeInfo::get_dimension(), get_int_array_type(), SQLTypeInfo::get_notnull(), SQLTypeInfo::get_size(), SQLTypeInfo::get_type(), CgenState::ir_builder_, SQLTypeInfo::is_boolean(), SQLTypeInfo::is_decimal(), SQLTypeInfo::is_integer(), SQLTypeInfo::is_string(), SQLTypeInfo::is_time(), SQLTypeInfo::is_timestamp(), 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  // cast boolean to int8
71  CHECK(operand_lv->getType()->isIntegerTy(1) ||
72  operand_lv->getType()->isIntegerTy(8));
73  if (operand_lv->getType()->isIntegerTy(1)) {
74  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
75  }
76  if (ti.is_boolean()) {
77  return operand_lv;
78  }
79  }
80  if (operand_ti.is_integer() && operand_lv->getType()->isIntegerTy(8) &&
81  ti.is_boolean()) {
82  // cast int8 to boolean
83  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
84  }
85  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
86  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
87  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
88  // whereas this cast returns a date. The underlying type for both is still the same,
89  // but it still doesn't look like a good idea to misuse DatetruncExpr.
90  // Date will have default precision of day, but TIMESTAMP dimension would
91  // matter but while converting date through seconds
93  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
94  }
95  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
96  ti.get_type() == kTIMESTAMP) {
97  const auto operand_dimen =
98  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
99  if (operand_dimen != ti.get_dimension()) {
101  operand_lv, operand_ti, ti, !ti.get_notnull());
102  }
103  }
104  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
105  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
106  } else {
107  return codegenCastToFp(operand_lv, operand_ti, ti);
108  }
109  } else {
110  return codegenCastFromFp(operand_lv, operand_ti, ti);
111  }
112  CHECK(false);
113  return nullptr;
114 }
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:106
llvm::Value * codegenCastFromFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:404
HOST DEVICE int get_size() const
Definition: sqltypes.h:268
bool is_timestamp() const
Definition: sqltypes.h:652
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:373
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:46
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
bool is_time() const
Definition: sqltypes.h:421
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
bool is_integer() const
Definition: sqltypes.h:417
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:244
bool is_boolean() const
Definition: sqltypes.h:422
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:116
Definition: sqltypes.h:54
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:260
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
Definition: CastIR.cpp:145
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:176
bool is_string() const
Definition: sqltypes.h:415
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_decimal() const
Definition: sqltypes.h:418

+ Here is the call graph for this function:

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

Definition at line 244 of file CastIR.cpp.

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

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

247  {
248  if (ti.is_decimal() &&
249  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
250  if (upscale) {
251  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
252  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
253  const auto scale_lv =
254  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
255  operand_lv = cgen_state_->ir_builder_.CreateSExt(
256  operand_lv, get_int_type(64, cgen_state_->context_));
257 
258  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
259 
260  if (operand_ti.get_notnull()) {
261  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
262  } else {
263  operand_lv = cgen_state_->emitCall(
264  "scale_decimal_up",
265  {operand_lv,
266  scale_lv,
267  cgen_state_->llInt(inline_int_null_val(operand_ti)),
269  }
270  }
271  }
272  } else if (operand_ti.is_decimal()) {
273  // rounded scale down
274  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
275  const auto scale_lv =
276  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
277 
278  const auto operand_width =
279  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
280 
281  std::string method_name = "scale_decimal_down_nullable";
282  if (operand_ti.get_notnull()) {
283  method_name = "scale_decimal_down_not_nullable";
284  }
285 
286  CHECK(operand_width == 64);
287  operand_lv = cgen_state_->emitCall(
288  method_name,
289  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
290  }
291  if (ti.is_integer() && operand_ti.is_integer() &&
292  operand_ti.get_logical_size() > ti.get_logical_size()) {
293  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
294  }
295 
296  const auto operand_width =
297  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
298  const auto target_width = get_bit_width(ti);
299  if (target_width == operand_width) {
300  return operand_lv;
301  }
302  if (operand_ti.get_notnull()) {
303  return cgen_state_->ir_builder_.CreateCast(
304  target_width > operand_width ? llvm::Instruction::CastOps::SExt
305  : llvm::Instruction::CastOps::Trunc,
306  operand_lv,
307  get_int_type(target_width, cgen_state_->context_));
308  }
309  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
310  numeric_type_name(ti) + "_nullable",
311  {operand_lv,
312  cgen_state_->inlineIntNull(operand_ti),
313  cgen_state_->inlineIntNull(ti)});
314 }
CgenState * cgen_state_
HOST DEVICE int get_scale() const
Definition: sqltypes.h:263
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
int get_logical_size() const
Definition: sqltypes.h:269
bool is_integer() const
Definition: sqltypes.h:417
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:316
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
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:138
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
bool is_decimal() const
Definition: sqltypes.h:418

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 316 of file CastIR.cpp.

References cgen_state_, CgenState::context_, CgenState::emitCall(), get_int_type(), SQLTypeInfo::get_logical_size(), SQLTypeInfo::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 codegenCastBetweenTimestamps().

320  {
321  llvm::Value* chosen_max{nullptr};
322  llvm::Value* chosen_min{nullptr};
323  std::tie(chosen_max, chosen_min) =
325 
327  auto cast_ok =
328  llvm::BasicBlock::Create(cgen_state_->context_, "cast_ok", cgen_state_->row_func_);
329  auto cast_fail = llvm::BasicBlock::Create(
330  cgen_state_->context_, "cast_fail", cgen_state_->row_func_);
331  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
332  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
333  const auto ti_llvm_type =
335  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
336  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
337  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
338  if (is_narrowing) {
339  const auto operand_ti_llvm_type =
341  operand_max_lv =
342  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
343  operand_min_lv =
344  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
345  }
346  llvm::Value* over{nullptr};
347  llvm::Value* under{nullptr};
348  if (operand_ti.get_notnull()) {
349  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
350  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
351  } else {
352  const auto type_name =
353  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
354  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
355  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
356  over = toBool(cgen_state_->emitCall(
357  "gt_" + type_name + "_nullable_lhs",
358  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
359  under = toBool(cgen_state_->emitCall(
360  "le_" + type_name + "_nullable_lhs",
361  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
362  }
363  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
364  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
365 
366  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
367  cgen_state_->ir_builder_.CreateRet(
369 
370  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
371 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:315
llvm::LLVMContext & context_
Definition: CgenState.h:317
int get_logical_size() const
Definition: sqltypes.h:269
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:941
bool needs_error_check_
Definition: CgenState.h:334
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:333
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:138
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:77

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 145 of file CastIR.cpp.

References cgen_state_, CHECK(), codegenCastBetweenIntTypesOverflowChecks(), CgenState::emitCall(), SQLTypeInfo::get_dimension(), DateTimeUtils::get_timestamp_precision_scale(), CgenState::inlineIntNull(), CgenState::ir_builder_, and CgenState::llInt().

Referenced by codegenCast().

148  {
149  const auto operand_dimen = operand_ti.get_dimension();
150  const auto target_dimen = target_ti.get_dimension();
151  if (operand_dimen == target_dimen) {
152  return ts_lv;
153  }
154  CHECK(ts_lv->getType()->isIntegerTy(64));
155  const auto scale =
156  DateTimeUtils::get_timestamp_precision_scale(abs(operand_dimen - target_dimen));
157  if (operand_dimen < target_dimen) {
158  codegenCastBetweenIntTypesOverflowChecks(ts_lv, operand_ti, target_ti, scale);
159  return nullable
160  ? cgen_state_->emitCall("mul_int64_t_nullable_lhs",
161  {ts_lv,
162  cgen_state_->llInt(static_cast<int64_t>(scale)),
163  cgen_state_->inlineIntNull(operand_ti)})
164  : cgen_state_->ir_builder_.CreateMul(
165  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
166  }
167  return nullable
168  ? cgen_state_->emitCall("floor_div_nullable_lhs",
169  {ts_lv,
170  cgen_state_->llInt(static_cast<int64_t>(scale)),
171  cgen_state_->inlineIntNull(operand_ti)})
172  : cgen_state_->ir_builder_.CreateSDiv(
173  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
174 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:316
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:260
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 404 of file CastIR.cpp.

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

Referenced by codegenCast().

406  {
407  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
408  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
409  ti.get_type_name() + " not supported");
410  }
411  if (operand_ti.get_type() == ti.get_type()) {
412  // Should not have been called when both dimensions are same.
413  return operand_lv;
414  }
415  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
416  if (operand_ti.get_notnull()) {
417  if (ti.get_type() == kDOUBLE) {
418  return cgen_state_->ir_builder_.CreateFPExt(
419  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
420  } else if (ti.get_type() == kFLOAT) {
421  return cgen_state_->ir_builder_.CreateFPTrunc(
422  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
423  } else if (ti.is_integer()) {
424  return cgen_state_->ir_builder_.CreateFPToSI(
425  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
426  } else {
427  CHECK(false);
428  }
429  } else {
430  const auto from_tname = numeric_type_name(operand_ti);
431  const auto to_tname = numeric_type_name(ti);
432  if (ti.is_fp()) {
433  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
434  {operand_lv,
435  cgen_state_->inlineFpNull(operand_ti),
436  cgen_state_->inlineFpNull(ti)});
437  } else if (ti.is_integer()) {
438  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
439  {operand_lv,
440  cgen_state_->inlineFpNull(operand_ti),
441  cgen_state_->inlineIntNull(ti)});
442  } else {
443  CHECK(false);
444  }
445  }
446  CHECK(false);
447  return nullptr;
448 }
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:419
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:420
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
bool is_integer() const
Definition: sqltypes.h:417
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::string get_type_name() const
Definition: sqltypes.h:361
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:138
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
bool is_decimal() const
Definition: sqltypes.h:418
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 176 of file CastIR.cpp.

References cgen_state_, CHECK(), CHECK_EQ, CgenState::context_, CompilationOptions::device_type, CgenState::emitExternalCall(), executor(), g_cluster, g_enable_watchdog, SQLTypeInfo::get_comp_param(), SQLTypeInfo::get_compression(), get_int_type(), SQLTypeInfo::get_type_name(), GPU, SQLTypeInfo::is_string(), kENCODING_DICT, kENCODING_NONE, and CgenState::llInt().

Referenced by codegenCast().

180  {
181  if (!ti.is_string()) {
182  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
183  ti.get_type_name() + " not supported");
184  }
185  if (operand_ti.get_compression() == kENCODING_NONE &&
187  return operand_lv;
188  }
189  // dictionary encode non-constant
190  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
191  if (g_cluster) {
192  throw std::runtime_error(
193  "Cast from none-encoded string to dictionary-encoded not supported for "
194  "distributed queries");
195  }
196  if (g_enable_watchdog) {
197  throw WatchdogException(
198  "Cast from none-encoded string to dictionary-encoded would be slow");
199  }
200  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
202  CHECK(operand_lv->getType()->isIntegerTy(64));
204  throw QueryMustRunOnCpu();
205  }
207  "string_compress",
209  {operand_lv,
210  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
211  ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
212  }
213  CHECK(operand_lv->getType()->isIntegerTy(32));
214  if (ti.get_compression() == kENCODING_NONE) {
215  if (g_cluster) {
216  throw std::runtime_error(
217  "Cast from dictionary-encoded string to none-encoded not supported for "
218  "distributed queries");
219  }
220  if (g_enable_watchdog) {
221  throw WatchdogException(
222  "Cast from dictionary-encoded string to none-encoded would be slow");
223  }
224  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
226  throw QueryMustRunOnCpu();
227  }
228  const int64_t string_dictionary_ptr =
229  operand_ti.get_comp_param() == 0
230  ? reinterpret_cast<int64_t>(
231  executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
232  : reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
233  operand_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true));
235  "string_decompress",
237  {operand_lv, cgen_state_->llInt(string_dictionary_ptr)});
238  }
239  CHECK(operand_is_const);
241  return operand_lv;
242 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
bool g_enable_watchdog
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
ExecutorDeviceType device_type
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:266
std::string get_type_name() const
Definition: sqltypes.h:361
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:267
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
bool g_cluster
bool is_string() const
Definition: sqltypes.h:415
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

118  {
119  CHECK(ts_lv->getType()->isIntegerTy(64));
120  std::vector<llvm::Value*> datetrunc_args{ts_lv};
121  if (dimen > 0) {
122  static const std::string hptodate_fname = "DateTruncateHighPrecisionToDate";
123  static const std::string hptodate_null_fname =
124  "DateTruncateHighPrecisionToDateNullable";
125  datetrunc_args.push_back(
127  if (nullable) {
128  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
129  }
130  return cgen_state_->emitExternalCall(nullable ? hptodate_null_fname : hptodate_fname,
132  datetrunc_args);
133  }
134  std::string datetrunc_fname{"DateTruncate"};
135  datetrunc_args.insert(datetrunc_args.begin(),
136  cgen_state_->llInt(static_cast<int32_t>(dtDAY)));
137  if (nullable) {
138  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
139  datetrunc_fname += "Nullable";
140  }
142  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
143 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 373 of file CastIR.cpp.

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

Referenced by codegenCast().

375  {
376  if (!ti.is_fp()) {
377  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
378  ti.get_type_name() + " not supported");
379  }
380  const auto to_tname = numeric_type_name(ti);
381  llvm::Value* result_lv{nullptr};
382  if (operand_ti.get_notnull()) {
383  result_lv = cgen_state_->ir_builder_.CreateSIToFP(
384  operand_lv,
385  ti.get_type() == kFLOAT ? llvm::Type::getFloatTy(cgen_state_->context_)
386  : llvm::Type::getDoubleTy(cgen_state_->context_));
387  } else {
388  result_lv = cgen_state_->emitCall(
389  "cast_" + numeric_type_name(operand_ti) + "_to_" + to_tname + "_nullable",
390  {operand_lv,
391  cgen_state_->inlineIntNull(operand_ti),
392  cgen_state_->inlineFpNull(ti)});
393  }
394  CHECK(result_lv);
395  if (operand_ti.get_scale()) {
396  result_lv = cgen_state_->ir_builder_.CreateFDiv(
397  result_lv,
398  llvm::ConstantFP::get(result_lv->getType(),
399  exp_to_scale(operand_ti.get_scale())));
400  }
401  return result_lv;
402 }
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:419
HOST DEVICE int get_scale() const
Definition: sqltypes.h:263
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::string get_type_name() const
Definition: sqltypes.h:361
uint64_t exp_to_scale(const unsigned exp)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:138
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 184 of file CompareIR.cpp.

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

Referenced by codegen(), and codegenCmpDecimalConst().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 395 of file CompareIR.cpp.

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

400  {
401  CHECK(IS_COMPARISON(optype));
402  const auto& rhs_ti = rhs->get_type_info();
403  if (rhs_ti.is_array()) {
404  return codegenQualifierCmp(optype, qualifier, lhs_lvs, rhs, co);
405  }
406  auto rhs_lvs = codegen(rhs, true, co);
407  CHECK_EQ(kONE, qualifier);
408  if (optype == kOVERLAPS) {
409  CHECK(lhs_ti.is_geometry());
410  CHECK(rhs_ti.is_array() ||
411  rhs_ti.is_geometry()); // allow geo col or bounds col to pass
412  } else {
413  CHECK((lhs_ti.get_type() == rhs_ti.get_type()) ||
414  (lhs_ti.is_string() && rhs_ti.is_string()));
415  }
416  const auto null_check_suffix = get_null_check_suffix(lhs_ti, rhs_ti);
417  if (lhs_ti.is_integer() || lhs_ti.is_decimal() || lhs_ti.is_time() ||
418  lhs_ti.is_boolean() || lhs_ti.is_string() || lhs_ti.is_timeinterval()) {
419  if (lhs_ti.is_string()) {
420  CHECK(rhs_ti.is_string());
421  CHECK_EQ(lhs_ti.get_compression(), rhs_ti.get_compression());
422  if (lhs_ti.get_compression() == kENCODING_NONE) {
423  // unpack pointer + length if necessary
424  if (lhs_lvs.size() != 3) {
425  CHECK_EQ(size_t(1), lhs_lvs.size());
426  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {lhs_lvs.front()}));
427  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {lhs_lvs.front()}));
428  }
429  if (rhs_lvs.size() != 3) {
430  CHECK_EQ(size_t(1), rhs_lvs.size());
431  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {rhs_lvs.front()}));
432  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {rhs_lvs.front()}));
433  }
434  std::vector<llvm::Value*> str_cmp_args{
435  lhs_lvs[1], lhs_lvs[2], rhs_lvs[1], rhs_lvs[2]};
436  if (!null_check_suffix.empty()) {
437  str_cmp_args.push_back(
439  }
440  return cgen_state_->emitCall(
441  string_cmp_func(optype) + (null_check_suffix.empty() ? "" : "_nullable"),
442  str_cmp_args);
443  } else {
444  CHECK(optype == kEQ || optype == kNE);
445  }
446  }
447 
448  if (lhs_ti.is_boolean() && rhs_ti.is_boolean()) {
449  auto& lhs_lv = lhs_lvs.front();
450  auto& rhs_lv = rhs_lvs.front();
451  CHECK(lhs_lv->getType()->isIntegerTy());
452  CHECK(rhs_lv->getType()->isIntegerTy());
453  if (lhs_lv->getType()->getIntegerBitWidth() <
454  rhs_lv->getType()->getIntegerBitWidth()) {
455  lhs_lv =
456  cgen_state_->castToTypeIn(lhs_lv, rhs_lv->getType()->getIntegerBitWidth());
457  } else {
458  rhs_lv =
459  cgen_state_->castToTypeIn(rhs_lv, lhs_lv->getType()->getIntegerBitWidth());
460  }
461  }
462 
463  return null_check_suffix.empty()
464  ? cgen_state_->ir_builder_.CreateICmp(
465  llvm_icmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
467  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
468  null_check_suffix,
469  {lhs_lvs.front(),
470  rhs_lvs.front(),
473  }
474  if (lhs_ti.get_type() == kFLOAT || lhs_ti.get_type() == kDOUBLE) {
475  return null_check_suffix.empty()
476  ? cgen_state_->ir_builder_.CreateFCmp(
477  llvm_fcmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
479  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
480  null_check_suffix,
481  {lhs_lvs.front(),
482  rhs_lvs.front(),
483  lhs_ti.get_type() == kFLOAT ? cgen_state_->llFp(NULL_FLOAT)
486  }
487  CHECK(false);
488  return nullptr;
489 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:106
#define NULL_DOUBLE
Definition: sqltypes.h:185
std::string icmp_name(const SQLOps op_type)
Definition: CompareIR.cpp:45
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
Definition: sqldefs.h:30
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
llvm::CmpInst::Predicate llvm_fcmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:83
bool is_time() const
Definition: sqltypes.h:421
CHECK(cgen_state)
bool is_integer() const
Definition: sqltypes.h:417
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define NULL_FLOAT
Definition: sqltypes.h:184
bool is_timeinterval() const
Definition: sqltypes.h:426
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:300
bool is_boolean() const
Definition: sqltypes.h:422
std::string get_null_check_suffix(const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
Definition: Execute.h:980
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqldefs.h:69
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:266
llvm::Value * codegenQualifierCmp(const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:491
Definition: sqldefs.h:32
llvm::CmpInst::Predicate llvm_icmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:26
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
bool is_geometry() const
Definition: sqltypes.h:427
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:138
bool is_string() const
Definition: sqltypes.h:415
bool is_decimal() const
Definition: sqltypes.h:418
std::string string_cmp_func(const SQLOps optype)
Definition: CompareIR.cpp:106
#define IS_COMPARISON(X)
Definition: sqldefs.h:57

+ Here is the call graph for this function:

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

Definition at line 345 of file CompareIR.cpp.

References Datum::bigintval, codegen(), codegenCast(), codegenCmp(), exp_to_scale(), SQLTypeInfo::get_scale(), Analyzer::Expr::get_type_info(), kCAST, and kDECIMAL.

Referenced by codegenCmp().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Reimplemented in ScalarCodeGenerator.

Definition at line 93 of file ColumnIR.cpp.

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

Referenced by codegen().

95  {
96  if (col_var->get_rte_idx() <= 0 ||
98  !foundOuterJoinMatch(col_var->get_rte_idx())) {
99  return codegenColVar(col_var, fetch_column, true, co);
100  }
101  return codegenOuterJoinNullPlaceholder(col_var, fetch_column, co);
102 }
std::vector< llvm::Value * > outer_join_match_found_per_level_
Definition: CgenState.h:330
CgenState * cgen_state_
std::vector< llvm::Value * > codegenOuterJoinNullPlaceholder(const Analyzer::ColumnVar *col_var, const bool fetch_column, const CompilationOptions &co)
Definition: ColumnIR.cpp:418
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:104
int get_rte_idx() const
Definition: Analyzer.h:197
llvm::Value * foundOuterJoinMatch(const ssize_t nesting_level) const
Definition: ColumnIR.cpp:411

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 104 of file ColumnIR.cpp.

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

Referenced by codegenColumn(), and codegenOuterJoinNullPlaceholder().

107  {
108  const bool hoist_literals = co.hoist_literals;
109  auto col_id = col_var->get_column_id();
110  const int rte_idx = adjusted_range_table_index(col_var);
111  CHECK_LT(static_cast<size_t>(rte_idx), cgen_state_->frag_offsets_.size());
112  const auto catalog = executor()->getCatalog();
113  CHECK(catalog);
114  if (col_var->get_table_id() > 0) {
115  auto cd = get_column_descriptor(col_id, col_var->get_table_id(), *catalog);
116  if (cd->isVirtualCol) {
117  CHECK(cd->columnName == "rowid");
118  return {codegenRowId(col_var, co)};
119  }
120  auto col_ti = cd->columnType;
121  if (col_ti.get_physical_coord_cols() > 0) {
122  std::vector<llvm::Value*> cols;
123  for (auto i = 0; i < col_ti.get_physical_coord_cols(); i++) {
124  auto cd0 =
125  get_column_descriptor(col_id + i + 1, col_var->get_table_id(), *catalog);
126  auto col0_ti = cd0->columnType;
127  CHECK(!cd0->isVirtualCol);
128  auto col0_var = makeExpr<Analyzer::ColumnVar>(
129  col0_ti, col_var->get_table_id(), cd0->columnId, rte_idx);
130  auto col = codegenColVar(col0_var.get(), fetch_column, false, co);
131  cols.insert(cols.end(), col.begin(), col.end());
132  if (!fetch_column && plan_state_->isLazyFetchColumn(col_var)) {
134  std::make_pair(col_var->get_table_id(), col0_var->get_column_id()));
135  }
136  }
137  if (!fetch_column && plan_state_->isLazyFetchColumn(col_var)) {
139  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
140  } else {
142  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
143  }
144  return cols;
145  }
146  } else {
147  if (col_var->get_type_info().is_geometry()) {
148  throw std::runtime_error(
149  "Geospatial columns not supported in temporary tables yet");
150  }
151  }
152  const auto grouped_col_lv = resolveGroupedColumnReference(col_var);
153  if (grouped_col_lv) {
154  return {grouped_col_lv};
155  }
156  const int local_col_id = plan_state_->getLocalColumnId(col_var, fetch_column);
157  const auto window_func_context =
159  // only generate the decoding code once; if a column has been previously
160  // fetched in the generated IR, we'll reuse it
161  if (!window_func_context) {
162  auto it = cgen_state_->fetch_cache_.find(local_col_id);
163  if (it != cgen_state_->fetch_cache_.end()) {
164  return {it->second};
165  }
166  }
167  const auto hash_join_lhs = hashJoinLhs(col_var);
168  // Note(jclay): This has been prone to cause failures in some overlaps joins.
169  // I believe most of the issues are worked out now, but a good place to check if
170  // failures are happening.
171 
172  // Use the already fetched left-hand side of an equi-join if the types are identical.
173  // Currently, types can only be different because of different underlying dictionaries.
174  if (hash_join_lhs && hash_join_lhs->get_type_info() == col_var->get_type_info()) {
175  if (plan_state_->isLazyFetchColumn(col_var)) {
177  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
178  }
179  return codegen(hash_join_lhs.get(), fetch_column, co);
180  }
181  auto pos_arg = posArg(col_var);
182  if (window_func_context) {
183  pos_arg = codegenWindowPosition(window_func_context, pos_arg);
184  }
185  auto col_byte_stream = colByteStream(col_var, fetch_column, hoist_literals);
186  if (plan_state_->isLazyFetchColumn(col_var)) {
187  if (update_query_plan) {
189  std::make_pair(col_var->get_table_id(), col_var->get_column_id()));
190  }
191  if (rte_idx > 0) {
192  const auto offset = cgen_state_->frag_offsets_[rte_idx];
193  if (offset) {
194  return {cgen_state_->ir_builder_.CreateAdd(pos_arg, offset)};
195  } else {
196  return {pos_arg};
197  }
198  }
199  return {pos_arg};
200  }
201  const auto& col_ti = col_var->get_type_info();
202  if (col_ti.is_string() && col_ti.get_compression() == kENCODING_NONE) {
203  const auto varlen_str_column_lvs =
204  codegenVariableLengthStringColVar(col_byte_stream, pos_arg);
205  if (!window_func_context) {
206  auto it_ok = cgen_state_->fetch_cache_.insert(
207  std::make_pair(local_col_id, varlen_str_column_lvs));
208  CHECK(it_ok.second);
209  }
210  return varlen_str_column_lvs;
211  }
212  if (col_ti.is_array()) {
213  return {col_byte_stream};
214  }
215  if (window_func_context) {
216  return {codegenFixedLengthColVarInWindow(col_var, col_byte_stream, pos_arg)};
217  }
218  const auto fixed_length_column_lv =
219  codegenFixedLengthColVar(col_var, col_byte_stream, pos_arg);
220  auto it_ok = cgen_state_->fetch_cache_.insert(
221  std::make_pair(local_col_id, std::vector<llvm::Value*>{fixed_length_column_lv}));
222  CHECK(it_ok.second);
223  return {it_ok.first->second};
224 }
int get_table_id() const
Definition: Analyzer.h:195
CgenState * cgen_state_
llvm::Value * codegenRowId(const Analyzer::ColumnVar *col_var, const CompilationOptions &co)
Definition: ColumnIR.cpp:318
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:509
std::set< std::pair< TableId, ColumnId > > columns_to_fetch_
Definition: PlanState.h:53
static WindowFunctionContext * getActiveWindowFunctionContext(Executor *executor)
std::set< std::pair< TableId, ColumnId > > columns_to_not_fetch_
Definition: PlanState.h:54
std::shared_ptr< const Analyzer::Expr > hashJoinLhs(const Analyzer::ColumnVar *rhs) const
Definition: ColumnIR.cpp:545
int getLocalColumnId(const Analyzer::ColumnVar *col_var, const bool fetch_column)
Definition: PlanState.cpp:62
CHECK(cgen_state)
std::unordered_map< int, std::vector< llvm::Value * > > fetch_cache_
Definition: CgenState.h:320
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:104
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
PlanState * plan_state_
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
#define CHECK_LT(x, y)
Definition: Logger.h:207
std::vector< llvm::Value * > frag_offsets_
Definition: CgenState.h:328
llvm::Value * codegenFixedLengthColVarInWindow(const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:276
bool is_geometry() const
Definition: sqltypes.h:427
llvm::Value * colByteStream(const Analyzer::ColumnVar *col_var, const bool fetch_column, const bool hoist_literals)
Definition: ColumnIR.cpp:493
llvm::Value * codegenWindowPosition(WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:226
SQLTypeInfo columnType
int get_column_id() const
Definition: Analyzer.h:196
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:304
llvm::Value * codegenFixedLengthColVar(const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg)
Definition: ColumnIR.cpp:239
int adjusted_range_table_index(const Analyzer::ColumnVar *col_var)
Definition: ColumnIR.cpp:87
const ColumnDescriptor * get_column_descriptor(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:120
llvm::Value * resolveGroupedColumnReference(const Analyzer::ColumnVar *)
Definition: ColumnIR.cpp:474
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

llvm::Value * CodeGenerator::codegenCompression ( const SQLTypeInfo type_info)
private

Definition at line 543 of file ExtensionsIR.cpp.

References cgen_state_, SQLTypeInfo::get_comp_param(), SQLTypeInfo::get_compression(), kENCODING_GEOINT, and CgenState::llInt().

Referenced by codegenFunctionOperCastArgs().

543  {
544  int32_t compression = (type_info.get_compression() == kENCODING_GEOINT &&
545  type_info.get_comp_param() == 32)
546  ? 1
547  : 0;
548 
549  return cgen_state_->llInt(compression);
550 }
CgenState * cgen_state_
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:266
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:267
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 277 of file DateTimeIR.cpp.

References cgen_state_, CHECK(), CgenState::emitCall(), DateTimeUtils::get_datetrunc_high_precision_scale(), SQLTypeInfo::get_dimension(), SQLTypeInfo::get_notnull(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfo::is_high_precision_timestamp(), DateTimeUtils::is_subsecond_datetrunc_field(), CgenState::llInt(), and run_benchmark_import::result.

Referenced by codegen().

280  {
282  CHECK(ts_lv->getType()->isIntegerTy(64));
285  if (result != -1) {
286  ts_lv =
287  ti.get_notnull()
288  ? cgen_state_->ir_builder_.CreateSDiv(
289  ts_lv, cgen_state_->llInt(static_cast<int64_t>(result)))
290  : cgen_state_->emitCall("floor_div_nullable_lhs",
291  {ts_lv,
292  cgen_state_->llInt(static_cast<int64_t>(result)),
293  cgen_state_->inlineIntNull(ti)});
294  return ti.get_notnull()
295  ? cgen_state_->ir_builder_.CreateMul(
296  ts_lv, cgen_state_->llInt(static_cast<int64_t>(result)))
298  "mul_int64_t_nullable_lhs",
299  {ts_lv,
300  cgen_state_->llInt(static_cast<int64_t>(result)),
301  cgen_state_->inlineIntNull(ti)});
302  } else {
303  return ts_lv;
304  }
305  }
306  std::string datetrunc_fname = "DateTruncate";
307  const int64_t scale = get_timestamp_precision_scale(ti.get_dimension());
308  ts_lv = ti.get_notnull()
309  ? cgen_state_->ir_builder_.CreateSDiv(
310  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)))
311  : cgen_state_->emitCall("floor_div_nullable_lhs",
312  {ts_lv,
313  cgen_state_->llInt(static_cast<int64_t>(scale)),
314  cgen_state_->inlineIntNull(ti)});
315  std::vector<llvm::Value*> datetrunc_args{
316  cgen_state_->llInt(static_cast<int32_t>(field)), ts_lv};
317  if (!ti.get_notnull()) {
318  datetrunc_fname += "Nullable";
319  datetrunc_args.push_back(cgen_state_->inlineIntNull(ti));
320  }
321  ts_lv = cgen_state_->emitExternalCall(
322  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
323  return ti.get_notnull()
324  ? cgen_state_->ir_builder_.CreateMul(
325  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)))
326  : cgen_state_->emitCall("mul_int64_t_nullable_lhs",
327  {ts_lv,
328  cgen_state_->llInt(static_cast<int64_t>(scale)),
329  cgen_state_->inlineIntNull(ti)});
330 }
CgenState * cgen_state_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:206
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
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:317
CHECK(cgen_state)
constexpr bool is_subsecond_datetrunc_field(const DatetruncField field)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:260
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51
bool is_high_precision_timestamp() const
Definition: sqltypes.h:642
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
const int64_t get_datetrunc_high_precision_scale(const DatetruncField &field, const int32_t dimen)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 534 of file ArithmeticIR.cpp.

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

Referenced by codegenArith().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 183 of file StringOpsIR.cpp.

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

Referenced by codegen().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 393 of file StringOpsIR.cpp.

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

Referenced by codegen().

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

+ Here is the call graph for this function: