21 #include <llvm/IR/MDBuilder.h>
28 if (bin_oper && bin_oper->get_optype() ==
kDIVIDE) {
31 if (!rhs_constant || rhs_constant->get_is_null()) {
35 const auto& ti = rhs_constant->get_type_info();
40 (
type ==
kINT && datum.intval == 0) ||
49 std::list<const Analyzer::Expr*> binoper_list;
51 return !binoper_list.empty();
55 if (std::dynamic_pointer_cast<Analyzer::LikeExpr>(expr)) {
58 if (std::dynamic_pointer_cast<Analyzer::RegexpExpr>(expr)) {
61 if (std::dynamic_pointer_cast<Analyzer::FunctionOper>(expr)) {
64 if (!std::dynamic_pointer_cast<Analyzer::BinOper>(expr)) {
71 if (bin_expr->is_overlaps_oper()) {
81 if (likelihood_expr) {
82 return Likelihood(likelihood_expr->get_likelihood());
90 if (u_oper->get_optype() ==
kNOT) {
91 return truth - oper_likelihood;
93 return oper_likelihood;
98 auto rhs = bin_oper->get_right_operand();
104 const auto optype = bin_oper->get_optype();
106 auto both_false = (truth - lhs_likelihood) * (truth - rhs_likelihood);
107 return truth - both_false;
109 if (optype ==
kAND) {
110 return lhs_likelihood * rhs_likelihood;
112 return (lhs_likelihood + rhs_likelihood) / 2.0;
122 return Weight((like_expr->get_is_simple()) ? 200 : 1000);
131 auto weight =
get_weight(u_oper->get_operand(), depth + 1);
137 auto rhs = bin_oper->get_right_operand();
140 if (rhs->get_type_info().is_array()) {
142 rhs_weight = rhs_weight +
Weight(100);
144 auto weight = lhs_weight + rhs_weight;
158 std::vector<Analyzer::Expr*>& primary_quals,
159 std::vector<Analyzer::Expr*>& deferred_quals,
162 if (hoisted_quals.find(expr) != hoisted_quals.end()) {
166 deferred_quals.push_back(expr.get());
169 primary_quals.push_back(expr.get());
172 bool short_circuit =
false;
174 for (
auto expr : ra_exe_unit.
quals) {
175 if (hoisted_quals.find(expr) != hoisted_quals.end()) {
180 if (!short_circuit) {
181 primary_quals.push_back(expr.get());
182 short_circuit =
true;
187 deferred_quals.push_back(expr.get());
190 primary_quals.push_back(expr.get());
193 return short_circuit;
224 auto lhs_lv =
codegen(lhs,
true, co).front();
233 auto rhs_bb = llvm::BasicBlock::Create(
235 auto ret_bb = llvm::BasicBlock::Create(
237 llvm::BasicBlock* nullcheck_ok_bb{
nullptr};
238 llvm::BasicBlock* nullcheck_fail_bb{
nullptr};
240 if (!ti.get_notnull()) {
242 nullcheck_ok_bb = llvm::BasicBlock::Create(
244 nullcheck_fail_bb = llvm::BasicBlock::Create(
246 if (lhs_lv->getType()->isIntegerTy(1)) {
252 lhs_nullcheck, nullcheck_fail_bb, nullcheck_ok_bb);
257 auto cnst_lv = llvm::ConstantInt::get(lhs_lv->getType(), (optype ==
kOR));
268 auto rhs_lv =
codegen(rhs,
true, co).front();
269 if (!ti.get_notnull()) {
271 if (rhs_lv->getType()->isIntegerTy(1)) {
282 if (!ti.get_notnull()) {
290 if (!ti.get_notnull()) {
293 result_phi->addIncoming(cnst_lv, sc_check_bb);
294 result_phi->addIncoming(rhs_lv, rhs_codegen_bb);
305 return short_circuit;
310 auto lhs_lv =
codegen(lhs,
true, co).front();
311 auto rhs_lv =
codegen(rhs,
true, co).front();
313 if (ti.get_notnull()) {
323 CHECK(lhs_lv->getType()->isIntegerTy(1) || lhs_lv->getType()->isIntegerTy(8));
324 CHECK(rhs_lv->getType()->isIntegerTy(1) || rhs_lv->getType()->isIntegerTy(8));
325 if (lhs_lv->getType()->isIntegerTy(1)) {
328 if (rhs_lv->getType()->isIntegerTy(1)) {
345 CHECK(lv->getType()->isIntegerTy());
346 if (static_cast<llvm::IntegerType*>(lv->getType())->getBitWidth() > 1) {
348 llvm::ICmpInst::ICMP_SGT, lv, llvm::ConstantInt::get(lv->getType(), 0));
369 CHECK(operand_ti.is_boolean());
370 const auto operand_lv =
codegen(operand,
true, co).front();
371 CHECK(operand_lv->getType()->isIntegerTy());
373 CHECK(not_null || operand_lv->getType()->isIntegerTy(8));
384 if (dynamic_cast<const Analyzer::Constant*>(operand) &&
385 dynamic_cast<const Analyzer::Constant*>(operand)->get_is_null()) {
389 const auto& ti = operand->get_type_info();
390 CHECK(ti.is_integer() || ti.is_boolean() || ti.is_decimal() || ti.is_time() ||
391 ti.is_string() || ti.is_fp() || ti.is_array() || ti.is_geometry());
393 if (ti.get_notnull()) {
396 llvm::Value* operand_lv =
codegen(operand,
true, co).front();
398 if (ti.is_array() || ti.is_geometry()) {
402 (ti.get_type() ==
kPOINT) ?
"point_coord_array_is_null" :
"array_is_null";
405 }
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)
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