OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StartEndPoint.h
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 #pragma once
18 
20 
21 namespace spatial_type {
22 
23 class StartEndPoint : public Codegen {
24  public:
25  StartEndPoint(const Analyzer::GeoOperator* geo_operator) : Codegen(geo_operator) {
26  CHECK_EQ(operator_->size(), size_t(1));
27  // nulls not supported yet
28  this->is_nullable_ = false;
29  }
30 
31  size_t size() const final { return 1; }
32 
33  SQLTypeInfo getNullType() const final { return SQLTypeInfo(kNULLT); }
34 
35  // returns arguments lvs and null lv
36  std::tuple<std::vector<llvm::Value*>, llvm::Value*> codegenLoads(
37  const std::vector<llvm::Value*>& arg_lvs,
38  const std::vector<llvm::Value*>& pos_lvs,
39  CgenState* cgen_state) final {
40  CHECK_EQ(pos_lvs.size(), size());
41  // TODO: add null handling
42  if (arg_lvs.size() == size_t(1)) {
43  // col byte stream from column on disk
44  auto operand = getOperand(0);
45  CHECK(operand);
46  const auto& geo_ti = operand->get_type_info();
47  CHECK(geo_ti.get_type() == kLINESTRING);
48 
49  std::vector<llvm::Value*> array_operand_lvs;
50  array_operand_lvs.push_back(
51  cgen_state->emitExternalCall("array_buff",
52  llvm::Type::getInt8PtrTy(cgen_state->context_),
53  {arg_lvs.front(), pos_lvs.front()}));
54  const bool is_nullable = !geo_ti.get_notnull();
55  std::string size_fn_name = "array_size";
56  if (is_nullable) {
57  size_fn_name += "_nullable";
58  }
59  uint32_t elem_sz = 1; // TINYINT coords array
60  std::vector<llvm::Value*> array_sz_args{
61  arg_lvs.front(), pos_lvs.front(), cgen_state->llInt(log2_bytes(elem_sz))};
62  if (is_nullable) {
63  array_sz_args.push_back(
64  cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
65  }
66  array_operand_lvs.push_back(cgen_state->emitExternalCall(
67  size_fn_name, get_int_type(32, cgen_state->context_), array_sz_args));
68  return std::make_tuple(array_operand_lvs, nullptr);
69  }
70  CHECK_EQ(arg_lvs.size(), size_t(2)); // ptr, size
71  return std::make_tuple(arg_lvs, nullptr);
72  }
73 
74  std::vector<llvm::Value*> codegen(const std::vector<llvm::Value*>& args,
75  CodeGenerator::NullCheckCodegen* nullcheck_codegen,
76  CgenState* cgen_state,
77  const CompilationOptions& co) final {
78  CHECK_EQ(args.size(), size_t(2)); // ptr, size
79  const auto& geo_ti = getOperand(0)->get_type_info();
80  CHECK(geo_ti.is_geometry());
81 
82  auto& builder = cgen_state->ir_builder_;
83  llvm::Value* array_buff_cast{nullptr};
84  int32_t elem_size_bytes = 0;
85  if (geo_ti.get_compression() == kENCODING_GEOINT) {
86  array_buff_cast = builder.CreateBitCast(
87  args.front(), llvm::Type::getInt32PtrTy(cgen_state->context_));
88  elem_size_bytes = 4; // 4-byte ints
89  } else {
90  array_buff_cast = builder.CreateBitCast(
91  args.front(), llvm::Type::getDoublePtrTy(cgen_state->context_));
92  elem_size_bytes = 8; // doubles
93  }
94  CHECK_GT(elem_size_bytes, 0);
95  const bool is_end_point = getName() == "ST_EndPoint";
96  const auto num_elements_lv =
97  builder.CreateSDiv(args.back(), cgen_state->llInt(elem_size_bytes));
98  const auto index_lv =
99  is_end_point ? builder.CreateSub(num_elements_lv, cgen_state->llInt(int32_t(2)))
100  : cgen_state->llInt(int32_t(0));
101  auto array_offset_lv = builder.CreateGEP(
102  array_buff_cast->getType()->getScalarType()->getPointerElementType(),
103  array_buff_cast,
104  index_lv,
105  operator_->getName() + "_Offset");
106  return {array_offset_lv, args.back()};
107  }
108 };
109 
110 } // namespace spatial_type
#define CHECK_EQ(x, y)
Definition: Logger.h:301
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
#define CHECK_GT(x, y)
Definition: Logger.h:305
std::vector< llvm::Value * > codegen(const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
Definition: StartEndPoint.h:74
StartEndPoint(const Analyzer::GeoOperator *geo_operator)
Definition: StartEndPoint.h:25
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
Definition: StartEndPoint.h:36
size_t size() const final
Definition: StartEndPoint.h:31
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:69
size_t size() const
Definition: Analyzer.cpp:4211
#define CHECK(condition)
Definition: Logger.h:291
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:64
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:198
SQLTypeInfo getNullType() const final
Definition: StartEndPoint.h:33