OmniSciDB  94e8789169
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CgenState.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2021 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 llvm::Constant* CgenState::inlineNull(const SQLTypeInfo& ti) {
78  return ti.is_fp() ? static_cast<llvm::Constant*>(inlineFpNull(ti))
79  : static_cast<llvm::Constant*>(inlineIntNull(ti));
80 }
81 
82 std::pair<llvm::ConstantInt*, llvm::ConstantInt*> CgenState::inlineIntMaxMin(
83  const size_t byte_width,
84  const bool is_signed) {
85  int64_t max_int{0}, min_int{0};
86  if (is_signed) {
87  std::tie(max_int, min_int) = inline_int_max_min(byte_width);
88  } else {
89  uint64_t max_uint{0}, min_uint{0};
90  std::tie(max_uint, min_uint) = inline_uint_max_min(byte_width);
91  max_int = static_cast<int64_t>(max_uint);
92  CHECK_EQ(uint64_t(0), min_uint);
93  }
94  switch (byte_width) {
95  case 1:
96  return std::make_pair(::ll_int(static_cast<int8_t>(max_int), context_),
97  ::ll_int(static_cast<int8_t>(min_int), context_));
98  case 2:
99  return std::make_pair(::ll_int(static_cast<int16_t>(max_int), context_),
100  ::ll_int(static_cast<int16_t>(min_int), context_));
101  case 4:
102  return std::make_pair(::ll_int(static_cast<int32_t>(max_int), context_),
103  ::ll_int(static_cast<int32_t>(min_int), context_));
104  case 8:
105  return std::make_pair(::ll_int(max_int, context_), ::ll_int(min_int, context_));
106  default:
107  abort();
108  }
109 }
110 
111 llvm::Value* CgenState::castToTypeIn(llvm::Value* val, const size_t dst_bits) {
112  auto src_bits = val->getType()->getScalarSizeInBits();
113  if (src_bits == dst_bits) {
114  return val;
115  }
116  if (val->getType()->isIntegerTy()) {
117  return ir_builder_.CreateIntCast(
118  val, get_int_type(dst_bits, context_), src_bits != 1);
119  }
120  // real (not dictionary-encoded) strings; store the pointer to the payload
121  if (val->getType()->isPointerTy()) {
122  return ir_builder_.CreatePointerCast(val, get_int_type(dst_bits, context_));
123  }
124 
125  CHECK(val->getType()->isFloatTy() || val->getType()->isDoubleTy());
126 
127  llvm::Type* dst_type = nullptr;
128  switch (dst_bits) {
129  case 64:
130  dst_type = llvm::Type::getDoubleTy(context_);
131  break;
132  case 32:
133  dst_type = llvm::Type::getFloatTy(context_);
134  break;
135  default:
136  CHECK(false);
137  }
138 
139  return ir_builder_.CreateFPCast(val, dst_type);
140 }
141 
142 llvm::Value* CgenState::emitCall(const std::string& fname,
143  const std::vector<llvm::Value*>& args) {
144  // Get the implementation from the runtime module.
145  auto func_impl = g_rt_module->getFunction(fname);
146  CHECK(func_impl) << fname;
147  // Get the function reference from the query module.
148  auto func = module_->getFunction(fname);
149  CHECK(func);
150  // If the function called isn't external, clone the implementation from the runtime
151  // module.
152  if (func->isDeclaration() && !func_impl->isDeclaration()) {
153  auto DestI = func->arg_begin();
154  for (auto arg_it = func_impl->arg_begin(); arg_it != func_impl->arg_end(); ++arg_it) {
155  DestI->setName(arg_it->getName());
156  vmap_[&*arg_it] = &*DestI++;
157  }
158 
159  llvm::SmallVector<llvm::ReturnInst*, 8> Returns; // Ignore returns cloned.
160  llvm::CloneFunctionInto(func, func_impl, vmap_, /*ModuleLevelChanges=*/true, Returns);
161  }
162 
163  return ir_builder_.CreateCall(func, args);
164 }
165 
166 void CgenState::emitErrorCheck(llvm::Value* condition,
167  llvm::Value* errorCode,
168  std::string label) {
169  needs_error_check_ = true;
170  auto check_ok = llvm::BasicBlock::Create(context_, label + "_ok", current_func_);
171  auto check_fail = llvm::BasicBlock::Create(context_, label + "_fail", current_func_);
172  ir_builder_.CreateCondBr(condition, check_ok, check_fail);
173  ir_builder_.SetInsertPoint(check_fail);
174  ir_builder_.CreateRet(errorCode);
175  ir_builder_.SetInsertPoint(check_ok);
176 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:111
#define NULL_DOUBLE
Definition: sqltypes.h:48
#define NULL_FLOAT
bool is_fp() const
Definition: sqltypes.h:482
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:329
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:311
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Module * module_
Definition: CgenState.h:318
llvm::LLVMContext & context_
Definition: CgenState.h:327
llvm::Function * current_func_
Definition: CgenState.h:321
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
std::unique_ptr< llvm::Module > g_rt_module
bool needs_error_check_
Definition: CgenState.h:344
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:304
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:142
std::pair< uint64_t, uint64_t > inline_uint_max_min(const size_t byte_width)
llvm::Constant * inlineNull(const SQLTypeInfo &)
Definition: CgenState.cpp:77
Definition: sqltypes.h:52
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:319
void emitErrorCheck(llvm::Value *condition, llvm::Value *errorCode, std::string label)
Definition: CgenState.cpp:166
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:300
#define CHECK(condition)
Definition: Logger.h:197
llvm::ValueToValueMapTy vmap_
Definition: CgenState.h:328
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:44
bool is_string() const
Definition: sqltypes.h:478
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:82
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65