OmniSciDB  1dac507f6e
 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 
24 llvm::ConstantInt* CgenState::inlineIntNull(const SQLTypeInfo& type_info) {
25  auto type = type_info.get_type();
26  if (type_info.is_string()) {
27  switch (type_info.get_compression()) {
28  case kENCODING_DICT:
29  return llInt(static_cast<int32_t>(inline_int_null_val(type_info)));
30  case kENCODING_NONE:
31  return llInt(int64_t(0));
32  default:
33  CHECK(false);
34  }
35  }
36  switch (type) {
37  case kBOOLEAN:
38  return llInt(static_cast<int8_t>(inline_int_null_val(type_info)));
39  case kTINYINT:
40  return llInt(static_cast<int8_t>(inline_int_null_val(type_info)));
41  case kSMALLINT:
42  return llInt(static_cast<int16_t>(inline_int_null_val(type_info)));
43  case kINT:
44  return llInt(static_cast<int32_t>(inline_int_null_val(type_info)));
45  case kBIGINT:
46  case kTIME:
47  case kTIMESTAMP:
48  case kDATE:
49  case kINTERVAL_DAY_TIME:
51  return llInt(inline_int_null_val(type_info));
52  case kDECIMAL:
53  case kNUMERIC:
54  return llInt(inline_int_null_val(type_info));
55  case kARRAY:
56  return llInt(int64_t(0));
57  default:
58  abort();
59  }
60 }
61 
62 llvm::ConstantFP* CgenState::inlineFpNull(const SQLTypeInfo& type_info) {
63  CHECK(type_info.is_fp());
64  switch (type_info.get_type()) {
65  case kFLOAT:
66  return llFp(NULL_FLOAT);
67  case kDOUBLE:
68  return llFp(NULL_DOUBLE);
69  default:
70  abort();
71  }
72 }
73 
74 std::pair<llvm::ConstantInt*, llvm::ConstantInt*> CgenState::inlineIntMaxMin(
75  const size_t byte_width,
76  const bool is_signed) {
77  int64_t max_int{0}, min_int{0};
78  if (is_signed) {
79  std::tie(max_int, min_int) = inline_int_max_min(byte_width);
80  } else {
81  uint64_t max_uint{0}, min_uint{0};
82  std::tie(max_uint, min_uint) = inline_uint_max_min(byte_width);
83  max_int = static_cast<int64_t>(max_uint);
84  CHECK_EQ(uint64_t(0), min_uint);
85  }
86  switch (byte_width) {
87  case 1:
88  return std::make_pair(::ll_int(static_cast<int8_t>(max_int), context_),
89  ::ll_int(static_cast<int8_t>(min_int), context_));
90  case 2:
91  return std::make_pair(::ll_int(static_cast<int16_t>(max_int), context_),
92  ::ll_int(static_cast<int16_t>(min_int), context_));
93  case 4:
94  return std::make_pair(::ll_int(static_cast<int32_t>(max_int), context_),
95  ::ll_int(static_cast<int32_t>(min_int), context_));
96  case 8:
97  return std::make_pair(::ll_int(max_int, context_), ::ll_int(min_int, context_));
98  default:
99  abort();
100  }
101 }
102 
103 llvm::Value* CgenState::castToTypeIn(llvm::Value* val, const size_t dst_bits) {
104  auto src_bits = val->getType()->getScalarSizeInBits();
105  if (src_bits == dst_bits) {
106  return val;
107  }
108  if (val->getType()->isIntegerTy()) {
109  return ir_builder_.CreateIntCast(
110  val, get_int_type(dst_bits, context_), src_bits != 1);
111  }
112  // real (not dictionary-encoded) strings; store the pointer to the payload
113  if (val->getType()->isPointerTy()) {
114  return ir_builder_.CreatePointerCast(val, get_int_type(dst_bits, context_));
115  }
116 
117  CHECK(val->getType()->isFloatTy() || val->getType()->isDoubleTy());
118 
119  llvm::Type* dst_type = nullptr;
120  switch (dst_bits) {
121  case 64:
122  dst_type = llvm::Type::getDoubleTy(context_);
123  break;
124  case 32:
125  dst_type = llvm::Type::getFloatTy(context_);
126  break;
127  default:
128  CHECK(false);
129  }
130 
131  return ir_builder_.CreateFPCast(val, dst_type);
132 }
133 
134 llvm::Value* CgenState::emitCall(const std::string& fname,
135  const std::vector<llvm::Value*>& args) {
136  // Get the implementation from the runtime module.
137  auto func_impl = g_rt_module->getFunction(fname);
138  CHECK(func_impl);
139  // Get the function reference from the query module.
140  auto func = module_->getFunction(fname);
141  CHECK(func);
142  // If the function called isn't external, clone the implementation from the runtime
143  // module.
144  if (func->isDeclaration() && !func_impl->isDeclaration()) {
145  auto DestI = func->arg_begin();
146  for (auto arg_it = func_impl->arg_begin(); arg_it != func_impl->arg_end(); ++arg_it) {
147  DestI->setName(arg_it->getName());
148  vmap_[&*arg_it] = &*DestI++;
149  }
150 
151  llvm::SmallVector<llvm::ReturnInst*, 8> Returns; // Ignore returns cloned.
152  llvm::CloneFunctionInto(func, func_impl, vmap_, /*ModuleLevelChanges=*/true, Returns);
153  }
154 
155  return ir_builder_.CreateCall(func, args);
156 }
bool is_fp() const
Definition: sqltypes.h:481
#define CHECK_EQ(x, y)
Definition: Logger.h:198
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:103
#define NULL_DOUBLE
Definition: sqltypes.h:179
Definition: sqltypes.h:52
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:334
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:269
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::Module * module_
Definition: CgenState.h:264
llvm::LLVMContext & context_
Definition: CgenState.h:267
CHECK(cgen_state)
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:326
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:24
std::unique_ptr< llvm::Module > g_rt_module
#define NULL_FLOAT
Definition: sqltypes.h:178
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:252
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:134
std::pair< uint64_t, uint64_t > inline_uint_max_min(const size_t byte_width)
Definition: sqltypes.h:56
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:248
bool is_string() const
Definition: sqltypes.h:477
llvm::ValueToValueMapTy vmap_
Definition: CgenState.h:268
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:48
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:74
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:62