21 namespace spatial_type {
37 Executor* executor)
final {
40 return std::make_unique<CodeGenerator::NullCheckCodegen>(
47 size_t size() const final {
return 2; }
56 const std::vector<llvm::Value*>& arg_lvs,
57 const std::vector<llvm::Value*>& pos_lvs,
60 CHECK_EQ(pos_lvs.front(), pos_lvs.back());
63 const auto& geo_ti = operand->get_type_info();
66 auto& builder = cgen_state->ir_builder_;
68 std::vector<llvm::Value*> array_operand_lvs;
69 CHECK(!arg_lvs.empty());
70 auto index_lv = builder.CreateMul(
71 builder.CreateSub(arg_lvs.back(), cgen_state->llInt(static_cast<int32_t>(1))),
72 cgen_state->llInt(static_cast<int32_t>(2)));
73 llvm::Value* is_null_lv{
nullptr};
74 if (arg_lvs.size() == 2) {
76 array_operand_lvs.push_back(
77 cgen_state->emitExternalCall(
"array_buff",
78 llvm::Type::getInt8PtrTy(cgen_state->context_),
79 {arg_lvs.front(), pos_lvs.front()}));
80 const bool is_nullable = !geo_ti.get_notnull();
81 std::string size_fn_name =
"array_size";
83 size_fn_name +=
"_nullable";
87 std::vector<llvm::Value*> array_sz_args{
88 arg_lvs.front(), pos_lvs.front(), cgen_state->llInt(
log2_bytes(elem_sz))};
90 array_sz_args.push_back(
91 cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
93 array_operand_lvs.push_back(cgen_state->emitExternalCall(
94 size_fn_name,
get_int_type(32, cgen_state->context_), array_sz_args));
96 auto geo_size_lv = array_operand_lvs.back();
98 const auto outside_linestring_bounds_lv = builder.CreateNot(builder.CreateICmp(
99 llvm::ICmpInst::ICMP_SLT,
100 builder.CreateMul(index_lv, cgen_state->llInt(static_cast<int32_t>(8))),
102 outside_linestring_bounds_lv->setName(
"outside_linestring_bounds");
103 const auto input_is_null_lv = builder.CreateICmp(
104 llvm::ICmpInst::ICMP_EQ,
106 cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
107 input_is_null_lv->setName(
"input_is_null");
108 is_null_lv = builder.CreateOr(outside_linestring_bounds_lv, input_is_null_lv);
110 CHECK_EQ(arg_lvs.size(), size_t(3));
111 array_operand_lvs.push_back(arg_lvs[0]);
112 array_operand_lvs.push_back(arg_lvs[1]);
114 const auto geo_size_lv = arg_lvs[1];
117 is_null_lv = builder.CreateNot(
118 builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, index_lv, geo_size_lv));
120 array_operand_lvs.push_back(index_lv);
121 return std::make_tuple(array_operand_lvs, is_null_lv);
124 std::vector<llvm::Value*>
codegen(
const std::vector<llvm::Value*>&
args,
129 const auto& geo_ti = getOperand(0)->get_type_info();
130 CHECK(geo_ti.is_geometry());
132 llvm::Value* array_buff_cast{
nullptr};
134 auto& builder = cgen_state->ir_builder_;
136 array_buff_cast = builder.CreateBitCast(
137 args.front(), llvm::Type::getInt32PtrTy(cgen_state->context_));
139 array_buff_cast = builder.CreateBitCast(
140 args.front(), llvm::Type::getDoublePtrTy(cgen_state->context_));
143 const auto index_lv =
args.back();
144 auto array_offset_lv = builder.CreateGEP(
145 array_buff_cast->getType()->getScalarType()->getPointerElementType(),
148 operator_->getName() +
"_Offset");
149 CHECK(nullcheck_codegen);
150 auto ret_lv = nullcheck_codegen->finalize(
151 llvm::ConstantPointerNull::get(
153 ? llvm::PointerType::get(llvm::Type::getInt32Ty(cgen_state->context_), 0)
154 : llvm::PointerType::get(llvm::Type::getDoubleTy(cgen_state->context_),
157 const auto geo_size_lv =
args[1];
158 return {ret_lv, geo_size_lv};
std::unique_ptr< CodeGenerator::NullCheckCodegen > getNullCheckCodegen(llvm::Value *null_lv, CgenState *cgen_state, Executor *executor) final
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
SQLTypeInfo getNullType() const final
std::vector< llvm::Value * > codegen(const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
const Analyzer::GeoOperator * operator_
size_t size() const final
virtual const Analyzer::Expr * getOperand(const size_t index)
std::string getName() const
uint32_t log2_bytes(const uint32_t bytes)
std::tuple< std::vector< llvm::Value * >, llvm::Value * > codegenLoads(const std::vector< llvm::Value * > &arg_lvs, const std::vector< llvm::Value * > &pos_lvs, CgenState *cgen_state) final
PointN(const Analyzer::GeoOperator *geo_operator)