OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 &)
 
llvm::Value * codegenPerRowStringOper (const Analyzer::StringOper *string_oper, const CompilationOptions &co)
 
llvm::Value * codegenPseudoStringOper (const Analyzer::ColumnVar *, const std::vector< StringOps_Namespace::StringOpInfo > &string_op_infos, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenHoistedConstants (const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const shared::StringDictKey &dict_id)
 
llvm::Value * codegenCastBetweenIntTypes (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
 
void codegenCastBetweenIntTypesOverflowChecks (llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
 
llvm::Value * posArg (const Analyzer::Expr *) const
 
llvm::Value * toBool (llvm::Value *)
 
llvm::Value * castArrayPointer (llvm::Value *ptr, const SQLTypeInfo &elem_ti)
 
llvm::Value * codegenCastBetweenTimestamps (llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
 
llvm::Value * codegenWindowPosition (const WindowFunctionContext *window_func_context, llvm::Value *pos_arg)
 

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 void linkModuleWithLibdevice (Executor *executor, llvm::Module &module, llvm::PassManagerBuilder &pass_manager_builder, const GPUTarget &gpu_target)
 
static std::shared_ptr
< GpuCompilationContext
generateNativeGPUCode (Executor *executor, llvm::Function *func, llvm::Function *wrapper_func, const std::unordered_set< llvm::Function * > &live_funcs, const bool is_gpu_smem_used, const CompilationOptions &co, const GPUTarget &gpu_target)
 
static void link_udf_module (const std::unique_ptr< llvm::Module > &udf_module, llvm::Module &module, CgenState *cgen_state, llvm::Linker::Flags flags=llvm::Linker::Flags::None)
 
static bool prioritizeQuals (const RelAlgExecutionUnit &ra_exe_unit, std::vector< Analyzer::Expr * > &primary_quals, std::vector< Analyzer::Expr * > &deferred_quals, const PlanState::HoistedFiltersSet &hoisted_quals)
 
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck (llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
 

Protected Member Functions

Executorexecutor () const
 

Protected Attributes

CgenStatecgen_state_
 
PlanStateplan_state_
 

Private Member Functions

std::vector< llvm::Value * > codegen (const Analyzer::Constant *, const EncodingType enc_type, const shared::StringDictKey &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::WidthBucketExpr *, const CompilationOptions &)
 
llvm::Value * codegenConstantWidthBucketExpr (const Analyzer::WidthBucketExpr *, const CompilationOptions &)
 
llvm::Value * codegenWidthBucketExpr (const Analyzer::WidthBucketExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::MLPredictExpr *, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::PCAProjectExpr *, const CompilationOptions &)
 
llvm::Value * codegenLinRegPredict (const Analyzer::MLPredictExpr *, const std::shared_ptr< AbstractMLModel > &model, const CompilationOptions &)
 
llvm::Value * codegenTreeRegPredict (const Analyzer::MLPredictExpr *, const std::shared_ptr< AbstractTreeModel > &tree_model, const CompilationOptions &)
 
llvm::Value * codegen (const Analyzer::StringOper *, 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 * > codegenGeoColumnVar (const Analyzer::GeoColumnVar *, const bool fetch_columns, const CompilationOptions &co)
 
std::vector< llvm::Value * > codegenGeoExpr (const Analyzer::GeoExpr *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoConstant (const Analyzer::GeoConstant *, const CompilationOptions &)
 
std::vector< llvm::Value * > codegenGeoOperator (const Analyzer::GeoOperator *, 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 * >, 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 shared::StringDictKey &dict_id, const int16_t lit_off, const size_t lit_bytes)
 
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, const WindowFunctionContext *window_function_context=nullptr)
 
llvm::Value * codegenFixedLengthColVarInWindow (const Analyzer::ColumnVar *col_var, llvm::Value *col_byte_stream, llvm::Value *pos_arg, const CompilationOptions &co, const WindowFunctionContext *window_function_context=nullptr)
 
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 * codegenCastTimestampToTime (llvm::Value *ts_lv, const int dimen, const bool nullable)
 
llvm::Value * codegenCastTimestampToDate (llvm::Value *ts_lv, const int 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 * codegenCastNonStringToString (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 * codegenBoundingBoxIntersect (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
 
bool needCastForHashJoinLhs (const Analyzer::ColumnVar *rhs) 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 codegenBufferArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *buffer_buf, llvm::Value *buffer_size, llvm::Value *buffer_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 * createMultiPointStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoMultiPointArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *multi_point_buf, llvm::Value *multi_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 * createMultiLineStringStructType (const std::string &udf_func_name, size_t param_num)
 
void codegenGeoMultiLineStringArgs (const std::string &udf_func_name, size_t param_num, llvm::Value *multi_linestring_coords, llvm::Value *multi_linestring_size, llvm::Value *linestring_sizes, llvm::Value *linestring_sizes_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::vector< size_t > &, const std::unordered_map< llvm::Value *, llvm::Value * > &, const CompilationOptions &)
 
llvm::StructType * createStringViewStructType ()
 
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)
 
std::pair< std::vector
< llvm::Value * >
, std::unique_ptr
< CodeGenerator::NullCheckCodegen > > 
codegenStringFetchAndEncode (const Analyzer::StringOper *expr, const CompilationOptions &co, const size_t arg_idx, const bool codegen_nullcheck)
 

Private Attributes

Executorexecutor_
 

Static Private Attributes

static std::mutex initialize_nvptx_mutex_
 
static std::mutex initialize_cpu_backend_mutex_
 

Friends

class GroupByAndAggregate
 

Detailed Description

Definition at line 29 of file CodeGenerator.h.

Constructor & Destructor Documentation

CodeGenerator::CodeGenerator ( Executor executor)
inline

Definition at line 31 of file CodeGenerator.h.

33  , cgen_state_(executor->cgen_state_.get())
34  , 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 38 of file CodeGenerator.h.

39  : 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 1574 of file NativeCodegen.cpp.

Referenced by CgenState::set_module_shallow_copy().

1574  {
1575  auto const candidate_func_name = func->getName().str();
1578  [candidate_func_name](std::string_view func_name) {
1579  return candidate_func_name == func_name;
1580  });
1581 }
bool any_of(std::vector< Analyzer::Expr * > const &target_exprs)
constexpr std::array< std::string_view, 18 > TARGET_RUNTIME_FUNCTIONS_FOR_MODULE_CLONING

+ Here is the caller graph for this function:

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 428 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_buffer_struct_type(), anonymous_namespace{ExtensionsIR.cpp}::get_llvm_type_from_sql_array_type(), Analyzer::Expr::get_type_info(), Analyzer::FunctionOper::getName(), and CgenState::ir_builder_.

Referenced by codegenFunctionOper(), and codegenFunctionOperWithCustomTypeHandling().

429  {
431  llvm::BasicBlock* args_null_bb{nullptr};
432  llvm::BasicBlock* args_notnull_bb{nullptr};
433  llvm::BasicBlock* orig_bb = cgen_state_->ir_builder_.GetInsertBlock();
434  llvm::Value* null_array_alloca{nullptr};
435  // Only generate the check if required (at least one argument must be nullable).
436  if (ext_func_call_requires_nullcheck(function_oper)) {
437  const auto func_ti = function_oper->get_type_info();
438  if (func_ti.is_buffer()) {
439  const auto arr_struct_ty = get_buffer_struct_type(
440  cgen_state_,
441  function_oper->getName(),
442  0,
444  null_array_alloca = cgen_state_->ir_builder_.CreateAlloca(arr_struct_ty);
445  }
446  const auto args_notnull_lv = cgen_state_->ir_builder_.CreateNot(
447  codegenFunctionOperNullArg(function_oper, orig_arg_lvs));
448  args_notnull_bb = llvm::BasicBlock::Create(
449  cgen_state_->context_, "args_notnull", cgen_state_->current_func_);
450  args_null_bb = llvm::BasicBlock::Create(
452  cgen_state_->ir_builder_.CreateCondBr(args_notnull_lv, args_notnull_bb, args_null_bb);
453  cgen_state_->ir_builder_.SetInsertPoint(args_notnull_bb);
454  }
455  return std::make_tuple(
456  CodeGenerator::ArgNullcheckBBs{args_null_bb, args_notnull_bb, orig_bb},
457  null_array_alloca);
458 }
CgenState * cgen_state_
llvm::Value * codegenFunctionOperNullArg(const Analyzer::FunctionOper *, const std::vector< llvm::Value * > &)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
bool ext_func_call_requires_nullcheck(const Analyzer::FunctionOper *function_oper)
llvm::StructType * get_buffer_struct_type(CgenState *cgen_state, const std::string &ext_func_name, size_t param_num, llvm::Type *elem_type)
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
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:79
std::string getName() const
Definition: Analyzer.h:2744

+ 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 1748 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(), RangeJoinHashTable::codegenKey(), and BoundingBoxIntersectJoinHashTable::codegenKey().

1749  {
1751  if (elem_ti.get_type() == kFLOAT) {
1752  return cgen_state_->ir_builder_.CreatePointerCast(
1753  ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
1754  }
1755  if (elem_ti.get_type() == kDOUBLE) {
1756  return cgen_state_->ir_builder_.CreatePointerCast(
1757  ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
1758  }
1759  CHECK(elem_ti.is_integer() || elem_ti.is_boolean() ||
1760  (elem_ti.is_string() && elem_ti.get_compression() == kENCODING_DICT));
1761  switch (elem_ti.get_size()) {
1762  case 1:
1763  return cgen_state_->ir_builder_.CreatePointerCast(
1764  ptr, llvm::Type::getInt8PtrTy(cgen_state_->context_));
1765  case 2:
1766  return cgen_state_->ir_builder_.CreatePointerCast(
1767  ptr, llvm::Type::getInt16PtrTy(cgen_state_->context_));
1768  case 4:
1769  return cgen_state_->ir_builder_.CreatePointerCast(
1770  ptr, llvm::Type::getInt32PtrTy(cgen_state_->context_));
1771  case 8:
1772  return cgen_state_->ir_builder_.CreatePointerCast(
1773  ptr, llvm::Type::getInt64PtrTy(cgen_state_->context_));
1774  default:
1775  CHECK(false);
1776  }
1777  return nullptr;
1778 }
HOST DEVICE int get_size() const
Definition: sqltypes.h:403
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
llvm::LLVMContext & context_
Definition: CgenState.h:382
bool is_integer() const
Definition: sqltypes.h:567
bool is_boolean() const
Definition: sqltypes.h:582
#define AUTOMATIC_IR_METADATA(CGENSTATE)
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:399
#define CHECK(condition)
Definition: Logger.h:291
bool is_string() const
Definition: sqltypes.h:561

+ 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 630 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().

632  {
633  if (uoper->get_type_info().is_decimal()) {
634  return false;
635  }
636 
638  if (executor_) {
639  auto expr_range_info =
640  plan_state_->query_infos_.size() > 0
642  : ExpressionRange::makeInvalidRange();
643  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
644  return false;
645  }
646  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
647  return true;
648  }
649  }
650 
651  return false;
652 }
Executor * executor_
const std::vector< InputTableInfo > & query_infos_
Definition: PlanState.h:65
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
PlanState * plan_state_
#define CHECK(condition)
Definition: Logger.h:291
bool is_decimal() const
Definition: sqltypes.h:570
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 189 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_.

191  {
192  if (is_temporary_column(bin_oper->get_left_operand()) ||
193  is_temporary_column(bin_oper->get_right_operand())) {
194  // Computing the range for temporary columns is a lot more expensive than the overflow
195  // check.
196  return false;
197  }
198  if (bin_oper->get_type_info().is_decimal()) {
199  return false;
200  }
201 
203  if (executor_) {
204  auto expr_range_info =
205  plan_state_->query_infos_.size() > 0
207  : ExpressionRange::makeInvalidRange();
208  if (expr_range_info.getType() != ExpressionRangeType::Integer) {
209  return false;
210  }
211  if (expr_range_info.getIntMin() >= min && expr_range_info.getIntMax() <= max) {
212  return true;
213  }
214  }
215 
216  return false;
217 }
const Expr * get_right_operand() const
Definition: Analyzer.h:456
bool is_temporary_column(const Analyzer::Expr *expr)
Executor * executor_
const std::vector< InputTableInfo > & query_infos_
Definition: PlanState.h:65
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
PlanState * plan_state_
#define CHECK(condition)
Definition: Logger.h:291
const Expr * get_left_operand() const
Definition: Analyzer.h:455
bool is_decimal() const
Definition: sqltypes.h:570
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 30 of file IRCodegen.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CHECK_NE, codegenArrayExpr(), codegenColumn(), codegenFunctionOper(), codegenFunctionOperWithCustomTypeHandling(), codegenGeoBinOper(), codegenGeoColumnVar(), codegenGeoExpr(), codegenGeoUOper(), CgenState::context_, createStringViewStructType(), executor_, get_int_type(), Analyzer::Expr::get_type_info(), CgenState::ir_builder_, kENCODING_DICT, kENCODING_NONE, kLINESTRING, kMULTILINESTRING, kMULTIPOINT, kMULTIPOLYGON, kNULLT, kPOINT, kPOLYGON, CgenState::llInt(), posArg(), and width_bucket_expr().

Referenced by Executor::buildHoistLeftHandSideFiltersCb(), Executor::buildIsDeletedCb(), Executor::buildJoinLoops(), TreeModelPredictionMgr::codegen(), codegen(), GroupByAndAggregate::codegenAggArg(), TargetExprCodegen::codegenAggregate(), codegenArith(), codegenArrayAt(), codegenArrayExpr(), codegenCase(), codegenCast(), codegenCmp(), codegenCmpDecimalConst(), HashJoin::codegenColOrStringOper(), codegenColVar(), codegenConstantWidthBucketExpr(), codegenDeciDiv(), codegenDictLike(), codegenDictRegexp(), codegenDictStrCmp(), Executor::codegenFrameBoundExpr(), codegenFunctionOper(), codegenFunctionOperWithCustomTypeHandling(), codegenGeoArgs(), codegenGeoColumnVar(), codegenGeoConstant(), codegenGeoOperator(), codegenIsNull(), RangeJoinHashTable::codegenKey(), BoundingBoxIntersectJoinHashTable::codegenKey(), codegenLogical(), codegenLogicalShortCircuit(), BoundingBoxIntersectJoinHashTable::codegenManyKey(), codegenOuterJoinNullPlaceholder(), GroupByAndAggregate::codegenOutputSlot(), codegenPseudoStringOper(), codegenQualifierCmp(), codegenRowId(), codegenStringFetchAndEncode(), codegenTreeRegPredict(), codegenUMinus(), codegenUnnest(), codegenWidthBucketExpr(), Executor::codegenWindowFunctionAggregateCalls(), ScalarCodeGenerator::compile(), and Executor::groupByColumnCodegen().

32  {
34  if (!expr) {
35  return {posArg(expr)};
36  }
37  auto bin_oper = dynamic_cast<const Analyzer::BinOper*>(expr);
38  if (bin_oper) {
39  return {codegen(bin_oper, co)};
40  }
41  auto u_oper = dynamic_cast<const Analyzer::UOper*>(expr);
42  if (u_oper) {
43  return {codegen(u_oper, co)};
44  }
45  auto geo_col_var = dynamic_cast<const Analyzer::GeoColumnVar*>(expr);
46  if (geo_col_var) {
47  // inherits from ColumnVar, so it is important we check this first
48  return codegenGeoColumnVar(geo_col_var, fetch_columns, co);
49  }
50  auto col_var = dynamic_cast<const Analyzer::ColumnVar*>(expr);
51  if (col_var) {
52  return codegenColumn(col_var, fetch_columns, co);
53  }
54  auto constant = dynamic_cast<const Analyzer::Constant*>(expr);
55  if (constant) {
56  const auto& ti = constant->get_type_info();
57  if (ti.get_type() == kNULLT) {
58  throw std::runtime_error(
59  "NULL type literals are not currently supported in this context.");
60  }
61  if (constant->get_is_null()) {
62  const auto i8p_ty =
63  llvm::PointerType::get(get_int_type(8, executor_->cgen_state_->context_), 0);
64  if (ti.is_string() && ti.get_compression() == kENCODING_NONE) {
65  std::vector<llvm::Value*> null_target_lvs;
66  llvm::StructType* str_view_ty = createStringViewStructType();
67  auto null_str_view_struct_lv = cgen_state_->ir_builder_.CreateAlloca(str_view_ty);
68  // we do not need to fill the values of the string_view struct representing null
69  // string
70  null_target_lvs.push_back(
71  cgen_state_->ir_builder_.CreateLoad(str_view_ty, null_str_view_struct_lv));
72  null_target_lvs.push_back(llvm::ConstantPointerNull::get(
73  llvm::PointerType::get(llvm::IntegerType::get(cgen_state_->context_, 8), 0)));
74  null_target_lvs.push_back(cgen_state_->llInt((int32_t)0));
75  return null_target_lvs;
76  } else if (ti.is_geometry()) {
77  std::vector<llvm::Value*> ret_lvs;
78  // we classify whether the geo col value is null from the rhs of the left-join
79  // qual i.e., table S in the qual: R left join S on R.v = S.v by checking 1)
80  // nulled chunk_iter and 2) its col buffer w/ the size 0 for instance, we consider
81  // the size of col buffer for point as 16 and for other types we use `array_size`
82  // function to determine it, and they all assume valid geos have their buf size >
83  // 0 thus, by returning all bufs' ptr as nullptr we can return 0 as the length of
84  // the nulled geos' col val, and remaining logic can exploit this to finally
85  // return "null" as the col value of the corresponding row in the resultset
86  switch (ti.get_type()) {
87  // outer join's phi node in the generated code expects the # returned lvs'
88  // is the same as `col_ti.get_physical_coord_cols()`
89  // now we have necessary logic to deal with these nullptr and can conclude
90  // it as nulled geo val, i.e., see ResultSetIteration::991
91  case kPOINT:
92  case kMULTIPOINT:
93  case kLINESTRING:
94  return {llvm::ConstantPointerNull::get(i8p_ty)};
95  case kMULTILINESTRING:
96  case kPOLYGON:
97  return {llvm::ConstantPointerNull::get(i8p_ty),
98  llvm::ConstantPointerNull::get(i8p_ty)};
99  case kMULTIPOLYGON:
100  return {llvm::ConstantPointerNull::get(i8p_ty),
101  llvm::ConstantPointerNull::get(i8p_ty),
102  llvm::ConstantPointerNull::get(i8p_ty)};
103  default:
104  CHECK(false);
105  return {nullptr};
106  }
107  } else if (ti.is_array()) {
108  // similar to above nulled geo case, we can use this `nullptr` to guide
109  // `array_buff` and `array_size` functions representing nulled array value
110  return {llvm::ConstantPointerNull::get(i8p_ty)};
111  }
112  return {ti.is_fp()
113  ? static_cast<llvm::Value*>(executor_->cgen_state_->inlineFpNull(ti))
114  : static_cast<llvm::Value*>(executor_->cgen_state_->inlineIntNull(ti))};
115  }
116  if (ti.get_compression() == kENCODING_DICT) {
117  // The dictionary encoding case should be handled by the parent expression
118  // (cast, for now), here is too late to know the dictionary id if not already set
119  CHECK_NE(ti.getStringDictKey().dict_id, 0);
120  return {codegen(constant, ti.get_compression(), ti.getStringDictKey(), co)};
121  }
122  return {codegen(constant, ti.get_compression(), {}, co)};
123  }
124  auto case_expr = dynamic_cast<const Analyzer::CaseExpr*>(expr);
125  if (case_expr) {
126  return {codegen(case_expr, co)};
127  }
128  auto extract_expr = dynamic_cast<const Analyzer::ExtractExpr*>(expr);
129  if (extract_expr) {
130  return {codegen(extract_expr, co)};
131  }
132  auto dateadd_expr = dynamic_cast<const Analyzer::DateaddExpr*>(expr);
133  if (dateadd_expr) {
134  return {codegen(dateadd_expr, co)};
135  }
136  auto datediff_expr = dynamic_cast<const Analyzer::DatediffExpr*>(expr);
137  if (datediff_expr) {
138  return {codegen(datediff_expr, co)};
139  }
140  auto datetrunc_expr = dynamic_cast<const Analyzer::DatetruncExpr*>(expr);
141  if (datetrunc_expr) {
142  return {codegen(datetrunc_expr, co)};
143  }
144  auto charlength_expr = dynamic_cast<const Analyzer::CharLengthExpr*>(expr);
145  if (charlength_expr) {
146  return {codegen(charlength_expr, co)};
147  }
148  auto keyforstring_expr = dynamic_cast<const Analyzer::KeyForStringExpr*>(expr);
149  if (keyforstring_expr) {
150  return {codegen(keyforstring_expr, co)};
151  }
152  auto sample_ratio_expr = dynamic_cast<const Analyzer::SampleRatioExpr*>(expr);
153  if (sample_ratio_expr) {
154  return {codegen(sample_ratio_expr, co)};
155  }
156  auto string_oper_expr = dynamic_cast<const Analyzer::StringOper*>(expr);
157  if (string_oper_expr) {
158  return {codegen(string_oper_expr, co)};
159  }
160  auto cardinality_expr = dynamic_cast<const Analyzer::CardinalityExpr*>(expr);
161  if (cardinality_expr) {
162  return {codegen(cardinality_expr, co)};
163  }
164  auto like_expr = dynamic_cast<const Analyzer::LikeExpr*>(expr);
165  if (like_expr) {
166  return {codegen(like_expr, co)};
167  }
168  auto regexp_expr = dynamic_cast<const Analyzer::RegexpExpr*>(expr);
169  if (regexp_expr) {
170  return {codegen(regexp_expr, co)};
171  }
172  auto width_bucket_expr = dynamic_cast<const Analyzer::WidthBucketExpr*>(expr);
173  if (width_bucket_expr) {
174  return {codegen(width_bucket_expr, co)};
175  }
176 
177  auto ml_predict_expr = dynamic_cast<const Analyzer::MLPredictExpr*>(expr);
178  if (ml_predict_expr) {
179  return {codegen(ml_predict_expr, co)};
180  }
181 
182  auto pca_project_expr = dynamic_cast<const Analyzer::PCAProjectExpr*>(expr);
183  if (pca_project_expr) {
184  return {codegen(pca_project_expr, co)};
185  }
186 
187  auto likelihood_expr = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
188  if (likelihood_expr) {
189  return {codegen(likelihood_expr->get_arg(), fetch_columns, co)};
190  }
191  auto in_expr = dynamic_cast<const Analyzer::InValues*>(expr);
192  if (in_expr) {
193  return {codegen(in_expr, co)};
194  }
195  auto in_integer_set_expr = dynamic_cast<const Analyzer::InIntegerSet*>(expr);
196  if (in_integer_set_expr) {
197  return {codegen(in_integer_set_expr, co)};
198  }
199  auto function_oper_with_custom_type_handling_expr =
200  dynamic_cast<const Analyzer::FunctionOperWithCustomTypeHandling*>(expr);
201  if (function_oper_with_custom_type_handling_expr) {
203  function_oper_with_custom_type_handling_expr, co)};
204  }
205  auto array_oper_expr = dynamic_cast<const Analyzer::ArrayExpr*>(expr);
206  if (array_oper_expr) {
207  return {codegenArrayExpr(array_oper_expr, co)};
208  }
209  auto geo_uop = dynamic_cast<const Analyzer::GeoUOper*>(expr);
210  if (geo_uop) {
211  return {codegenGeoUOper(geo_uop, co)};
212  }
213  auto geo_binop = dynamic_cast<const Analyzer::GeoBinOper*>(expr);
214  if (geo_binop) {
215  return {codegenGeoBinOper(geo_binop, co)};
216  }
217  auto function_oper_expr = dynamic_cast<const Analyzer::FunctionOper*>(expr);
218  if (function_oper_expr) {
219  return {codegenFunctionOper(function_oper_expr, co)};
220  }
221  auto geo_expr = dynamic_cast<const Analyzer::GeoExpr*>(expr);
222  if (geo_expr) {
223  return codegenGeoExpr(geo_expr, co);
224  }
225  if (dynamic_cast<const Analyzer::OffsetInFragment*>(expr)) {
226  return {posArg(nullptr)};
227  }
228  if (dynamic_cast<const Analyzer::WindowFunction*>(expr)) {
229  throw NativeExecutionError("Window expression not supported in this context");
230  }
231  abort();
232 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:590
virtual std::vector< llvm::Value * > codegenColumn(const Analyzer::ColumnVar *, const bool fetch_column, const CompilationOptions &)
Definition: ColumnIR.cpp:94
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::vector< llvm::Value * > codegenGeoBinOper(const Analyzer::GeoBinOper *, const CompilationOptions &)
Definition: GeoIR.cpp:263
std::vector< llvm::Value * > codegenGeoExpr(const Analyzer::GeoExpr *, const CompilationOptions &)
Definition: GeoIR.cpp:97
llvm::LLVMContext & context_
Definition: CgenState.h:382
#define CHECK_NE(x, y)
Definition: Logger.h:302
std::vector< llvm::Value * > codegenGeoUOper(const Analyzer::GeoUOper *, const CompilationOptions &)
Definition: GeoIR.cpp:183
llvm::Value * codegenFunctionOper(const Analyzer::FunctionOper *, const CompilationOptions &)
Executor * executor_
std::vector< llvm::Value * > codegenArrayExpr(const Analyzer::ArrayExpr *, const CompilationOptions &)
Definition: ArrayIR.cpp:97
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
Expression class for string functions The &quot;arg&quot; constructor parameter must be an expression that reso...
Definition: Analyzer.h:1601
llvm::StructType * createStringViewStructType()
std::vector< llvm::Value * > codegenGeoColumnVar(const Analyzer::GeoColumnVar *, const bool fetch_columns, const CompilationOptions &co)
Definition: GeoIR.cpp:54
llvm::Value * codegenFunctionOperWithCustomTypeHandling(const Analyzer::FunctionOperWithCustomTypeHandling *, const CompilationOptions &)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int32_t width_bucket_expr(const double target_value, const bool reversed, const double lower_bound, const double upper_bound, const int32_t partition_count)

+ 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 shared::StringDictKey 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, codegenGeoConstant(), 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  if (const auto geo_constant = dynamic_cast<const Analyzer::GeoConstant*>(constant)) {
27  return codegenGeoConstant(geo_constant, co);
28  } else {
29  std::vector<const Analyzer::Constant*> constants(
30  executor()->deviceCount(co.device_type), constant);
31  return codegenHoistedConstants(constants, enc_type, dict_id);
32  }
33  }
34  const auto& type_info = constant->get_type_info();
35  const auto type =
36  type_info.is_decimal() ? decimal_to_int_type(type_info) : type_info.get_type();
37  switch (type) {
38  case kBOOLEAN:
39  return {llvm::ConstantInt::get(get_int_type(8, cgen_state_->context_),
40  constant->get_constval().boolval)};
41  case kTINYINT:
42  case kSMALLINT:
43  case kINT:
44  case kBIGINT:
45  case kTIME:
46  case kTIMESTAMP:
47  case kDATE:
48  case kINTERVAL_DAY_TIME:
50  return {CodeGenerator::codegenIntConst(constant, cgen_state_)};
51  case kFLOAT:
52  return {llvm::ConstantFP::get(llvm::Type::getFloatTy(cgen_state_->context_),
53  constant->get_constval().floatval)};
54  case kDOUBLE:
55  return {llvm::ConstantFP::get(llvm::Type::getDoubleTy(cgen_state_->context_),
56  constant->get_constval().doubleval)};
57  case kVARCHAR:
58  case kCHAR:
59  case kTEXT: {
60  CHECK(constant->get_constval().stringval || constant->get_is_null());
61  if (constant->get_is_null()) {
62  if (enc_type == kENCODING_DICT) {
63  return {
64  cgen_state_->llInt(static_cast<int32_t>(inline_int_null_val(type_info)))};
65  }
66  return {cgen_state_->llInt(int64_t(0)),
67  llvm::Constant::getNullValue(
68  llvm::PointerType::get(get_int_type(8, cgen_state_->context_), 0)),
69  cgen_state_->llInt(int32_t(0))};
70  }
71  const auto& str_const = *constant->get_constval().stringval;
72  if (enc_type == kENCODING_DICT) {
73  return {
75  ->getStringDictionaryProxy(
76  dict_id, executor()->getRowSetMemoryOwner(), true)
77  ->getIdOfString(str_const))};
78  }
79  return {cgen_state_->llInt(int64_t(0)),
80  cgen_state_->addStringConstant(str_const),
81  cgen_state_->llInt(static_cast<int32_t>(str_const.size()))};
82  }
83  default:
84  CHECK(false);
85  }
86  abort();
87 }
Definition: sqltypes.h:76
CgenState * cgen_state_
llvm::Value * addStringConstant(const std::string &str)
Definition: CgenState.h:190
int8_t boolval
Definition: Datum.h:72
bool get_is_null() const
Definition: Analyzer.h:347
std::vector< llvm::Value * > codegenHoistedConstants(const std::vector< const Analyzer::Constant * > &constants, const EncodingType enc_type, const shared::StringDictKey &dict_id)
Definition: ConstantIR.cpp:373
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
float floatval
Definition: Datum.h:77
llvm::LLVMContext & context_
Definition: CgenState.h:382
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::string * stringval
Definition: Datum.h:81
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:561
ExecutorDeviceType device_type
Definition: sqltypes.h:79
Definition: sqltypes.h:80
static llvm::ConstantInt * codegenIntConst(const Analyzer::Constant *constant, CgenState *cgen_state)
Definition: ConstantIR.cpp:89
Datum get_constval() const
Definition: Analyzer.h:348
Definition: sqltypes.h:68
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::vector< llvm::Value * > codegenGeoConstant(const Analyzer::GeoConstant *, const CompilationOptions &)
Definition: GeoIR.cpp:111
Definition: sqltypes.h:72
double doubleval
Definition: Datum.h:78
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:301
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
Definition: sqldefs.h:32
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:211
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
Definition: sqldefs.h:74
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:646
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:344
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:230
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
std::unique_ptr< InValuesBitmap > createInValuesBitmap(const Analyzer::InValues *, const CompilationOptions &)
Definition: InValuesIR.cpp:112
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1677
const Expr * get_arg() const
Definition: Analyzer.h:644
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()->data_mgr_,
95  co);
96  const auto& in_integer_set_ti = in_integer_set->get_type_info();
97  CHECK(in_integer_set_ti.is_boolean());
98  const auto lhs_lvs = codegen(in_arg, true, co);
99  llvm::Value* result{nullptr};
100  if (in_integer_set_ti.get_notnull()) {
101  result = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(cgen_state_->context_),
102  false);
103  } else {
104  result = cgen_state_->llInt(int8_t(0));
105  }
106  CHECK(result);
107  CHECK_EQ(size_t(1), lhs_lvs.size());
108  return cgen_state_->addInValuesBitmap(in_vals_bitmap)
109  ->codegen(lhs_lvs.front(), executor());
110 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
llvm::LLVMContext & context_
Definition: CgenState.h:382
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:211
#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:30
llvm::Value * codegen(llvm::Value *needle, Executor *executor) const
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1677
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_, createStringViewStructType(), get_bit_width(), Analyzer::CaseExpr::get_else_expr(), get_int_type(), Analyzer::Expr::get_type_info(), CgenState::ir_builder_, 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 = createStringViewStructType();
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  } else if (case_ti.is_geometry()) {
43  throw std::runtime_error(
44  "Geospatial column projections are currently not supported in conditional "
45  "expressions.");
46  } else if (case_ti.is_array()) {
47  throw std::runtime_error(
48  "Array column projections are currently not supported in conditional "
49  "expressions.");
50  }
51  CHECK(case_llvm_type);
52  const auto& else_ti = case_expr->get_else_expr()->get_type_info();
53  CHECK_EQ(else_ti.get_type(), case_ti.get_type());
54  llvm::Value* case_val = codegenCase(case_expr, case_llvm_type, is_real_str, co);
55  std::vector<llvm::Value*> ret_vals{case_val};
56  if (is_real_str) {
57  ret_vals.push_back(cgen_state_->ir_builder_.CreateExtractValue(case_val, 0));
58  ret_vals.push_back(cgen_state_->ir_builder_.CreateExtractValue(case_val, 1));
59  ret_vals.back() = cgen_state_->ir_builder_.CreateTrunc(
60  ret_vals.back(), llvm::Type::getInt32Ty(cgen_state_->context_));
61  }
62  return ret_vals;
63 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const Expr * get_else_expr() const
Definition: Analyzer.h:1387
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
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:382
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::StructType * createStringViewStructType()
llvm::Value * codegenCase(const Analyzer::CaseExpr *, llvm::Type *case_llvm_type, const bool is_real_str, const CompilationOptions &)
Definition: CaseIR.cpp:65
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

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

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

77  {
79  auto from_expr = codegen(extract_expr->get_from_expr(), true, co).front();
80  const int32_t extract_field{extract_expr->get_field()};
81  const auto& extract_expr_ti = extract_expr->get_from_expr()->get_type_info();
82  if (extract_field == kEPOCH) {
83  CHECK(extract_expr_ti.get_type() == kTIMESTAMP ||
84  extract_expr_ti.get_type() == kDATE);
85  if (from_expr->getType()->isIntegerTy(32)) {
86  from_expr =
87  cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
88  from_expr,
90  return from_expr;
91  }
92  }
93  CHECK(from_expr->getType()->isIntegerTy(64));
94  if (extract_expr_ti.is_high_precision_timestamp()) {
96  from_expr, extract_expr_ti, extract_expr->get_field());
97  }
98  if (!extract_expr_ti.is_high_precision_timestamp() &&
99  is_subsecond_extract_field(extract_expr->get_field())) {
100  from_expr =
101  extract_expr_ti.get_notnull()
102  ? cgen_state_->ir_builder_.CreateMul(
103  from_expr,
107  "mul_int64_t_nullable_lhs",
108  {from_expr,
111  cgen_state_->inlineIntNull(extract_expr_ti)});
112  }
113  const auto extract_fname = get_extract_function_name(extract_expr->get_field());
114  if (!extract_expr_ti.get_notnull()) {
115  llvm::BasicBlock* extract_nullcheck_bb{nullptr};
116  llvm::PHINode* extract_nullcheck_value{nullptr};
117  {
118  DiamondCodegen null_check(cgen_state_->ir_builder_.CreateICmp(
119  llvm::ICmpInst::ICMP_EQ,
120  from_expr,
121  cgen_state_->inlineIntNull(extract_expr_ti)),
122  executor(),
123  false,
124  "extract_nullcheck",
125  nullptr,
126  false);
127  // generate a phi node depending on whether we got a null or not
128  extract_nullcheck_bb = llvm::BasicBlock::Create(
129  cgen_state_->context_, "extract_nullcheck_bb", cgen_state_->current_func_);
130 
131  // update the blocks created by diamond codegen to point to the newly created phi
132  // block
133  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_true_);
134  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
135  cgen_state_->ir_builder_.SetInsertPoint(null_check.cond_false_);
136  auto extract_call =
137  cgen_state_->emitExternalCall(extract_fname,
139  std::vector<llvm::Value*>{from_expr});
140  cgen_state_->ir_builder_.CreateBr(extract_nullcheck_bb);
141 
142  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
143  extract_nullcheck_value = cgen_state_->ir_builder_.CreatePHI(
144  get_int_type(64, cgen_state_->context_), 2, "extract_value");
145  extract_nullcheck_value->addIncoming(extract_call, null_check.cond_false_);
146  extract_nullcheck_value->addIncoming(cgen_state_->inlineIntNull(extract_expr_ti),
147  null_check.cond_true_);
148  }
149 
150  // diamond codegen will set the insert point in its destructor. override it to
151  // continue using the extract nullcheck bb
152  CHECK(extract_nullcheck_bb);
153  cgen_state_->ir_builder_.SetInsertPoint(extract_nullcheck_bb);
154  CHECK(extract_nullcheck_value);
155  return extract_nullcheck_value;
156  } else {
157  return cgen_state_->emitExternalCall(extract_fname,
159  std::vector<llvm::Value*>{from_expr});
160  }
161 }
const Expr * get_from_expr() const
Definition: Analyzer.h:1432
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:1431
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
const char * get_extract_function_name(ExtractField field)
Definition: DateTimeIR.cpp:26
llvm::Value * codegenExtractHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const ExtractField &)
Definition: DateTimeIR.cpp:260
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
Definition: sqltypes.h:80
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
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 163 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(), inline_fixed_encoding_null_val(), inline_int_null_val(), DateTimeUtils::is_subsecond_dateadd_field(), kDATE, kTIMESTAMP, CgenState::llInt(), and Analyzer::DateaddExpr::use_fixed_encoding_null_val().

164  {
166  const auto& dateadd_expr_ti = dateadd_expr->get_type_info();
167  CHECK(dateadd_expr_ti.get_type() == kTIMESTAMP || dateadd_expr_ti.get_type() == kDATE);
168  auto datetime = codegen(dateadd_expr->get_datetime_expr(), true, co).front();
169  CHECK(datetime->getType()->isIntegerTy(64));
170  auto number = codegen(dateadd_expr->get_number_expr(), true, co).front();
171 
172  const auto& datetime_ti = dateadd_expr->get_datetime_expr()->get_type_info();
173  std::vector<llvm::Value*> dateadd_args{
174  cgen_state_->llInt(static_cast<int32_t>(dateadd_expr->get_field())),
175  number,
176  datetime};
177  std::string dateadd_fname{"DateAdd"};
178  if (is_subsecond_dateadd_field(dateadd_expr->get_field()) ||
179  dateadd_expr_ti.is_high_precision_timestamp()) {
180  dateadd_fname += "HighPrecision";
181  dateadd_args.push_back(
182  cgen_state_->llInt(static_cast<int32_t>(datetime_ti.get_dimension())));
183  }
184  if (!datetime_ti.get_notnull()) {
185  auto null_val = dateadd_expr->use_fixed_encoding_null_val()
186  ? inline_fixed_encoding_null_val(datetime_ti)
187  : inline_int_null_val(datetime_ti);
188  dateadd_args.push_back(cgen_state_->llInt((int64_t)null_val));
189  dateadd_fname += "Nullable";
190  }
191  return cgen_state_->emitExternalCall(dateadd_fname,
193  dateadd_args,
194  {llvm::Attribute::NoUnwind,
195  llvm::Attribute::ReadNone,
196  llvm::Attribute::Speculatable});
197 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
Definition: sqltypes.h:80
const Expr * get_datetime_expr() const
Definition: Analyzer.h:1478
DateaddField get_field() const
Definition: Analyzer.h:1476
constexpr bool is_subsecond_dateadd_field(const DateaddField field)
Definition: DateTimeUtils.h:99
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
bool use_fixed_encoding_null_val() const
Definition: Analyzer.h:1480
const Expr * get_number_expr() const
Definition: Analyzer.h:1477

+ Here is the call graph for this function:

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

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

200  {
202  auto start = codegen(datediff_expr->get_start_expr(), true, co).front();
203  CHECK(start->getType()->isIntegerTy(64));
204  auto end = codegen(datediff_expr->get_end_expr(), true, co).front();
205  CHECK(end->getType()->isIntegerTy(32) || end->getType()->isIntegerTy(64));
206  const auto& start_ti = datediff_expr->get_start_expr()->get_type_info();
207  const auto& end_ti = datediff_expr->get_end_expr()->get_type_info();
208  std::vector<llvm::Value*> datediff_args{
209  cgen_state_->llInt(static_cast<int32_t>(datediff_expr->get_field())), start, end};
210  std::string datediff_fname{"DateDiff"};
211  if (start_ti.is_high_precision_timestamp() || end_ti.is_high_precision_timestamp()) {
212  datediff_fname += "HighPrecision";
213  datediff_args.push_back(
214  cgen_state_->llInt(static_cast<int32_t>(start_ti.get_dimension())));
215  datediff_args.push_back(
216  cgen_state_->llInt(static_cast<int32_t>(end_ti.get_dimension())));
217  }
218  const auto& ret_ti = datediff_expr->get_type_info();
219  if (!start_ti.get_notnull() || !end_ti.get_notnull()) {
220  datediff_args.push_back(cgen_state_->inlineIntNull(ret_ti));
221  datediff_fname += "Nullable";
222  }
224  datediff_fname, get_int_type(64, cgen_state_->context_), datediff_args);
225 }
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const Expr * get_start_expr() const
Definition: Analyzer.h:1525
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
const Expr * get_end_expr() const
Definition: Analyzer.h:1526
#define CHECK(condition)
Definition: Logger.h:291
DatetruncField get_field() const
Definition: Analyzer.h:1524

+ Here is the call graph for this function:

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

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

228  {
230  auto from_expr = codegen(datetrunc_expr->get_from_expr(), true, co).front();
231  const auto& datetrunc_expr_ti = datetrunc_expr->get_from_expr()->get_type_info();
232  CHECK(from_expr->getType()->isIntegerTy(64));
233  DatetruncField const field = datetrunc_expr->get_field();
234  if (datetrunc_expr_ti.is_high_precision_timestamp()) {
235  return codegenDateTruncHighPrecisionTimestamps(from_expr, datetrunc_expr_ti, field);
236  }
237  static_assert(dtSECOND + 1 == dtMILLISECOND, "Please keep these consecutive.");
238  static_assert(dtMILLISECOND + 1 == dtMICROSECOND, "Please keep these consecutive.");
239  static_assert(dtMICROSECOND + 1 == dtNANOSECOND, "Please keep these consecutive.");
240  if (dtSECOND <= field && field <= dtNANOSECOND) {
241  return cgen_state_->ir_builder_.CreateCast(llvm::Instruction::CastOps::SExt,
242  from_expr,
244  }
245  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
246  const bool is_nullable = !datetrunc_expr_ti.get_notnull();
247  if (is_nullable) {
248  nullcheck_codegen = std::make_unique<NullCheckCodegen>(
249  cgen_state_, executor(), from_expr, datetrunc_expr_ti, "date_trunc_nullcheck");
250  }
251  char const* const fname = datetrunc_fname_lookup.at(field);
252  auto ret = cgen_state_->emitExternalCall(
253  fname, get_int_type(64, cgen_state_->context_), {from_expr});
254  if (is_nullable) {
255  ret = nullcheck_codegen->finalize(ll_int(NULL_BIGINT, cgen_state_->context_), ret);
256  }
257  return ret;
258 }
CgenState * cgen_state_
#define NULL_BIGINT
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
DatetruncField get_field() const
Definition: Analyzer.h:1566
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:33
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
DatetruncField
Definition: DateTruncate.h:27
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
constexpr std::array< char const *, dtINVALID > datetrunc_fname_lookup
Definition: DateTruncate.h:49
const Expr * get_from_expr() const
Definition: Analyzer.h:1567
#define CHECK(condition)
Definition: Logger.h:291
llvm::Value * codegenDateTruncHighPrecisionTimestamps(llvm::Value *, const SQLTypeInfo &, const DatetruncField &)
Definition: DateTimeIR.cpp:304
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 239 of file StringOpsIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK_EQ, codegen(), CgenState::context_, CompilationOptions::device_type, CgenState::emitCall(), CgenState::emitExternalCall(), Analyzer::CharLengthExpr::get_arg(), Analyzer::CharLengthExpr::get_calc_encoded_length(), get_int_type(), SQLTypeInfo::get_notnull(), Analyzer::Expr::get_type_info(), GPU, CgenState::inlineIntNull(), and CgenState::ir_builder_.

240  {
242  auto str_lv = codegen(expr->get_arg(), true, co);
243  if (str_lv.size() != 3) {
244  CHECK_EQ(size_t(1), str_lv.size());
245  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 0));
246  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 1));
247  str_lv.back() = cgen_state_->ir_builder_.CreateTrunc(
248  str_lv.back(), llvm::Type::getInt32Ty(cgen_state_->context_));
250  throw QueryMustRunOnCpu();
251  }
252  }
253  std::vector<llvm::Value*> charlength_args{str_lv[1], str_lv[2]};
254  std::string fn_name("char_length");
255  if (expr->get_calc_encoded_length()) {
256  fn_name += "_encoded";
257  }
258  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
259  if (is_nullable) {
260  fn_name += "_nullable";
261  charlength_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
262  }
263  return expr->get_calc_encoded_length()
265  fn_name, get_int_type(32, cgen_state_->context_), charlength_args)
266  : cgen_state_->emitCall(fn_name, charlength_args);
267 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool get_calc_encoded_length() const
Definition: Analyzer.h:870
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_arg() const
Definition: Analyzer.h:868
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398

+ Here is the call graph for this function:

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

Definition at line 269 of file StringOpsIR.cpp.

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

270  {
272  auto str_lv = codegen(expr->get_arg(), true, co);
273  CHECK_EQ(size_t(1), str_lv.size());
274  return cgen_state_->emitCall("key_for_string_encoded", str_lv);
275 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_arg() const
Definition: Analyzer.h:917

+ Here is the call graph for this function:

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

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

279  {
281  auto input_expr = expr->get_arg();
282  CHECK(input_expr);
283 
284  auto double_lv = codegen(input_expr, true, co);
285  CHECK_EQ(size_t(1), double_lv.size());
286 
287  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
288  const bool is_nullable = !input_expr->get_type_info().get_notnull();
289  if (is_nullable) {
290  nullcheck_codegen = std::make_unique<NullCheckCodegen>(cgen_state_,
291  executor(),
292  double_lv.front(),
293  input_expr->get_type_info(),
294  "sample_ratio_nullcheck");
295  }
296  CHECK_EQ(input_expr->get_type_info().get_type(), kDOUBLE);
297  std::vector<llvm::Value*> args{double_lv[0], posArg(nullptr)};
298  auto ret = cgen_state_->emitCall("sample_ratio", args);
299  if (nullcheck_codegen) {
300  ret = nullcheck_codegen->finalize(ll_bool(false, cgen_state_->context_), ret);
301  }
302  return ret;
303 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:590
#define AUTOMATIC_IR_METADATA(CGENSTATE)
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_arg() const
Definition: Analyzer.h:962
#define CHECK(condition)
Definition: Logger.h:291
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::WidthBucketExpr expr,
const CompilationOptions co 
)
private

Definition at line 305 of file IRCodegen.cpp.

References AUTOMATIC_IR_METADATA, Analyzer::WidthBucketExpr::can_skip_out_of_bound_check(), cgen_state_, CHECK, codegenConstantWidthBucketExpr(), codegenWidthBucketExpr(), executor_, Analyzer::WidthBucketExpr::get_lower_bound(), Analyzer::WidthBucketExpr::get_partition_count(), Analyzer::WidthBucketExpr::get_partition_count_val(), Analyzer::WidthBucketExpr::get_target_value(), Analyzer::WidthBucketExpr::get_upper_bound(), getExpressionRange(), PlanState::getSimpleQuals(), Integer, Analyzer::WidthBucketExpr::is_constant_expr(), kCAST, plan_state_, PlanState::query_infos_, Analyzer::WidthBucketExpr::set_constant_expr(), and Analyzer::WidthBucketExpr::skip_out_of_bound_check().

306  {
308  auto target_value_expr = expr->get_target_value();
309  auto lower_bound_expr = expr->get_lower_bound();
310  auto upper_bound_expr = expr->get_upper_bound();
311  auto partition_count_expr = expr->get_partition_count();
312  CHECK(target_value_expr);
313  CHECK(lower_bound_expr);
314  CHECK(upper_bound_expr);
315  CHECK(partition_count_expr);
316 
317  auto is_constant_expr = [](const Analyzer::Expr* expr) {
318  auto target_expr = expr;
319  if (auto cast_expr = dynamic_cast<const Analyzer::UOper*>(expr)) {
320  if (cast_expr->get_optype() == SQLOps::kCAST) {
321  target_expr = cast_expr->get_operand();
322  }
323  }
324  // there are more complex constant expr like 1+2, 1/2*3, and so on
325  // but when considering a typical usage of width_bucket function
326  // it is sufficient to consider a singleton constant expr
327  auto constant_expr = dynamic_cast<const Analyzer::Constant*>(target_expr);
328  if (constant_expr) {
329  return true;
330  }
331  return false;
332  };
333  if (is_constant_expr(lower_bound_expr) && is_constant_expr(upper_bound_expr) &&
334  is_constant_expr(partition_count_expr)) {
335  expr->set_constant_expr();
336  }
337  // compute width_bucket's expresn range and check the possibility of avoiding oob check
338  auto col_range =
339  getExpressionRange(expr,
341  executor_,
342  boost::make_optional(plan_state_->getSimpleQuals()));
343  // check whether target_expr is valid
344  if (col_range.getType() == ExpressionRangeType::Integer &&
345  !expr->can_skip_out_of_bound_check() && col_range.getIntMin() > 0 &&
346  col_range.getIntMax() <= expr->get_partition_count_val()) {
347  // check whether target_col is not-nullable or has filter expr on it
348  if (!col_range.hasNulls()) {
349  // Even if the target_expr has its filter expression, target_col_range may exactly
350  // the same with the col_range of the target_expr's operand col,
351  // i.e., SELECT WIDTH_BUCKET(v1, 1, 10, 10) FROM T WHERE v1 != 1;
352  // In that query, col_range of v1 with/without considering the filter expression
353  // v1 != 1 have exactly the same col ranges, so we cannot recognize the existence
354  // of the filter expression based on them. Also, is (not) null is located in
355  // FilterNode, so we cannot trace it in here.
356  // todo (yoonmin): relax this to allow skipping oob check more cases
357  expr->skip_out_of_bound_check();
358  }
359  }
360  return expr->is_constant_expr() ? codegenConstantWidthBucketExpr(expr, co)
361  : codegenWidthBucketExpr(expr, co);
362 }
const Expr * get_partition_count() const
Definition: Analyzer.h:1201
bool is_constant_expr() const
Definition: Analyzer.h:1246
llvm::Value * codegenConstantWidthBucketExpr(const Analyzer::WidthBucketExpr *, const CompilationOptions &)
Definition: IRCodegen.cpp:364
CgenState * cgen_state_
Definition: sqldefs.h:51
void set_constant_expr() const
Definition: Analyzer.h:1245
llvm::Value * codegenWidthBucketExpr(const Analyzer::WidthBucketExpr *, const CompilationOptions &)
Definition: IRCodegen.cpp:437
Executor * executor_
const std::vector< InputTableInfo > & query_infos_
Definition: PlanState.h:65
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)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
PlanState * plan_state_
int32_t get_partition_count_val() const
Definition: Analyzer.cpp:3946
std::list< std::shared_ptr< Analyzer::Expr > > getSimpleQuals() const
Definition: PlanState.h:97
const Expr * get_target_value() const
Definition: Analyzer.h:1198
#define CHECK(condition)
Definition: Logger.h:291
bool can_skip_out_of_bound_check() const
Definition: Analyzer.h:1243
void skip_out_of_bound_check() const
Definition: Analyzer.h:1244
const Expr * get_lower_bound() const
Definition: Analyzer.h:1199
const Expr * get_upper_bound() const
Definition: Analyzer.h:1200

+ Here is the call graph for this function:

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

Definition at line 288 of file MLPredictCodegen.cpp.

References CHECK, codegenLinRegPredict(), codegenTreeRegPredict(), DEBUG_TIMER, DECISION_TREE_REG, g_ml_models, GBT_REG, Analyzer::MLPredictExpr::get_model_value(), Analyzer::MLPredictExpr::get_regressor_values(), MLModelMap::getModel(), LINEAR_REG, and RANDOM_FOREST_REG.

289  {
290  auto timer = DEBUG_TIMER(__func__);
291  const auto& model_expr = expr->get_model_value();
292  CHECK(model_expr);
293  auto model_constant_expr = dynamic_cast<const Analyzer::Constant*>(model_expr);
294  CHECK(model_constant_expr);
295  const auto model_datum = model_constant_expr->get_constval();
296  const auto model_name_ptr = model_datum.stringval;
297  CHECK(model_name_ptr);
298  const auto model_name = *model_name_ptr;
299  const auto abstract_model = g_ml_models.getModel(model_name);
300  const auto model_type = abstract_model->getModelType();
301  const auto& regressor_exprs = expr->get_regressor_values();
302  if (abstract_model->getNumLogicalFeatures() !=
303  static_cast<int64_t>(regressor_exprs.size())) {
304  std::ostringstream error_oss;
305  error_oss << "ML_PREDICT: Model '" << model_name
306  << "' expects different number of predictor variables ("
307  << abstract_model->getNumLogicalFeatures() << ") than provided ("
308  << regressor_exprs.size() << ").";
309  throw std::runtime_error(error_oss.str());
310  }
311 
312  switch (model_type) {
314  return codegenLinRegPredict(expr, abstract_model, co);
315  }
319  if (auto tree_model =
320  std::dynamic_pointer_cast<AbstractTreeModel>(abstract_model)) {
321  return codegenTreeRegPredict(expr, tree_model, co);
322  } else {
323  throw std::runtime_error(
324  "Invalid ML model codegen call. Input model is not of expected type "
325  "TreeModel.");
326  }
327  }
328  default: {
329  throw std::runtime_error("Unsupported model type.");
330  }
331  }
332 }
llvm::Value * codegenTreeRegPredict(const Analyzer::MLPredictExpr *, const std::shared_ptr< AbstractTreeModel > &tree_model, const CompilationOptions &)
llvm::Value * codegenLinRegPredict(const Analyzer::MLPredictExpr *, const std::shared_ptr< AbstractMLModel > &model, const CompilationOptions &)
std::shared_ptr< AbstractMLModel > getModel(const std::string &model_name) const
Definition: MLModel.h:51
MLModelMap g_ml_models
Definition: MLModel.h:125
#define CHECK(condition)
Definition: Logger.h:291
#define DEBUG_TIMER(name)
Definition: Logger.h:412
const Expr * get_model_value() const
Definition: Analyzer.h:713
const std::vector< std::shared_ptr< Analyzer::Expr > > & get_regressor_values() const
Definition: Analyzer.h:714

+ Here is the call graph for this function:

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

Definition at line 334 of file MLPredictCodegen.cpp.

References CHECK, codegenArith(), DEBUG_TIMER, Datum::doubleval, executor(), g_ml_models, generated_encoded_and_casted_features(), Analyzer::Constant::get_constval(), Analyzer::PCAProjectExpr::get_feature_values(), Analyzer::PCAProjectExpr::get_model_value(), Analyzer::PCAProjectExpr::get_pc_dimension_value(), MLModelMap::getModel(), Datum::intval, kDIVIDE, kDOUBLE, kMINUS, kMULTIPLY, kONE, kPLUS, PCA, and run_benchmark_import::result.

335  {
336  auto timer = DEBUG_TIMER(__func__);
337  const auto& model_expr = expr->get_model_value();
338  CHECK(model_expr);
339  auto model_constant_expr = dynamic_cast<const Analyzer::Constant*>(model_expr);
340  CHECK(model_constant_expr);
341  const auto model_datum = model_constant_expr->get_constval();
342  const auto model_name_ptr = model_datum.stringval;
343  CHECK(model_name_ptr);
344  const auto model_name = *model_name_ptr;
345  const auto abstract_model = g_ml_models.getModel(model_name);
346  const auto model_type = abstract_model->getModelType();
347  if (model_type != MLModelType::PCA) {
348  throw std::runtime_error("PCA_PROJECT: Model '" + model_name +
349  "' is not a PCA model.");
350  }
351  const auto pca_model = std::dynamic_pointer_cast<PcaModel>(abstract_model);
352  const auto& feature_exprs = expr->get_feature_values();
353  if (pca_model->getNumLogicalFeatures() != static_cast<int64_t>(feature_exprs.size())) {
354  std::ostringstream error_oss;
355  error_oss << "PCA_PROJECT: Model '" << model_name
356  << "' expects different number of predictor variables ("
357  << pca_model->getNumLogicalFeatures() << ") than provided ("
358  << feature_exprs.size() << ").";
359  throw std::runtime_error(error_oss.str());
360  }
361 
362  const auto& pc_dimension_expr = expr->get_pc_dimension_value();
363  auto pc_dimension_const_expr =
364  dynamic_cast<const Analyzer::Constant*>(pc_dimension_expr);
365  const auto pc_dimension_datum = pc_dimension_const_expr->get_constval();
366  const auto pc_dimension = pc_dimension_datum.intval - 1;
367  if (pc_dimension < 0 || pc_dimension >= pca_model->getNumFeatures()) {
368  std::ostringstream error_oss;
369  error_oss << "PCA_PROJECT: Invalid PC dimension (" << pc_dimension + 1
370  << ") provided. Valid range is [1, " << pca_model->getNumFeatures() << "].";
371  throw std::runtime_error(error_oss.str());
372  }
373 
374  const auto& column_means = pca_model->getColumnMeans();
375  const auto& column_std_devs = pca_model->getColumnStdDevs();
376  const auto& eigenvectors = pca_model->getEigenvectors();
377 
378  const auto& cat_feature_keys = pca_model->getCatFeatureKeys();
379 
380  const auto casted_feature_exprs = generated_encoded_and_casted_features(
381  feature_exprs,
382  cat_feature_keys,
383  pca_model->getModelMetadata().getFeaturePermutations(),
384  executor());
385 
386  auto get_double_constant_expr = [](double const_val) {
387  Datum d;
388  d.doubleval = const_val;
389  return makeExpr<Analyzer::Constant>(SQLTypeInfo(kDOUBLE, false), false, d);
390  };
391 
392  std::shared_ptr<Analyzer::Expr> result;
393 
394  for (size_t feature_idx = 0; feature_idx < feature_exprs.size(); ++feature_idx) {
395  auto mean_expr = get_double_constant_expr(column_means[feature_idx]);
396  const auto& casted_feature_expr = casted_feature_exprs[feature_idx];
397  // Subtract column mean from feature
398  auto mean_diff_expr = makeExpr<Analyzer::BinOper>(
399  SQLTypeInfo(kDOUBLE, false), false, kMINUS, kONE, casted_feature_expr, mean_expr);
400  auto std_dev_expr = get_double_constant_expr(column_std_devs[feature_idx]);
401  auto z_score_expr = makeExpr<Analyzer::BinOper>(
402  SQLTypeInfo(kDOUBLE, false), false, kDIVIDE, kONE, mean_diff_expr, std_dev_expr);
403  auto pc_term_expr = get_double_constant_expr(eigenvectors[pc_dimension][feature_idx]);
404  auto pca_mul_expr = makeExpr<Analyzer::BinOper>(
405  SQLTypeInfo(kDOUBLE, false), false, kMULTIPLY, kONE, z_score_expr, pc_term_expr);
406  if (feature_idx == 0) {
407  // There is no result yet, so set the result to the first term
408  result = pca_mul_expr;
409  } else {
410  // Add the term to the result
411  result = makeExpr<Analyzer::BinOper>(
412  SQLTypeInfo(kDOUBLE, false), false, kPLUS, kONE, result, pca_mul_expr);
413  }
414  }
415 
416  // The following will codegen the expression tree we just created modeling
417  // the linear regression formula
418  return codegenArith(dynamic_cast<Analyzer::BinOper*>(result.get()), co);
419 }
llvm::Value * codegenArith(const Analyzer::BinOper *, const CompilationOptions &)
Definition: sqldefs.h:43
int32_t intval
Definition: Datum.h:75
std::vector< std::shared_ptr< Analyzer::Expr > > generated_encoded_and_casted_features(const std::vector< std::shared_ptr< Analyzer::Expr >> &feature_exprs, const std::vector< std::vector< std::string >> &cat_feature_keys, const std::vector< int64_t > &feature_permutations, Executor *executor)
const Expr * get_pc_dimension_value() const
Definition: Analyzer.h:792
std::shared_ptr< AbstractMLModel > getModel(const std::string &model_name) const
Definition: MLModel.h:51
MLModelMap g_ml_models
Definition: MLModel.h:125
Definition: sqldefs.h:42
Definition: sqldefs.h:74
Datum get_constval() const
Definition: Analyzer.h:348
const Expr * get_model_value() const
Definition: Analyzer.h:788
const std::vector< std::shared_ptr< Analyzer::Expr > > & get_feature_values() const
Definition: Analyzer.h:789
#define CHECK(condition)
Definition: Logger.h:291
#define DEBUG_TIMER(name)
Definition: Logger.h:412
Definition: Datum.h:71
double doubleval
Definition: Datum.h:78
Executor * executor() const

+ Here is the call graph for this function:

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

Definition at line 533 of file StringOpsIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK_EQ, CHECK_GE, codegen(), StringDictionaryTranslationMgr::codegen(), codegenPerRowStringOper(), CompilationOptions::device_type, executor(), Analyzer::Expr::get_type_info(), Analyzer::StringOper::getArg(), Analyzer::StringOper::getArity(), CgenState::moveStringDictionaryTranslationMgr(), Analyzer::StringOper::requiresPerRowTranslation(), and translate_dict_strings().

534  {
535  CHECK_GE(expr->getArity(), 1UL);
536  if (expr->requiresPerRowTranslation()) {
537  return codegenPerRowStringOper(expr, co);
538  }
539 
541 
542  auto string_dictionary_translation_mgr =
544 
545  auto str_id_lv = codegen(expr->getArg(0), true, co);
546  CHECK_EQ(size_t(1), str_id_lv.size());
547  const auto& expr_ti = expr->get_type_info();
548 
549  return cgen_state_
550  ->moveStringDictionaryTranslationMgr(std::move(string_dictionary_translation_mgr))
551  ->codegen(str_id_lv[0], expr_ti, true /* add_nullcheck */, co);
552 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
llvm::Value * codegenPerRowStringOper(const Analyzer::StringOper *string_oper, const CompilationOptions &co)
CgenState * cgen_state_
std::unique_ptr< StringDictionaryTranslationMgr > translate_dict_strings(const Analyzer::StringOper *expr, const ExecutorDeviceType device_type, Executor *executor)
#define CHECK_GE(x, y)
Definition: Logger.h:306
size_t getArity() const
Definition: Analyzer.h:1674
bool requiresPerRowTranslation() const
Definition: Analyzer.h:1704
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const StringDictionaryTranslationMgr * moveStringDictionaryTranslationMgr(std::unique_ptr< const StringDictionaryTranslationMgr > &&str_dict_translation_mgr)
Definition: CgenState.h:199
llvm::Value * codegen(llvm::Value *str_id_input, const SQLTypeInfo &input_ti, const bool add_nullcheck, const CompilationOptions &co) const
const Expr * getArg(const size_t i) const
Definition: Analyzer.h:1688
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 587 of file StringOpsIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CHECK_EQ, codegen(), codegenDictLike(), CgenState::context_, CompilationOptions::device_type, CgenState::emitCall(), extract_cast_arg(), g_enable_watchdog, Analyzer::LikeExpr::get_arg(), Analyzer::LikeExpr::get_escape_expr(), Analyzer::LikeExpr::get_is_ilike(), Analyzer::LikeExpr::get_is_simple(), Analyzer::LikeExpr::get_like_expr(), SQLTypeInfo::get_notnull(), Analyzer::LikeExpr::get_own_arg(), Analyzer::Expr::get_type_info(), GPU, CgenState::inlineIntNull(), CgenState::ir_builder_, is_unnest(), kENCODING_NONE, and CgenState::llInt().

588  {
590  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
591  throw std::runtime_error("LIKE not supported for unnested expressions");
592  }
593  char escape_char{'\\'};
594  if (expr->get_escape_expr()) {
595  auto escape_char_expr =
596  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
597  CHECK(escape_char_expr);
598  CHECK(escape_char_expr->get_type_info().is_string());
599  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
600  escape_char = (*escape_char_expr->get_constval().stringval)[0];
601  }
602  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_like_expr());
603  CHECK(pattern);
604  auto fast_dict_like_lv = codegenDictLike(expr->get_own_arg(),
605  pattern,
606  expr->get_is_ilike(),
607  expr->get_is_simple(),
608  escape_char,
609  co);
610  if (fast_dict_like_lv) {
611  return fast_dict_like_lv;
612  }
613  const auto& ti = expr->get_arg()->get_type_info();
614  CHECK(ti.is_string());
615  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
616  throw WatchdogException(
617  "Cannot do LIKE / ILIKE on this dictionary encoded column, its cardinality is "
618  "too high");
619  }
620  auto str_lv = codegen(expr->get_arg(), true, co);
621  if (str_lv.size() != 3) {
622  CHECK_EQ(size_t(1), str_lv.size());
623  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 0));
624  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 1));
625  str_lv.back() = cgen_state_->ir_builder_.CreateTrunc(
626  str_lv.back(), llvm::Type::getInt32Ty(cgen_state_->context_));
628  throw QueryMustRunOnCpu();
629  }
630  }
631  auto like_expr_arg_lvs = codegen(expr->get_like_expr(), true, co);
632  CHECK_EQ(size_t(3), like_expr_arg_lvs.size());
633  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
634  std::vector<llvm::Value*> str_like_args{str_lv[1],
635  str_lv[2],
636  like_expr_arg_lvs[1],
637  like_expr_arg_lvs[2],
638  cgen_state_->llInt(int8_t(escape_char))};
639  std::string fn_name{expr->get_is_ilike() ? "string_ilike" : "string_like"};
640  if (expr->get_is_simple()) {
641  fn_name += "_simple";
642  }
643  if (is_nullable) {
644  fn_name += "_nullable";
645  str_like_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
646  }
647  return cgen_state_->emitCall(fn_name, str_like_args);
648 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const Expr * get_escape_expr() const
Definition: Analyzer.h:1064
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:222
const Expr * get_arg() const
Definition: Analyzer.h:1061
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
bool g_enable_watchdog
bool get_is_simple() const
Definition: Analyzer.h:1066
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_like_expr() const
Definition: Analyzer.h:1063
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:1062
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1677
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
bool get_is_ilike() const
Definition: Analyzer.h:1065
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 845 of file StringOpsIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CHECK_EQ, codegen(), codegenDictRegexp(), CgenState::context_, CompilationOptions::device_type, CgenState::emitExternalCall(), extract_cast_arg(), g_enable_watchdog, Analyzer::RegexpExpr::get_arg(), Analyzer::RegexpExpr::get_escape_expr(), get_int_type(), SQLTypeInfo::get_notnull(), Analyzer::RegexpExpr::get_own_arg(), Analyzer::RegexpExpr::get_pattern_expr(), Analyzer::Expr::get_type_info(), GPU, CgenState::inlineIntNull(), CgenState::ir_builder_, is_unnest(), kENCODING_NONE, and CgenState::llInt().

846  {
848  if (is_unnest(extract_cast_arg(expr->get_arg()))) {
849  throw std::runtime_error("REGEXP not supported for unnested expressions");
850  }
851  char escape_char{'\\'};
852  if (expr->get_escape_expr()) {
853  auto escape_char_expr =
854  dynamic_cast<const Analyzer::Constant*>(expr->get_escape_expr());
855  CHECK(escape_char_expr);
856  CHECK(escape_char_expr->get_type_info().is_string());
857  CHECK_EQ(size_t(1), escape_char_expr->get_constval().stringval->size());
858  escape_char = (*escape_char_expr->get_constval().stringval)[0];
859  }
860  auto pattern = dynamic_cast<const Analyzer::Constant*>(expr->get_pattern_expr());
861  CHECK(pattern);
862  auto fast_dict_pattern_lv =
863  codegenDictRegexp(expr->get_own_arg(), pattern, escape_char, co);
864  if (fast_dict_pattern_lv) {
865  return fast_dict_pattern_lv;
866  }
867  const auto& ti = expr->get_arg()->get_type_info();
868  CHECK(ti.is_string());
869  if (g_enable_watchdog && ti.get_compression() != kENCODING_NONE) {
870  throw WatchdogException(
871  "Cannot do REGEXP_LIKE on this dictionary encoded column, its cardinality is too "
872  "high");
873  }
874  // Now we know we are working on NONE ENCODED column. So switch back to CPU
876  throw QueryMustRunOnCpu();
877  }
878  auto str_lv = codegen(expr->get_arg(), true, co);
879  if (str_lv.size() != 3) {
880  CHECK_EQ(size_t(1), str_lv.size());
881  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 0));
882  str_lv.push_back(cgen_state_->ir_builder_.CreateExtractValue(str_lv.front(), 1));
883  str_lv.back() = cgen_state_->ir_builder_.CreateTrunc(
884  str_lv.back(), llvm::Type::getInt32Ty(cgen_state_->context_));
885  }
886  auto regexp_expr_arg_lvs = codegen(expr->get_pattern_expr(), true, co);
887  CHECK_EQ(size_t(3), regexp_expr_arg_lvs.size());
888  const bool is_nullable{!expr->get_arg()->get_type_info().get_notnull()};
889  std::vector<llvm::Value*> regexp_args{
890  str_lv[1], str_lv[2], regexp_expr_arg_lvs[1], regexp_expr_arg_lvs[2]};
891  std::string fn_name("regexp_like");
892  regexp_args.push_back(cgen_state_->llInt(int8_t(escape_char)));
893  if (is_nullable) {
894  fn_name += "_nullable";
895  regexp_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
897  fn_name, get_int_type(8, cgen_state_->context_), regexp_args);
898  }
900  fn_name, get_int_type(1, cgen_state_->context_), regexp_args);
901 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const std::shared_ptr< Analyzer::Expr > get_own_arg() const
Definition: Analyzer.h:1134
CgenState * cgen_state_
const Expr * get_escape_expr() const
Definition: Analyzer.h:1136
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
const Expr * get_arg() const
Definition: Analyzer.h:1133
const Analyzer::Expr * extract_cast_arg(const Analyzer::Expr *expr)
Definition: Execute.h:222
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
bool g_enable_watchdog
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:79
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_pattern_expr() const
Definition: Analyzer.h:1135
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
bool is_unnest(const Analyzer::Expr *expr)
Definition: Execute.h:1677
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398

+ 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  if (auto alloca = llvm::dyn_cast<llvm::AllocaInst>(arr_lv.front())) {
79  if (alloca->getAllocatedType()->isStructTy()) {
80  throw std::runtime_error("Unsupported type used in 'cardinality'");
81  }
82  }
83 
84  std::vector<llvm::Value*> array_size_args{
85  arr_lv.front(),
86  posArg(arr_expr),
87  cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))};
88  const bool is_nullable{!arr_expr->get_type_info().get_notnull()};
89  if (is_nullable) {
90  fn_name += "_nullable";
91  array_size_args.push_back(cgen_state_->inlineIntNull(expr->get_type_info()));
92  }
94  fn_name, get_int_type(32, cgen_state_->context_), array_size_args);
95 }
CgenState * cgen_state_
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:590
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:198
const Expr * get_arg() const
Definition: Analyzer.h:1007

+ Here is the call graph for this function:

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

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

235  {
237  const auto optype = bin_oper->get_optype();
238  if (IS_ARITHMETIC(optype)) {
239  return codegenArith(bin_oper, co);
240  }
241  if (IS_COMPARISON(optype)) {
242  return codegenCmp(bin_oper, co);
243  }
244  if (IS_LOGIC(optype)) {
245  return codegenLogical(bin_oper, co);
246  }
247  if (optype == kARRAY_AT) {
248  return codegenArrayAt(bin_oper, co);
249  }
250  abort();
251 }
#define IS_LOGIC(X)
Definition: sqldefs.h:64
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:452
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define IS_ARITHMETIC(X)
Definition: sqldefs.h:65
llvm::Value * codegenCmp(const Analyzer::BinOper *, const CompilationOptions &)
Definition: CompareIR.cpp:230
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:299
#define IS_COMPARISON(X)
Definition: sqldefs.h:61

+ Here is the call graph for this function:

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

Definition at line 253 of file IRCodegen.cpp.

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

254  {
256  const auto optype = u_oper->get_optype();
257  switch (optype) {
258  case kNOT: {
259  return codegenLogical(u_oper, co);
260  }
261  case kCAST: {
262  return codegenCast(u_oper, co);
263  }
264  case kUMINUS: {
265  return codegenUMinus(u_oper, co);
266  }
267  case kISNULL: {
268  return codegenIsNull(u_oper, co);
269  }
270  case kUNNEST:
271  return codegenUnnest(u_oper, co);
272  default:
273  UNREACHABLE();
274  }
275  return nullptr;
276 }
CgenState * cgen_state_
#define UNREACHABLE()
Definition: Logger.h:338
Definition: sqldefs.h:51
llvm::Value * codegenIsNull(const Analyzer::UOper *, const CompilationOptions &)
Definition: LogicalIR.cpp:381
#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:299
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:21
Definition: sqldefs.h:41
SQLOps get_optype() const
Definition: Analyzer.h:383

+ 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 219 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(), 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().

225  {
227  CHECK_EQ(lhs_lv->getType(), rhs_lv->getType());
228  CHECK(ti.is_integer() || ti.is_decimal() || ti.is_timeinterval());
229  llvm::Value* chosen_max{nullptr};
230  llvm::Value* chosen_min{nullptr};
231  std::tie(chosen_max, chosen_min) = cgen_state_->inlineIntMaxMin(ti.get_size(), true);
232  auto need_overflow_check =
233  !checkExpressionRanges(bin_oper,
234  static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue(),
235  static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue());
236 
237  if (need_overflow_check && co.device_type == ExecutorDeviceType::CPU) {
239  bin_oper, lhs_lv, rhs_lv, null_check_suffix, ti);
240  }
241 
242  llvm::BasicBlock* add_ok{nullptr};
243  llvm::BasicBlock* add_fail{nullptr};
244  if (need_overflow_check) {
246  add_ok = llvm::BasicBlock::Create(
248  if (!null_check_suffix.empty()) {
249  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, add_ok, ti);
250  }
251  add_fail = llvm::BasicBlock::Create(
253  llvm::Value* detected{nullptr};
254  auto const_zero = llvm::ConstantInt::get(lhs_lv->getType(), 0, true);
255  auto overflow = cgen_state_->ir_builder_.CreateAnd(
256  cgen_state_->ir_builder_.CreateICmpSGT(lhs_lv, const_zero),
257  cgen_state_->ir_builder_.CreateICmpSGT(
258  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_max, lhs_lv)));
259  auto underflow = cgen_state_->ir_builder_.CreateAnd(
260  cgen_state_->ir_builder_.CreateICmpSLT(lhs_lv, const_zero),
261  cgen_state_->ir_builder_.CreateICmpSLT(
262  rhs_lv, cgen_state_->ir_builder_.CreateSub(chosen_min, lhs_lv)));
263  detected = cgen_state_->ir_builder_.CreateOr(overflow, underflow);
264  cgen_state_->ir_builder_.CreateCondBr(detected, add_fail, add_ok);
265  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
266  }
267  auto ret = null_check_suffix.empty()
268  ? cgen_state_->ir_builder_.CreateAdd(lhs_lv, rhs_lv)
270  "add_" + null_typename + null_check_suffix,
271  {lhs_lv, rhs_lv, cgen_state_->llInt(inline_int_null_val(ti))});
272  if (need_overflow_check) {
273  cgen_state_->ir_builder_.SetInsertPoint(add_fail);
274  cgen_state_->ir_builder_.CreateRet(
275  cgen_state_->llInt(int32_t(ErrorCode::OVERFLOW_OR_UNDERFLOW)));
276  cgen_state_->ir_builder_.SetInsertPoint(add_ok);
277  }
278  return ret;
279 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
HOST DEVICE int get_size() const
Definition: sqltypes.h:403
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
bool is_integer() const
Definition: sqltypes.h:567
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)
bool is_timeinterval() const
Definition: sqltypes.h:594
bool needs_error_check_
Definition: CgenState.h:405
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
ExecutorDeviceType device_type
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
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:570
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:121

+ 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 38 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(), and codegenLinRegPredict().

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

+ 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:301
CgenState * cgen_state_
const Expr * get_right_operand() const
Definition: Analyzer.h:456
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:590
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string to_string(char const *&&v)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
#define CHECK(condition)
Definition: Logger.h:291
const Expr * get_left_operand() const
Definition: Analyzer.h:455
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:104

+ 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 685 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().

689  {
691  const auto elem_ti =
692  SQLTypeInfo(
693  SQLTypes::kARRAY, 0, 0, false, EncodingType::kENCODING_NONE, 0, array_type)
694  .get_elem_type();
695 
696  auto buff = cgen_state_->emitExternalCall(
697  "array_buff", llvm::Type::getInt32PtrTy(cgen_state_->context_), {chunk, row_pos});
698 
699  auto len = cgen_state_->emitExternalCall(
700  "array_size",
702  {chunk, row_pos, cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))});
703 
704  if (cast_and_extend) {
705  buff = castArrayPointer(buff, elem_ti);
706  len =
707  cgen_state_->ir_builder_.CreateZExt(len, get_int_type(64, cgen_state_->context_));
708  }
709 
710  return std::make_pair(buff, len);
711 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
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:382
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.cpp:395
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:198
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:977

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

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, 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(), kENCODING_GEOINT, CgenState::llFp(), and CgenState::llInt().

Referenced by codegen().

99  {
101  using ValueVector = std::vector<llvm::Value*>;
102  ValueVector argument_list;
103  auto& ir_builder(cgen_state_->ir_builder_);
104 
105  const auto& return_type = array_expr->get_type_info();
106  auto coord_compression = (return_type.get_compression() == kENCODING_GEOINT);
107  if (coord_compression) {
108  CHECK(array_expr->isLocalAlloc() && array_expr->getElementCount() == 2);
109  }
110  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
111  const auto arg = array_expr->getElement(i);
112  const auto arg_lvs = codegen(arg, true, co);
113  if (arg_lvs.size() == 1) {
114  if (coord_compression) {
115  // Compress double coords on the fly
116  auto mult = cgen_state_->llFp(2147483647.0 / (i == 0 ? 180.0 : 90.0));
117  auto c = ir_builder.CreateCast(llvm::Instruction::CastOps::FPToSI,
118  ir_builder.CreateFMul(arg_lvs.front(), mult),
120  argument_list.push_back(c);
121  } else {
122  argument_list.push_back(arg_lvs.front());
123  }
124  } else {
125  throw std::runtime_error(
126  "Unexpected argument count during array[] code generation.");
127  }
128  }
129 
130  auto array_element_size_bytes =
131  return_type.get_elem_type().get_array_context_logical_size();
132  auto* array_index_type =
133  get_int_type(array_element_size_bytes * 8, cgen_state_->context_);
134  auto* array_type = get_int_array_type(
135  array_element_size_bytes * 8, array_expr->getElementCount(), cgen_state_->context_);
136 
137  if (array_expr->isNull()) {
138  return {llvm::ConstantPointerNull::get(
139  llvm::PointerType::get(get_int_type(64, cgen_state_->context_), 0)),
140  cgen_state_->llInt(0)};
141  }
142 
143  if (0 == array_expr->getElementCount()) {
144  llvm::Constant* dead_const = cgen_state_->llInt(0xdead);
145  llvm::Value* dead_pointer = llvm::ConstantExpr::getIntToPtr(
146  dead_const, llvm::PointerType::get(get_int_type(64, cgen_state_->context_), 0));
147  return {dead_pointer, cgen_state_->llInt(0)};
148  }
149 
150  llvm::Value* allocated_target_buffer;
151  if (array_expr->isLocalAlloc()) {
152  allocated_target_buffer = ir_builder.CreateAlloca(array_type);
153  } else {
155  throw QueryMustRunOnCpu();
156  }
157 
158  allocated_target_buffer =
159  cgen_state_->emitExternalCall("allocate_varlen_buffer",
160  llvm::Type::getInt8PtrTy(cgen_state_->context_),
161  {cgen_state_->llInt(array_expr->getElementCount()),
162  cgen_state_->llInt(array_element_size_bytes)});
164  "register_buffer_with_executor_rsm",
165  llvm::Type::getVoidTy(cgen_state_->context_),
166  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
167  allocated_target_buffer});
168  }
169  llvm::Value* casted_allocated_target_buffer =
170  ir_builder.CreatePointerCast(allocated_target_buffer, array_type->getPointerTo());
171 
172  for (size_t i = 0; i < array_expr->getElementCount(); i++) {
173  auto* element = argument_list[i];
174  auto* element_ptr = ir_builder.CreateGEP(
175  array_type,
176  casted_allocated_target_buffer,
177  std::vector<llvm::Value*>{cgen_state_->llInt(0), cgen_state_->llInt(i)});
178 
179  const auto& elem_ti = return_type.get_elem_type();
180  if (elem_ti.is_boolean()) {
181  const auto byte_casted_bit =
182  ir_builder.CreateIntCast(element, array_index_type, true);
183  ir_builder.CreateStore(byte_casted_bit, element_ptr);
184  } else if (elem_ti.is_fp()) {
185  switch (elem_ti.get_size()) {
186  case sizeof(double): {
187  const auto double_element_ptr = ir_builder.CreatePointerCast(
188  element_ptr, llvm::Type::getDoublePtrTy(cgen_state_->context_));
189  ir_builder.CreateStore(element, double_element_ptr);
190  break;
191  }
192  case sizeof(float): {
193  const auto float_element_ptr = ir_builder.CreatePointerCast(
194  element_ptr, llvm::Type::getFloatPtrTy(cgen_state_->context_));
195  ir_builder.CreateStore(element, float_element_ptr);
196  break;
197  }
198  default:
199  UNREACHABLE();
200  }
201  } else if (elem_ti.is_integer() || elem_ti.is_decimal() || elem_ti.is_date() ||
202  elem_ti.is_timestamp() || elem_ti.is_time() || elem_ti.is_timeinterval() ||
203  elem_ti.is_dict_encoded_string()) {
204  // TODO(adb): this validation and handling should be done elsewhere
205  const auto sign_extended_element = ir_builder.CreateSExt(element, array_index_type);
206  ir_builder.CreateStore(sign_extended_element, element_ptr);
207  } else {
208  throw std::runtime_error("Unsupported type used in ARRAY construction.");
209  }
210  }
211 
212  return {ir_builder.CreateGEP(
213  array_type, casted_allocated_target_buffer, cgen_state_->llInt(0)),
214  cgen_state_->llInt(array_expr->getElementCount())};
215 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
#define UNREACHABLE()
Definition: Logger.h:338
bool isNull() const
Definition: Analyzer.h:3025
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:253
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
size_t getElementCount() const
Definition: Analyzer.h:3023
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
bool isLocalAlloc() const
Definition: Analyzer.h:3024
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
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:3027
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 728 of file ArithmeticIR.cpp.

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

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

733  {
736 
737  llvm::BasicBlock* check_ok = llvm::BasicBlock::Create(
739  llvm::BasicBlock* check_fail = llvm::BasicBlock::Create(
740  cgen_state_->context_, "ovf_detected", cgen_state_->current_func_);
741  llvm::BasicBlock* null_check{nullptr};
742 
743  if (!null_check_suffix.empty()) {
744  null_check = cgen_state_->ir_builder_.GetInsertBlock();
745  codegenSkipOverflowCheckForNull(lhs_lv, rhs_lv, check_ok, ti);
746  }
747 
748  // Compute result and overflow flag
749  auto func = getArithWithOverflowIntrinsic(bin_oper, lhs_lv->getType());
750  auto ret_and_overflow = cgen_state_->ir_builder_.CreateCall(
751  func, std::vector<llvm::Value*>{lhs_lv, rhs_lv});
752  auto ret = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
753  std::vector<unsigned>{0});
754  auto overflow = cgen_state_->ir_builder_.CreateExtractValue(ret_and_overflow,
755  std::vector<unsigned>{1});
756  auto val_bb = cgen_state_->ir_builder_.GetInsertBlock();
757 
758  // Return error on overflow
759  cgen_state_->ir_builder_.CreateCondBr(overflow, check_fail, check_ok);
760  cgen_state_->ir_builder_.SetInsertPoint(check_fail);
761  cgen_state_->ir_builder_.CreateRet(
762  cgen_state_->llInt(int32_t(ErrorCode::OVERFLOW_OR_UNDERFLOW)));
763 
764  cgen_state_->ir_builder_.SetInsertPoint(check_ok);
765 
766  // In case of null check we have to use NULL result on check fail
767  if (null_check) {
768  auto phi = cgen_state_->ir_builder_.CreatePHI(ret->getType(), 2);
769  phi->addIncoming(llvm::ConstantInt::get(ret->getType(), inline_int_null_val(ti)),
770  null_check);
771  phi->addIncoming(ret, val_bb);
772  ret = phi;
773  }
774 
775  return ret;
776 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
void codegenSkipOverflowCheckForNull(llvm::Value *lhs_lv, llvm::Value *rhs_lv, llvm::BasicBlock *no_overflow_bb, const SQLTypeInfo &ti)
bool needs_error_check_
Definition: CgenState.h:405
#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:249
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::codegenBoundingBoxIntersect ( const SQLOps  optype,
const SQLQualifier  qualifier,
const std::shared_ptr< Analyzer::Expr lhs,
const std::shared_ptr< Analyzer::Expr rhs,
const CompilationOptions co 
)
private

Definition at line 285 of file CompareIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, codegenFunctionOper(), CgenState::context_, g_enable_bbox_intersect_hashjoin, get_int_type(), Catalog_Namespace::get_metadata_for_column(), Datum::intval, IS_GEO_POLY, kBOOLEAN, kDOUBLE, kENCODING_GEOINT, kINT, kPOINT, and VLOG.

Referenced by codegenCmp().

290  {
292  const auto lhs_ti = lhs->get_type_info();
294  // failed to build a suitable hash table. short circuit the bounding box interesect
295  // expression by always returning true. this will fall into the ST_Contains check,
296  // which will do bounding box intersection before the heavier contains computation.
297  VLOG(1) << "Failed to build bounding box intersect hash table, short circuiting "
298  "bounding box intersect operator.";
299  return llvm::ConstantInt::get(get_int_type(8, cgen_state_->context_), true);
300  }
301  // TODO(adb): we should never get here, but going to leave this in place for now since
302  // it will likely be useful in factoring the bounds check out of ST_Contains
303  CHECK(lhs_ti.is_geometry());
304 
305  if (lhs_ti.is_geometry()) {
306  // only point in linestring/poly/mpoly is currently supported
307  CHECK(lhs_ti.get_type() == kPOINT);
308  const auto lhs_col = dynamic_cast<Analyzer::ColumnVar*>(lhs.get());
309  CHECK(lhs_col);
310 
311  // Get the actual point data column descriptor
312  auto lhs_column_key = lhs_col->getColumnKey();
313  lhs_column_key.column_id = lhs_column_key.column_id + 1;
314  const auto coords_cd = Catalog_Namespace::get_metadata_for_column(lhs_column_key);
315  CHECK(coords_cd);
316 
317  std::vector<std::shared_ptr<Analyzer::Expr>> geoargs;
318  geoargs.push_back(makeExpr<Analyzer::ColumnVar>(
319  coords_cd->columnType,
320  shared::ColumnKey{lhs_col->getTableKey(), coords_cd->columnId},
321  lhs_col->get_rte_idx()));
322 
323  Datum input_compression;
324  input_compression.intval =
325  (lhs_ti.get_compression() == kENCODING_GEOINT && lhs_ti.get_comp_param() == 32)
326  ? 1
327  : 0;
328  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_compression));
329  Datum input_srid;
330  input_srid.intval = lhs_ti.get_input_srid();
331  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, input_srid));
332  Datum output_srid;
333  output_srid.intval = lhs_ti.get_output_srid();
334  geoargs.push_back(makeExpr<Analyzer::Constant>(kINT, false, output_srid));
335 
336  const auto x_ptr_oper = makeExpr<Analyzer::FunctionOper>(
337  SQLTypeInfo(kDOUBLE, true), "ST_X_Point", geoargs);
338  const auto y_ptr_oper = makeExpr<Analyzer::FunctionOper>(
339  SQLTypeInfo(kDOUBLE, true), "ST_Y_Point", geoargs);
340 
341  const auto rhs_ti = rhs->get_type_info();
342  CHECK(IS_GEO_POLY(rhs_ti.get_type()));
343  const auto rhs_col = dynamic_cast<Analyzer::ColumnVar*>(rhs.get());
344  CHECK(rhs_col);
345 
346  auto rhs_column_key = rhs_col->getColumnKey();
347  rhs_column_key.column_id =
348  rhs_column_key.column_id + rhs_ti.get_physical_coord_cols() + 1;
349  const auto poly_bounds_cd =
351  CHECK(poly_bounds_cd);
352 
353  auto bbox_col_var = makeExpr<Analyzer::ColumnVar>(
354  poly_bounds_cd->columnType,
355  shared::ColumnKey{rhs_col->getTableKey(), poly_bounds_cd->columnId},
356  rhs_col->get_rte_idx());
357 
358  const auto bbox_contains_func_oper =
359  makeExpr<Analyzer::FunctionOper>(SQLTypeInfo(kBOOLEAN, false),
360  "Point_Overlaps_Box",
361  std::vector<std::shared_ptr<Analyzer::Expr>>{
362  bbox_col_var, x_ptr_oper, y_ptr_oper});
363 
364  return codegenFunctionOper(bbox_contains_func_oper.get(), co);
365  }
366 
367  CHECK(false) << "Unsupported type for bounding box intersect operator: "
368  << lhs_ti.get_type_name();
369  return nullptr;
370 }
CgenState * cgen_state_
const ColumnDescriptor * get_metadata_for_column(const ::shared::ColumnKey &column_key)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
int32_t intval
Definition: Datum.h:75
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Value * codegenFunctionOper(const Analyzer::FunctionOper *, const CompilationOptions &)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
bool g_enable_bbox_intersect_hashjoin
Definition: Execute.cpp:109
#define CHECK(condition)
Definition: Logger.h:291
Definition: sqltypes.h:72
Definition: Datum.h:71
#define VLOG(n)
Definition: Logger.h:388
#define IS_GEO_POLY(T)
Definition: sqltypes.h:315

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void CodeGenerator::codegenBufferArgs ( const std::string &  udf_func_name,
size_t  param_num,
llvm::Value *  buffer_buf,
llvm::Value *  buffer_size,
llvm::Value *  buffer_is_null,
std::vector< llvm::Value * > &  output_args 
)
private

Definition at line 713 of file ExtensionsIR.cpp.

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

Referenced by codegenFunctionOperCastArgs().

718  {
720  CHECK(buffer_buf);
721  CHECK(buffer_size);
722 
723  auto buffer_abstraction = get_buffer_struct_type(
724  cgen_state_, ext_func_name, param_num, buffer_buf->getType());
725  auto alloc_mem = cgen_state_->ir_builder_.CreateAlloca(buffer_abstraction);
726 
727  auto buffer_buf_ptr =
728  cgen_state_->ir_builder_.CreateStructGEP(buffer_abstraction, alloc_mem, 0);
729  cgen_state_->ir_builder_.CreateStore(buffer_buf, buffer_buf_ptr);
730 
731  auto buffer_size_ptr =
732  cgen_state_->ir_builder_.CreateStructGEP(buffer_abstraction, alloc_mem, 1);
733  cgen_state_->ir_builder_.CreateStore(buffer_size, buffer_size_ptr);
734 
735  auto bool_extended_type = llvm::Type::getInt8Ty(cgen_state_->context_);
736  auto buffer_null_extended =
737  cgen_state_->ir_builder_.CreateZExt(buffer_null, bool_extended_type);
738  auto buffer_is_null_ptr =
739  cgen_state_->ir_builder_.CreateStructGEP(buffer_abstraction, alloc_mem, 2);
740  cgen_state_->ir_builder_.CreateStore(buffer_null_extended, buffer_is_null_ptr);
741  output_args.push_back(alloc_mem);
742 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::StructType * get_buffer_struct_type(CgenState *cgen_state, const std::string &ext_func_name, size_t param_num, llvm::Type *elem_type)
llvm::LLVMContext & context_
Definition: CgenState.h:382
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define CHECK(condition)
Definition: Logger.h:291

+ 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 65 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().

68  {
70  // Here the linear control flow will diverge and expressions cached during the
71  // code branch code generation (currently just column decoding) are not going
72  // to be available once we're done generating the case. Take a snapshot of
73  // the cache with FetchCacheAnchor and restore it once we're done with CASE.
75  const auto& expr_pair_list = case_expr->get_expr_pair_list();
76  std::vector<llvm::Value*> then_lvs;
77  std::vector<llvm::BasicBlock*> then_bbs;
78  const auto end_bb = llvm::BasicBlock::Create(
80  for (const auto& expr_pair : expr_pair_list) {
82  const auto when_lv = toBool(codegen(expr_pair.first.get(), true, co).front());
83  const auto cmp_bb = cgen_state_->ir_builder_.GetInsertBlock();
84  const auto then_bb = llvm::BasicBlock::Create(cgen_state_->context_,
85  "then_case",
87  /*insert_before=*/end_bb);
88  cgen_state_->ir_builder_.SetInsertPoint(then_bb);
89  auto then_bb_lvs = codegen(expr_pair.second.get(), true, co);
90  if (is_real_str) {
91  if (then_bb_lvs.size() == 3) {
92  then_lvs.push_back(
93  cgen_state_->emitCall("string_pack", {then_bb_lvs[1], then_bb_lvs[2]}));
94  } else {
95  then_lvs.push_back(then_bb_lvs.front());
96  }
97  } else {
98  CHECK_EQ(size_t(1), then_bb_lvs.size());
99  then_lvs.push_back(then_bb_lvs.front());
100  }
101  then_bbs.push_back(cgen_state_->ir_builder_.GetInsertBlock());
102  cgen_state_->ir_builder_.CreateBr(end_bb);
103  const auto when_bb = llvm::BasicBlock::Create(
105  cgen_state_->ir_builder_.SetInsertPoint(cmp_bb);
106  cgen_state_->ir_builder_.CreateCondBr(when_lv, then_bb, when_bb);
107  cgen_state_->ir_builder_.SetInsertPoint(when_bb);
108  }
109  const auto else_expr = case_expr->get_else_expr();
110  CHECK(else_expr);
111  auto else_lvs = codegen(else_expr, true, co);
112  llvm::Value* else_lv{nullptr};
113  if (else_lvs.size() == 3) {
114  else_lv = cgen_state_->emitCall("string_pack", {else_lvs[1], else_lvs[2]});
115  } else {
116  else_lv = else_lvs.front();
117  }
118  CHECK(else_lv);
119  auto else_bb = cgen_state_->ir_builder_.GetInsertBlock();
120  cgen_state_->ir_builder_.CreateBr(end_bb);
121  cgen_state_->ir_builder_.SetInsertPoint(end_bb);
122  auto then_phi =
123  cgen_state_->ir_builder_.CreatePHI(case_llvm_type, expr_pair_list.size() + 1);
124  CHECK_EQ(then_bbs.size(), then_lvs.size());
125  for (size_t i = 0; i < then_bbs.size(); ++i) {
126  then_phi->addIncoming(then_lvs[i], then_bbs[i]);
127  }
128  then_phi->addIncoming(else_lv, else_bb);
129  return then_phi;
130 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const Expr * get_else_expr() const
Definition: Analyzer.h:1387
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:344
#define CHECK(condition)
Definition: Logger.h:291
const std::list< std::pair< std::shared_ptr< Analyzer::Expr >, std::shared_ptr< Analyzer::Expr > > > & get_expr_pair_list() const
Definition: Analyzer.h:1384

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

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK_EQ, codegen(), CgenState::context_, CgenState::emitCall(), executor_, get_int_type(), Analyzer::UOper::get_operand(), Analyzer::UOper::get_optype(), Analyzer::Expr::get_type_info(), CgenState::ir_builder_, and kCAST.

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

22  {
24  CHECK_EQ(uoper->get_optype(), kCAST);
25  const auto& ti = uoper->get_type_info();
26  const auto operand = uoper->get_operand();
27  const auto operand_as_const = dynamic_cast<const Analyzer::Constant*>(operand);
28  // For dictionary encoded constants, the cast holds the dictionary id
29  // information as the compression parameter; handle this case separately.
30  llvm::Value* operand_lv{nullptr};
31  if (operand_as_const) {
32  const auto operand_lvs =
33  codegen(operand_as_const, ti.get_compression(), ti.getStringDictKey(), co);
34  if (operand_lvs.size() == 3) {
35  operand_lv = cgen_state_->emitCall("string_pack", {operand_lvs[1], operand_lvs[2]});
36  } else {
37  operand_lv = operand_lvs.front();
38  }
39  } else {
40  operand_lv = codegen(operand, true, co).front();
41  }
42 
43  // If the operand is a TextEncodingNone struct ({i8*, i64, i8})
44  // unpack it into an int64_t using "string_pack" so that codegenCast
45  // can properly cast it to a TextEncodingDict
46  if (operand_lv->getType()->isPointerTy() &&
47  operand_lv->getType()->getPointerElementType()->isStructTy()) {
48  auto _struct = cgen_state_->ir_builder_.CreateLoad(
49  operand_lv->getType()->getPointerElementType(), operand_lv);
50  auto ptr = cgen_state_->ir_builder_.CreateExtractValue(_struct, {0});
51  auto len = cgen_state_->ir_builder_.CreateTrunc(
52  cgen_state_->ir_builder_.CreateExtractValue(_struct, {1}),
54  executor_->cgen_state_->emitExternalCall(
55  "register_buffer_with_executor_rsm",
56  llvm::Type::getVoidTy(executor_->cgen_state_->context_),
57  {executor_->cgen_state_->llInt(reinterpret_cast<int64_t>(executor_)), ptr});
58  operand_lv = cgen_state_->emitCall("string_pack", {ptr, len});
59  }
60  const auto& operand_ti = operand->get_type_info();
61  return codegenCast(operand_lv, operand_ti, ti, operand_as_const, co);
62 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
Definition: sqldefs.h:51
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
Executor * executor_
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
const Expr * get_operand() const
Definition: Analyzer.h:384
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:21
SQLOps get_optype() const
Definition: Analyzer.h:383

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

References AUTOMATIC_IR_METADATA, anonymous_namespace{CastIR.cpp}::byte_array_cast(), CgenState::castToTypeIn(), cgen_state_, CHECK, codegenCastBetweenIntTypes(), codegenCastBetweenTimestamps(), codegenCastFromFp(), codegenCastFromString(), codegenCastNonStringToString(), codegenCastTimestampToDate(), codegenCastTimestampToTime(), 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_text_encoding_dict(), SQLTypeInfo::is_time(), SQLTypeInfo::is_timestamp(), kDATE, kTIME, and kTIMESTAMP.

77  {
79  if (byte_array_cast(operand_ti, ti)) {
80  auto* byte_array_type = get_int_array_type(8, ti.get_size(), cgen_state_->context_);
81  return cgen_state_->ir_builder_.CreatePointerCast(operand_lv,
82  byte_array_type->getPointerTo());
83  } else if (!operand_ti.is_string() && ti.is_text_encoding_dict()) {
84  return codegenCastNonStringToString(operand_lv, operand_ti, ti, operand_is_const, co);
85  } else if (operand_ti.is_string()) {
86  return codegenCastFromString(operand_lv, operand_ti, ti, operand_is_const, co);
87  } else if (operand_lv->getType()->isIntegerTy()) {
88  CHECK(operand_ti.is_integer() || operand_ti.is_decimal() || operand_ti.is_time() ||
89  operand_ti.is_boolean());
90 
91  if (operand_ti.is_boolean()) {
92  // cast boolean to int8
93  CHECK(operand_lv->getType()->isIntegerTy(1) ||
94  operand_lv->getType()->isIntegerTy(8));
95  if (operand_lv->getType()->isIntegerTy(1)) {
96  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
97  }
98  if (ti.is_boolean()) {
99  return operand_lv;
100  }
101  }
102  if (operand_ti.is_integer() && operand_lv->getType()->isIntegerTy(8) &&
103  ti.is_boolean()) {
104  // cast int8 to boolean
105  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
106  }
107  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
108  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
109  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
110  // whereas this cast returns a date. The underlying type for both is still the same,
111  // but it still doesn't look like a good idea to misuse DatetruncExpr.
112  // Date will have default precision of day, but TIMESTAMP dimension would
113  // matter but while converting date through seconds
115  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
116  }
117  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kTIME) {
119  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
120  }
121  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
122  ti.get_type() == kTIMESTAMP) {
123  const auto operand_dimen =
124  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
125  if (operand_dimen != ti.get_dimension()) {
127  operand_lv, operand_ti, ti, !ti.get_notnull());
128  }
129  }
130  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
131  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
132  } else {
133  return codegenCastToFp(operand_lv, operand_ti, ti);
134  }
135  } else {
136  return codegenCastFromFp(operand_lv, operand_ti, ti);
137  }
138  CHECK(false);
139  return nullptr;
140 }
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:150
llvm::Value * codegenCastFromFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:601
HOST DEVICE int get_size() const
Definition: sqltypes.h:403
Definition: sqltypes.h:76
bool is_timestamp() const
Definition: sqltypes.h:1046
CgenState * cgen_state_
llvm::Value * codegenCastNonStringToString(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
Definition: CastIR.cpp:350
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:558
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:66
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
bool is_time() const
Definition: sqltypes.h:579
llvm::LLVMContext & context_
Definition: CgenState.h:382
bool is_integer() const
Definition: sqltypes.h:567
bool is_text_encoding_dict() const
Definition: sqltypes.h:617
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:427
bool is_boolean() const
Definition: sqltypes.h:582
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:162
#define AUTOMATIC_IR_METADATA(CGENSTATE)
Definition: sqltypes.h:80
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:393
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
Definition: CastIR.cpp:199
#define CHECK(condition)
Definition: Logger.h:291
llvm::Value * codegenCastTimestampToTime(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:142
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:231
bool is_string() const
Definition: sqltypes.h:561
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_decimal() const
Definition: sqltypes.h:570

+ 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 427 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(), codegenWidthBucketExpr(), and Executor::codegenWindowFunctionAggregateCalls().

430  {
432  if (ti.is_decimal() &&
433  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
434  if (upscale) {
435  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
436  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
437  const auto scale_lv =
438  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
439  operand_lv = cgen_state_->ir_builder_.CreateSExt(
440  operand_lv, get_int_type(64, cgen_state_->context_));
441 
442  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
443 
444  if (operand_ti.get_notnull()) {
445  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
446  } else {
447  operand_lv = cgen_state_->emitCall(
448  "scale_decimal_up",
449  {operand_lv,
450  scale_lv,
451  cgen_state_->llInt(inline_int_null_val(operand_ti)),
453  }
454  }
455  }
456  } else if (operand_ti.is_decimal()) {
457  // rounded scale down
458  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
459  const auto scale_lv =
460  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
461 
462  const auto operand_width =
463  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
464 
465  std::string method_name = "scale_decimal_down_nullable";
466  if (operand_ti.get_notnull()) {
467  method_name = "scale_decimal_down_not_nullable";
468  }
469 
470  CHECK(operand_width == 64);
471  operand_lv = cgen_state_->emitCall(
472  method_name,
473  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
474  }
475  if (ti.is_integer() && operand_ti.is_integer() &&
476  operand_ti.get_logical_size() > ti.get_logical_size()) {
477  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
478  }
479 
480  const auto operand_width =
481  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
482  const auto target_width = get_bit_width(ti);
483  if (target_width == operand_width) {
484  return operand_lv;
485  }
486  if (operand_ti.get_notnull()) {
487  return cgen_state_->ir_builder_.CreateCast(
488  target_width > operand_width ? llvm::Instruction::CastOps::SExt
489  : llvm::Instruction::CastOps::Trunc,
490  operand_lv,
491  get_int_type(target_width, cgen_state_->context_));
492  }
493  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
494  numeric_type_name(ti) + "_nullable",
495  {operand_lv,
496  cgen_state_->inlineIntNull(operand_ti),
497  cgen_state_->inlineIntNull(ti)});
498 }
CgenState * cgen_state_
HOST DEVICE int get_scale() const
Definition: sqltypes.h:396
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
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:382
int get_logical_size() const
Definition: sqltypes.h:421
bool is_integer() const
Definition: sqltypes.h:567
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:500
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
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:230
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
bool is_decimal() const
Definition: sqltypes.h:570

+ 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 500 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(), toBool(), and type_name().

Referenced by codegenCastBetweenIntTypes(), and codegenCastBetweenTimestamps().

504  {
506  llvm::Value* chosen_max{nullptr};
507  llvm::Value* chosen_min{nullptr};
508  std::tie(chosen_max, chosen_min) =
510 
512  auto cast_ok = llvm::BasicBlock::Create(
514  auto cast_fail = llvm::BasicBlock::Create(
516  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
517  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
518  const auto ti_llvm_type =
520  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
521  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
522  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
523  if (is_narrowing) {
524  const auto operand_ti_llvm_type =
526  operand_max_lv =
527  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
528  operand_min_lv =
529  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
530  }
531  llvm::Value* over{nullptr};
532  llvm::Value* under{nullptr};
533  if (operand_ti.get_notnull()) {
534  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
535  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
536  } else {
537  const auto type_name =
538  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
539  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
540  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
541  over = toBool(cgen_state_->emitCall(
542  "gt_" + type_name + "_nullable_lhs",
543  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
544  under = toBool(cgen_state_->emitCall(
545  "le_" + type_name + "_nullable_lhs",
546  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
547  }
548  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
549  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
550 
551  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
552  cgen_state_->ir_builder_.CreateRet(
553  cgen_state_->llInt(int32_t(heavyai::ErrorCode::OVERFLOW_OR_UNDERFLOW)));
554 
555  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
556 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Function * current_func_
Definition: CgenState.h:376
int get_logical_size() const
Definition: sqltypes.h:421
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
bool needs_error_check_
Definition: CgenState.h:405
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:344
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:230
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
constexpr auto type_name() noexcept
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:121

+ 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 
)

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

202  {
204  const auto operand_dimen = operand_ti.get_dimension();
205  const auto target_dimen = target_ti.get_dimension();
206  if (operand_dimen == target_dimen) {
207  return ts_lv;
208  }
209  CHECK(ts_lv->getType()->isIntegerTy(64));
210  const auto scale =
211  DateTimeUtils::get_timestamp_precision_scale(abs(operand_dimen - target_dimen));
212  if (operand_dimen < target_dimen) {
213  codegenCastBetweenIntTypesOverflowChecks(ts_lv, operand_ti, target_ti, scale);
214  return nullable
215  ? cgen_state_->emitCall("mul_int64_t_nullable_lhs",
216  {ts_lv,
217  cgen_state_->llInt(static_cast<int64_t>(scale)),
218  cgen_state_->inlineIntNull(operand_ti)})
219  : cgen_state_->ir_builder_.CreateMul(
220  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
221  }
222  return nullable
223  ? cgen_state_->emitCall("floor_div_nullable_lhs",
224  {ts_lv,
225  cgen_state_->llInt(static_cast<int64_t>(scale)),
226  cgen_state_->inlineIntNull(operand_ti)})
227  : cgen_state_->ir_builder_.CreateSDiv(
228  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
229 }
CgenState * cgen_state_
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:500
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:393
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
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 601 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().

603  {
605  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
606  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
607  ti.get_type_name() + " not supported");
608  }
609  if (operand_ti.get_type() == ti.get_type()) {
610  // Should not have been called when both dimensions are same.
611  return operand_lv;
612  }
613  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
614  if (operand_ti.get_notnull()) {
615  if (ti.get_type() == kDOUBLE) {
616  return cgen_state_->ir_builder_.CreateFPExt(
617  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
618  } else if (ti.get_type() == kFLOAT) {
619  return cgen_state_->ir_builder_.CreateFPTrunc(
620  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
621  } else if (ti.is_integer()) {
622  // Round by adding/subtracting 0.5 before fptosi.
623  auto* fp_type = operand_lv->getType()->isFloatTy()
624  ? llvm::Type::getFloatTy(cgen_state_->context_)
625  : llvm::Type::getDoubleTy(cgen_state_->context_);
626  auto* zero = llvm::ConstantFP::get(fp_type, 0.0);
627  auto* mhalf = llvm::ConstantFP::get(fp_type, -0.5);
628  auto* phalf = llvm::ConstantFP::get(fp_type, 0.5);
629  auto* is_negative = cgen_state_->ir_builder_.CreateFCmpOLT(operand_lv, zero);
630  auto* offset = cgen_state_->ir_builder_.CreateSelect(is_negative, mhalf, phalf);
631  operand_lv = cgen_state_->ir_builder_.CreateFAdd(operand_lv, offset);
632  return cgen_state_->ir_builder_.CreateFPToSI(
633  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
634  } else {
635  CHECK(false);
636  }
637  } else {
638  const auto from_tname = numeric_type_name(operand_ti);
639  const auto to_tname = numeric_type_name(ti);
640  if (ti.is_fp()) {
641  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
642  {operand_lv,
643  cgen_state_->inlineFpNull(operand_ti),
644  cgen_state_->inlineFpNull(ti)});
645  } else if (ti.is_integer()) {
646  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
647  {operand_lv,
648  cgen_state_->inlineFpNull(operand_ti),
649  cgen_state_->inlineIntNull(ti)});
650  } else {
651  CHECK(false);
652  }
653  }
654  CHECK(false);
655  return nullptr;
656 }
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:573
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:576
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:382
bool is_integer() const
Definition: sqltypes.h:567
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
std::string get_type_name() const
Definition: sqltypes.h:484
#define CHECK(condition)
Definition: Logger.h:291
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:230
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
bool is_decimal() const
Definition: sqltypes.h:570
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:104

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

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CHECK_EQ, StringDictionaryTranslationMgr::codegen(), CgenState::context_, CPU, Data_Namespace::CPU_LEVEL, createStringViewStructType(), CompilationOptions::device_type, shared::StringDictKey::dict_id, CgenState::emitExternalCall(), executor(), g_cluster, SQLTypeInfo::get_compression(), get_int_type(), SQLTypeInfo::get_type_name(), SQLTypeInfo::getStringDictKey(), GPU, Data_Namespace::GPU_LEVEL, SQLTypeInfo::is_dict_intersection(), SQLTypeInfo::is_string(), kENCODING_DICT, kENCODING_NONE, dict_ref_t::literalsDictId, CgenState::llInt(), and CgenState::moveStringDictionaryTranslationMgr().

Referenced by codegenCast().

235  {
237  if (!ti.is_string()) {
238  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
239  ti.get_type_name() + " not supported");
240  }
241  if (operand_ti.get_compression() == kENCODING_NONE &&
243  return operand_lv;
244  }
245  if (ti.get_compression() == kENCODING_DICT &&
246  operand_ti.get_compression() == kENCODING_DICT) {
247  if (ti.getStringDictKey() == operand_ti.getStringDictKey()) {
248  return operand_lv;
249  }
250  if (operand_ti.getStringDictKey().dict_id == DictRef::literalsDictId) {
251  // Anything being casted from a literal dictionary is not materialized at this point
252  // Should already have been kicked to CPU if it was originally a GPU query
253 
255  const int64_t source_string_proxy_handle =
256  reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
257  operand_ti.getStringDictKey(), executor()->getRowSetMemoryOwner(), true));
258 
259  const int64_t dest_string_proxy_handle =
260  reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
261  ti.getStringDictKey(), executor()->getRowSetMemoryOwner(), true));
262 
263  auto source_string_proxy_handle_lv = cgen_state_->llInt(source_string_proxy_handle);
264  auto dest_string_proxy_handle_lv = cgen_state_->llInt(dest_string_proxy_handle);
265 
266  std::vector<llvm::Value*> string_cast_lvs{
267  operand_lv, source_string_proxy_handle_lv, dest_string_proxy_handle_lv};
268  if (ti.is_dict_intersection()) {
270  "intersect_translate_string_id_to_other_dict",
272  string_cast_lvs);
273  } else {
274  return cgen_state_->emitExternalCall("union_translate_string_id_to_other_dict",
276  string_cast_lvs);
277  }
278  }
279 
280  const std::vector<StringOps_Namespace::StringOpInfo> string_op_infos;
281  auto string_dictionary_translation_mgr =
282  std::make_unique<StringDictionaryTranslationMgr>(
283  operand_ti.getStringDictKey(),
284  ti.getStringDictKey(),
286  ti,
287  string_op_infos,
290  executor()->deviceCount(co.device_type),
291  executor(),
292  executor()->getDataMgr(),
293  false /* delay_translation */);
294 
295  return cgen_state_
296  ->moveStringDictionaryTranslationMgr(std::move(string_dictionary_translation_mgr))
297  ->codegen(operand_lv, operand_ti, true /* add_nullcheck */, co);
298  }
299  // dictionary encode non-constant
300  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
301  if (g_cluster) {
302  throw std::runtime_error(
303  "Cast from none-encoded string to dictionary-encoded not supported for "
304  "distributed queries");
305  }
306  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
308  CHECK(operand_lv->getType()->isStructTy()); // StringView
310  throw QueryMustRunOnCpu();
311  }
313  "string_compress",
315  {operand_lv,
316  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
317  ti.getStringDictKey(), executor()->getRowSetMemoryOwner(), true)))});
318  }
319  CHECK(operand_lv->getType()->isIntegerTy(32));
320  if (ti.get_compression() == kENCODING_NONE) {
321  if (g_cluster) {
322  throw std::runtime_error(
323  "Cast from dictionary-encoded string to none-encoded not "
324  "currently supported for distributed queries.");
325  }
326  // Removed watchdog check here in exchange for row cardinality based check in
327  // RelAlgExecutor
328  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
330  throw QueryMustRunOnCpu();
331  }
332  const int64_t string_dictionary_ptr =
333  operand_ti.getStringDictKey().dict_id == 0
334  ? reinterpret_cast<int64_t>(
335  executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
336  : reinterpret_cast<int64_t>(
337  executor()->getStringDictionaryProxy(operand_ti.getStringDictKey(),
338  executor()->getRowSetMemoryOwner(),
339  true));
341  "string_decompress",
343  {operand_lv, cgen_state_->llInt(string_dictionary_ptr)});
344  }
345  CHECK(operand_is_const);
347  return operand_lv;
348 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
CgenState * cgen_state_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
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.cpp:395
bool is_dict_intersection() const
Definition: sqltypes.h:660
#define AUTOMATIC_IR_METADATA(CGENSTATE)
ExecutorDeviceType device_type
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:399
llvm::StructType * createStringViewStructType()
std::string get_type_name() const
Definition: sqltypes.h:484
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster
const StringDictionaryTranslationMgr * moveStringDictionaryTranslationMgr(std::unique_ptr< const StringDictionaryTranslationMgr > &&str_dict_translation_mgr)
Definition: CgenState.h:199
bool is_string() const
Definition: sqltypes.h:561
llvm::Value * codegen(llvm::Value *str_id_input, const SQLTypeInfo &input_ti, const bool add_nullcheck, const CompilationOptions &co) const
static constexpr int32_t literalsDictId
Definition: DictRef.h:18
const shared::StringDictKey & getStringDictKey() const
Definition: sqltypes.h:1057
Executor * executor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 350 of file CastIR.cpp.

References AUTOMATIC_IR_METADATA, cgen_state_, CHECK, CgenState::context_, CompilationOptions::device_type, CgenState::emitExternalCall(), executor(), g_cluster, SQLTypeInfo::get_compression(), SQLTypeInfo::get_dimension(), get_int_type(), SQLTypeInfo::get_notnull(), SQLTypeInfo::get_precision(), SQLTypeInfo::get_scale(), SQLTypeInfo::get_type(), SQLTypeInfo::getStringDictKey(), GPU, SQLTypeInfo::is_string(), kBIGINT, kBOOLEAN, kDATE, kDECIMAL, kDOUBLE, kENCODING_NONE, kFLOAT, kINT, kNUMERIC, kSMALLINT, kTIME, kTIMESTAMP, kTINYINT, CgenState::llInt(), to_lower(), and toString().

Referenced by codegenCast().

354  {
356  CHECK(!operand_ti.is_string());
357  if (ti.get_compression() == kENCODING_NONE) {
358  throw std::runtime_error("Cast to none-encoded strings currently unsupported.");
359  }
360  if (g_cluster) {
361  throw std::runtime_error(
362  "Cast to dictionary-encoded string type not supported for "
363  "distributed queries");
364  }
366  throw QueryMustRunOnCpu();
367  }
368  std::string fn_call{"convert_to_string_and_encode_"};
369  const auto operand_type = operand_ti.get_type();
370  std::vector operand_lvs{operand_lv};
371  switch (operand_type) {
372  case kBOOLEAN:
373  fn_call += "bool";
374  break;
375  case kTINYINT:
376  case kSMALLINT:
377  case kINT:
378  case kBIGINT:
379  case kFLOAT:
380  case kDOUBLE:
381  fn_call += to_lower(toString(operand_type));
382  break;
383  case kNUMERIC:
384  case kDECIMAL:
385  fn_call += "decimal";
386  operand_lvs.emplace_back(llvm::ConstantInt::get(
387  get_int_type(32, cgen_state_->context_), operand_ti.get_precision()));
388  operand_lvs.emplace_back(llvm::ConstantInt::get(
389  get_int_type(32, cgen_state_->context_), operand_ti.get_scale()));
390  break;
391  case kTIME:
392  fn_call += "time";
393  break;
394  case kTIMESTAMP:
395  fn_call += "timestamp";
396  operand_lvs.emplace_back(llvm::ConstantInt::get(
397  get_int_type(32, cgen_state_->context_), operand_ti.get_dimension()));
398  break;
399  case kDATE:
400  fn_call += "date";
401  break;
402  default:
403  throw std::runtime_error("Unimplemented type for string cast");
404  }
405  operand_lvs.emplace_back(
406  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
407  ti.getStringDictKey(), executor()->getRowSetMemoryOwner(), true))));
408 
409  auto ret = cgen_state_->emitExternalCall(
410  fn_call, get_int_type(32, cgen_state_->context_), operand_lvs);
411 
412  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
413  const bool is_nullable = !operand_ti.get_notnull();
414  if (is_nullable) {
415  nullcheck_codegen =
416  std::make_unique<NullCheckCodegen>(cgen_state_,
417  executor(),
418  operand_lvs.front(),
419  operand_ti,
420  "cast_non_string_to_string_nullcheck");
421  CHECK(nullcheck_codegen);
422  ret = nullcheck_codegen->finalize(cgen_state_->inlineNull(ti), ret);
423  }
424  return ret;
425 }
std::string to_lower(const std::string &str)