OmniSciDB  467d548b97
 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::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 llvm::ConstantInt * codegenIntConst (const Analyzer::Constant *constant, CgenState *cgen_state)
 
static std::unordered_set
< llvm::Function * > 
markDeadRuntimeFuncs (llvm::Module &module, const std::vector< llvm::Function * > &roots, const std::vector< llvm::Function * > &leaves)
 
static ExecutionEngineWrapper generateNativeCPUCode (llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
 
static std::string generatePTX (const std::string &cuda_llir, llvm::TargetMachine *nvptx_target_machine, llvm::LLVMContext &context)
 
static std::unique_ptr
< llvm::TargetMachine > 
initializeNVPTXBackend (const CudaMgr_Namespace::NvidiaDeviceArch arch)
 
static bool alwaysCloneRuntimeFunction (const llvm::Function *func)
 
static 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 size_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 1043 of file NativeCodegen.cpp.

1043  {
1044  return func->getName() == "query_stub_hoisted_literals" ||
1045  func->getName() == "multifrag_query_hoisted_literals" ||
1046  func->getName() == "query_stub" || func->getName() == "multifrag_query" ||
1047  func->getName() == "fixed_width_int_decode" ||
1048  func->getName() == "fixed_width_unsigned_decode" ||
1049  func->getName() == "diff_fixed_width_int_decode" ||
1050  func->getName() == "fixed_width_double_decode" ||
1051  func->getName() == "fixed_width_float_decode" ||
1052  func->getName() == "fixed_width_small_date_decode" ||
1053  func->getName() == "record_error_code";
1054 }
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 333 of file ExtensionsIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, codegenFunctionOperNullArg(), CgenState::context_, CgenState::current_func_, 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_, and SQLTypeInfo::is_array().

Referenced by codegenFunctionOper(), and codegenFunctionOperWithCustomTypeHandling().

334  {
336  llvm::BasicBlock* args_null_bb{nullptr};
337  llvm::BasicBlock* args_notnull_bb{nullptr};
338  llvm::BasicBlock* orig_bb = cgen_state_->ir_builder_.GetInsertBlock();
339  llvm::Value* null_array_alloca{nullptr};
340  // Only generate the check if required (at least one argument must be nullable).
341  if (ext_func_call_requires_nullcheck(function_oper)) {
342  if (function_oper->get_type_info().is_array()) {
343  const auto arr_struct_ty =
345  function_oper->getName(),
347  function_oper->get_type_info(), cgen_state_->context_),
348  0);
349  null_array_alloca = cgen_state_->ir_builder_.CreateAlloca(arr_struct_ty);
350  }
351  const auto args_notnull_lv = cgen_state_->ir_builder_.CreateNot(
352  codegenFunctionOperNullArg(function_oper, orig_arg_lvs));
353  args_notnull_bb = llvm::BasicBlock::Create(
354  cgen_state_->context_, "args_notnull", cgen_state_->current_func_);
355  args_null_bb = llvm::BasicBlock::Create(
357  cgen_state_->ir_builder_.CreateCondBr(args_notnull_lv, args_notnull_bb, args_null_bb);
358  cgen_state_->ir_builder_.SetInsertPoint(args_notnull_bb);
359  }
360  return std::make_tuple(
361  CodeGenerator::ArgNullcheckBBs{args_null_bb, args_notnull_bb, orig_bb},
362  null_array_alloca);
363 }
CgenState * cgen_state_
llvm::Value * codegenFunctionOperNullArg(const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
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::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
llvm::Type * get_llvm_type_from_sql_array_type(const SQLTypeInfo ti, llvm::LLVMContext &ctx)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::string getName() const
Definition: Analyzer.h:1358
bool is_array() const
Definition: sqltypes.h:425

+ 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 1189 of file ExtensionsIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

1190  {
1192  if (elem_ti.get_type() == kFLOAT) {
1193  return cgen_state_->ir_builder_.CreatePointerCast(
1194  ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
1195  }
1196  if (elem_ti.get_type() == kDOUBLE) {
1197  return cgen_state_->ir_builder_.CreatePointerCast(
1198  ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
1199  }
1200  CHECK(elem_ti.is_integer() || elem_ti.is_boolean() ||
1201  (elem_ti.is_string() && elem_ti.get_compression() == kENCODING_DICT));
1202  switch (elem_ti.get_size()) {
1203  case 1:
1204  return cgen_state_->ir_builder_.CreatePointerCast(
1205  ptr, llvm::Type::getInt8PtrTy(cgen_state_->context_));
1206  case 2:
1207  return cgen_state_->ir_builder_.CreatePointerCast(
1208  ptr, llvm::Type::getInt16PtrTy(cgen_state_->context_));
1209  case 4:
1210  return cgen_state_->ir_builder_.CreatePointerCast(
1211  ptr, llvm::Type::getInt32PtrTy(cgen_state_->context_));
1212  case 8:
1213  return cgen_state_->ir_builder_.CreatePointerCast(
1214  ptr, llvm::Type::getInt64PtrTy(cgen_state_->context_));
1215  default:
1216  CHECK(false);
1217  }
1218  return nullptr;
1219 }
HOST DEVICE int get_size() const
Definition: sqltypes.h:269
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
llvm::LLVMContext & context_
Definition: CgenState.h:339
bool is_integer() const
Definition: sqltypes.h:419
bool is_boolean() const
Definition: sqltypes.h:424
#define AUTOMATIC_IR_METADATA(CGENSTATE)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:267
#define CHECK(condition)
Definition: Logger.h:197
bool is_string() const
Definition: sqltypes.h:417

+ 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 628 of file ArithmeticIR.cpp.

References CHECK, executor(), executor_, Analyzer::Expr::get_type_info(), getExpressionRange(), Integer, SQLTypeInfo::is_decimal(), ExpressionRange::makeInvalidRange(), plan_state_, and PlanState::query_infos_.

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

630  {
631  if (uoper->get_type_info().is_decimal()) {
632  return false;
633  }
634 
636  if (executor_) {
637  auto expr_range_info =
638  plan_state_->query_infos_.size() > 0
640  : ExpressionRange::makeInvalidRange();
641  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
642  return false;
643  }
644  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
645  return true;
646  }
647  }
648 
649  return false;
650 }
Executor * executor_
const std::vector< InputTableInfo > & query_infos_
Definition: PlanState.h:64
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
PlanState * plan_state_
#define CHECK(condition)
Definition: Logger.h:197
bool is_decimal() const
Definition: sqltypes.h:420
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 187 of file ArithmeticIR.cpp.

References CHECK, executor(), 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(), plan_state_, and PlanState::query_infos_.

189  {
190  if (is_temporary_column(bin_oper->get_left_operand()) ||
191  is_temporary_column(bin_oper->get_right_operand())) {
192  // Computing the range for temporary columns is a lot more expensive than the overflow
193  // check.
194  return false;
195  }
196  if (bin_oper->get_type_info().is_decimal()) {
197  return false;
198  }
199 
201  if (executor_) {
202  auto expr_range_info =
203  plan_state_->query_infos_.size() > 0
205  : ExpressionRange::makeInvalidRange();
206  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
207  return false;
208  }
209  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
210  return true;
211  }
212  }
213 
214  return false;
215 }
const Expr * get_right_operand() const
Definition: Analyzer.h:443
bool is_temporary_column(const Analyzer::Expr *expr)
Executor * executor_
const std::vector< InputTableInfo > & query_infos_
Definition: PlanState.h:64
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
PlanState * plan_state_
#define CHECK(condition)
Definition: Logger.h:197
const Expr * get_left_operand() const
Definition: Analyzer.h:442
bool is_decimal() const
Definition: sqltypes.h:420
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 AUTOMATIC_IR_METADATA, cgen_state_, CHECK_NE, 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::codegenWindowFunctionAggregateCalls(), ScalarCodeGenerator::compile(), and Executor::groupByColumnCodegen().

28  {
30  if (!expr) {
31  return {posArg(expr)};
32  }
33  auto bin_oper = dynamic_cast<const Analyzer::BinOper*>(expr);
34  if (bin_oper) {
35  return {codegen(bin_oper, co)};
36  }
37  auto u_oper = dynamic_cast<const Analyzer::UOper*>(expr);
38  if (u_oper) {
39  return {codegen(u_oper, co)};
40  }
41  auto col_var = dynamic_cast<const Analyzer::ColumnVar*>(expr);
42  if (col_var) {
43  return codegenColumn(col_var, fetch_columns, co);
44  }
45  auto constant = dynamic_cast<const Analyzer::Constant*>(expr);
46  if (constant) {
47  const auto& ti = constant->get_type_info();
48  if (ti.get_type() == kNULLT) {
49  throw std::runtime_error(
50  "NULL type literals are not currently supported in this context.");
51  }
52  if (constant->get_is_null()) {
53  return {ti.is_fp()
54  ? static_cast<llvm::Value*>(executor_->cgen_state_->inlineFpNull(ti))
55  : static_cast<llvm::Value*>(executor_->cgen_state_->inlineIntNull(ti))};
56  }
57  if (ti.get_compression() == kENCODING_DICT) {
58  // The dictionary encoding case should be handled by the parent expression
59  // (cast, for now), here is too late to know the dictionary id if not already set
60  CHECK_NE(ti.get_comp_param(), 0);
61  return {codegen(constant, ti.get_compression(), ti.get_comp_param(), co)};
62  }
63  return {codegen(constant, ti.get_compression(), 0, co)};
64  }
65  auto case_expr = dynamic_cast<const Analyzer::CaseExpr*>(expr);
66  if (case_expr) {
67  return {codegen(case_expr, co)};
68  }
69  auto extract_expr = dynamic_cast<const Analyzer::ExtractExpr*>(expr);
70  if (extract_expr) {
71  return {codegen(extract_expr, co)};
72  }
73  auto dateadd_expr = dynamic_cast<const Analyzer::DateaddExpr*>(expr);
74  if (dateadd_expr) {
75  return {codegen(dateadd_expr, co)};
76  }
77  auto datediff_expr = dynamic_cast<const Analyzer::DatediffExpr*>(expr);
78  if (datediff_expr) {
79  return {codegen(datediff_expr, co)};
80  }
81  auto datetrunc_expr = dynamic_cast<const Analyzer::DatetruncExpr*>(expr);
82  if (datetrunc_expr) {
83  return {codegen(datetrunc_expr, co)};
84  }
85  auto charlength_expr = dynamic_cast<const Analyzer::CharLengthExpr*>(expr);
86  if (charlength_expr) {
87  return {codegen(charlength_expr, co)};
88  }
89  auto keyforstring_expr = dynamic_cast<const Analyzer::KeyForStringExpr*>(expr);
90  if (keyforstring_expr) {
91  return {codegen(keyforstring_expr, co)};
92  }
93  auto sample_ratio_expr = dynamic_cast<const Analyzer::SampleRatioExpr*>(expr);
94  if (sample_ratio_expr) {
95  return {codegen(sample_ratio_expr, co)};
96  }
97  auto lower_expr = dynamic_cast<const Analyzer::LowerExpr*>(expr);
98  if (lower_expr) {
99  return {codegen(lower_expr, co)};
100  }
101  auto cardinality_expr = dynamic_cast<const Analyzer::CardinalityExpr*>(expr);
102  if (cardinality_expr) {
103  return {codegen(cardinality_expr, co)};
104  }
105  auto like_expr = dynamic_cast<const Analyzer::LikeExpr*>(expr);
106  if (like_expr) {
107  return {codegen(like_expr, co)};
108  }
109  auto regexp_expr = dynamic_cast<const Analyzer::RegexpExpr*>(expr);
110  if (regexp_expr) {
111  return {codegen(regexp_expr, co)};
112  }
113  auto likelihood_expr = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
114  if (likelihood_expr) {
115  return {codegen(likelihood_expr->get_arg(), fetch_columns, co)};
116  }
117  auto in_expr = dynamic_cast<const Analyzer::InValues*>(expr);
118  if (in_expr) {
119  return {codegen(in_expr, co)};
120  }
121  auto in_integer_set_expr = dynamic_cast<const Analyzer::InIntegerSet*>(expr);
122  if (in_integer_set_expr) {
123  return {codegen(in_integer_set_expr, co)};
124  }
125  auto function_oper_with_custom_type_handling_expr =
126  dynamic_cast<const Analyzer::FunctionOperWithCustomTypeHandling*>(expr);
127  if (function_oper_with_custom_type_handling_expr) {
129  function_oper_with_custom_type_handling_expr, co)};
130  }
131  auto array_oper_expr = dynamic_cast<const Analyzer::ArrayExpr*>(expr);
132  if (array_oper_expr) {
133  return {codegenArrayExpr(array_oper_expr, co)};
134  }
135  auto geo_uop = dynamic_cast<const Analyzer::GeoUOper*>(expr);
136  if (geo_uop) {
137  return {codegenGeoUOper(geo_uop, co)};
138  }
139  auto geo_binop = dynamic_cast<const Analyzer::GeoBinOper*>(expr);
140  if (geo_binop) {
141  return {codegenGeoBinOper(geo_binop, co)};
142  }
143  auto function_oper_expr = dynamic_cast<const Analyzer::FunctionOper*>(expr);
144  if (function_oper_expr) {
145  return {codegenFunctionOper(function_oper_expr, co)};
146  }
147  if (dynamic_cast<const Analyzer::OffsetInFragment*>(expr)) {
148  return {posArg(nullptr)};
149  }
150  if (dynamic_cast<const Analyzer::WindowFunction*>(expr)) {
151  throw NativeExecutionError("Window expression not supported in this context");
152  }
153  abort();
154 }
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:515
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:81
#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:91
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Expression class for the LOWER (lowercase) string function. The &quot;arg&quot; constructor parameter must be a...
Definition: Analyzer.h:791
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(), AUTOMATIC_IR_METADATA, 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  {
25  if (co.hoist_literals) {
26  std::vector<const Analyzer::Constant*> constants(
27  executor()->deviceCount(co.device_type), constant);
28  return codegenHoistedConstants(constants, enc_type, dict_id);
29  }
30  const auto& type_info = constant->get_type_info();
31  const auto type =
32  type_info.is_decimal() ? decimal_to_int_type(type_info) : type_info.get_type();
33  switch (type) {
34  case kBOOLEAN:
35  return {llvm::ConstantInt::get(get_int_type(8, cgen_state_->context_),
36  constant->get_constval().boolval)};
37  case kTINYINT:
38  case kSMALLINT:
39  case kINT:
40  case kBIGINT:
41  case kTIME:
42  case kTIMESTAMP:
43  case kDATE:
44  case kINTERVAL_DAY_TIME:
46  return {CodeGenerator::codegenIntConst(constant, cgen_state_)};
47  case kFLOAT:
48  return {llvm::ConstantFP::get(llvm::Type::getFloatTy(cgen_state_->context_),
49  constant->get_constval().floatval)};
50  case kDOUBLE:
51  return {llvm::ConstantFP::get(llvm::Type::getDoubleTy(cgen_state_->context_),
52  constant->get_constval().doubleval)};
53  case kVARCHAR:
54  case kCHAR:
55  case kTEXT: {
56  CHECK(constant->get_constval().stringval || constant->get_is_null());
57  if (constant->get_is_null()) {
58  if (enc_type == kENCODING_DICT) {
59  return {
60  cgen_state_->llInt(static_cast<int32_t>(inline_int_null_val(type_info)))};
61  }
62  return {cgen_state_->llInt(int64_t(0)),
63  llvm::Constant::getNullValue(
64  llvm::PointerType::get(get_int_type(8, cgen_state_->context_), 0)),
65  cgen_state_->llInt(int32_t(0))};
66  }
67  const auto& str_const = *constant->get_constval().stringval;
68  if (enc_type == kENCODING_DICT) {
69  return {
71  ->getStringDictionaryProxy(
72  dict_id, executor()->getRowSetMemoryOwner(), true)
73  ->getIdOfString(str_const))};
74  }
75  return {cgen_state_->llInt(int64_t(0)),
76  cgen_state_->addStringConstant(str_const),
77  cgen_state_->llInt(static_cast<int32_t>(str_const.size()))};
78  }
79  default:
80  CHECK(false);
81  }
82  abort();
83 }
Definition: sqltypes.h:51
CgenState * cgen_state_
llvm::Value * addStringConstant(const std::string &str)
Definition: CgenState.h:203
bool boolval
Definition: sqltypes.h:134
bool get_is_null() const
Definition: Analyzer.h:334
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
float floatval
Definition: sqltypes.h:139
llvm::LLVMContext & context_
Definition: CgenState.h:339
std::vector< llvm::Value * > codegenHoistedConstants(const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const int dict_id)
Definition: ConstantIR.cpp:279
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::string * stringval
Definition: sqltypes.h:143
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:302
ExecutorDeviceType device_type
Definition: sqltypes.h:54
Definition: sqltypes.h:55
static llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant, CgenState *cgen_state)
Definition: ConstantIR.cpp:85
Datum get_constval() const
Definition: Analyzer.h:335
Definition: sqltypes.h:43
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
Definition: sqltypes.h:47
double doubleval
Definition: sqltypes.h:140
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(), AUTOMATIC_IR_METADATA, 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  {
26  const auto in_arg = expr->get_arg();
27  if (is_unnest(in_arg)) {
28  throw std::runtime_error("IN not supported for unnested expressions");
29  }
30  const auto& expr_ti = expr->get_type_info();
31  CHECK(expr_ti.is_boolean());
32  const auto lhs_lvs = codegen(in_arg, true, co);
33  llvm::Value* result{nullptr};
34  if (expr_ti.get_notnull()) {
35  result = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(cgen_state_->context_),
36  false);
37  } else {
38  result = cgen_state_->llInt(int8_t(0));
39  }
40  CHECK(result);
41  if (co.hoist_literals) { // TODO(alex): remove this constraint
42  auto in_vals_bitmap = createInValuesBitmap(expr, co);
43  if (in_vals_bitmap) {
44  if (in_vals_bitmap->isEmpty()) {
45  return in_vals_bitmap->hasNull()
47  : result;
48  }
49  CHECK_EQ(size_t(1), lhs_lvs.size());
50  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
51  ->codegen(lhs_lvs.front(), executor());
52  }
53  }
54  if (expr_ti.get_notnull()) {
55  for (auto in_val : expr->get_value_list()) {
56  result = cgen_state_->ir_builder_.CreateOr(
57  result,
58  toBool(
59  codegenCmp(kEQ, kONE, lhs_lvs, in_arg->get_type_info(), in_val.get(), co)));
60  }
61  } else {
62  for (auto in_val : expr->get_value_list()) {
63  const auto crt =
64  codegenCmp(kEQ, kONE, lhs_lvs, in_arg->get_type_info(), in_val.get(), co);
65  result = cgen_state_->emitCall("logical_or",
66  {result, crt, cgen_state_->inlineIntNull(expr_ti)});
67  }
68  }
69  return result;
70 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
Definition: sqldefs.h:30
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:212
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp: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:586
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:335
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:184
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
std::unique_ptr< InValuesBitmap > createInValuesBitmap(const Analyzer::InValues *, const CompilationOptions &)
Definition: InValuesIR.cpp:111
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1042
const Expr * get_arg() const
Definition: Analyzer.h:584
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 72 of file InValuesIR.cpp.

References CgenState::addInValuesBitmap(), AUTOMATIC_IR_METADATA, 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.

73  {
75  const auto in_arg = in_integer_set->get_arg();
76  if (is_unnest(in_arg)) {
77  throw std::runtime_error("IN not supported for unnested expressions");
78  }
79  const auto& ti = in_integer_set->get_arg()->get_type_info();
80  const auto needle_null_val = inline_int_null_val(ti);
81  if (!co.hoist_literals) {
82  // We never run without literal hoisting in real world scenarios, this avoids a crash
83  // when testing.
84  throw std::runtime_error(
85  "IN subquery with many right-hand side values not supported when literal "
86  "hoisting is disabled");
87  }
88  auto in_vals_bitmap = std::make_unique<InValuesBitmap>(
89  in_integer_set->get_value_list(),
90  needle_null_val,
93  executor()->deviceCount(co.device_type),
94  &executor()->getCatalog()->getDataMgr());
95  const auto& in_integer_set_ti = in_integer_set->get_type_info();
96  CHECK(in_integer_set_ti.is_boolean());
97  const auto lhs_lvs = codegen(in_arg, true, co);
98  llvm::Value* result{nullptr};
99  if (in_integer_set_ti.get_notnull()) {
100  result = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(cgen_state_->context_),
101  false);
102  } else {
103  result = cgen_state_->llInt(int8_t(0));
104  }
105  CHECK(result);
106  CHECK_EQ(size_t(1), lhs_lvs.size());
107  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
108  ->codegen(lhs_lvs.front(), executor());
109 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
llvm::LLVMContext & context_
Definition: CgenState.h:339
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:212
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:312
#define CHECK(condition)
Definition: Logger.h:197
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1042
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 AUTOMATIC_IR_METADATA, 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  {
23  const auto case_ti = case_expr->get_type_info();
24  llvm::Type* case_llvm_type = nullptr;
25  bool is_real_str = false;
26  if (case_ti.is_integer() || case_ti.is_time() || case_ti.is_decimal()) {
27  case_llvm_type = get_int_type(get_bit_width(case_ti), cgen_state_->context_);
28  } else if (case_ti.is_fp()) {
29  case_llvm_type = case_ti.get_type() == kFLOAT
30  ? llvm::Type::getFloatTy(cgen_state_->context_)
31  : llvm::Type::getDoubleTy(cgen_state_->context_);
32  } else if (case_ti.is_string()) {
33  if (case_ti.get_compression() == kENCODING_DICT) {
34  case_llvm_type =
35  get_int_type(8 * case_ti.get_logical_size(), cgen_state_->context_);
36  } else {
37  is_real_str = true;
38  case_llvm_type = get_int_type(64, cgen_state_->context_);
39  }
40  } else if (case_ti.is_boolean()) {
41  case_llvm_type = get_int_type(8 * case_ti.get_logical_size(), cgen_state_->context_);
42  }
43  CHECK(case_llvm_type);
44  const auto& else_ti = case_expr->get_else_expr()->get_type_info();
45  CHECK_EQ(else_ti.get_type(), case_ti.get_type());
46  llvm::Value* case_val = codegenCase(case_expr, case_llvm_type, is_real_str, co);
47  std::vector<llvm::Value*> ret_vals{case_val};
48  if (is_real_str) {
49  ret_vals.push_back(cgen_state_->emitCall("extract_str_ptr", {case_val}));
50  ret_vals.push_back(cgen_state_->emitCall("extract_str_len", {case_val}));
51  }
52  return ret_vals;
53 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const Expr * get_else_expr() const
Definition: Analyzer.h:1152
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:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
llvm::Value * codegenCase(const Analyzer::CaseExpr *, llvm::Type *case_llvm_type, const bool is_real_str, const CompilationOptions &)
Definition: CaseIR.cpp:55
#define CHECK(condition)
Definition: Logger.h:197

+ 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 AUTOMATIC_IR_METADATA, 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  {
72  auto from_expr = codegen(extract_expr->get_from_expr(), true, co).front();
73  const int32_t extract_field{extract_expr->get_field()};
74  const auto& extract_expr_ti = extract_expr->get_from_expr()->get_type_info();
75  if (extract_field == kEPOCH) {
76  CHECK(extract_expr_ti.get_type() == kTIMESTAMP ||
77  extract_expr_ti.get_type() == kDATE);
78  if (from_expr->getType()->isIntegerTy(32)) {
79  from_expr =
80  cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
81  from_expr,
83  return from_expr;
84  }
85  }
86  CHECK(from_expr->getType()->isIntegerTy(64));
87  if (extract_expr_ti.is_high_precision_timestamp()) {
89  from_expr, extract_expr_ti, extract_expr->get_field());
90  }
91  if (!extract_expr_ti.is_high_precision_timestamp() &&
92  is_subsecond_extract_field(extract_expr->get_field())) {
93  from_expr =
94  extract_expr_ti.get_notnull()
95  ? cgen_state_->ir_builder_.CreateMul(
96  from_expr,
100  "mul_int64_t_nullable_lhs",
101  {from_expr,
104  cgen_state_->inlineIntNull(extract_expr_ti)});
105  }
106  const auto extract_fname = get_extract_function_name(extract_expr->get_field());
107  if (!extract_expr_ti.get_notnull()) {
108  llvm::BasicBlock* extract_nullcheck_bb{nullptr};
109  llvm::PHINode* extract_nullcheck_value{nullptr};
110  {
112  cgen_state_->ir_builder_.CreateICmp(
113  llvm::ICmpInst::ICMP_EQ,
114  from_expr,
115  cgen_state_->inlineIntNull(extract_expr_ti)),
116  executor(),
117  false,
118  "extract_nullcheck",
119  nullptr,
120  false);
121  // generate a phi node depending on whether we got a null or not
122  extract_nullcheck_bb = llvm::BasicBlock::Create(
123  cgen_state_->context_, "extract_nullcheck_bb", cgen_state_->current_func_);
124 
125  // update the blocks created by diamond codegen to point to the newly created phi
126  // block
127  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_true_);
128  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
129  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_false_);
130  auto extract_call =
131  cgen_state_->emitExternalCall(extract_fname,
133  std::vector<llvm::Value*>{from_expr});
134  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
135 
136  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
137  extract_nullcheck_value = cgen_state_->ir_builder_.CreatePHI(
138  get_int_type(64, cgen_state_->context_), 2, "extract_value");
139  extract_nullcheck_value->addIncoming(extract_call, null_check.cond_false_);
140  extract_nullcheck_value->addIncoming(cgen_state_->inlineIntNull(extract_expr_ti),
141  null_check.cond_true_);
142  }
143 
144  // diamond codegen will set the insert point in its destructor. override it to
145  // continue using the extract nullcheck bb
146  CHECK(extract_nullcheck_bb);
147  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
148  CHECK(extract_nullcheck_value);
149  return extract_nullcheck_value;
150  } else {
151  return cgen_state_->emitExternalCall(extract_fname,
153  std::vector<llvm::Value*>{from_expr});
154  }
155 }
const Expr * get_from_expr() const
Definition: Analyzer.h:1197
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:1196
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:222
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
const char * get_extract_function_name(ExtractField field)
Definition: DateTimeIR.cpp:26
llvm::Value * codegenExtractHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const ExtractField &)
Definition: DateTimeIR.cpp:251
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqltypes.h:55
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
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 157 of file DateTimeIR.cpp.

References AUTOMATIC_IR_METADATA, 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(), Analyzer::Expr::get_type_info(), CgenState::inlineIntNull(), DateTimeUtils::is_subsecond_dateadd_field(), kDATE, kTIMESTAMP, and CgenState::llInt().

158  {
160  const auto& dateadd_expr_ti = dateadd_expr->get_type_info();
161  CHECK(dateadd_expr_ti.get_type() == kTIMESTAMP || dateadd_expr_ti.get_type() == kDATE);
162  auto datetime = codegen(dateadd_expr->get_datetime_expr(), true, co).front();
163  CHECK(datetime->getType()->isIntegerTy(64));
164  auto number = codegen(dateadd_expr->get_number_expr(), true, co).front();
165 
166  const auto& datetime_ti = dateadd_expr->get_datetime_expr()->get_type_info();
167  std::vector<llvm::Value*> dateadd_args{
168  cgen_state_->llInt(static_cast<int32_t>(dateadd_expr->get_field())),
169  number,
170  datetime};
171  std::string dateadd_fname{"DateAdd"};
172  if (is_subsecond_dateadd_field(dateadd_expr->get_field()) ||
173  dateadd_expr_ti.is_high_precision_timestamp()) {
174  dateadd_fname += "HighPrecision";
175  dateadd_args.push_back(
176  cgen_state_->llInt(static_cast<int32_t>(datetime_ti.get_dimension())));
177  }
178  if (!datetime_ti.get_notnull()) {
179  dateadd_args.push_back(cgen_state_->inlineIntNull(datetime_ti));
180  dateadd_fname += "Nullable";
181  }
182  return cgen_state_->emitExternalCall(dateadd_fname,
184  dateadd_args,
185  {llvm::Attribute::NoUnwind,
186  llvm::Attribute::ReadNone,
187  llvm::Attribute::Speculatable});
188 }
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:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqltypes.h:55
const Expr * get_datetime_expr() const
Definition: Analyzer.h:1239
DateaddField get_field() const
Definition: Analyzer.h:1237
constexpr bool is_subsecond_dateadd_field(const DateaddField field)
Definition: DateTimeUtils.h:99
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
const Expr * get_number_expr() const
Definition: Analyzer.h:1238

+ Here is the call graph for this function:

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

Definition at line 190 of file DateTimeIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

191  {
193  auto start = codegen(datediff_expr->get_start_expr(), true, co).front();
194  CHECK(start->getType()->isIntegerTy(64));
195  auto end = codegen(datediff_expr->get_end_expr(), true, co).front();
196  CHECK(end->getType()->isIntegerTy(32) || end->getType()->isIntegerTy(64));
197  const auto& start_ti = datediff_expr->get_start_expr()->get_type_info();
198  const auto& end_ti = datediff_expr->get_end_expr()->get_type_info();
199  std::vector<llvm::Value*> datediff_args{
200  cgen_state_->llInt(static_cast<int32_t>(datediff_expr->get_field())), start, end};
201  std::string datediff_fname{"DateDiff"};
202  if (start_ti.is_high_precision_timestamp() || end_ti.is_high_precision_timestamp()) {
203  datediff_fname += "HighPrecision";
204  datediff_args.push_back(
205  cgen_state_->llInt(static_cast<int32_t>(start_ti.get_dimension())));
206  datediff_args.push_back(
207  cgen_state_->llInt(static_cast<int32_t>(end_ti.get_dimension())));
208  }
209  const auto& ret_ti = datediff_expr->get_type_info();
210  if (!start_ti.get_notnull() || !end_ti.get_notnull()) {
211  datediff_args.push_back(cgen_state_->inlineIntNull(ret_ti));
212  datediff_fname += "Nullable";
213  }
215  datediff_fname, get_int_type(64, cgen_state_->context_), datediff_args);
216 }
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:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const Expr * get_start_expr() const
Definition: Analyzer.h:1280
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
const Expr * get_end_expr() const
Definition: Analyzer.h:1281
#define CHECK(condition)
Definition: Logger.h:197
DatetruncField get_field() const
Definition: Analyzer.h:1279

+ Here is the call graph for this function:

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

Definition at line 218 of file DateTimeIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, codegen(), codegenDateTruncHighPrecisionTimestamps(), CgenState::context_, datetrunc_fname_lookup, dtMICROSECOND, dtMILLISECOND, dtNANOSECOND, dtSECOND, CgenState::emitExternalCall(), executor(), field(), Analyzer::DatetruncExpr::get_field(), Analyzer::DatetruncExpr::get_from_expr(), get_int_type(), Analyzer::Expr::get_type_info(), and CgenState::ir_builder_.

219  {
221  auto from_expr = codegen(datetrunc_expr->get_from_expr(), true, co).front();
222  const auto& datetrunc_expr_ti = datetrunc_expr->get_from_expr()->get_type_info();
223  CHECK(from_expr->getType()->isIntegerTy(64));
224  DatetruncField const field = datetrunc_expr->get_field();
225  if (datetrunc_expr_ti.is_high_precision_timestamp()) {
226  return codegenDateTruncHighPrecisionTimestamps(from_expr, datetrunc_expr_ti, field);
227  }
228  static_assert(dtSECOND + 1 == dtMILLISECOND, "Please keep these consecutive.");
229  static_assert(dtMILLISECOND + 1 == dtMICROSECOND, "Please keep these consecutive.");
230  static_assert(dtMICROSECOND + 1 == dtNANOSECOND, "Please keep these consecutive.");
231  if (dtSECOND <= field && field <= dtNANOSECOND) {
232  return cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
233  from_expr,
235  }
236  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
237  const bool is_nullable = !datetrunc_expr_ti.get_notnull();
238  if (is_nullable) {
239  nullcheck_codegen = std::make_unique<NullCheckCodegen>(
240  cgen_state_, executor(), from_expr, datetrunc_expr_ti, "date_trunc_nullcheck");
241  }
242  char const* const fname = datetrunc_fname_lookup.at(field);
243  auto ret = cgen_state_->emitExternalCall(
244  fname, get_int_type(64, cgen_state_->context_), {from_expr});
245  if (is_nullable) {
246  ret = nullcheck_codegen->finalize(ll_int(NULL_BIGINT, cgen_state_->context_), ret);
247  }
248  return ret;
249 }
CgenState * cgen_state_
#define NULL_BIGINT
Definition: sqltypes.h:184
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:222
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
DatetruncField get_field() const
Definition: Analyzer.h:1321
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:339
DatetruncField
Definition: DateTruncate.h:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
constexpr std::array< char const *, dtINVALID > datetrunc_fname_lookup
Definition: DateTruncate.h:47
const Expr * get_from_expr() const
Definition: Analyzer.h:1322
#define CHECK(condition)
Definition: Logger.h:197
llvm::Value * codegenDateTruncHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
Definition: DateTimeIR.cpp:295
Executor * executor() const

+ 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 AUTOMATIC_IR_METADATA, cgen_state_, CHECK_EQ, codegen(), CgenState::emitCall(), g_enable_watchdog, and Analyzer::CharLengthExpr::get_arg().

66  {
68  auto str_lv = codegen(expr->get_arg(), true, co);
69  if (str_lv.size() != 3) {
70  CHECK_EQ(size_t(1), str_lv.size());
71  if (g_enable_watchdog) {
72  throw WatchdogException(
73  "LENGTH / CHAR_LENGTH on dictionary-encoded strings would be slow");
74  }
75  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
76  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
78  throw QueryMustRunOnCpu();
79  }
80  }
81  std::vector<llvm::Value*> charlength_args{str_lv[1], str_lv[2]};
82  std::string fn_name("char_length");
83  if (expr->get_calc_encoded_length()) {
84  fn_name += "_encoded";
85  }
86  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
87  if (is_nullable) {
88  fn_name += "_nullable";
89  charlength_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
90  }
91  return expr->get_calc_encoded_length()
93  fn_name, get_int_type(32, cgen_state_->context_), charlength_args)
94  : cgen_state_->emitCall(fn_name, charlength_args);
95 }
#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:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool get_calc_encoded_length() const
Definition: Analyzer.h:658
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp: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:656
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266

+ Here is the call graph for this function:

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

Definition at line 97 of file StringOpsIR.cpp.

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

98  {
100  auto str_lv = codegen(expr->get_arg(), true, co);
101  CHECK_EQ(size_t(1), str_lv.size());
102  return cgen_state_->emitCall("key_for_string_encoded", str_lv);
103 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:705

+ Here is the call graph for this function:

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

Definition at line 199 of file IRCodegen.cpp.

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

200  {
202  auto input_expr = expr->get_arg();
203  CHECK(input_expr);
204 
205  auto double_lv = codegen(input_expr, true, co);
206  CHECK_EQ(size_t(1), double_lv.size());
207 
208  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
209  const bool is_nullable = !input_expr->get_type_info().get_notnull();
210  if (is_nullable) {
211  nullcheck_codegen = std::make_unique<NullCheckCodegen>(cgen_state_,
212  executor(),
213  double_lv.front(),
214  input_expr->get_type_info(),
215  "sample_ratio_nullcheck");
216  }
217  CHECK_EQ(input_expr->get_type_info().get_type(), kDOUBLE);
218  std::vector<llvm::Value*> args{double_lv[0], posArg(nullptr)};
219  auto ret = cgen_state_->emitCall("sample_ratio", args);
220  if (nullcheck_codegen) {
221  ret = nullcheck_codegen->finalize(ll_bool(false, cgen_state_->context_), ret);
222  }
223  return ret;
224 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:515
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:750
#define CHECK(condition)
Definition: Logger.h:197
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 105 of file StringOpsIR.cpp.

References run_benchmark_import::args, AUTOMATIC_IR_METADATA, 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().

106  {
109  throw QueryMustRunOnCpu();
110  }
111 
112  auto str_id_lv = codegen(expr->get_arg(), true, co);
113  CHECK_EQ(size_t(1), str_id_lv.size());
114 
115  const auto string_dictionary_proxy = executor()->getStringDictionaryProxy(
116  expr->get_type_info().get_comp_param(), executor()->getRowSetMemoryOwner(), true);
117  CHECK(string_dictionary_proxy);
118 
119  std::vector<llvm::Value*> args{
120  str_id_lv[0],
121  cgen_state_->llInt(reinterpret_cast<int64_t>(string_dictionary_proxy))};
122 
124  "lower_encoded", get_int_type(32, cgen_state_->context_), args);
125 }
#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:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:268
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
const Expr * get_arg() const
Definition: Analyzer.h:795
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 127 of file StringOpsIR.cpp.

References AUTOMATIC_IR_METADATA, 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.

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

References AUTOMATIC_IR_METADATA, 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.

345  {
347  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
348  throw std::runtime_error("REGEXP not supported for unnested expressions");
349  }
350  char escape_char{'\\'};
351  if (expr->get_escape_expr()) {
352  auto escape_char_expr =
353  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
354  CHECK(escape_char_expr);
355  CHECK(escape_char_expr->get_type_info().is_string());
356  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
357  escape_char = (*escape_char_expr->get_constval().stringval)[0];
358  }
359  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_pattern_expr());
360  CHECK(pattern);
361  auto fast_dict_pattern_lv =
362  codegenDictRegexp(expr->get_own_arg(), pattern, escape_char, co);
363  if (fast_dict_pattern_lv) {
364  return fast_dict_pattern_lv;
365  }
366  const auto& ti = expr->get_arg()->get_type_info();
367  CHECK(ti.is_string());
368  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
369  throw WatchdogException(
370  "Cannot do REGEXP_LIKE on this dictionary encoded column, its cardinality is too "
371  "high");
372  }
373  // Now we know we are working on NONE ENCODED column. So switch back to CPU
375  throw QueryMustRunOnCpu();
376  }
377  auto str_lv = codegen(expr->get_arg(), true, co);
378  if (str_lv.size() != 3) {
379  CHECK_EQ(size_t(1), str_lv.size());
380  str_lv.push_back(cgen_state_->emitCall("extract_str_ptr", {str_lv.front()}));
381  str_lv.push_back(cgen_state_->emitCall("extract_str_len", {str_lv.front()}));
382  }
383  auto regexp_expr_arg_lvs = codegen(expr->get_pattern_expr(), true, co);
384  CHECK_EQ(size_t(3), regexp_expr_arg_lvs.size());
385  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
386  std::vector<llvm::Value*> regexp_args{
387  str_lv[1], str_lv[2], regexp_expr_arg_lvs[1], regexp_expr_arg_lvs[2]};
388  std::string fn_name("regexp_like");
389  regexp_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
390  if (is_nullable) {
391  fn_name += "_nullable";
392  regexp_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
394  fn_name, get_int_type(8, cgen_state_->context_), regexp_args);
395  }
397  fn_name, get_int_type(1, cgen_state_->context_), regexp_args);
398 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:978
bool g_enable_watchdog
CgenState * cgen_state_
const Expr * get_escape_expr() const
Definition: Analyzer.h:980
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:222
const Expr * get_arg() const
Definition: Analyzer.h:977
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:164
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
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 &)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp: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:979
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1042
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266

+ Here is the call graph for this function:

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

Definition at line 68 of file ArrayIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

69  {
71  const auto arr_expr = expr->get_arg();
72  const auto& array_ti = arr_expr->get_type_info();
73  CHECK(array_ti.is_array());
74  const auto& elem_ti = array_ti.get_elem_type();
75  auto arr_lv = codegen(arr_expr, true, co);
76  std::string fn_name("array_size");
77 
78  std::vector<llvm::Value*> array_size_args{
79  arr_lv.front(),
80  posArg(arr_expr),
81  cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))};
82  const bool is_nullable{!arr_expr->get_type_info().get_notnull()};
83  if (is_nullable) {
84  fn_name += "_nullable";
85  array_size_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
86  }
88  fn_name, get_int_type(32, cgen_state_->context_), array_size_args);
89 }
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:222
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:515
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:139
const Expr * get_arg() const
Definition: Analyzer.h:851

+ Here is the call graph for this function:

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

Definition at line 156 of file IRCodegen.cpp.

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

157  {
159  const auto optype = bin_oper->get_optype();
160  if (IS_ARITHMETIC(optype)) {
161  return codegenArith(bin_oper, co);
162  }
163  if (IS_COMPARISON(optype)) {
164  return codegenCmp(bin_oper, co);
165  }
166  if (IS_LOGIC(optype)) {
167  return codegenLogical(bin_oper, co);
168  }
169  if (optype == kARRAY_AT) {
170  return codegenArrayAt(bin_oper, co);
171  }
172  abort();
173 }
#define IS_LOGIC(X)
Definition: sqldefs.h:60
llvm::Value * codegenArith(const Analyzer::BinOper *, const CompilationOptions &)
CgenState * cgen_state_
llvm::Value * codegenArrayAt(const Analyzer::BinOper *, const CompilationOptions &)
Definition: ArrayIR.cpp:26
SQLOps get_optype() const
Definition: Analyzer.h:439
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#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:290
#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 175 of file IRCodegen.cpp.

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

176  {
178  const auto optype = u_oper->get_optype();
179  switch (optype) {
180  case kNOT: {
181  return codegenLogical(u_oper, co);
182  }
183  case kCAST: {
184  return codegenCast(u_oper, co);
185  }
186  case kUMINUS: {
187  return codegenUMinus(u_oper, co);
188  }
189  case kISNULL: {
190  return codegenIsNull(u_oper, co);
191  }
192  case kUNNEST:
193  return codegenUnnest(u_oper, co);
194  default:
195  abort();
196  }
197 }
CgenState * cgen_state_
Definition: sqldefs.h:49
llvm::Value * codegenIsNull(const Analyzer::UOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:372
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:290
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
Definition: sqldefs.h:39
SQLOps get_optype() const
Definition: Analyzer.h:370

+ 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 217 of file ArithmeticIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CHECK_EQ, checkExpressionRanges(), codegenBinOpWithOverflowForCPU(), codegenSkipOverflowCheckForNull(), CgenState::context_, CPU, CgenState::current_func_, 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(), and CgenState::needs_error_check_.

Referenced by codegenIntArith().

223  {
225  CHECK_EQ(lhs_lv->getType(), rhs_lv->getType());
226  CHECK(ti.is_integer() || ti.is_decimal() || ti.is_timeinterval());
227  llvm::Value* chosen_max{nullptr};
228  llvm::Value* chosen_min{nullptr};
229  std::tie(chosen_max, chosen_min) = cgen_state_->inlineIntMaxMin(ti.get_size(), true);
230  auto need_overflow_check =
231  !checkExpressionRanges(bin_oper,
232  static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue(),
233  static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue());
234 
235  if (need_overflow_check && co.device_type == ExecutorDeviceType::CPU) {
237  bin_oper, lhs_lv, rhs_lv, null_check_suffix, ti);
238  }
239 
240  llvm::BasicBlock* add_ok{nullptr};
241  llvm::BasicBlock* add_fail{nullptr};
242  if (need_overflow_check) {
244  add_ok = llvm::BasicBlock::Create(
246  if (!null_check_suffix.empty()) {
247  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, add_ok, ti);
248  }
249  add_fail = llvm::BasicBlock::Create(
251  llvm::Value* detected{nullptr};
252  auto const_zero = llvm::ConstantInt::get(lhs_lv->getType(), 0, true);
253  auto overflow = cgen_state_->ir_builder_.CreateAnd(
254  cgen_state_->ir_builder_.CreateICmpSGT(lhs_lv, const_zero),
255  cgen_state_->ir_builder_.CreateICmpSGT(
256  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_max, lhs_lv)));
257  auto underflow = cgen_state_->ir_builder_.CreateAnd(
258  cgen_state_->ir_builder_.CreateICmpSLT(lhs_lv, const_zero),
259  cgen_state_->ir_builder_.CreateICmpSLT(
260  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_min, lhs_lv)));
261  detected = cgen_state_->ir_builder_.CreateOr(overflow, underflow);
262  cgen_state_->ir_builder_.CreateCondBr(detected, add_fail, add_ok);
263  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
264  }
265  auto ret = null_check_suffix.empty()
266  ? cgen_state_->ir_builder_.CreateAdd(lhs_lv, rhs_lv)
268  "add_" + null_typename + null_check_suffix,
269  {lhs_lv, rhs_lv, cgen_state_->llInt(inline_int_null_val(ti))});
270  if (need_overflow_check) {
271  cgen_state_->ir_builder_.SetInsertPoint(add_fail);
272  cgen_state_->ir_builder_.CreateRet(
274  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
275  }
276  return ret;
277 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
HOST DEVICE int get_size() const
Definition: sqltypes.h:269
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
bool is_integer() const
Definition: sqltypes.h:419
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:987
bool is_timeinterval() const
Definition: sqltypes.h:428
bool needs_error_check_
Definition: CgenState.h:356
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:312
#define CHECK(condition)
Definition: Logger.h:197
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:420
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 AUTOMATIC_IR_METADATA, cgen_state_, 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  {
39  const auto optype = bin_oper->get_optype();
40  CHECK(IS_ARITHMETIC(optype));
41  const auto lhs = bin_oper->get_left_operand();
42  const auto rhs = bin_oper->get_right_operand();
43  const auto& lhs_type = lhs->get_type_info();
44  const auto& rhs_type = rhs->get_type_info();
45 
46  if (lhs_type.is_decimal() && rhs_type.is_decimal() && optype == kDIVIDE) {
47  const auto ret = codegenDeciDiv(bin_oper, co);
48  if (ret) {
49  return ret;
50  }
51  }
52 
53  auto lhs_lv = codegen(lhs, true, co).front();
54  auto rhs_lv = codegen(rhs, true, co).front();
55  // Handle operations when a time interval operand is involved, an operation
56  // between an integer and a time interval isn't normalized by the analyzer.
57  if (lhs_type.is_timeinterval()) {
58  rhs_lv = codegenCastBetweenIntTypes(rhs_lv, rhs_type, lhs_type);
59  } else if (rhs_type.is_timeinterval()) {
60  lhs_lv = codegenCastBetweenIntTypes(lhs_lv, lhs_type, rhs_type);
61  } else {
62  CHECK_EQ(lhs_type.get_type(), rhs_type.get_type());
63  }
64  if (lhs_type.is_integer() || lhs_type.is_decimal() || lhs_type.is_timeinterval()) {
65  return codegenIntArith(bin_oper, lhs_lv, rhs_lv, co);
66  }
67  if (lhs_type.is_fp()) {
68  return codegenFpArith(bin_oper, lhs_lv, rhs_lv);
69  }
70  CHECK(false);
71  return nullptr;
72 }
llvm::Value * codegenIntArith(const Analyzer::BinOper *, llvm::Value *, llvm::Value *, const CompilationOptions &)
#define CHECK_EQ(x, y)
Definition: Logger.h:205
CgenState * cgen_state_
const Expr * get_right_operand() const
Definition: Analyzer.h:443
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:439
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:256
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
#define IS_ARITHMETIC(X)
Definition: sqldefs.h:61
#define CHECK(condition)
Definition: Logger.h:197
const Expr * get_left_operand() const
Definition: Analyzer.h:442

+ 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 592 of file ExtensionsIR.cpp.

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

Referenced by codegenFunctionOperCastArgs().

597  {
599  CHECK(array_buf);
600  CHECK(array_size);
601  CHECK(array_null);
602 
603  auto array_abstraction =
604  get_arr_struct_type(cgen_state_, ext_func_name, array_buf->getType(), param_num);
605  auto alloc_mem = cgen_state_->ir_builder_.CreateAlloca(array_abstraction);
606 
607  auto array_buf_ptr =
608  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 0);
609  cgen_state_->ir_builder_.CreateStore(array_buf, array_buf_ptr);
610 
611  auto array_size_ptr =
612  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 1);
613  cgen_state_->ir_builder_.CreateStore(array_size, array_size_ptr);
614 
615  auto bool_extended_type = llvm::Type::getInt8Ty(cgen_state_->context_);
616  auto array_null_extended =
617  cgen_state_->ir_builder_.CreateZExt(array_null, bool_extended_type);
618  auto array_is_null_ptr =
619  cgen_state_->ir_builder_.CreateStructGEP(array_abstraction, alloc_mem, 2);
620  cgen_state_->ir_builder_.CreateStore(array_null_extended, array_is_null_ptr);
621  output_args.push_back(alloc_mem);
622 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
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:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define CHECK(condition)
Definition: Logger.h:197

+ 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 26 of file ArrayIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

27  {
29  const auto arr_expr = array_at->get_left_operand();
30  const auto idx_expr = array_at->get_right_operand();
31  const auto& idx_ti = idx_expr->get_type_info();
32  CHECK(idx_ti.is_integer());
33  auto idx_lvs = codegen(idx_expr, true, co);
34  CHECK_EQ(size_t(1), idx_lvs.size());
35  auto idx_lv = idx_lvs.front();
36  if (idx_ti.get_logical_size() < 8) {
37  idx_lv = cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
38  idx_lv,
40  }
41  const auto& array_ti = arr_expr->get_type_info();
42  CHECK(array_ti.is_array());
43  const auto& elem_ti = array_ti.get_elem_type();
44  const std::string array_at_fname{
45  elem_ti.is_fp()
46  ? "array_at_" + std::string(elem_ti.get_type() == kDOUBLE ? "double_checked"
47  : "float_checked")
48  : "array_at_int" + std::to_string(elem_ti.get_logical_size() * 8) +
49  "_t_checked"};
50  const auto ret_ty =
51  elem_ti.is_fp()
52  ? (elem_ti.get_type() == kDOUBLE
53  ? llvm::Type::getDoubleTy(cgen_state_->context_)
54  : llvm::Type::getFloatTy(cgen_state_->context_))
55  : get_int_type(elem_ti.get_logical_size() * 8, cgen_state_->context_);
56  const auto arr_lvs = codegen(arr_expr, true, co);
57  CHECK_EQ(size_t(1), arr_lvs.size());
59  array_at_fname,
60  ret_ty,
61  {arr_lvs.front(),
62  posArg(arr_expr),
63  idx_lv,
64  elem_ti.is_fp() ? static_cast<llvm::Value*>(cgen_state_->inlineFpNull(elem_ti))
65  : static_cast<llvm::Value*>(cgen_state_->inlineIntNull(elem_ti))});
66 }
#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:222
const Expr * get_right_operand() const
Definition: Analyzer.h:443
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:515
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
#define CHECK(condition)
Definition: Logger.h:197
const Expr * get_left_operand() const
Definition: Analyzer.h:442
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 564 of file ExtensionsIR.cpp.

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

Referenced by codegenFunctionOperCastArgs().

568  {
570  const auto elem_ti =
571  SQLTypeInfo(
572  SQLTypes::kARRAY, 0, 0, false, EncodingType::kENCODING_NONE, 0, array_type)
573  .get_elem_type();
574 
575  auto buff = cgen_state_->emitExternalCall(
576  "array_buff", llvm::Type::getInt32PtrTy(cgen_state_->context_), {chunk, row_pos});
577 
578  auto len = cgen_state_->emitExternalCall(
579  "array_size",
581  {chunk, row_pos, cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))});
582 
583  if (cast_and_extend) {
584  buff = castArrayPointer(buff, elem_ti);
585  len =
586  cgen_state_->ir_builder_.CreateZExt(len, get_int_type(64, cgen_state_->context_));
587  }
588 
589  return std::make_pair(buff, len);
590 }
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:222
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
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:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:139
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:624

+ 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 91 of file ArrayIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

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

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

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

731  {
734 
735  llvm::BasicBlock* check_ok = llvm::BasicBlock::Create(
737  llvm::BasicBlock* check_fail = llvm::BasicBlock::Create(
738  cgen_state_->context_, "ovf_detected", cgen_state_->current_func_);
739  llvm::BasicBlock* null_check{nullptr};
740 
741  if (!null_check_suffix.empty()) {
742  null_check = cgen_state_->ir_builder_.GetInsertBlock();
743  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, check_ok, ti);
744  }
745 
746  // Compute result and overflow flag
747  auto func = getArithWithOverflowIntrinsic(bin_oper, lhs_lv->getType());
748  auto ret_and_overflow = cgen_state_->ir_builder_.CreateCall(
749  func, std::vector<llvm::Value*>{lhs_lv, rhs_lv});
750  auto ret = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
751  std::vector<unsigned>{0});
752  auto overflow = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
753  std::vector<unsigned>{1});
754  auto val_bb = cgen_state_->ir_builder_.GetInsertBlock();
755 
756  // Return error on overflow
757  cgen_state_->ir_builder_.CreateCondBr(overflow, check_fail, check_ok);
758  cgen_state_->ir_builder_.SetInsertPoint(check_fail);
759  cgen_state_->ir_builder_.CreateRet(
761 
762  cgen_state_->ir_builder_.SetInsertPoint(check_ok);
763 
764  // In case of null check we have to use NULL result on check fail
765  if (null_check) {
766  auto phi = cgen_state_->ir_builder_.CreatePHI(ret->getType(), 2);
767  phi->addIncoming(llvm::ConstantInt::get(ret->getType(), inline_int_null_val(ti)),
768  null_check);
769  phi->addIncoming(ret, val_bb);
770  ret = phi;
771  }
772 
773  return ret;
774 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
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:987
bool needs_error_check_
Definition: CgenState.h:356
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Function * getArithWithOverflowIntrinsic(const Analyzer::BinOper *bin_oper, llvm::Type *type)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
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 55 of file CaseIR.cpp.

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

Referenced by codegen().

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

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

+ 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 54 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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.

58  {
60  if (byte_array_cast(operand_ti, ti)) {
61  auto* byte_array_type = get_int_array_type(8, ti.get_size(), cgen_state_->context_);
62  return cgen_state_->ir_builder_.CreatePointerCast(operand_lv,
63  byte_array_type->getPointerTo());
64  }
65  if (operand_lv->getType()->isIntegerTy()) {
66  if (operand_ti.is_string()) {
67  return codegenCastFromString(operand_lv, operand_ti, ti, operand_is_const, co);
68  }
69  CHECK(operand_ti.is_integer() || operand_ti.is_decimal() || operand_ti.is_time() ||
70  operand_ti.is_boolean());
71  if (operand_ti.is_boolean()) {
72  // cast boolean to int8
73  CHECK(operand_lv->getType()->isIntegerTy(1) ||
74  operand_lv->getType()->isIntegerTy(8));
75  if (operand_lv->getType()->isIntegerTy(1)) {
76  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
77  }
78  if (ti.is_boolean()) {
79  return operand_lv;
80  }
81  }
82  if (operand_ti.is_integer() && operand_lv->getType()->isIntegerTy(8) &&
83  ti.is_boolean()) {
84  // cast int8 to boolean
85  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
86  }
87  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
88  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
89  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
90  // whereas this cast returns a date. The underlying type for both is still the same,
91  // but it still doesn't look like a good idea to misuse DatetruncExpr.
92  // Date will have default precision of day, but TIMESTAMP dimension would
93  // matter but while converting date through seconds
95  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
96  }
97  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
98  ti.get_type() == kTIMESTAMP) {
99  const auto operand_dimen =
100  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
101  if (operand_dimen != ti.get_dimension()) {
103  operand_lv, operand_ti, ti, !ti.get_notnull());
104  }
105  }
106  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
107  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
108  } else {
109  return codegenCastToFp(operand_lv, operand_ti, ti);
110  }
111  } else {
112  return codegenCastFromFp(operand_lv, operand_ti, ti);
113  }
114  CHECK(false);
115  return nullptr;
116 }
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:419
HOST DEVICE int get_size() const
Definition: sqltypes.h:269
bool is_timestamp() const
Definition: sqltypes.h:654
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:387
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:47
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
bool is_time() const
Definition: sqltypes.h:423
llvm::LLVMContext & context_
Definition: CgenState.h:339
bool is_integer() const
Definition: sqltypes.h:419
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:256
bool is_boolean() const
Definition: sqltypes.h:424
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:118
#define AUTOMATIC_IR_METADATA(CGENSTATE)
Definition: sqltypes.h:55
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:261
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
Definition: CastIR.cpp:155
#define CHECK(condition)
Definition: Logger.h:197
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:187
bool is_string() const
Definition: sqltypes.h:417
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_decimal() const
Definition: sqltypes.h:420

+ 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 256 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

259  {
261  if (ti.is_decimal() &&
262  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
263  if (upscale) {
264  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
265  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
266  const auto scale_lv =
267  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
268  operand_lv = cgen_state_->ir_builder_.CreateSExt(
269  operand_lv, get_int_type(64, cgen_state_->context_));
270 
271  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
272 
273  if (operand_ti.get_notnull()) {
274  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
275  } else {
276  operand_lv = cgen_state_->emitCall(
277  "scale_decimal_up",
278  {operand_lv,
279  scale_lv,
280  cgen_state_->llInt(inline_int_null_val(operand_ti)),
282  }
283  }
284  }
285  } else if (operand_ti.is_decimal()) {
286  // rounded scale down
287  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
288  const auto scale_lv =
289  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
290 
291  const auto operand_width =
292  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
293 
294  std::string method_name = "scale_decimal_down_nullable";
295  if (operand_ti.get_notnull()) {
296  method_name = "scale_decimal_down_not_nullable";
297  }
298 
299  CHECK(operand_width == 64);
300  operand_lv = cgen_state_->emitCall(
301  method_name,
302  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
303  }
304  if (ti.is_integer() && operand_ti.is_integer() &&
305  operand_ti.get_logical_size() > ti.get_logical_size()) {
306  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
307  }
308 
309  const auto operand_width =
310  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
311  const auto target_width = get_bit_width(ti);
312  if (target_width == operand_width) {
313  return operand_lv;
314  }
315  if (operand_ti.get_notnull()) {
316  return cgen_state_->ir_builder_.CreateCast(
317  target_width > operand_width ? llvm::Instruction::CastOps::SExt
318  : llvm::Instruction::CastOps::Trunc,
319  operand_lv,
320  get_int_type(target_width, cgen_state_->context_));
321  }
322  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
323  numeric_type_name(ti) + "_nullable",
324  {operand_lv,
325  cgen_state_->inlineIntNull(operand_ti),
326  cgen_state_->inlineIntNull(ti)});
327 }
CgenState * cgen_state_
HOST DEVICE int get_scale() const
Definition: sqltypes.h:264
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
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:339
int get_logical_size() const
Definition: sqltypes.h:270
bool is_integer() const
Definition: sqltypes.h:419
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:329
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
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:172
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
bool is_decimal() const
Definition: sqltypes.h:420

+ 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 329 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CgenState::context_, CgenState::current_func_, 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(), and toBool().

Referenced by codegenCastBetweenIntTypes(), and codegenCastBetweenTimestamps().

333  {
335  llvm::Value* chosen_max{nullptr};
336  llvm::Value* chosen_min{nullptr};
337  std::tie(chosen_max, chosen_min) =
339 
341  auto cast_ok = llvm::BasicBlock::Create(
343  auto cast_fail = llvm::BasicBlock::Create(
345  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
346  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
347  const auto ti_llvm_type =
349  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
350  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
351  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
352  if (is_narrowing) {
353  const auto operand_ti_llvm_type =
355  operand_max_lv =
356  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
357  operand_min_lv =
358  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
359  }
360  llvm::Value* over{nullptr};
361  llvm::Value* under{nullptr};
362  if (operand_ti.get_notnull()) {
363  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
364  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
365  } else {
366  const auto type_name =
367  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
368  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
369  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
370  over = toBool(cgen_state_->emitCall(
371  "gt_" + type_name + "_nullable_lhs",
372  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
373  under = toBool(cgen_state_->emitCall(
374  "le_" + type_name + "_nullable_lhs",
375  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
376  }
377  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
378  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
379 
380  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
381  cgen_state_->ir_builder_.CreateRet(
383 
384  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
385 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
int get_logical_size() const
Definition: sqltypes.h:270
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:987
bool needs_error_check_
Definition: CgenState.h:356
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:335
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:172
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
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 155 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

158  {
160  const auto operand_dimen = operand_ti.get_dimension();
161  const auto target_dimen = target_ti.get_dimension();
162  if (operand_dimen == target_dimen) {
163  return ts_lv;
164  }
165  CHECK(ts_lv->getType()->isIntegerTy(64));
166  const auto scale =
167  DateTimeUtils::get_timestamp_precision_scale(abs(operand_dimen - target_dimen));
168  if (operand_dimen < target_dimen) {
169  codegenCastBetweenIntTypesOverflowChecks(ts_lv, operand_ti, target_ti, scale);
170  return nullable
171  ? cgen_state_->emitCall("mul_int64_t_nullable_lhs",
172  {ts_lv,
173  cgen_state_->llInt(static_cast<int64_t>(scale)),
174  cgen_state_->inlineIntNull(operand_ti)})
175  : cgen_state_->ir_builder_.CreateMul(
176  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
177  }
178  return nullable
179  ? cgen_state_->emitCall("floor_div_nullable_lhs",
180  {ts_lv,
181  cgen_state_->llInt(static_cast<int64_t>(scale)),
182  cgen_state_->inlineIntNull(operand_ti)})
183  : cgen_state_->ir_builder_.CreateSDiv(
184  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
185 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:329
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:261
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
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 419 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

421  {
423  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
424  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
425  ti.get_type_name() + " not supported");
426  }
427  if (operand_ti.get_type() == ti.get_type()) {
428  // Should not have been called when both dimensions are same.
429  return operand_lv;
430  }
431  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
432  if (operand_ti.get_notnull()) {
433  if (ti.get_type() == kDOUBLE) {
434  return cgen_state_->ir_builder_.CreateFPExt(
435  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
436  } else if (ti.get_type() == kFLOAT) {
437  return cgen_state_->ir_builder_.CreateFPTrunc(
438  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
439  } else if (ti.is_integer()) {
440  return cgen_state_->ir_builder_.CreateFPToSI(
441  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
442  } else {
443  CHECK(false);
444  }
445  } else {
446  const auto from_tname = numeric_type_name(operand_ti);
447  const auto to_tname = numeric_type_name(ti);
448  if (ti.is_fp()) {
449  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
450  {operand_lv,
451  cgen_state_->inlineFpNull(operand_ti),
452  cgen_state_->inlineFpNull(ti)});
453  } else if (ti.is_integer()) {
454  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
455  {operand_lv,
456  cgen_state_->inlineFpNull(operand_ti),
457  cgen_state_->inlineIntNull(ti)});
458  } else {
459  CHECK(false);
460  }
461  }
462  CHECK(false);
463  return nullptr;
464 }
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:421
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:422
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:339
bool is_integer() const
Definition: sqltypes.h:419
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:362
#define CHECK(condition)
Definition: Logger.h:197
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:172
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
bool is_decimal() const
Definition: sqltypes.h:420
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 187 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

191  {
193  if (!ti.is_string()) {
194  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
195  ti.get_type_name() + " not supported");
196  }
197  if (operand_ti.get_compression() == kENCODING_NONE &&
199  return operand_lv;
200  }
201  // dictionary encode non-constant
202  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
203  if (g_cluster) {
204  throw std::runtime_error(
205  "Cast from none-encoded string to dictionary-encoded not supported for "
206  "distributed queries");
207  }
208  if (g_enable_watchdog) {
209  throw WatchdogException(
210  "Cast from none-encoded string to dictionary-encoded would be slow");
211  }
212  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
214  CHECK(operand_lv->getType()->isIntegerTy(64));
216  throw QueryMustRunOnCpu();
217  }
219  "string_compress",
221  {operand_lv,
222  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
223  ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
224  }
225  CHECK(operand_lv->getType()->isIntegerTy(32));
226  if (ti.get_compression() == kENCODING_NONE) {
227  if (g_cluster) {
228  throw std::runtime_error(
229  "Cast from dictionary-encoded string to none-encoded not supported for "
230  "distributed queries");
231  }
232  if (g_enable_watchdog) {
233  throw WatchdogException(
234  "Cast from dictionary-encoded string to none-encoded would be slow");
235  }
236  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
238  throw QueryMustRunOnCpu();
239  }
240  const int64_t string_dictionary_ptr =
241  operand_ti.get_comp_param() == 0
242  ? reinterpret_cast<int64_t>(
243  executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
244  : reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
245  operand_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true));
247  "string_decompress",
249  {operand_lv, cgen_state_->llInt(string_dictionary_ptr)});
250  }
251  CHECK(operand_is_const);
253  return operand_lv;
254 }
#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:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:267
std::string get_type_name() const
Definition: sqltypes.h:362
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:268
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
bool g_cluster
bool is_string() const
Definition: sqltypes.h:417
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 118 of file CastIR.cpp.

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

Referenced by codegenCast().

120  {
122  CHECK(ts_lv->getType()->isIntegerTy(64));
123  if (dimen > 0) {
124  if (nullable) {
126  "DateTruncateHighPrecisionToDateNullable",
128  {{ts_lv,
131  }
133  "DateTruncateHighPrecisionToDate",
135  {{ts_lv,
137  }
138  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
139  if (nullable) {
140  nullcheck_codegen =
141  std::make_unique<NullCheckCodegen>(cgen_state_,
142  executor(),
143  ts_lv,
144  SQLTypeInfo(kTIMESTAMP, dimen, 0, !nullable),
145  "cast_timestamp_nullcheck");
146  }
147  auto ret = cgen_state_->emitExternalCall(
148  "datetrunc_day", get_int_type(64, cgen_state_->context_), {ts_lv});
149  if (nullcheck_codegen) {
150  ret = nullcheck_codegen->finalize(ll_int(NULL_BIGINT, cgen_state_->context_), ret);
151  }
152  return ret;
153 }
CgenState * cgen_state_
#define NULL_BIGINT
Definition: sqltypes.h:184
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:222
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51
Executor * executor() const

+ 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 387 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, 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().

389  {
391  if (!ti.is_fp()) {
392  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
393  ti.get_type_name() + " not supported");
394  }
395  const auto to_tname = numeric_type_name(ti);
396  llvm::Value* result_lv{nullptr};
397  if (operand_ti.get_notnull()) {
398  result_lv = cgen_state_->ir_builder_.CreateSIToFP(
399  operand_lv,
400  ti.get_type() == kFLOAT ? llvm::Type::getFloatTy(cgen_state_->context_)
401  : llvm::Type::getDoubleTy(cgen_state_->context_));
402  } else {
403  result_lv = cgen_state_->emitCall(
404  "cast_" + numeric_type_name(operand_ti) + "_to_" + to_tname + "_nullable",
405  {operand_lv,
406  cgen_state_->inlineIntNull(operand_ti),
407  cgen_state_->inlineFpNull(ti)});
408  }
409  CHECK(result_lv);
410  if (operand_ti.get_scale()) {
411  result_lv = cgen_state_->ir_builder_.CreateFDiv(
412  result_lv,
413  llvm::ConstantFP::get(result_lv->getType(),
414  exp_to_scale(operand_ti.get_scale())));
415  }
416  return result_lv;
417 }
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:421
HOST DEVICE int get_scale() const
Definition: sqltypes.h:264
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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:362
#define CHECK(condition)
Definition: Logger.h:197
uint64_t exp_to_scale(const unsigned exp)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:172
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
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 AUTOMATIC_IR_METADATA, cgen_state_, 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  {
187  const auto qualifier = bin_oper->get_qualifier();
188  const auto lhs = bin_oper->get_left_operand();
189  const auto rhs = bin_oper->get_right_operand();
190  if (dynamic_cast<const Analyzer::ExpressionTuple*>(lhs)) {
191  CHECK(dynamic_cast<const Analyzer::ExpressionTuple*>(rhs));
192  const auto lowered = lower_multicol_compare(bin_oper);
193  const auto lowered_lvs = codegen(lowered.get(), true, co);
194  CHECK_EQ(size_t(1), lowered_lvs.size());
195  return lowered_lvs.front();
196  }
197  const auto optype = bin_oper->get_optype();
198  if (optype == kBW_EQ) {
199  const auto bw_eq_oper = lower_bw_eq(bin_oper);
200  return codegenLogical(bw_eq_oper.get(), co);
201  }
202  if (optype == kOVERLAPS) {
203  return codegenOverlaps(optype,
204  qualifier,
205  bin_oper->get_own_left_operand(),
206  bin_oper->get_own_right_operand(),
207  co);
208  }
209  if (is_unnest(lhs) || is_unnest(rhs)) {
210  throw std::runtime_error("Unnest not supported in comparisons");
211  }
212  const auto& lhs_ti = lhs->get_type_info();
213  const auto& rhs_ti = rhs->get_type_info();
214 
215  if (lhs_ti.is_string() && rhs_ti.is_string() &&
216  !(IS_EQUIVALENCE(optype) || optype == kNE)) {
217  auto cmp_str = codegenStrCmp(optype,
218  qualifier,
219  bin_oper->get_own_left_operand(),
220  bin_oper->get_own_right_operand(),
221  co);
222  if (cmp_str) {
223  return cmp_str;
224  }
225  }
226 
227  if (lhs_ti.is_decimal()) {
228  auto cmp_decimal_const =
229  codegenCmpDecimalConst(optype, qualifier, lhs, lhs_ti, rhs, co);
230  if (cmp_decimal_const) {
231  return cmp_decimal_const;
232  }
233  }
234 
235  auto lhs_lvs = codegen(lhs, true, co);
236  return codegenCmp(optype, qualifier, lhs_lvs, lhs_ti, rhs, co);
237 }
#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:317
#define IS_EQUIVALENCE(X)
Definition: sqldefs.h:67
CgenState * cgen_state_
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:443
std::shared_ptr< Analyzer::BinOper > lower_bw_eq(const Analyzer::BinOper *bw_eq)
Definition: CompareIR.cpp:125
SQLOps get_optype() const
Definition: Analyzer.h:439
llvm::Value * codegenCmpDecimalConst(const SQLOps, const SQLQualifier, const Analyzer::Expr *, const SQLTypeInfo &, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:349
llvm::Value * codegenOverlaps(const SQLOps, const SQLQualifier, const std::shared_ptr< Analyzer::Expr >, const std::shared_ptr< Analyzer::Expr >, const CompilationOptions &)
Definition: CompareIR.cpp:239
#define AUTOMATIC_IR_METADATA(CGENSTATE)
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
#define CHECK(condition)
Definition: Logger.h:197
Definition: sqldefs.h:31
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:290
const Expr * get_left_operand() const
Definition: Analyzer.h:442
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1042
const std::shared_ptr< Analyzer::Expr > get_own_right_operand() const
Definition: Analyzer.h:447
const std::shared_ptr< Analyzer::Expr > get_own_left_operand() const
Definition: Analyzer.h:444
SQLQualifier get_qualifier() const
Definition: Analyzer.h:441

+ 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 400 of file CompareIR.cpp.

References AUTOMATIC_IR_METADATA, 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.

405  {
407  CHECK(IS_COMPARISON(optype));
408  const auto& rhs_ti = rhs->get_type_info();
409  if (rhs_ti.is_array()) {
410  return codegenQualifierCmp(optype, qualifier, lhs_lvs, rhs, co);
411  }
412  auto rhs_lvs = codegen(rhs, true, co);
413  CHECK_EQ(kONE, qualifier);
414  if (optype == kOVERLAPS) {
415  CHECK(lhs_ti.is_geometry());
416  CHECK(rhs_ti.is_array() ||
417  rhs_ti.is_geometry()); // allow geo col or bounds col to pass
418  } else {
419  CHECK((lhs_ti.get_type() == rhs_ti.get_type()) ||
420  (lhs_ti.is_string() && rhs_ti.is_string()));
421  }
422  const auto null_check_suffix = get_null_check_suffix(lhs_ti, rhs_ti);
423  if (lhs_ti.is_integer() || lhs_ti.is_decimal() || lhs_ti.is_time() ||
424  lhs_ti.is_boolean() || lhs_ti.is_string() || lhs_ti.is_timeinterval()) {
425  if (lhs_ti.is_string()) {
426  CHECK(rhs_ti.is_string());
427  CHECK_EQ(lhs_ti.get_compression(), rhs_ti.get_compression());
428  if (lhs_ti.get_compression() == kENCODING_NONE) {
429  // unpack pointer + length if necessary
430  if (lhs_lvs.size() != 3) {
431  CHECK_EQ(size_t(1), lhs_lvs.size());
432  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {lhs_lvs.front()}));
433  lhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {lhs_lvs.front()}));
434  }
435  if (rhs_lvs.size() != 3) {
436  CHECK_EQ(size_t(1), rhs_lvs.size());
437  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_ptr", {rhs_lvs.front()}));
438  rhs_lvs.push_back(cgen_state_->emitCall("extract_str_len", {rhs_lvs.front()}));
439  }
440  std::vector<llvm::Value*> str_cmp_args{
441  lhs_lvs[1], lhs_lvs[2], rhs_lvs[1], rhs_lvs[2]};
442  if (!null_check_suffix.empty()) {
443  str_cmp_args.push_back(
445  }
446  return cgen_state_->emitCall(
447  string_cmp_func(optype) + (null_check_suffix.empty() ? "" : "_nullable"),
448  str_cmp_args);
449  } else {
450  CHECK(optype == kEQ || optype == kNE);
451  }
452  }
453 
454  if (lhs_ti.is_boolean() && rhs_ti.is_boolean()) {
455  auto& lhs_lv = lhs_lvs.front();
456  auto& rhs_lv = rhs_lvs.front();
457  CHECK(lhs_lv->getType()->isIntegerTy());
458  CHECK(rhs_lv->getType()->isIntegerTy());
459  if (lhs_lv->getType()->getIntegerBitWidth() <
460  rhs_lv->getType()->getIntegerBitWidth()) {
461  lhs_lv =
462  cgen_state_->castToTypeIn(lhs_lv, rhs_lv->getType()->getIntegerBitWidth());
463  } else {
464  rhs_lv =
465  cgen_state_->castToTypeIn(rhs_lv, lhs_lv->getType()->getIntegerBitWidth());
466  }
467  }
468 
469  return null_check_suffix.empty()
470  ? cgen_state_->ir_builder_.CreateICmp(
471  llvm_icmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
473  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
474  null_check_suffix,
475  {lhs_lvs.front(),
476  rhs_lvs.front(),
479  }
480  if (lhs_ti.get_type() == kFLOAT || lhs_ti.get_type() == kDOUBLE) {
481  return null_check_suffix.empty()
482  ? cgen_state_->ir_builder_.CreateFCmp(
483  llvm_fcmp_pred(optype), lhs_lvs.front(), rhs_lvs.front())
485  icmp_name(optype) + "_" + numeric_type_name(lhs_ti) +
486  null_check_suffix,
487  {lhs_lvs.front(),
488  rhs_lvs.front(),
489  lhs_ti.get_type() == kFLOAT ? cgen_state_->llFp(NULL_FLOAT)
492  }
493  CHECK(false);
494  return nullptr;
495 }
#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:186
std::string icmp_name(const SQLOps op_type)
Definition: CompareIR.cpp:45
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
Definition: sqldefs.h:30
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
llvm::CmpInst::Predicate llvm_fcmp_pred(const SQLOps op_type)
Definition: CompareIR.cpp:83
bool is_time() const
Definition: sqltypes.h:423
bool is_integer() const
Definition: sqltypes.h:419
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define NULL_FLOAT
Definition: sqltypes.h:185
bool is_timeinterval() const
Definition: sqltypes.h:428
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:316
bool is_boolean() const
Definition: sqltypes.h:424
#define AUTOMATIC_IR_METADATA(CGENSTATE)
std::string get_null_check_suffix(const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
Definition: Execute.h:1026
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp: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:267
llvm::Value * codegenQualifierCmp(const SQLOps, const SQLQualifier, std::vector< llvm::Value * >, const Analyzer::Expr *, const CompilationOptions &)
Definition: CompareIR.cpp:497
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:312
#define CHECK(condition)
Definition: Logger.h:197
bool is_geometry() const
Definition: sqltypes.h:429
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:172
bool is_string() const
Definition: sqltypes.h:417
bool is_decimal() const
Definition: sqltypes.h:420
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 349 of file CompareIR.cpp.

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

Referenced by codegenCmp().

354  {
356  auto u_oper = dynamic_cast<const Analyzer::UOper*>(lhs);
357  if (!u_oper || u_oper->get_optype() != kCAST) {
358  return nullptr;
359  }
360  auto rhs_constant = dynamic_cast<const Analyzer::Constant*>(rhs);
361  if (!rhs_constant) {
362  return nullptr;
363  }
364  const auto operand = u_oper->get_operand();
365  const auto& operand_ti = operand->get_type_info();
366  if (operand_ti.is_decimal() && operand_ti.get_scale() < lhs_ti.get_scale()) {
367  // lhs decimal type has smaller scale
368  } else if (operand_ti.is_integer() && 0 < lhs_ti.get_scale()) {
369  // lhs is integer, no need to scale it all the way up to the cmp expr scale
370  } else {
371  return nullptr;
372  }
373 
374  auto scale_diff = lhs_ti.get_scale() - operand_ti.get_scale() - 1;
375  int64_t bigintval = rhs_constant->get_constval().bigintval;
376  bool negative = false;
377  if (bigintval < 0) {
378  negative = true;
379  bigintval = -bigintval;
380  }
381  int64_t truncated_decimal = bigintval / exp_to_scale(scale_diff);
382  int64_t decimal_tail = bigintval % exp_to_scale(scale_diff);
383  if (truncated_decimal % 10 == 0 && decimal_tail > 0) {
384  truncated_decimal += 1;
385  }
386  SQLTypeInfo new_ti = SQLTypeInfo(
387  kDECIMAL, 19, lhs_ti.get_scale() - scale_diff, operand_ti.get_notnull());
388  if (negative) {
389  truncated_decimal = -truncated_decimal;
390  }
391  Datum d;
392  d.bigintval = truncated_decimal;
393  const auto new_rhs_lit =
394  makeExpr<Analyzer::Constant>(new_ti, rhs_constant->get_is_null(), d);
395  const auto operand_lv = codegen(operand, true, co).front();
396  const auto lhs_lv = codegenCast(operand_lv, operand_ti, new_ti, false, co);
397  return codegenCmp(optype, qualifier, {lhs_lv}, new_ti, new_rhs_lit.get(), co);
398 }
CgenState * cgen_state_
HOST DEVICE int get_scale() const
Definition: sqltypes.h:264
Definition: sqldefs.h:49
int64_t bigintval
Definition: sqltypes.h:138
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp: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 AUTOMATIC_IR_METADATA, cgen_state_, codegenColVar(), codegenOuterJoinNullPlaceholder(), foundOuterJoinMatch(), Analyzer::ColumnVar::get_rte_idx(), and CgenState::outer_join_match_found_per_level_.

Referenced by codegen().

95  {
97  if (col_var->get_rte_idx() <= 0 ||
99  !foundOuterJoinMatch(col_var->get_rte_idx())) {
100  return codegenColVar(col_var, fetch_column, true, co);
101  }
102  return codegenOuterJoinNullPlaceholder(col_var, fetch_column, co);
103 }
std::vector< llvm::Value * > outer_join_match_found_per_level_
Definition: CgenState.h:352
CgenState * cgen_state_
std::vector< llvm::Value * > codegenOuterJoinNullPlaceholder(const Analyzer::ColumnVar *col_var, const bool fetch_column, const CompilationOptions &co)
Definition: ColumnIR.cpp:425
llvm::Value * foundOuterJoinMatch(const size_t nesting_level) const
Definition: ColumnIR.cpp:418
#define AUTOMATIC_IR_METADATA(CGENSTATE)
std::vector< llvm::Value * > codegenColVar(const Analyzer::ColumnVar *, const bool fetch_column, const bool update_query_plan, const CompilationOptions &)
Definition: ColumnIR.cpp:105
int get_rte_idx() const
Definition: Analyzer.h:196

+ 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 105 of file ColumnIR.cpp.

References anonymous_namespace{ColumnIR.cpp}::adjusted_range_table_index(), AUTOMATIC_IR_METADATA, 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().

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

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

Referenced by codegenFunctionOperCastArgs().

554  {
556  int32_t compression = (type_info.get_compression() == kENCODING_GEOINT &&
557  type_info.get_comp_param() == 32)
558  ? 1
559  : 0;
560 
561  return cgen_state_->llInt(compression);
562 }
CgenState * cgen_state_
#define AUTOMATIC_IR_METADATA(CGENSTATE)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:267
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:268
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312

+ 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 295 of file DateTimeIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CgenState::context_, datetrunc_fname_lookup, dtMICROSECOND, dtMILLISECOND, dtNANOSECOND, dtSECOND, CgenState::emitCall(), CgenState::emitExternalCall(), executor(), SQLTypeInfo::get_dimension(), get_int_type(), SQLTypeInfo::get_notnull(), CgenState::inlineIntNull(), CgenState::ir_builder_, SQLTypeInfo::is_high_precision_timestamp(), and CgenState::llInt().

Referenced by codegen().

298  {
299  // Only needed for i in { 0, 3, 6, 9 }.
300  constexpr int64_t pow10[10]{1, 0, 0, 1000, 0, 0, 1000000, 0, 0, 1000000000};
303  CHECK(ts_lv->getType()->isIntegerTy(64));
304  bool const is_nullable = !ti.get_notnull();
305  static_assert(dtSECOND + 1 == dtMILLISECOND, "Please keep these consecutive.");
306  static_assert(dtMILLISECOND + 1 == dtMICROSECOND, "Please keep these consecutive.");
307  static_assert(dtMICROSECOND + 1 == dtNANOSECOND, "Please keep these consecutive.");
308  if (dtSECOND <= field && field <= dtNANOSECOND) {
309  unsigned const start_dim = ti.get_dimension(); // 0, 3, 6, 9
310  unsigned const trunc_dim = (field - dtSECOND) * 3; // 0, 3, 6, 9
311  if (start_dim <= trunc_dim) {
312  return ts_lv; // Truncating to an equal or higher precision has no effect.
313  }
314  int64_t const dscale = pow10[start_dim - trunc_dim]; // 1e3, 1e6, 1e9
315  if (is_nullable) {
316  ts_lv = cgen_state_->emitCall(
317  "floor_div_nullable_lhs",
318  {ts_lv, cgen_state_->llInt(dscale), cgen_state_->inlineIntNull(ti)});
319  return cgen_state_->emitCall(
320  "mul_int64_t_nullable_lhs",
321  {ts_lv, cgen_state_->llInt(dscale), cgen_state_->inlineIntNull(ti)});
322  } else {
323  ts_lv = cgen_state_->ir_builder_.CreateSDiv(ts_lv, cgen_state_->llInt(dscale));
324  return cgen_state_->ir_builder_.CreateMul(ts_lv, cgen_state_->llInt(dscale));
325  }
326  }
327  int64_t const scale = pow10[ti.get_dimension()];
328  ts_lv = is_nullable
330  "floor_div_nullable_lhs",
331  {ts_lv, cgen_state_->llInt(scale), cgen_state_->inlineIntNull(ti)})
332  : cgen_state_->ir_builder_.CreateSDiv(ts_lv, cgen_state_->llInt(scale));
333 
334  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
335  if (is_nullable) {
336  nullcheck_codegen = std::make_unique<NullCheckCodegen>(
337  cgen_state_, executor(), ts_lv, ti, "date_trunc_hp_nullcheck");
338  }
339  char const* const fname = datetrunc_fname_lookup.at(field);
340  ts_lv = cgen_state_->emitExternalCall(
341  fname, get_int_type(64, cgen_state_->context_), {ts_lv});
342  if (is_nullable) {
343  ts_lv =
344  nullcheck_codegen->finalize(ll_int(NULL_BIGINT, cgen_state_->context_), ts_lv);
345  }
346 
347  return is_nullable
349  "mul_int64_t_nullable_lhs",
350  {ts_lv, cgen_state_->llInt(scale), cgen_state_->inlineIntNull(ti)})
351  : cgen_state_->ir_builder_.CreateMul(ts_lv, cgen_state_->llInt(scale));
352 }
CgenState * cgen_state_
#define NULL_BIGINT
Definition: sqltypes.h:184
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:222
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
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:339
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)