19 namespace spatial_type {
27 dynamic_cast<const Analyzer::GeoTransformOperator*>(geo_operator)) {
31 if (ti.get_notnull()) {
38 size_t size()
const override {
return 1; }
42 inline static bool isUtm(
unsigned const srid) {
43 return (32601 <= srid && srid <= 32660) || (32701 <= srid && srid <= 32760);
47 const std::vector<llvm::Value*>& arg_lvs,
48 const std::vector<llvm::Value*>& pos_lvs,
52 const auto& operand_ti = geo_operand->get_type_info();
53 CHECK(operand_ti.is_geometry() && operand_ti.get_type() ==
kPOINT);
55 if (dynamic_cast<const Analyzer::ColumnVar*>(geo_operand)) {
58 arg_lvs.front(), pos_lvs.front(), operand_ti, cgen_state);
59 return std::make_tuple(std::vector<llvm::Value*>{arr_load_lvs.buffer},
60 arr_load_lvs.is_null);
61 }
else if (dynamic_cast<const Analyzer::GeoConstant*>(geo_operand)) {
67 return std::make_tuple(std::vector<llvm::Value*>{arg_lvs.front()},
nullptr);
69 CHECK(arg_lvs.size() == size_t(1) ||
70 arg_lvs.size() == size_t(2));
74 llvm::Value*
const is_null = cgen_state->
emitCall(fname, {arg_lvs.front()});
75 return std::make_tuple(std::vector<llvm::Value*>{arg_lvs.front()},
is_null);
79 std::vector<llvm::Value*>
codegen(
const std::vector<llvm::Value*>&
args,
86 const auto& operand_ti = geo_operand->get_type_info();
89 llvm::Value* arr_buff_ptr = args.front();
93 builder.CreateAlloca(llvm::Type::getDoubleTy(cgen_state->
context_),
94 cgen_state->
llInt(int32_t(2)),
96 auto compressed_arr_ptr = builder.CreateBitCast(
97 arr_buff_ptr, llvm::Type::getInt32PtrTy(cgen_state->
context_));
99 auto* gep = builder.CreateGEP(
100 compressed_arr_ptr->getType()->getScalarType()->getPointerElementType(),
102 cgen_state->
llInt(0));
104 "decompress_x_coord_geoint",
105 llvm::Type::getDoubleTy(cgen_state->
context_),
107 gep->getType()->getPointerElementType(), gep,
"compressed_x_coord")});
111 new_arr_ptr->getType()->getScalarType()->getPointerElementType(),
113 cgen_state->
llInt(0)));
114 gep = builder.CreateGEP(
115 compressed_arr_ptr->getType()->getScalarType()->getPointerElementType(),
117 cgen_state->
llInt(1));
119 "decompress_y_coord_geoint",
120 llvm::Type::getDoubleTy(cgen_state->
context_),
122 gep->getType()->getPointerElementType(), gep,
"compressed_y_coord")});
126 new_arr_ptr->getType()->getScalarType()->getPointerElementType(),
128 cgen_state->
llInt(1)));
129 arr_buff_ptr = new_arr_ptr;
132 builder.CreateAlloca(llvm::Type::getDoubleTy(cgen_state->
context_),
133 cgen_state->
llInt(int32_t(2)),
135 const auto arr_buff_ptr_cast = builder.CreateBitCast(
136 arr_buff_ptr, llvm::Type::getDoublePtrTy(cgen_state->
context_));
138 auto* gep = builder.CreateGEP(
139 arr_buff_ptr_cast->getType()->getScalarType()->getPointerElementType(),
141 cgen_state->
llInt(0));
143 builder.CreateLoad(gep->getType()->getPointerElementType(), gep),
145 new_arr_ptr->getType()->getScalarType()->getPointerElementType(),
147 cgen_state->
llInt(0)));
148 gep = builder.CreateGEP(
149 arr_buff_ptr_cast->getType()->getScalarType()->getPointerElementType(),
151 cgen_state->
llInt(1));
153 builder.CreateLoad(gep->getType()->getPointerElementType(), gep),
155 new_arr_ptr->getType()->getScalarType()->getPointerElementType(),
157 cgen_state->
llInt(1)));
158 arr_buff_ptr = new_arr_ptr;
160 CHECK(arr_buff_ptr->getType() == llvm::Type::getDoublePtrTy(cgen_state->
context_));
164 if (srid_in == srid_out) {
166 return {args.front()};
170 std::string transform_function_prefix{
""};
171 std::vector<llvm::Value*> transform_args;
173 if (srid_out == 900913) {
174 if (srid_in == 4326) {
175 transform_function_prefix =
"transform_4326_900913_";
176 }
else if (
isUtm(srid_in)) {
177 transform_function_prefix =
"transform_utm_900913_";
178 transform_args.push_back(cgen_state->
llInt(srid_in));
180 throw std::runtime_error(
"Unsupported input SRID " +
std::to_string(srid_in) +
183 }
else if (srid_out == 4326) {
184 if (srid_in == 900913) {
185 transform_function_prefix =
"transform_900913_4326_";
186 }
else if (
isUtm(srid_in)) {
187 transform_function_prefix =
"transform_utm_4326_";
188 transform_args.push_back(cgen_state->
llInt(srid_in));
190 throw std::runtime_error(
"Unsupported input SRID " +
std::to_string(srid_in) +
193 }
else if (
isUtm(srid_out)) {
194 if (srid_in == 4326) {
195 transform_function_prefix =
"transform_4326_utm_";
196 }
else if (srid_in == 900913) {
197 transform_function_prefix =
"transform_900913_utm_";
199 throw std::runtime_error(
"Unsupported input SRID " +
std::to_string(srid_in) +
202 transform_args.push_back(cgen_state->
llInt(srid_out));
204 throw std::runtime_error(
"Unsupported output SRID for ST_Transform: " +
207 CHECK(!transform_function_prefix.empty());
209 auto x_coord_ptr_lv = builder.CreateGEP(
210 arr_buff_ptr->getType()->getScalarType()->getPointerElementType(),
212 cgen_state->
llInt(0),
214 transform_args.push_back(builder.CreateLoad(
215 x_coord_ptr_lv->getType()->getPointerElementType(), x_coord_ptr_lv,
"x_coord"));
216 auto y_coord_ptr_lv = builder.CreateGEP(
217 arr_buff_ptr->getType()->getScalarType()->getPointerElementType(),
219 cgen_state->
llInt(1),
221 transform_args.push_back(builder.CreateLoad(
222 y_coord_ptr_lv->getType()->getPointerElementType(), y_coord_ptr_lv,
"y_coord"));
224 auto fn_x = cgen_state->
module_->getFunction(transform_function_prefix +
'x');
227 CHECK(!fn_x->isDeclaration());
230 for (
const auto& fcn_name : gpu_functions_to_replace) {
234 auto transform_call = builder.CreateCall(fn_x, transform_args);
235 builder.CreateStore(transform_call, x_coord_ptr_lv);
237 auto fn_y = cgen_state->
module_->getFunction(transform_function_prefix +
'y');
240 CHECK(!fn_y->isDeclaration());
243 for (
const auto& fcn_name : gpu_functions_to_replace) {
247 transform_call = builder.CreateCall(fn_y, transform_args);
248 builder.CreateStore(transform_call, y_coord_ptr_lv);
251 cgen_state->
emitCall(transform_function_prefix +
'x', transform_args),
254 cgen_state->
emitCall(transform_function_prefix +
'y', transform_args),
257 auto ret = arr_buff_ptr;
261 CHECK(nullcheck_codegen);
263 llvm::ConstantPointerNull::get(
265 ? llvm::PointerType::get(llvm::Type::getInt32Ty(cgen_state->
context_),
267 : llvm::PointerType::get(llvm::Type::getDoubleTy(cgen_state->
context_),
272 cgen_state->
llInt(static_cast<int32_t>(
void maybeCloneFunctionRecursive(llvm::Function *fn)
llvm::IRBuilder ir_builder_
static char const * pointIsNullFunctionName(SQLTypeInfo const &)
void verify_function_ir(const llvm::Function *func)
llvm::LLVMContext & context_
CONSTEXPR DEVICE bool is_null(const T &value)
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)
void replaceFunctionForGpu(const std::string &fcn_to_replace, llvm::Function *fn)
std::vector< std::string > gpuFunctionsToReplace(llvm::Function *fn)
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
ExecutorDeviceType device_type
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck(llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
const Analyzer::GeoOperator * operator_
llvm::ConstantInt * llInt(const T v) const
llvm::Value * finalize(llvm::Value *null_lv, llvm::Value *notnull_lv)
virtual const Analyzer::Expr * getOperand(const size_t index)
std::string getName() const