OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GeoIR.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Geospatial/Compression.h"
19 #include "QueryEngine/Execute.h"
22 
24  llvm::Value* pos,
25  const SQLTypeInfo& ti,
26  CgenState* cgen_state) {
27  CHECK(byte_stream);
28 
29  const auto key = std::make_pair(byte_stream, pos);
30  auto cache_itr = cgen_state->array_load_cache_.find(key);
31  if (cache_itr != cgen_state->array_load_cache_.end()) {
32  return cache_itr->second;
33  }
34  const bool is_nullable = !ti.get_notnull();
35  CHECK(ti.get_type() == kPOINT); // TODO: lift this
36 
37  auto pt_arr_buf =
38  cgen_state->emitExternalCall("array_buff",
39  llvm::Type::getInt8PtrTy(cgen_state->context_),
40  {key.first, key.second});
41  llvm::Value* pt_is_null{nullptr};
42  if (is_nullable) {
43  pt_is_null = cgen_state->emitExternalCall("point_coord_array_is_null",
44  llvm::Type::getInt1Ty(cgen_state->context_),
45  {key.first, key.second});
46  }
47  ArrayLoadCodegen arr_load{pt_arr_buf, nullptr, pt_is_null};
48  cgen_state->array_load_cache_.insert(std::make_pair(key, arr_load));
49  return arr_load;
50 }
51 
52 std::vector<llvm::Value*> CodeGenerator::codegenGeoColumnVar(
53  const Analyzer::GeoColumnVar* geo_col_var,
54  const bool fetch_columns,
55  const CompilationOptions& co) {
56  auto generate_column_lvs = [this, geo_col_var, &co](const int column_id) {
57  auto column_key = geo_col_var->getColumnKey();
58  column_key.column_id = column_id;
59 
60  auto cd = get_column_descriptor(column_key);
61  CHECK(cd);
62 
63  const auto col_var =
64  Analyzer::ColumnVar(cd->columnType, column_key, geo_col_var->get_rte_idx());
65  const auto lv_vec = codegen(&col_var, /*fetch_columns=*/true, co);
66  CHECK_EQ(lv_vec.size(), size_t(1)); // ptr
67  return lv_vec;
68  };
69 
70  const auto& ti = geo_col_var->get_type_info();
71  switch (ti.get_type()) {
72  case kPOINT:
73  case kLINESTRING:
74  case kMULTILINESTRING:
75  case kPOLYGON:
76  case kMULTIPOLYGON: {
77  std::vector<llvm::Value*> geo_lvs;
78  // iterate over physical columns
79  for (int i = 0; i < ti.get_physical_coord_cols(); i++) {
80  const auto column_id = geo_col_var->getColumnKey().column_id + 1 + i;
81  const auto lvs = generate_column_lvs(column_id);
82  CHECK_EQ(lvs.size(), size_t(1)); // expecting ptr for each column
83  geo_lvs.insert(geo_lvs.end(), lvs.begin(), lvs.end());
84  }
85 
86  return geo_lvs;
87  }
88  default:
89  UNREACHABLE() << geo_col_var->toString();
90  }
91  UNREACHABLE();
92  return {};
93 }
94 
95 std::vector<llvm::Value*> CodeGenerator::codegenGeoExpr(const Analyzer::GeoExpr* expr,
96  const CompilationOptions& co) {
97  auto geo_constant = dynamic_cast<const Analyzer::GeoConstant*>(expr);
98  if (geo_constant) {
99  return codegenGeoConstant(geo_constant, co);
100  }
101  auto geo_operator = dynamic_cast<const Analyzer::GeoOperator*>(expr);
102  if (geo_operator) {
103  return codegenGeoOperator(geo_operator, co);
104  }
105  UNREACHABLE() << expr->toString();
106  return {};
107 }
108 
109 std::vector<llvm::Value*> CodeGenerator::codegenGeoConstant(
110  const Analyzer::GeoConstant* geo_constant,
111  const CompilationOptions& co) {
113 
114  std::vector<llvm::Value*> ret;
115  for (size_t i = 0; i < geo_constant->physicalCols(); i++) {
116  auto physical_constant = geo_constant->makePhysicalConstant(i);
117  auto operand_lvs = codegen(physical_constant.get(), /*fetch_columns=*/true, co);
118  CHECK_EQ(operand_lvs.size(), size_t(2));
119  auto array_buff_lv = operand_lvs[0];
120  if (i > 0) {
121  array_buff_lv = cgen_state_->ir_builder_.CreateBitCast(
122  operand_lvs[0], llvm::Type::getInt8PtrTy(cgen_state_->context_));
123  }
124  ret.push_back(array_buff_lv);
125  ret.push_back(operand_lvs[1]);
126  }
127  return ret;
128 }
129 
130 std::vector<llvm::Value*> CodeGenerator::codegenGeoOperator(
131  const Analyzer::GeoOperator* geo_operator,
132  const CompilationOptions& co) {
134 
135  if (geo_operator->getName() == "ST_X" || geo_operator->getName() == "ST_Y") {
136  const auto key = geo_operator->toString();
137  auto geo_target_cache_it = cgen_state_->geo_target_cache_.find(key);
138  if (geo_target_cache_it != cgen_state_->geo_target_cache_.end()) {
139  return {geo_target_cache_it->second};
140  }
141  }
142 
143  auto op_codegen = spatial_type::Codegen::init(geo_operator);
144  CHECK(op_codegen);
145 
146  std::vector<llvm::Value*> load_lvs;
147  std::vector<llvm::Value*> pos_lvs;
148  for (size_t i = 0; i < op_codegen->size(); i++) {
149  auto intermediate_lvs =
150  codegen(op_codegen->getOperand(i), /*fetch_columns=*/true, co);
151  load_lvs.insert(load_lvs.end(), intermediate_lvs.begin(), intermediate_lvs.end());
152  pos_lvs.push_back(posArg(op_codegen->getOperand(i)));
153  }
154 
155  auto [arg_lvs, null_lv] = op_codegen->codegenLoads(load_lvs, pos_lvs, cgen_state_);
156 
157  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen =
158  op_codegen->getNullCheckCodegen(null_lv, cgen_state_, executor());
159  return op_codegen->codegen(arg_lvs, nullcheck_codegen.get(), cgen_state_, co);
160 }
161 
162 std::vector<llvm::Value*> CodeGenerator::codegenGeoUOper(
163  const Analyzer::GeoUOper* geo_expr,
164  const CompilationOptions& co) {
167  if (geo_expr->getOp() != Geospatial::GeoBase::GeoOp::kPROJECTION) {
168  throw QueryMustRunOnCpu();
169  }
170  }
171 
172  auto argument_list = codegenGeoArgs(geo_expr->getArgs0(), co);
173 
174  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kPROJECTION) {
175  return argument_list;
176  }
177 
178 #ifndef ENABLE_GEOS
179  throw std::runtime_error("Geo operation requires GEOS support.");
180 #endif
181 
182  // Basic set of arguments is currently common to all Geos_* func invocations:
183  // op kind, type of the first geo arg0, geo arg0 components
184  std::string func = "Geos_Wkb"s;
185 
186  if (geo_expr->getTypeInfo0().transforms() || geo_expr->get_type_info().transforms()) {
187  // If there is a transform on the argument and/or on the result of the operation,
188  // verify that the argument's output srid is equal to result's input srid
189  if (geo_expr->getTypeInfo0().get_output_srid() !=
190  geo_expr->get_type_info().get_input_srid()) {
191  throw std::runtime_error("GEOS runtime: input/output srids have to match.");
192  }
193  }
194  // Prepend arg0 geo SQLType
195  argument_list.insert(
196  argument_list.begin(),
197  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_type())));
198  // Prepend geo expr op
199  argument_list.insert(argument_list.begin(),
200  cgen_state_->llInt(static_cast<int>(geo_expr->getOp())));
201  for (auto i = 3; i > geo_expr->getTypeInfo0().get_physical_coord_cols(); i--) {
202  argument_list.insert(argument_list.end(),
203  llvm::ConstantPointerNull::get(
204  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
205  argument_list.insert(argument_list.end(), cgen_state_->llInt(int64_t(0)));
206  }
207  // Append geo expr compression
208  argument_list.insert(
209  argument_list.end(),
210  cgen_state_->llInt(static_cast<int>(
212  // Append geo expr input srid
213  argument_list.insert(
214  argument_list.end(),
215  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_input_srid())));
216  // Append geo expr output srid
217  argument_list.insert(
218  argument_list.end(),
219  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_output_srid())));
220 
221  // Deal with unary geo predicates
222  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kISEMPTY ||
224  return codegenGeosPredicateCall(func, argument_list, co);
225  }
226 
227  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kCONVEXHULL) {
228  func += "_double"s; // Use same interface as ST_ConcaveHull, with a dummy double
229 
230  // Insert that dummy double arg
231  argument_list.insert(argument_list.end(), cgen_state_->llFp(double(0)));
232 
233  auto result_srid = cgen_state_->llInt(geo_expr->get_type_info().get_output_srid());
234 
235  return codegenGeosConstructorCall(func, argument_list, result_srid, co);
236  }
237 
238  throw std::runtime_error("Unsupported unary geo operation.");
239  return {};
240 }
241 
242 std::vector<llvm::Value*> CodeGenerator::codegenGeoBinOper(
243  Analyzer::GeoBinOper const* geo_expr,
244  CompilationOptions const& co) {
247  throw QueryMustRunOnCpu();
248  }
249 #ifndef ENABLE_GEOS
250  throw std::runtime_error("Geo operation requires GEOS support.");
251 #endif
252 
253  auto argument_list = codegenGeoArgs(geo_expr->getArgs0(), co);
254 
255  // Basic set of arguments is currently common to all Geos_* func invocations:
256  // op kind, type of the first geo arg0, geo arg0 components
257  std::string func = "Geos_Wkb"s;
258  if (geo_expr->getTypeInfo0().transforms() || geo_expr->get_type_info().transforms()) {
259  // If there is a transform on the argument and/or on the result of the operation,
260  // verify that the argument's output srid is equal to result's input srid
261  if (geo_expr->getTypeInfo0().get_output_srid() !=
262  geo_expr->get_type_info().get_input_srid()) {
263  throw std::runtime_error("GEOS runtime: input/output srids have to match.");
264  }
265  }
266  // Prepend arg0 geo SQLType
267  argument_list.insert(
268  argument_list.begin(),
269  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_type())));
270  // Prepend geo expr op
271  argument_list.insert(argument_list.begin(),
272  cgen_state_->llInt(static_cast<int>(geo_expr->getOp())));
273  for (auto i = 3; i > geo_expr->getTypeInfo0().get_physical_coord_cols(); i--) {
274  argument_list.insert(argument_list.end(),
275  llvm::ConstantPointerNull::get(
276  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
277  argument_list.insert(argument_list.end(), cgen_state_->llInt(int64_t(0)));
278  }
279  // Append geo expr compression
280  argument_list.insert(
281  argument_list.end(),
282  cgen_state_->llInt(static_cast<int>(
284  // Append geo expr input srid
285  argument_list.insert(
286  argument_list.end(),
287  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_input_srid())));
288  // Append geo expr output srid
289  argument_list.insert(
290  argument_list.end(),
291  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_output_srid())));
292 
293  auto arg1_list = codegenGeoArgs(geo_expr->getArgs1(), co);
294 
295  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kDIFFERENCE ||
297  geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kUNION ||
299  func += "_Wkb"s;
300  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kEQUALS) {
301  func += "_Predicate"s;
302  }
303  // Prepend arg1 geo SQLType
304  arg1_list.insert(
305  arg1_list.begin(),
306  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo1().get_type())));
307  for (auto i = 3; i > geo_expr->getTypeInfo1().get_physical_coord_cols(); i--) {
308  arg1_list.insert(arg1_list.end(),
309  llvm::ConstantPointerNull::get(
310  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
311  arg1_list.insert(arg1_list.end(), cgen_state_->llInt(int64_t(0)));
312  }
313  // Append geo expr compression
314  arg1_list.insert(arg1_list.end(),
315  cgen_state_->llInt(static_cast<int>(
317  // Append geo expr input srid
318  arg1_list.insert(arg1_list.end(),
319  cgen_state_->llInt(geo_expr->getTypeInfo1().get_input_srid()));
320  // Append geo expr output srid
321  arg1_list.insert(arg1_list.end(),
323  } else if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kBUFFER) {
324  // Extra argument in this case is double
325  func += "_double"s;
326  } else if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kCONCAVEHULL) {
327 #if (GEOS_VERSION_MAJOR > 3) || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11)
328  // Extra argument in this case is double
329  func += "_double"s;
330 #else
331  throw std::runtime_error("ST_ConcaveHull requires GEOS 3.11 or newer");
332 #endif
333  } else {
334  throw std::runtime_error("Unsupported binary geo operation.");
335  }
336 
337  // Append arg1 to the list
338  argument_list.insert(argument_list.end(), arg1_list.begin(), arg1_list.end());
339 
340  // Deal with binary geo predicates
341  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kEQUALS) {
342  return codegenGeosPredicateCall(func, argument_list, co);
343  }
344 
345  auto result_srid = cgen_state_->llInt(geo_expr->get_type_info().get_output_srid());
346 
347  return codegenGeosConstructorCall(func, argument_list, result_srid, co);
348 }
349 
350 std::vector<llvm::Value*> CodeGenerator::codegenGeoArgs(
351  const std::vector<std::shared_ptr<Analyzer::Expr>>& geo_args,
352  const CompilationOptions& co) {
354  std::vector<llvm::Value*> argument_list;
355  bool coord_col = true;
356  for (const auto& geo_arg : geo_args) {
357  const auto arg = geo_arg.get();
358  const auto& arg_ti = arg->get_type_info();
359  const auto elem_ti = arg_ti.get_elem_type();
360  const auto arg_lvs = codegen(arg, true, co);
361  if (arg_ti.is_number()) {
362  argument_list.emplace_back(arg_lvs.front());
363  continue;
364  }
365  if (arg_ti.is_geometry()) {
366  argument_list.insert(argument_list.end(), arg_lvs.begin(), arg_lvs.end());
367  continue;
368  }
369  CHECK(arg_ti.is_array());
370  if (arg_lvs.size() > 1) {
371  CHECK_EQ(size_t(2), arg_lvs.size());
372  auto ptr_lv = arg_lvs.front();
373  if (coord_col) {
374  coord_col = false;
375  } else {
376  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
377  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
378  }
379  argument_list.emplace_back(ptr_lv);
380  auto cast_len_lv = cgen_state_->ir_builder_.CreateZExt(
381  arg_lvs.back(), get_int_type(64, cgen_state_->context_));
382  argument_list.emplace_back(cast_len_lv);
383  } else {
384  CHECK_EQ(size_t(1), arg_lvs.size());
385  if (arg_ti.get_size() > 0) {
386  // Set up the pointer lv for a dynamically generated point
387  auto ptr_lv = arg_lvs.front();
388  auto col_var = dynamic_cast<const Analyzer::ColumnVar*>(arg);
389  // Override for point coord column access
390  if (col_var) {
391  ptr_lv = cgen_state_->emitExternalCall(
392  "fast_fixlen_array_buff",
393  llvm::Type::getInt8PtrTy(cgen_state_->context_),
394  {arg_lvs.front(), posArg(arg)});
395  }
396  if (coord_col) {
397  coord_col = false;
398  } else {
399  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
400  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
401  }
402  argument_list.emplace_back(ptr_lv);
403  argument_list.emplace_back(cgen_state_->llInt<int64_t>(arg_ti.get_size()));
404  } else {
405  auto ptr_lv =
406  cgen_state_->emitExternalCall("array_buff",
407  llvm::Type::getInt8PtrTy(cgen_state_->context_),
408  {arg_lvs.front(), posArg(arg)});
409  if (coord_col) {
410  coord_col = false;
411  } else {
412  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
413  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
414  }
415  argument_list.emplace_back(ptr_lv);
416  const auto len_lv = cgen_state_->emitExternalCall(
417  "array_size",
419  {arg_lvs.front(),
420  posArg(arg),
421  cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))});
422  auto cast_len_lv = cgen_state_->ir_builder_.CreateZExt(
423  len_lv, get_int_type(64, cgen_state_->context_));
424  argument_list.emplace_back(cast_len_lv);
425  }
426  }
427  }
428  return argument_list;
429 }
430 
431 std::vector<llvm::Value*> CodeGenerator::codegenGeosPredicateCall(
432  const std::string& func,
433  std::vector<llvm::Value*> argument_list,
434  const CompilationOptions& co) {
436  auto i8_type = get_int_type(8, cgen_state_->context_);
437  auto result = cgen_state_->ir_builder_.CreateAlloca(i8_type, nullptr, "result");
438  argument_list.emplace_back(result);
439 
440  // Generate call to GEOS wrapper
441  cgen_state_->needs_geos_ = true;
442  auto status_lv = cgen_state_->emitExternalCall(
443  func, llvm::Type::getInt1Ty(cgen_state_->context_), argument_list);
444  // Need to check the status and throw an error if this call has failed.
445  llvm::BasicBlock* geos_pred_ok_bb{nullptr};
446  llvm::BasicBlock* geos_pred_fail_bb{nullptr};
447  geos_pred_ok_bb = llvm::BasicBlock::Create(
448  cgen_state_->context_, "geos_pred_ok_bb", cgen_state_->current_func_);
449  geos_pred_fail_bb = llvm::BasicBlock::Create(
450  cgen_state_->context_, "geos_pred_fail_bb", cgen_state_->current_func_);
451  if (!status_lv) {
452  status_lv = cgen_state_->llBool(false);
453  }
454  cgen_state_->ir_builder_.CreateCondBr(status_lv, geos_pred_ok_bb, geos_pred_fail_bb);
455  cgen_state_->ir_builder_.SetInsertPoint(geos_pred_fail_bb);
458  cgen_state_->ir_builder_.SetInsertPoint(geos_pred_ok_bb);
459  auto res = cgen_state_->ir_builder_.CreateLoad(
460  result->getType()->getPointerElementType(), result);
461  return {res};
462 }
463 
465  const std::string& func,
466  std::vector<llvm::Value*> argument_list,
467  llvm::Value* result_srid,
468  const CompilationOptions& co) {
470  // Create output buffer pointers, append pointers to output args to
471  auto i8_type = get_int_type(8, cgen_state_->context_);
472  auto i32_type = get_int_type(32, cgen_state_->context_);
473  auto i64_type = get_int_type(64, cgen_state_->context_);
474  auto pi8_type = llvm::PointerType::get(i8_type, 0);
475  auto pi32_type = llvm::PointerType::get(i32_type, 0);
476 
477  auto result_type =
478  cgen_state_->ir_builder_.CreateAlloca(i32_type, nullptr, "result_type");
479  auto result_coords =
480  cgen_state_->ir_builder_.CreateAlloca(pi8_type, nullptr, "result_coords");
481  auto result_coords_size =
482  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_coords_size");
483  auto result_ring_sizes =
484  cgen_state_->ir_builder_.CreateAlloca(pi32_type, nullptr, "result_ring_sizes");
485  auto result_ring_sizes_size =
486  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_ring_sizes_size");
487  auto result_poly_rings =
488  cgen_state_->ir_builder_.CreateAlloca(pi32_type, nullptr, "result_poly_rings");
489  auto result_poly_rings_size =
490  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_poly_rings_size");
491 
492  argument_list.emplace_back(result_type);
493  argument_list.emplace_back(result_coords);
494  argument_list.emplace_back(result_coords_size);
495  argument_list.emplace_back(result_ring_sizes);
496  argument_list.emplace_back(result_ring_sizes_size);
497  argument_list.emplace_back(result_poly_rings);
498  argument_list.emplace_back(result_poly_rings_size);
499  argument_list.emplace_back(result_srid);
500 
501  // Generate call to GEOS wrapper
502  cgen_state_->needs_geos_ = true;
503  auto status_lv = cgen_state_->emitExternalCall(
504  func, llvm::Type::getInt1Ty(cgen_state_->context_), argument_list);
505  // Need to check the status and throw an error if this call has failed.
506  llvm::BasicBlock* geos_ok_bb{nullptr};
507  llvm::BasicBlock* geos_fail_bb{nullptr};
508  geos_ok_bb = llvm::BasicBlock::Create(
509  cgen_state_->context_, "geos_ok_bb", cgen_state_->current_func_);
510  geos_fail_bb = llvm::BasicBlock::Create(
511  cgen_state_->context_, "geos_fail_bb", cgen_state_->current_func_);
512  if (!status_lv) {
513  status_lv = cgen_state_->llBool(false);
514  }
515  cgen_state_->ir_builder_.CreateCondBr(status_lv, geos_ok_bb, geos_fail_bb);
516  cgen_state_->ir_builder_.SetInsertPoint(geos_fail_bb);
519  cgen_state_->ir_builder_.SetInsertPoint(geos_ok_bb);
520 
521  // TODO: Currently forcing the output to MULTIPOLYGON, but need to handle
522  // other possible geometries that geos may return, e.g. a POINT, a LINESTRING
523  // Need to handle empty result, e.g. empty intersection.
524  // The type of result is returned in `result_type`
525 
526  // Load return values
527  auto buf1 = cgen_state_->ir_builder_.CreateLoad(
528  result_coords->getType()->getPointerElementType(), result_coords);
529  auto buf1s = cgen_state_->ir_builder_.CreateLoad(
530  result_coords_size->getType()->getPointerElementType(), result_coords_size);
531  auto buf2 = cgen_state_->ir_builder_.CreateLoad(
532  result_ring_sizes->getType()->getPointerElementType(), result_ring_sizes);
533  auto buf2s = cgen_state_->ir_builder_.CreateLoad(
534  result_ring_sizes_size->getType()->getPointerElementType(), result_ring_sizes_size);
535  auto buf3 = cgen_state_->ir_builder_.CreateLoad(
536  result_poly_rings->getType()->getPointerElementType(), result_poly_rings);
537  auto buf3s = cgen_state_->ir_builder_.CreateLoad(
538  result_poly_rings_size->getType()->getPointerElementType(), result_poly_rings_size);
539 
540  // generate register_buffer_with_executor_rsm() calls to register all output buffers
542  "register_buffer_with_executor_rsm",
543  llvm::Type::getVoidTy(cgen_state_->context_),
544  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
545  cgen_state_->ir_builder_.CreatePointerCast(buf1, pi8_type)});
546  cgen_state_->emitExternalCall(
547  "register_buffer_with_executor_rsm",
548  llvm::Type::getVoidTy(cgen_state_->context_),
549  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
550  cgen_state_->ir_builder_.CreatePointerCast(buf2, pi8_type)});
551  cgen_state_->emitExternalCall(
552  "register_buffer_with_executor_rsm",
553  llvm::Type::getVoidTy(cgen_state_->context_),
554  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
555  cgen_state_->ir_builder_.CreatePointerCast(buf3, pi8_type)});
556 
557  return {cgen_state_->ir_builder_.CreatePointerCast(buf1, pi8_type),
558  buf1s,
559  cgen_state_->ir_builder_.CreatePointerCast(buf2, pi32_type),
560  buf2s,
561  cgen_state_->ir_builder_.CreatePointerCast(buf3, pi32_type),
562  buf3s};
563 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const SQLTypeInfo getTypeInfo0() const
Definition: Analyzer.h:2735
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs0() const
Definition: Analyzer.h:2737
const SQLTypeInfo getTypeInfo0() const
Definition: Analyzer.h:2706
CgenState * cgen_state_
std::map< std::pair< llvm::Value *, llvm::Value * >, ArrayLoadCodegen > array_load_cache_
Definition: CgenState.h:395
llvm::IRBuilder ir_builder_
Definition: CgenState.h:377
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:580
#define UNREACHABLE()
Definition: Logger.h:337
const SQLTypeInfo getTypeInfo1() const
Definition: Analyzer.h:2736
llvm::ConstantInt * llBool(const bool v) const
Definition: CgenState.h:256
bool needs_geos_
Definition: CgenState.h:398
static const int32_t ERR_GEOS
Definition: Execute.h:1442
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:381
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::vector< llvm::Value * > codegenGeoBinOper(const Analyzer::GeoBinOper *, const CompilationOptions &)
Definition: GeoIR.cpp:242
std::unordered_map< std::string, llvm::Value * > geo_target_cache_
Definition: CgenState.h:396
std::vector< llvm::Value * > codegenGeoExpr(const Analyzer::GeoExpr *, const CompilationOptions &)
Definition: GeoIR.cpp:95
llvm::LLVMContext & context_
Definition: CgenState.h:375
llvm::Function * current_func_
Definition: CgenState.h:369
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)
Definition: CgenState.cpp:396
std::vector< llvm::Value * > codegenGeoOperator(const Analyzer::GeoOperator *, const CompilationOptions &)
Definition: GeoIR.cpp:130
std::vector< llvm::Value * > codegenGeoUOper(const Analyzer::GeoUOper *, const CompilationOptions &)
Definition: GeoIR.cpp:162
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs0() const
Definition: Analyzer.h:2707
std::string toString() const override
Definition: Analyzer.cpp:2614
const ColumnDescriptor * get_column_descriptor(const shared::ColumnKey &column_key)
Definition: Execute.h:192
const std::string & getName() const
Definition: Analyzer.h:2949
bool needs_error_check_
Definition: CgenState.h:397
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:246
#define AUTOMATIC_IR_METADATA(CGENSTATE)
std::vector< llvm::Value * > codegenGeosConstructorCall(const std::string &, std::vector< llvm::Value * >, llvm::Value *, const CompilationOptions &)
Definition: GeoIR.cpp:464
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
virtual std::string toString() const =0
const shared::ColumnKey & getColumnKey() const
Definition: Analyzer.h:198
std::vector< llvm::Value * > codegenGeosPredicateCall(const std::string &, std::vector< llvm::Value * >, const CompilationOptions &)
Definition: GeoIR.cpp:431
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck(llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
Definition: GeoIR.cpp:23
std::vector< llvm::Value * > codegenGeoColumnVar(const Analyzer::GeoColumnVar *, const bool fetch_columns, const CompilationOptions &co)
Definition: GeoIR.cpp:52
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:385
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:242
std::vector< llvm::Value * > codegenGeoArgs(const std::vector< std::shared_ptr< Analyzer::Expr >> &, const CompilationOptions &)
Definition: GeoIR.cpp:350
#define CHECK(condition)
Definition: Logger.h:291
Geospatial::GeoBase::GeoOp getOp() const
Definition: Analyzer.h:2705
std::vector< llvm::Value * > codegenGeoConstant(const Analyzer::GeoConstant *, const CompilationOptions &)
Definition: GeoIR.cpp:109
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:177
std::shared_ptr< Analyzer::Constant > makePhysicalConstant(const size_t index) const
Definition: Analyzer.cpp:3870
bool transforms() const
Definition: sqltypes.h:615
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:388
std::string toString() const override
Definition: Analyzer.cpp:3954
int32_t get_rte_idx() const
Definition: Analyzer.h:202
int get_physical_coord_cols() const
Definition: sqltypes.h:433
size_t physicalCols() const
Definition: Analyzer.cpp:3865
Geospatial::GeoBase::GeoOp getOp() const
Definition: Analyzer.h:2734
static std::unique_ptr< Codegen > init(const Analyzer::GeoOperator *geo_operator)
Definition: Codegen.cpp:22
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs1() const
Definition: Analyzer.h:2738
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:387
Executor * executor() const