OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
spatial_type::Centroid Class Reference

#include <Centroid.h>

+ Inheritance diagram for spatial_type::Centroid:
+ Collaboration diagram for spatial_type::Centroid:

Public Member Functions

 Centroid (const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
 
size_t size () const final
 
SQLTypeInfo getNullType () const final
 
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
 
std::vector< llvm::Value * > codegen (const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
 
- Public Member Functions inherited from spatial_type::Codegen
 Codegen (const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
 
auto isNullable () const
 
auto getTypeInfo () const
 
std::string getName () const
 
virtual std::unique_ptr
< CodeGenerator::NullCheckCodegen
getNullCheckCodegen (llvm::Value *null_lv, CgenState *cgen_state, Executor *executor)
 
virtual const Analyzer::ExprgetOperand (const size_t index)
 
virtual ~Codegen ()
 

Additional Inherited Members

- Static Public Member Functions inherited from spatial_type::Codegen
static std::unique_ptr< Codegeninit (const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
 
- Protected Attributes inherited from spatial_type::Codegen
const Analyzer::GeoOperatoroperator_
 
const Catalog_Namespace::Catalogcat_
 
bool is_nullable_ {true}
 

Detailed Description

Definition at line 23 of file Centroid.h.

Constructor & Destructor Documentation

spatial_type::Centroid::Centroid ( const Analyzer::GeoOperator geo_operator,
const Catalog_Namespace::Catalog catalog 
)
inline

Definition at line 25 of file Centroid.h.

References CHECK_EQ, Analyzer::Expr::get_type_info(), spatial_type::Codegen::is_nullable_, spatial_type::Codegen::operator_, and Analyzer::GeoOperator::size().

27  : Codegen(geo_operator, catalog) {
28  CHECK_EQ(operator_->size(), size_t(1));
29  const auto& ti = operator_->get_type_info();
30  is_nullable_ = !ti.get_notnull();
31  }
Codegen(const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
Definition: Codegen.h:28
#define CHECK_EQ(x, y)
Definition: Logger.h:230
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:82
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:70
size_t size() const
Definition: Analyzer.cpp:3913

+ Here is the call graph for this function:

Member Function Documentation

std::vector<llvm::Value*> spatial_type::Centroid::codegen ( const std::vector< llvm::Value * > &  args,
CodeGenerator::NullCheckCodegen nullcheck_codegen,
CgenState cgen_state,
const CompilationOptions co 
)
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 114 of file Centroid.h.

References run_benchmark_import::args, CHECK, Geospatial::get_compression_scheme(), kENCODING_GEOINT, kPOINT, and spatial_type::suffix().

117  {
118  std::string func_name = "ST_Centroid";
119  const auto& ret_ti = operator_->get_type_info();
120  CHECK(ret_ti.is_geometry() && ret_ti.get_type() == kPOINT);
121  const auto& operand_ti = getOperand(0)->get_type_info();
122 
123  auto& builder = cgen_state->ir_builder_;
124 
125  // Allocate local storage for centroid point
126  auto elem_ty = llvm::Type::getDoubleTy(cgen_state->context_);
127  llvm::ArrayType* arr_type = llvm::ArrayType::get(elem_ty, 2);
128  auto pt_local_storage_lv =
129  builder.CreateAlloca(arr_type, nullptr, func_name + "_Local_Storage");
130 
131  llvm::Value* pt_compressed_local_storage_lv{NULL};
132  // Allocate local storage for compressed centroid point
133  if (ret_ti.get_compression() == kENCODING_GEOINT) {
134  auto elem_ty = llvm::Type::getInt32Ty(cgen_state->context_);
135  llvm::ArrayType* arr_type = llvm::ArrayType::get(elem_ty, 2);
136  pt_compressed_local_storage_lv = builder.CreateAlloca(
137  arr_type, nullptr, func_name + "_Compressed_Local_Storage");
138  }
139 
140  func_name += spatial_type::suffix(operand_ti.get_type());
141 
142  auto operand_lvs = args;
143 
144  // push back ic, isr, osr for now
145  operand_lvs.push_back(
146  cgen_state->llInt(Geospatial::get_compression_scheme(operand_ti))); // ic
147  operand_lvs.push_back(cgen_state->llInt(operand_ti.get_input_srid())); // in srid
148  auto output_srid = operand_ti.get_output_srid();
149  if (const auto srid_override = operator_->getOutputSridOverride()) {
150  output_srid = *srid_override;
151  }
152  operand_lvs.push_back(cgen_state->llInt(output_srid)); // out srid
153 
154  auto idx_lv = cgen_state->llInt(0);
155  auto pt_local_storage_gep = llvm::GetElementPtrInst::CreateInBounds(
156  pt_local_storage_lv->getType()->getScalarType()->getPointerElementType(),
157  pt_local_storage_lv,
158  {idx_lv, idx_lv},
159  "",
160  builder.GetInsertBlock());
161  // Pass local storage to centroid function
162  operand_lvs.push_back(pt_local_storage_gep);
163  CHECK(ret_ti.get_type() == kPOINT);
164  cgen_state->emitExternalCall(
165  func_name, llvm::Type::getVoidTy(cgen_state->context_), operand_lvs);
166 
167  llvm::Value* ret_coords = pt_local_storage_lv;
168  if (ret_ti.get_compression() == kENCODING_GEOINT) {
169  // Compress centroid point if requested
170  // Take values out of local storage, compress, store in compressed local storage
171 
172  auto x_ptr = builder.CreateGEP(
173  pt_local_storage_lv->getType()->getScalarType()->getPointerElementType(),
174  pt_local_storage_lv,
175  {cgen_state->llInt(0), cgen_state->llInt(0)},
176  "x_ptr");
177  auto x_lv = builder.CreateLoad(x_ptr->getType()->getPointerElementType(), x_ptr);
178  auto compressed_x_lv =
179  cgen_state->emitExternalCall("compress_x_coord_geoint",
180  llvm::Type::getInt32Ty(cgen_state->context_),
181  {x_lv});
182  auto compressed_x_ptr =
183  builder.CreateGEP(pt_compressed_local_storage_lv->getType()
184  ->getScalarType()
185  ->getPointerElementType(),
186  pt_compressed_local_storage_lv,
187  {cgen_state->llInt(0), cgen_state->llInt(0)},
188  "compressed_x_ptr");
189  builder.CreateStore(compressed_x_lv, compressed_x_ptr);
190 
191  auto y_ptr = builder.CreateGEP(
192  pt_local_storage_lv->getType()->getScalarType()->getPointerElementType(),
193  pt_local_storage_lv,
194  {cgen_state->llInt(0), cgen_state->llInt(1)},
195  "y_ptr");
196  auto y_lv = builder.CreateLoad(y_ptr->getType()->getPointerElementType(), y_ptr);
197  auto compressed_y_lv =
198  cgen_state->emitExternalCall("compress_y_coord_geoint",
199  llvm::Type::getInt32Ty(cgen_state->context_),
200  {y_lv});
201  auto compressed_y_ptr =
202  builder.CreateGEP(pt_compressed_local_storage_lv->getType()
203  ->getScalarType()
204  ->getPointerElementType(),
205  pt_compressed_local_storage_lv,
206  {cgen_state->llInt(0), cgen_state->llInt(1)},
207  "compressed_y_ptr");
208  builder.CreateStore(compressed_y_lv, compressed_y_ptr);
209 
210  ret_coords = pt_compressed_local_storage_lv;
211  } else {
212  CHECK(ret_ti.get_compression() == kENCODING_NONE);
213  }
214 
215  auto ret_ty = ret_ti.get_compression() == kENCODING_GEOINT
216  ? llvm::Type::getInt32PtrTy(cgen_state->context_)
217  : llvm::Type::getDoublePtrTy(cgen_state->context_);
218  ret_coords = builder.CreateBitCast(ret_coords, ret_ty);
219 
220  if (is_nullable_) {
221  CHECK(nullcheck_codegen);
222  ret_coords = nullcheck_codegen->finalize(
223  llvm::ConstantPointerNull::get(
224  ret_ti.get_compression() == kENCODING_GEOINT
225  ? llvm::PointerType::get(llvm::Type::getInt32Ty(cgen_state->context_),
226  0)
227  : llvm::PointerType::get(llvm::Type::getDoubleTy(cgen_state->context_),
228  0)),
229  ret_coords);
230  }
231 
232  return {ret_coords,
233  cgen_state->llInt(ret_ti.get_compression() == kENCODING_GEOINT ? 8 : 16)};
234  }
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.h:217
auto getOutputSridOverride() const
Definition: Analyzer.h:2790
llvm::IRBuilder ir_builder_
Definition: CgenState.h:441
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
std::string suffix(SQLTypes type)
Definition: Codegen.cpp:68
llvm::LLVMContext & context_
Definition: CgenState.h:439
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:82
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:70
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:306
llvm::Value * finalize(llvm::Value *null_lv, llvm::Value *notnull_lv)
Definition: IRCodegen.cpp:1437
#define CHECK(condition)
Definition: Logger.h:222
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:63

+ Here is the call graph for this function:

std::tuple<std::vector<llvm::Value*>, llvm::Value*> spatial_type::Centroid::codegenLoads ( const std::vector< llvm::Value * > &  arg_lvs,
const std::vector< llvm::Value * > &  pos_lvs,
CgenState cgen_state 
)
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 37 of file Centroid.h.

References CHECK, CHECK_EQ, get_int_type(), spatial_type::Codegen::getOperand(), spatial_type::Codegen::is_nullable_, log2_bytes(), and size().

40  {
41  CHECK_EQ(pos_lvs.size(), size());
42  const auto operand = getOperand(0);
43  CHECK(operand);
44  const auto& operand_ti = operand->get_type_info();
45 
46  std::string size_fn_name = "array_size";
47  if (is_nullable_) {
48  size_fn_name += "_nullable";
49  }
50 
51  auto& builder = cgen_state->ir_builder_;
52 
53  std::vector<llvm::Value*> operand_lvs;
54  // iterate over column inputs
55  if (dynamic_cast<const Analyzer::ColumnVar*>(operand)) {
56  for (size_t i = 0; i < arg_lvs.size(); i++) {
57  auto lv = arg_lvs[i];
58  auto array_buff_lv =
59  cgen_state->emitExternalCall("array_buff",
60  llvm::Type::getInt8PtrTy(cgen_state->context_),
61  {lv, pos_lvs.front()});
62  auto const is_coords = (i == 0);
63  if (!is_coords) {
64  array_buff_lv = builder.CreateBitCast(
65  array_buff_lv, llvm::Type::getInt32PtrTy(cgen_state->context_));
66  }
67  operand_lvs.push_back(array_buff_lv);
68  const auto ptr_type = llvm::dyn_cast_or_null<llvm::PointerType>(lv->getType());
69  CHECK(ptr_type);
70  const auto elem_type = ptr_type->getPointerElementType();
71  CHECK(elem_type);
72  auto const shift = log2_bytes(is_coords ? 1 : 4);
73  std::vector<llvm::Value*> array_sz_args{
74  lv, pos_lvs.front(), cgen_state->llInt(shift)};
75  if (is_nullable_) { // TODO: should we do this for all arguments, or just points?
76  array_sz_args.push_back(
77  cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
78  }
79  operand_lvs.push_back(cgen_state->emitExternalCall(
80  size_fn_name, get_int_type(32, cgen_state->context_), array_sz_args));
81  }
82  } else {
83  for (size_t i = 0; i < arg_lvs.size(); i++) {
84  auto arg_lv = arg_lvs[i];
85  if (i > 0 && arg_lv->getType()->isPointerTy()) {
86  arg_lv = builder.CreateBitCast(arg_lv,
87  llvm::Type::getInt32PtrTy(cgen_state->context_));
88  }
89  operand_lvs.push_back(arg_lv);
90  }
91  }
92  CHECK_EQ(operand_lvs.size(),
93  size_t(2 * operand_ti.get_physical_coord_cols())); // array ptr and size
94 
95  // note that this block is the only one that differs from Area/Perimeter
96  // use the points array size argument for nullability
97  llvm::Value* null_check_operand_lv{nullptr};
98  if (is_nullable_) {
99  null_check_operand_lv = operand_lvs[1];
100  if (null_check_operand_lv->getType() !=
101  llvm::Type::getInt32Ty(cgen_state->context_)) {
102  CHECK(null_check_operand_lv->getType() ==
103  llvm::Type::getInt64Ty(cgen_state->context_));
104  // Geos functions come out 64-bit, cast down to 32 for now
105 
106  null_check_operand_lv = builder.CreateTrunc(
107  null_check_operand_lv, llvm::Type::getInt32Ty(cgen_state->context_));
108  }
109  }
110 
111  return std::make_tuple(operand_lvs, null_check_operand_lv);
112  }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
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.h:217
llvm::IRBuilder ir_builder_
Definition: CgenState.h:441
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:439
size_t size() const final
Definition: Centroid.h:33
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:306
#define CHECK(condition)
Definition: Logger.h:222
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:63
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:176

+ Here is the call graph for this function:

SQLTypeInfo spatial_type::Centroid::getNullType ( ) const
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 35 of file Centroid.h.

References kINT.

35 { return SQLTypeInfo(kINT); }
Definition: sqltypes.h:59
size_t spatial_type::Centroid::size ( ) const
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 33 of file Centroid.h.

Referenced by codegenLoads().

33 { return 1; }

+ Here is the caller graph for this function:


The documentation for this class was generated from the following file: