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) {
58 llvm::Value* geo_size_lv{
nullptr};
59 if (arg_lvs.size() == 2) {
61 std::string size_fn_name =
"array_size";
63 size_fn_name +=
"_nullable";
67 std::vector<llvm::Value*> array_sz_args{
68 arg_lvs.front(), pos_lvs.front(), cgen_state->
llInt(
log2_bytes(elem_sz))};
70 array_sz_args.push_back(
71 cgen_state->
llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
76 geo_size_lv = arg_lvs[1];
83 llvm::Value* index_lv,
84 llvm::Value* geosize_lv) {
85 llvm::Value* is_null_lv = cgen_state->
llBool(
false);
88 cgen_state->
ir_builder_.CreateICmp(llvm::ICmpInst::ICMP_SLT,
90 cgen_state->
llInt(static_cast<int32_t>(0))));
94 llvm::ICmpInst::ICMP_SGE,
96 cgen_state->
llInt(static_cast<int32_t>(8))),
102 const std::vector<llvm::Value*>& arg_lvs,
103 const std::vector<llvm::Value*>& pos_lvs,
106 CHECK_EQ(pos_lvs.front(), pos_lvs.back());
109 const auto& geo_ti = operand->get_type_info();
112 auto& builder = cgen_state->ir_builder_;
114 std::vector<llvm::Value*> array_operand_lvs;
115 CHECK(!arg_lvs.empty());
116 llvm::Value* raw_index_lv = arg_lvs.back();
117 llvm::Value* geo_size_lv =
codegenGeoSize(cgen_state, geo_ti, arg_lvs, pos_lvs);
118 llvm::Value* pt_size_lv = cgen_state->llInt(16);
119 llvm::Value* num_pts_lv = builder.CreateUDiv(geo_size_lv, pt_size_lv);
120 llvm::Value* is_negative_lv =
121 builder.CreateICmpSLT(raw_index_lv, cgen_state->llInt(0));
122 llvm::Value* negative_raw_index_lv = builder.CreateAdd(raw_index_lv, num_pts_lv);
123 llvm::Value* positive_raw_index_lv =
124 builder.CreateSub(raw_index_lv, cgen_state->llInt(1));
125 raw_index_lv = builder.CreateSelect(
126 is_negative_lv, negative_raw_index_lv, positive_raw_index_lv);
128 builder.CreateMul(raw_index_lv, cgen_state->llInt(static_cast<int32_t>(2)));
129 llvm::Value* is_null_lv =
131 if (arg_lvs.size() == 2) {
133 array_operand_lvs.push_back(
134 cgen_state->emitExternalCall(
"array_buff",
135 llvm::Type::getInt8PtrTy(cgen_state->context_),
136 {arg_lvs.front(), pos_lvs.front()}));
137 array_operand_lvs.push_back(geo_size_lv);
140 builder.CreateMul(raw_index_lv, cgen_state->llInt(static_cast<int32_t>(8)));
141 const auto input_is_null_lv = builder.CreateICmp(
142 llvm::ICmpInst::ICMP_EQ,
144 cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
145 is_null_lv = builder.CreateOr(is_null_lv, input_is_null_lv);
147 CHECK_EQ(arg_lvs.size(), size_t(3));
148 array_operand_lvs.push_back(arg_lvs[0]);
149 array_operand_lvs.push_back(arg_lvs[1]);
151 array_operand_lvs.push_back(raw_index_lv);
152 return std::make_tuple(array_operand_lvs, is_null_lv);
155 std::vector<llvm::Value*>
codegen(
const std::vector<llvm::Value*>&
args,
160 const auto& geo_ti = getOperand(0)->get_type_info();
161 CHECK(geo_ti.is_geometry());
163 llvm::Value* array_buff_cast{
nullptr};
165 auto& builder = cgen_state->ir_builder_;
167 array_buff_cast = builder.CreateBitCast(
168 args.front(), llvm::Type::getInt32PtrTy(cgen_state->context_));
170 array_buff_cast = builder.CreateBitCast(
171 args.front(), llvm::Type::getDoublePtrTy(cgen_state->context_));
174 const auto index_lv =
args.back();
175 auto array_offset_lv = builder.CreateGEP(
176 array_buff_cast->getType()->getScalarType()->getPointerElementType(),
179 operator_->getName() +
"_Offset");
180 CHECK(nullcheck_codegen);
181 auto ret_lv = nullcheck_codegen->finalize(
182 llvm::ConstantPointerNull::get(
184 ? llvm::PointerType::get(llvm::Type::getInt32Ty(cgen_state->context_), 0)
185 : llvm::PointerType::get(llvm::Type::getDoubleTy(cgen_state->context_),
188 const auto geo_size_lv =
args[1];
189 return {ret_lv, geo_size_lv};
std::unique_ptr< CodeGenerator::NullCheckCodegen > getNullCheckCodegen(llvm::Value *null_lv, CgenState *cgen_state, Executor *executor) final
llvm::IRBuilder ir_builder_
llvm::ConstantInt * llBool(const bool v) const
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
SQLTypeInfo getNullType() const final
llvm::LLVMContext & context_
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)
std::vector< llvm::Value * > codegen(const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
llvm::Value * codegenGeoSize(CgenState *cgen_state, SQLTypeInfo const &geo_ti, const std::vector< llvm::Value * > &arg_lvs, const std::vector< llvm::Value * > &pos_lvs)
const Analyzer::GeoOperator * operator_
llvm::Value * codegenIndexOutOfBoundCheck(CgenState *cgen_state, llvm::Value *index_lv, llvm::Value *geosize_lv)
size_t size() const final
llvm::ConstantInt * llInt(const T v) const
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
HOST DEVICE bool get_notnull() const
PointN(const Analyzer::GeoOperator *geo_operator)