OmniSciDB  6686921089
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CgenState.h
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 #pragma once
18 
19 #include "IRCodegenUtils.h"
20 #include "InValuesBitmap.h"
21 #include "InputMetadata.h"
22 #include "LLVMGlobalContext.h"
23 
24 #include "../Analyzer/Analyzer.h"
25 #include "../Shared/InsertionOrderedMap.h"
26 
27 #include <llvm/IR/Constants.h>
28 #include <llvm/IR/IRBuilder.h>
29 #include <llvm/Transforms/Utils/ValueMapper.h>
30 
32  llvm::Value* buffer;
33  llvm::Value* size;
34  llvm::Value* is_null;
35 };
36 
37 struct CgenState {
38  public:
39  CgenState(const size_t num_query_infos, const bool contains_left_deep_outer_join)
40  : module_(nullptr)
41  , row_func_(nullptr)
42  , filter_func_(nullptr)
43  , current_func_(nullptr)
44  , row_func_bb_(nullptr)
45  , filter_func_bb_(nullptr)
46  , row_func_call_(nullptr)
47  , filter_func_call_(nullptr)
50  , contains_left_deep_outer_join_(contains_left_deep_outer_join)
51  , outer_join_match_found_per_level_(std::max(num_query_infos, size_t(1)) - 1)
54  , query_func_(nullptr)
56 
57  CgenState(llvm::LLVMContext& context)
58  : module_(nullptr)
59  , row_func_(nullptr)
60  , context_(context)
65  , query_func_(nullptr)
67 
68  size_t getOrAddLiteral(const Analyzer::Constant* constant,
69  const EncodingType enc_type,
70  const int dict_id,
71  const int device_id) {
72  const auto& ti = constant->get_type_info();
73  const auto type = ti.is_decimal() ? decimal_to_int_type(ti) : ti.get_type();
74  switch (type) {
75  case kBOOLEAN:
76  return getOrAddLiteral(constant->get_is_null()
77  ? int8_t(inline_int_null_val(ti))
78  : int8_t(constant->get_constval().boolval ? 1 : 0),
79  device_id);
80  case kTINYINT:
81  return getOrAddLiteral(constant->get_is_null()
82  ? int8_t(inline_int_null_val(ti))
83  : constant->get_constval().tinyintval,
84  device_id);
85  case kSMALLINT:
86  return getOrAddLiteral(constant->get_is_null()
87  ? int16_t(inline_int_null_val(ti))
88  : constant->get_constval().smallintval,
89  device_id);
90  case kINT:
91  return getOrAddLiteral(constant->get_is_null() ? int32_t(inline_int_null_val(ti))
92  : constant->get_constval().intval,
93  device_id);
94  case kBIGINT:
95  return getOrAddLiteral(constant->get_is_null()
96  ? int64_t(inline_int_null_val(ti))
97  : constant->get_constval().bigintval,
98  device_id);
99  case kFLOAT:
100  return getOrAddLiteral(constant->get_is_null()
101  ? float(inline_fp_null_val(ti))
102  : constant->get_constval().floatval,
103  device_id);
104  case kDOUBLE:
105  return getOrAddLiteral(constant->get_is_null()
106  ? inline_fp_null_val(ti)
107  : constant->get_constval().doubleval,
108  device_id);
109  case kCHAR:
110  case kTEXT:
111  case kVARCHAR:
112  if (enc_type == kENCODING_DICT) {
113  if (constant->get_is_null()) {
114  return getOrAddLiteral(int32_t(inline_int_null_val(ti)), device_id);
115  }
116  return getOrAddLiteral(
117  std::make_pair(*constant->get_constval().stringval, dict_id), device_id);
118  }
119  CHECK_EQ(kENCODING_NONE, enc_type);
120  if (constant->get_is_null()) {
121  throw std::runtime_error(
122  "CHAR / VARCHAR NULL literal not supported in this context"); // TODO(alex):
123  // support
124  // null
125  }
126  return getOrAddLiteral(*constant->get_constval().stringval, device_id);
127  case kTIME:
128  case kTIMESTAMP:
129  case kDATE:
130  case kINTERVAL_DAY_TIME:
132  // TODO(alex): support null
133  return getOrAddLiteral(constant->get_constval().bigintval, device_id);
134  case kARRAY: {
135  if (enc_type == kENCODING_NONE) {
136  if (ti.get_subtype() == kDOUBLE) {
137  std::vector<double> double_array_literal;
138  for (const auto& value : constant->get_value_list()) {
139  const auto c = dynamic_cast<const Analyzer::Constant*>(value.get());
140  CHECK(c);
141  double d = c->get_constval().doubleval;
142  double_array_literal.push_back(d);
143  }
144  return getOrAddLiteral(double_array_literal, device_id);
145  }
146  if (ti.get_subtype() == kINT) {
147  std::vector<int32_t> int32_array_literal;
148  for (const auto& value : constant->get_value_list()) {
149  const auto c = dynamic_cast<const Analyzer::Constant*>(value.get());
150  CHECK(c);
151  int32_t i = c->get_constval().intval;
152  int32_array_literal.push_back(i);
153  }
154  return getOrAddLiteral(int32_array_literal, device_id);
155  }
156  if (ti.get_subtype() == kTINYINT) {
157  std::vector<int8_t> int8_array_literal;
158  for (const auto& value : constant->get_value_list()) {
159  const auto c = dynamic_cast<const Analyzer::Constant*>(value.get());
160  CHECK(c);
161  int8_t i = c->get_constval().tinyintval;
162  int8_array_literal.push_back(i);
163  }
164  if (ti.get_comp_param() == 64) {
165  return getOrAddLiteral(std::make_pair(int8_array_literal, 64), device_id);
166  }
167  return getOrAddLiteral(int8_array_literal, device_id);
168  }
169  throw std::runtime_error("Unsupported literal array");
170  }
171  if (enc_type == kENCODING_GEOINT) {
172  if (ti.get_subtype() == kTINYINT) {
173  std::vector<int8_t> int8_array_literal;
174  for (const auto& value : constant->get_value_list()) {
175  const auto c = dynamic_cast<const Analyzer::Constant*>(value.get());
176  CHECK(c);
177  int8_t i = c->get_constval().tinyintval;
178  int8_array_literal.push_back(i);
179  }
180  if (ti.get_comp_param() == 32) {
181  return getOrAddLiteral(std::make_pair(int8_array_literal, 32), device_id);
182  }
183  return getOrAddLiteral(int8_array_literal, device_id);
184  }
185  }
186  throw std::runtime_error("Encoded literal arrays are not supported");
187  }
188  default:
189  abort();
190  }
191  }
192 
193  using LiteralValue = boost::variant<int8_t,
194  int16_t,
195  int32_t,
196  int64_t,
197  float,
198  double,
199  std::pair<std::string, int>,
200  std::string,
201  std::vector<double>,
202  std::vector<int32_t>,
203  std::vector<int8_t>,
204  std::pair<std::vector<int8_t>, int>>;
205  using LiteralValues = std::vector<LiteralValue>;
206 
207  const std::unordered_map<int, LiteralValues>& getLiterals() const { return literals_; }
208 
209  llvm::Value* addStringConstant(const std::string& str) {
210  llvm::Value* str_lv = ir_builder_.CreateGlobalString(
211  str, "str_const_" + std::to_string(std::hash<std::string>()(str)));
212  auto i8_ptr = llvm::PointerType::get(get_int_type(8, context_), 0);
213  str_constants_.push_back(str_lv);
214  str_lv = ir_builder_.CreateBitCast(str_lv, i8_ptr);
215  return str_lv;
216  }
217 
219  std::unique_ptr<InValuesBitmap>& in_values_bitmap) {
220  if (in_values_bitmap->isEmpty()) {
221  return in_values_bitmap.get();
222  }
223  in_values_bitmaps_.emplace_back(std::move(in_values_bitmap));
224  return in_values_bitmaps_.back().get();
225  }
226  // look up a runtime function based on the name, return type and type of
227  // the arguments and call it; x64 only, don't call from GPU codegen
228  llvm::Value* emitExternalCall(
229  const std::string& fname,
230  llvm::Type* ret_type,
231  const std::vector<llvm::Value*> args,
232  const std::vector<llvm::Attribute::AttrKind>& fnattrs = {},
233  const bool has_struct_return = false) {
234  std::vector<llvm::Type*> arg_types;
235  for (const auto arg : args) {
236  CHECK(arg);
237  arg_types.push_back(arg->getType());
238  }
239  auto func_ty = llvm::FunctionType::get(ret_type, arg_types, false);
240  llvm::AttributeList attrs;
241  if (!fnattrs.empty()) {
242  std::vector<std::pair<unsigned, llvm::Attribute>> indexedAttrs;
243  indexedAttrs.reserve(fnattrs.size());
244  for (auto attr : fnattrs) {
245  indexedAttrs.emplace_back(llvm::AttributeList::FunctionIndex,
246  llvm::Attribute::get(context_, attr));
247  }
248  attrs = llvm::AttributeList::get(context_,
249  {&indexedAttrs.front(), indexedAttrs.size()});
250  }
251 
252  auto func_p = module_->getOrInsertFunction(fname, func_ty, attrs);
253  CHECK(func_p);
254  auto callee = func_p.getCallee();
255  llvm::Function* func{nullptr};
256  if (auto callee_cast = llvm::dyn_cast<llvm::ConstantExpr>(callee)) {
257  // Get or insert function automatically adds a ConstantExpr cast if the return type
258  // of the existing function does not match the supplied return type.
259  CHECK(callee_cast->isCast());
260  CHECK_EQ(callee_cast->getNumOperands(), size_t(1));
261  func = llvm::dyn_cast<llvm::Function>(callee_cast->getOperand(0));
262  } else {
263  func = llvm::dyn_cast<llvm::Function>(callee);
264  }
265  CHECK(func);
266  llvm::FunctionType* func_type = func_p.getFunctionType();
267  CHECK(func_type);
268  if (has_struct_return) {
269  const auto arg_ti = func_type->getParamType(0);
270  CHECK(arg_ti->isPointerTy() && arg_ti->getPointerElementType()->isStructTy());
271  auto attr_list = func->getAttributes();
272  llvm::AttrBuilder arr_arg_builder(attr_list.getParamAttributes(0));
273  arr_arg_builder.addAttribute(llvm::Attribute::StructRet);
274  func->addParamAttrs(0, arr_arg_builder);
275  }
276  const size_t arg_start = has_struct_return ? 1 : 0;
277  for (size_t i = arg_start; i < func->arg_size(); i++) {
278  const auto arg_ti = func_type->getParamType(i);
279  if (arg_ti->isPointerTy() && arg_ti->getPointerElementType()->isStructTy()) {
280  auto attr_list = func->getAttributes();
281  llvm::AttrBuilder arr_arg_builder(attr_list.getParamAttributes(i));
282  arr_arg_builder.addByValAttr(arg_ti->getPointerElementType());
283  func->addParamAttrs(i, arr_arg_builder);
284  }
285  }
286  llvm::Value* result = ir_builder_.CreateCall(func_p, args);
287  // check the assumed type
288  CHECK_EQ(result->getType(), ret_type);
289  return result;
290  }
291 
292  llvm::Value* emitCall(const std::string& fname, const std::vector<llvm::Value*>& args);
293 
294  size_t getLiteralBufferUsage(const int device_id) { return literal_bytes_[device_id]; }
295 
296  llvm::Value* castToTypeIn(llvm::Value* val, const size_t bit_width);
297 
298  std::pair<llvm::ConstantInt*, llvm::ConstantInt*> inlineIntMaxMin(
299  const size_t byte_width,
300  const bool is_signed);
301 
302  llvm::ConstantInt* inlineIntNull(const SQLTypeInfo&);
303  llvm::ConstantFP* inlineFpNull(const SQLTypeInfo&);
304  llvm::Constant* inlineNull(const SQLTypeInfo&);
305 
306  template <class T>
307  llvm::ConstantInt* llInt(const T v) const {
309  }
310 
311  llvm::ConstantFP* llFp(const float v) const {
312  return static_cast<llvm::ConstantFP*>(
313  llvm::ConstantFP::get(llvm::Type::getFloatTy(context_), v));
314  }
315 
316  llvm::ConstantFP* llFp(const double v) const {
317  return static_cast<llvm::ConstantFP*>(
318  llvm::ConstantFP::get(llvm::Type::getDoubleTy(context_), v));
319  }
320 
321  llvm::ConstantInt* llBool(const bool v) const { return ::ll_bool(v, context_); }
322 
323  void emitErrorCheck(llvm::Value* condition, llvm::Value* errorCode, std::string label);
324 
325  std::vector<std::string> gpuFunctionsToReplace(llvm::Function* fn);
326 
327  void replaceFunctionForGpu(const std::string& fcn_to_replace, llvm::Function* fn);
328 
329  llvm::Module* module_;
330  llvm::Function* row_func_;
331  llvm::Function* filter_func_;
332  llvm::Function* current_func_;
333  llvm::BasicBlock* row_func_bb_;
334  llvm::BasicBlock* filter_func_bb_;
335  llvm::CallInst* row_func_call_;
336  llvm::CallInst* filter_func_call_;
337  std::vector<llvm::Function*> helper_functions_;
338  llvm::LLVMContext& context_;
339  llvm::ValueToValueMapTy vmap_; // used for cloning the runtime module
340  llvm::IRBuilder<> ir_builder_;
341  std::unordered_map<int, std::vector<llvm::Value*>> fetch_cache_;
344  llvm::Value* lv;
345  };
346  std::vector<FunctionOperValue> ext_call_cache_;
347  std::vector<llvm::Value*> group_by_expr_cache_;
348  std::vector<llvm::Value*> str_constants_;
349  std::vector<llvm::Value*> frag_offsets_;
351  std::vector<llvm::Value*> outer_join_match_found_per_level_;
352  std::unordered_map<int, llvm::Value*> scan_idx_to_hash_pos_;
354  std::vector<std::unique_ptr<const InValuesBitmap>> in_values_bitmaps_;
355  std::map<std::pair<llvm::Value*, llvm::Value*>, ArrayLoadCodegen>
356  array_load_cache_; // byte stream to array info
357  std::unordered_map<std::string, llvm::Value*> geo_target_cache_;
360 
361  llvm::Function* query_func_;
362  llvm::IRBuilder<> query_func_entry_ir_builder_;
363  std::unordered_map<int, std::vector<llvm::Value*>> query_func_literal_loads_;
364 
368  };
369  std::unordered_map<llvm::Value*, HoistedLiteralLoadLocator> row_func_hoisted_literals_;
370 
371  static size_t literalBytes(const CgenState::LiteralValue& lit) {
372  switch (lit.which()) {
373  case 0:
374  return 1; // int8_t
375  case 1:
376  return 2; // int16_t
377  case 2:
378  return 4; // int32_t
379  case 3:
380  return 8; // int64_t
381  case 4:
382  return 4; // float
383  case 5:
384  return 8; // double
385  case 6:
386  return 4; // std::pair<std::string, int>
387  case 7:
388  return 4; // std::string
389  case 8:
390  return 4; // std::vector<double>
391  case 9:
392  return 4; // std::vector<int32_t>
393  case 10:
394  return 4; // std::vector<int8_t>
395  case 11:
396  return 4; // std::pair<std::vector<int8_t>, int>
397  default:
398  abort();
399  }
400  }
401 
402  static size_t addAligned(const size_t off_in, const size_t alignment) {
403  size_t off = off_in;
404  if (off % alignment != 0) {
405  off += (alignment - off % alignment);
406  }
407  return off + alignment;
408  }
409 
410  void maybeCloneFunctionRecursive(llvm::Function* fn);
411 
412  private:
413  template <class T>
414  size_t getOrAddLiteral(const T& val, const int device_id) {
415  const LiteralValue var_val(val);
416  size_t literal_found_off{0};
417  auto& literals = literals_[device_id];
418  for (const auto& literal : literals) {
419  const auto lit_bytes = literalBytes(literal);
420  literal_found_off = addAligned(literal_found_off, lit_bytes);
421  if (literal == var_val) {
422  return literal_found_off - lit_bytes;
423  }
424  }
425  literals.emplace_back(val);
426  const auto lit_bytes = literalBytes(var_val);
427  literal_bytes_[device_id] = addAligned(literal_bytes_[device_id], lit_bytes);
428  return literal_bytes_[device_id] - lit_bytes;
429  }
430 
431  std::unordered_map<int, LiteralValues> literals_;
432  std::unordered_map<int, size_t> literal_bytes_;
433 };
434 
std::vector< llvm::Function * > helper_functions_
Definition: CgenState.h:337
int8_t tinyintval
Definition: sqltypes.h:212
CgenState(const size_t num_query_infos, const bool contains_left_deep_outer_join)
Definition: CgenState.h:39
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
Definition: Analyzer.h:336
#define CHECK_EQ(x, y)
Definition: Logger.h:217
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:113
std::vector< llvm::Value * > outer_join_match_found_per_level_
Definition: CgenState.h:351
Definition: sqltypes.h:49
std::map< std::pair< llvm::Value *, llvm::Value * >, ArrayLoadCodegen > array_load_cache_
Definition: CgenState.h:356
const Analyzer::FunctionOper * foper
Definition: CgenState.h:343
llvm::Value * addStringConstant(const std::string &str)
Definition: CgenState.h:209
void maybeCloneFunctionRecursive(llvm::Function *fn)
Definition: CgenState.cpp:144
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:228
llvm::Function * query_func_
Definition: CgenState.h:361
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
std::unordered_map< llvm::Value *, HoistedLiteralLoadLocator > row_func_hoisted_literals_
Definition: CgenState.h:369
llvm::IRBuilder ir_builder_
Definition: CgenState.h:340
int8_t boolval
Definition: sqltypes.h:211
bool get_is_null() const
Definition: Analyzer.h:333
std::vector< llvm::Value * > str_constants_
Definition: CgenState.h:348
llvm::ConstantInt * llBool(const bool v) const
Definition: CgenState.h:321
std::unordered_map< int, std::vector< llvm::Value * > > query_func_literal_loads_
Definition: CgenState.h:363
bool needs_geos_
Definition: CgenState.h:359
InsertionOrderedMap filter_func_args_
Definition: CgenState.h:353
const bool contains_left_deep_outer_join_
Definition: CgenState.h:350
llvm::Value * buffer
Definition: CgenState.h:32
CgenState(llvm::LLVMContext &context)
Definition: CgenState.h:57
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const std::unordered_map< int, LiteralValues > & getLiterals() const
Definition: CgenState.h:207
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
int32_t intval
Definition: sqltypes.h:214
std::unordered_map< std::string, llvm::Value * > geo_target_cache_
Definition: CgenState.h:357
size_t getOrAddLiteral(const T &val, const int device_id)
Definition: CgenState.h:414
llvm::ConstantFP * llFp(const double v) const
Definition: CgenState.h:316
std::string to_string(char const *&&v)
static size_t literalBytes(const CgenState::LiteralValue &lit)
Definition: CgenState.h:371
std::vector< FunctionOperValue > ext_call_cache_
Definition: CgenState.h:346
llvm::Function * row_func_
Definition: CgenState.h:330
float floatval
Definition: sqltypes.h:216
std::vector< llvm::Value * > group_by_expr_cache_
Definition: CgenState.h:347
boost::variant< int8_t, int16_t, int32_t, int64_t, float, double, std::pair< std::string, int >, std::string, std::vector< double >, std::vector< int32_t >, std::vector< int8_t >, std::pair< std::vector< int8_t >, int >> LiteralValue
Definition: CgenState.h:204
EncodingType
Definition: sqltypes.h:233
llvm::Module * module_
Definition: CgenState.h:329
llvm::LLVMContext & context_
Definition: CgenState.h:338
llvm::Function * current_func_
Definition: CgenState.h:332
size_t getOrAddLiteral(const Analyzer::Constant *constant, const EncodingType enc_type, const int dict_id, const int device_id)
Definition: CgenState.h:68
std::unordered_map< int, std::vector< llvm::Value * > > fetch_cache_
Definition: CgenState.h:341
static size_t addAligned(const size_t off_in, const size_t alignment)
Definition: CgenState.h:402
llvm::CallInst * filter_func_call_
Definition: CgenState.h:336
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:29
int64_t bigintval
Definition: sqltypes.h:215
std::vector< LiteralValue > LiteralValues
Definition: CgenState.h:205
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
Definition: CgenState.h:218
void replaceFunctionForGpu(const std::string &fcn_to_replace, llvm::Function *fn)
Definition: CgenState.cpp:275
std::unordered_map< int, size_t > literal_bytes_
Definition: CgenState.h:432
int16_t smallintval
Definition: sqltypes.h:213
std::unordered_map< int, llvm::Value * > scan_idx_to_hash_pos_
Definition: CgenState.h:352
bool needs_error_check_
Definition: CgenState.h:358
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:311
std::vector< std::string > gpuFunctionsToReplace(llvm::Function *fn)
Definition: CgenState.cpp:252
llvm::IRBuilder query_func_entry_ir_builder_
Definition: CgenState.h:362
llvm::BasicBlock * filter_func_bb_
Definition: CgenState.h:334
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:175
std::string * stringval
Definition: sqltypes.h:220
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:455
llvm::Constant * inlineNull(const SQLTypeInfo &)
Definition: CgenState.cpp:79
std::vector< std::unique_ptr< const InValuesBitmap > > in_values_bitmaps_
Definition: CgenState.h:354
Definition: sqltypes.h:52
Definition: sqltypes.h:53
llvm::Function * filter_func_
Definition: CgenState.h:331
std::unordered_map< int, LiteralValues > literals_
Definition: CgenState.h:431
std::vector< llvm::Value * > frag_offsets_
Definition: CgenState.h:349
llvm::Value * is_null
Definition: CgenState.h:34
size_t getLiteralBufferUsage(const int device_id)
Definition: CgenState.h:294
Datum get_constval() const
Definition: Analyzer.h:334
void emitErrorCheck(llvm::Value *condition, llvm::Value *errorCode, std::string label)
Definition: CgenState.cpp:187
Definition: sqltypes.h:41
llvm::LLVMContext & getGlobalLLVMContext()
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:307
bool g_enable_watchdog false
Definition: Execute.cpp:76
#define CHECK(condition)
Definition: Logger.h:209
llvm::ValueToValueMapTy vmap_
Definition: CgenState.h:339
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
llvm::ConstantInt * ll_bool(const bool v, llvm::LLVMContext &context)
Definition: sqltypes.h:45
llvm::Value * size
Definition: CgenState.h:33
llvm::CallInst * row_func_call_
Definition: CgenState.h:335
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:84
double doubleval
Definition: sqltypes.h:217
llvm::BasicBlock * row_func_bb_
Definition: CgenState.h:333
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:67