22 #include <llvm/IR/MDBuilder.h>
29 if (bin_oper && bin_oper->get_optype() ==
kDIVIDE) {
32 if (!rhs_constant || rhs_constant->get_is_null()) {
36 const auto& ti = rhs_constant->get_type_info();
41 (
type ==
kINT && datum.intval == 0) ||
50 std::list<const Analyzer::Expr*> binoper_list;
52 return !binoper_list.empty();
56 if (std::dynamic_pointer_cast<Analyzer::LikeExpr>(expr)) {
59 if (std::dynamic_pointer_cast<Analyzer::RegexpExpr>(expr)) {
62 if (std::dynamic_pointer_cast<Analyzer::FunctionOper>(expr)) {
65 if (!std::dynamic_pointer_cast<Analyzer::BinOper>(expr)) {
72 if (bin_expr->is_bbox_intersect_oper()) {
82 if (likelihood_expr) {
83 return Likelihood(likelihood_expr->get_likelihood());
91 if (u_oper->get_optype() ==
kNOT) {
92 return truth - oper_likelihood;
94 return oper_likelihood;
99 auto rhs = bin_oper->get_right_operand();
105 const auto optype = bin_oper->get_optype();
107 auto both_false = (truth - lhs_likelihood) * (truth - rhs_likelihood);
108 return truth - both_false;
110 if (optype ==
kAND) {
111 return lhs_likelihood * rhs_likelihood;
113 return (lhs_likelihood + rhs_likelihood) / 2.0;
123 return Weight((like_expr->get_is_simple()) ? 200 : 1000);
132 auto weight =
get_weight(u_oper->get_operand(), depth + 1);
138 auto rhs = bin_oper->get_right_operand();
141 if (rhs->get_type_info().is_array()) {
143 rhs_weight = rhs_weight +
Weight(100);
145 auto weight = lhs_weight + rhs_weight;
159 std::vector<Analyzer::Expr*>& primary_quals,
160 std::vector<Analyzer::Expr*>& deferred_quals,
163 if (hoisted_quals.find(expr) != hoisted_quals.end()) {
167 deferred_quals.push_back(expr.get());
170 primary_quals.push_back(expr.get());
173 bool short_circuit =
false;
175 for (
auto expr : ra_exe_unit.
quals) {
176 if (hoisted_quals.find(expr) != hoisted_quals.end()) {
181 if (!short_circuit) {
182 primary_quals.push_back(expr.get());
183 short_circuit =
true;
188 deferred_quals.push_back(expr.get());
191 primary_quals.push_back(expr.get());
194 return short_circuit;
225 auto lhs_lv =
codegen(lhs,
true, co).front();
234 auto rhs_bb = llvm::BasicBlock::Create(
236 auto ret_bb = llvm::BasicBlock::Create(
238 llvm::BasicBlock* nullcheck_ok_bb{
nullptr};
239 llvm::BasicBlock* nullcheck_fail_bb{
nullptr};
241 if (!ti.get_notnull()) {
243 nullcheck_ok_bb = llvm::BasicBlock::Create(
245 nullcheck_fail_bb = llvm::BasicBlock::Create(
247 if (lhs_lv->getType()->isIntegerTy(1)) {
253 lhs_nullcheck, nullcheck_fail_bb, nullcheck_ok_bb);
258 auto cnst_lv = llvm::ConstantInt::get(lhs_lv->getType(), (optype ==
kOR));
269 auto rhs_lv =
codegen(rhs,
true, co).front();
270 if (!ti.get_notnull()) {
272 if (rhs_lv->getType()->isIntegerTy(1)) {
283 if (!ti.get_notnull()) {
291 if (!ti.get_notnull()) {
294 result_phi->addIncoming(cnst_lv, sc_check_bb);
295 result_phi->addIncoming(rhs_lv, rhs_codegen_bb);
306 return short_circuit;
311 auto lhs_lv =
codegen(lhs,
true, co).front();
312 auto rhs_lv =
codegen(rhs,
true, co).front();
314 if (ti.get_notnull()) {
324 CHECK(lhs_lv->getType()->isIntegerTy(1) || lhs_lv->getType()->isIntegerTy(8));
325 CHECK(rhs_lv->getType()->isIntegerTy(1) || rhs_lv->getType()->isIntegerTy(8));
326 if (lhs_lv->getType()->isIntegerTy(1)) {
329 if (rhs_lv->getType()->isIntegerTy(1)) {
346 CHECK(lv->getType()->isIntegerTy());
347 if (static_cast<llvm::IntegerType*>(lv->getType())->getBitWidth() > 1) {
349 llvm::ICmpInst::ICMP_SGT, lv, llvm::ConstantInt::get(lv->getType(), 0));
370 CHECK(operand_ti.is_boolean());
371 const auto operand_lv =
codegen(operand,
true, co).front();
372 CHECK(operand_lv->getType()->isIntegerTy());
374 CHECK(not_null || operand_lv->getType()->isIntegerTy(8));
385 if (dynamic_cast<const Analyzer::Constant*>(operand) &&
386 dynamic_cast<const Analyzer::Constant*>(operand)->get_is_null()) {
390 const auto& ti = operand->get_type_info();
391 CHECK(ti.is_integer() || ti.is_boolean() || ti.is_decimal() || ti.is_time() ||
392 ti.is_string() || ti.is_fp() || ti.is_array() || ti.is_geometry());
394 if (ti.get_notnull()) {
397 llvm::Value* operand_lv =
codegen(operand,
true, co).front();
402 }
else if (ti.is_array() || ti.is_geometry()) {
406 (ti.get_type() ==
kPOINT) ?
"point_coord_array_is_null" :
"array_is_null";
409 }
else if (ti.is_none_encoded_string()) {
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
bool should_defer_eval(const std::shared_ptr< Analyzer::Expr > expr)
const Expr * get_right_operand() const
llvm::IRBuilder ir_builder_
llvm::Value * posArg(const Analyzer::Expr *) const
std::unordered_set< std::shared_ptr< Analyzer::Expr >> HoistedFiltersSet
HOST DEVICE SQLTypes get_type() const
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
static char const * pointIsNullFunctionName(SQLTypeInfo const &)
llvm::Value * codegenIsNull(const Analyzer::UOper *, const CompilationOptions &)
SQLOps get_optype() const
Likelihood get_likelihood(const Analyzer::Expr *expr)
llvm::LLVMContext & context_
llvm::Function * current_func_
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)
bool is_qualified_bin_oper(const Analyzer::Expr *expr)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Weight get_weight(const Analyzer::Expr *expr, int depth=0)
NullableValue< float > Likelihood
llvm::ConstantFP * llFp(const float v) const
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
const Expr * get_operand() const
Datum get_constval() const
llvm::Value * toBool(llvm::Value *)
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)
std::list< std::shared_ptr< Analyzer::Expr > > quals
llvm::Value * codegenIsNullNumber(llvm::Value *, const SQLTypeInfo &)
llvm::Value * codegenLogical(const Analyzer::BinOper *, const CompilationOptions &)
bool contains_unsafe_division(const Analyzer::Expr *expr)
const Expr * get_left_operand() const
llvm::Value * codegenLogicalShortCircuit(const Analyzer::BinOper *, const CompilationOptions &)
virtual void find_expr(std::function< bool(const Expr *)> f, std::list< const Expr * > &expr_list) const
DEVICE void swap(ARGS &&...args)
SQLOps get_optype() const
NullableValue< uint64_t > Weight
std::list< std::shared_ptr< Analyzer::Expr > > simple_quals
SQLQualifier get_qualifier() const