OmniSciDB  72180abbfe
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CgenState.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019 OmniSci, 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 "CgenState.h"
19 
20 #include <llvm/Transforms/Utils/Cloning.h>
21 
22 extern std::unique_ptr<llvm::Module> g_rt_module;
23 #ifdef ENABLE_GEOS
24 extern std::unique_ptr<llvm::Module> g_rt_geos_module;
25 #endif
26 
27 llvm::ConstantInt* CgenState::inlineIntNull(const SQLTypeInfo& type_info) {
28  auto type = type_info.get_type();
29  if (type_info.is_string()) {
30  switch (type_info.get_compression()) {
31  case kENCODING_DICT:
32  return llInt(static_cast<int32_t>(inline_int_null_val(type_info)));
33  case kENCODING_NONE:
34  return llInt(int64_t(0));
35  default:
36  CHECK(false);
37  }
38  }
39  switch (type) {
40  case kBOOLEAN:
41  return llInt(static_cast<int8_t>(inline_int_null_val(type_info)));
42  case kTINYINT:
43  return llInt(static_cast<int8_t>(inline_int_null_val(type_info)));
44  case kSMALLINT:
45  return llInt(static_cast<int16_t>(inline_int_null_val(type_info)));
46  case kINT:
47  return llInt(static_cast<int32_t>(inline_int_null_val(type_info)));
48  case kBIGINT:
49  case kTIME:
50  case kTIMESTAMP:
51  case kDATE:
52  case kINTERVAL_DAY_TIME:
54  return llInt(inline_int_null_val(type_info));
55  case kDECIMAL:
56  case kNUMERIC:
57  return llInt(inline_int_null_val(type_info));
58  case kARRAY:
59  return llInt(int64_t(0));
60  default:
61  abort();
62  }
63 }
64 
65 llvm::ConstantFP* CgenState::inlineFpNull(const SQLTypeInfo& type_info) {
66  CHECK(type_info.is_fp());
67  switch (type_info.get_type()) {
68  case kFLOAT:
69  return llFp(NULL_FLOAT);
70  case kDOUBLE:
71  return llFp(NULL_DOUBLE);
72  default:
73  abort();
74  }
75 }
76 
77 std::pair<llvm::ConstantInt*, llvm::ConstantInt*> CgenState::inlineIntMaxMin(
78  const size_t byte_width,
79  const bool is_signed) {
80  int64_t max_int{0}, min_int{0};
81  if (is_signed) {
82  std::tie(max_int, min_int) = inline_int_max_min(byte_width);
83  } else {
84  uint64_t max_uint{0}, min_uint{0};
85  std::tie(max_uint, min_uint) = inline_uint_max_min(byte_width);
86  max_int = static_cast<int64_t>(max_uint);
87  CHECK_EQ(uint64_t(0), min_uint);
88  }
89  switch (byte_width) {
90  case 1:
91  return std::make_pair(::ll_int(static_cast<int8_t>(max_int), context_),
92  ::ll_int(static_cast<int8_t>(min_int), context_));
93  case 2:
94  return std::make_pair(::ll_int(static_cast<int16_t>(max_int), context_),
95  ::ll_int(static_cast<int16_t>(min_int), context_));
96  case 4:
97  return std::make_pair(::ll_int(static_cast<int32_t>(max_int), context_),
98  ::ll_int(static_cast<int32_t>(min_int), context_));
99  case 8:
100  return std::make_pair(::ll_int(max_int, context_), ::ll_int(min_int, context_));
101  default:
102  abort();
103  }
104 }
105 
106 llvm::Value* CgenState::castToTypeIn(llvm::Value* val, const size_t dst_bits) {
107  auto src_bits = val->getType()->getScalarSizeInBits();
108  if (src_bits == dst_bits) {
109  return val;
110  }
111  if (val->getType()->isIntegerTy()) {
112  return ir_builder_.CreateIntCast(
113  val, get_int_type(dst_bits, context_), src_bits != 1);
114  }
115  // real (not dictionary-encoded) strings; store the pointer to the payload
116  if (val->getType()->isPointerTy()) {
117  return ir_builder_.CreatePointerCast(val, get_int_type(dst_bits, context_));
118  }
119 
120  CHECK(val->getType()->isFloatTy() || val->getType()->isDoubleTy());
121 
122  llvm::Type* dst_type = nullptr;
123  switch (dst_bits) {
124  case 64:
125  dst_type = llvm::Type::getDoubleTy(context_);
126  break;
127  case 32:
128  dst_type = llvm::Type::getFloatTy(context_);
129  break;
130  default:
131  CHECK(false);
132  }
133 
134  return ir_builder_.CreateFPCast(val, dst_type);
135 }
136 
137 llvm::Value* CgenState::emitCall(const std::string& fname,
138  const std::vector<llvm::Value*>& args) {
139  // Get the implementation from the runtime module.
140  auto func_impl = g_rt_module->getFunction(fname);
141  CHECK(func_impl);
142  // Get the function reference from the query module.
143  auto func = module_->getFunction(fname);
144  CHECK(func);
145  // If the function called isn't external, clone the implementation from the runtime
146  // module.
147  if (func->isDeclaration() && !func_impl->isDeclaration()) {
148  auto DestI = func->arg_begin();
149  for (auto arg_it = func_impl->arg_begin(); arg_it != func_impl->arg_end(); ++arg_it) {
150  DestI->setName(arg_it->getName());
151  vmap_[&*arg_it] = &*DestI++;
152  }
153 
154  llvm::SmallVector<llvm::ReturnInst*, 8> Returns; // Ignore returns cloned.
155  llvm::CloneFunctionInto(func, func_impl, vmap_, /*ModuleLevelChanges=*/true, Returns);
156  }
157 
158  return ir_builder_.CreateCall(func, args);
159 }
160 
161 void CgenState::emitErrorCheck(llvm::Value* condition,
162  llvm::Value* errorCode,
163  std::string label) {
164  needs_error_check_ = true;
165  auto check_ok = llvm::BasicBlock::Create(context_, label + "_ok", row_func_);
166  auto check_fail = llvm::BasicBlock::Create(context_, label + "_fail", row_func_);
167  ir_builder_.CreateCondBr(condition, check_ok, check_fail);
168  ir_builder_.SetInsertPoint(check_fail);
169  ir_builder_.CreateRet(errorCode);
170  ir_builder_.SetInsertPoint(check_ok);
171 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:106
#define NULL_DOUBLE
Definition: sqltypes.h:184
Definition: sqltypes.h:50
bool is_fp() const
Definition: sqltypes.h:412
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:257
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Function * row_func_
Definition: CgenState.h:315
llvm::Module * module_
Definition: CgenState.h:314
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
std::unique_ptr< llvm::Module > g_rt_module
#define NULL_FLOAT
Definition: sqltypes.h:183
bool needs_error_check_
Definition: CgenState.h:334
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:300
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
std::pair< uint64_t, uint64_t > inline_uint_max_min(const size_t byte_width)
Definition: sqltypes.h:54
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:265
void emitErrorCheck(llvm::Value *condition, llvm::Value *errorCode, std::string label)
Definition: CgenState.cpp:161
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
llvm::ValueToValueMapTy vmap_
Definition: CgenState.h:318
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
std::pair< int64_t, int64_t > inline_int_max_min(const size_t byte_width)
Definition: sqltypes.h:46
bool is_string() const
Definition: sqltypes.h:408
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:77
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65