25 #include "../Analyzer/Analyzer.h"
26 #include "../Shared/InsertionOrderedMap.h"
28 #include <llvm/IR/Constants.h>
29 #include <llvm/IR/IRBuilder.h>
30 #include <llvm/Transforms/Utils/ValueMapper.h>
41 const bool contains_left_deep_outer_join,
43 CgenState(
const size_t num_query_infos,
const bool contains_left_deep_outer_join);
49 const int device_id) {
99 throw std::runtime_error(
100 "CHAR / VARCHAR NULL literal not supported in this context");
114 if (ti.get_subtype() ==
kDOUBLE) {
115 std::vector<double> double_array_literal;
119 double d = c->get_constval().doubleval;
120 double_array_literal.push_back(d);
124 if (ti.get_subtype() ==
kINT) {
125 std::vector<int32_t> int32_array_literal;
129 int32_t i = c->get_constval().intval;
130 int32_array_literal.push_back(i);
135 std::vector<int8_t> int8_array_literal;
139 int8_t i = c->get_constval().tinyintval;
140 int8_array_literal.push_back(i);
142 if (ti.get_comp_param() == 64) {
143 return getOrAddLiteral(std::make_pair(int8_array_literal, 64), device_id);
147 throw std::runtime_error(
"Unsupported literal array");
151 std::vector<int8_t> int8_array_literal;
155 int8_t i = c->get_constval().tinyintval;
156 int8_array_literal.push_back(i);
158 if (ti.get_comp_param() == 32) {
159 return getOrAddLiteral(std::make_pair(int8_array_literal, 32), device_id);
164 throw std::runtime_error(
"Encoded literal arrays are not supported");
177 std::pair<std::string, int>,
180 std::vector<int32_t>,
182 std::pair<std::vector<int8_t>,
int>>;
188 llvm::Value* str_lv =
ir_builder_.CreateGlobalString(
189 str,
"str_const_" +
std::to_string(std::hash<std::string>()(str)));
192 str_lv =
ir_builder_.CreateBitCast(str_lv, i8_ptr);
197 std::unique_ptr<const StringDictionaryTranslationMgr>&& str_dict_translation_mgr) {
203 std::unique_ptr<InValuesBitmap>& in_values_bitmap) {
204 if (in_values_bitmap->isEmpty()) {
205 return in_values_bitmap.get();
211 if (!in_values_bitmap->isEmpty()) {
218 const std::string& fname,
220 const std::vector<llvm::Value*>
args,
221 const std::vector<llvm::Attribute::AttrKind>& fnattrs = {},
222 const bool has_struct_return =
false) {
223 std::vector<llvm::Type*> arg_types;
224 for (
const auto arg : args) {
226 arg_types.push_back(arg->getType());
228 auto func_ty = llvm::FunctionType::get(ret_type, arg_types,
false);
229 llvm::AttributeList attrs;
230 if (!fnattrs.empty()) {
231 std::vector<std::pair<unsigned, llvm::Attribute>> indexedAttrs;
232 indexedAttrs.reserve(fnattrs.size());
233 for (
auto attr : fnattrs) {
234 indexedAttrs.emplace_back(llvm::AttributeList::FunctionIndex,
235 llvm::Attribute::get(
context_, attr));
237 attrs = llvm::AttributeList::get(
context_,
238 {&indexedAttrs.front(), indexedAttrs.size()});
241 auto func_p =
module_->getOrInsertFunction(fname, func_ty, attrs);
243 auto callee = func_p.getCallee();
244 llvm::Function* func{
nullptr};
245 if (
auto callee_cast = llvm::dyn_cast<llvm::ConstantExpr>(callee)) {
248 CHECK(callee_cast->isCast());
249 CHECK_EQ(callee_cast->getNumOperands(), size_t(1));
250 func = llvm::dyn_cast<llvm::Function>(callee_cast->getOperand(0));
252 func = llvm::dyn_cast<llvm::Function>(callee);
255 llvm::FunctionType* func_type = func_p.getFunctionType();
257 if (has_struct_return) {
258 const auto arg_ti = func_type->getParamType(0);
259 CHECK(arg_ti->isPointerTy() && arg_ti->getPointerElementType()->isStructTy());
260 auto attr_list = func->getAttributes();
261 #if 14 <= LLVM_VERSION_MAJOR
262 llvm::AttrBuilder arr_arg_builder(
context_, attr_list.getParamAttrs(0));
264 llvm::AttrBuilder arr_arg_builder(attr_list.getParamAttributes(0));
266 arr_arg_builder.addAttribute(llvm::Attribute::StructRet);
267 func->addParamAttrs(0, arr_arg_builder);
269 const size_t arg_start = has_struct_return ? 1 : 0;
270 for (
size_t i = arg_start; i < func->arg_size(); i++) {
271 const auto arg_ti = func_type->getParamType(i);
272 if (arg_ti->isPointerTy() && arg_ti->getPointerElementType()->isStructTy()) {
273 auto attr_list = func->getAttributes();
274 #if 14 <= LLVM_VERSION_MAJOR
275 llvm::AttrBuilder arr_arg_builder(
context_, attr_list.getParamAttrs(i));
277 llvm::AttrBuilder arr_arg_builder(attr_list.getParamAttributes(i));
279 arr_arg_builder.addByValAttr(arg_ti->getPointerElementType());
280 func->addParamAttrs(i, arr_arg_builder);
285 CHECK_EQ(result->getType(), ret_type);
289 llvm::Value*
emitCall(
const std::string& fname,
const std::vector<llvm::Value*>& args);
291 const std::vector<llvm::Value*>& args);
295 llvm::Value*
castToTypeIn(llvm::Value* val,
const size_t bit_width);
298 const size_t byte_width,
299 const bool is_signed);
306 llvm::ConstantInt*
llInt(
const T v)
const {
310 llvm::ConstantFP*
llFp(
const float v)
const {
311 return static_cast<llvm::ConstantFP*
>(
312 llvm::ConstantFP::get(llvm::Type::getFloatTy(
context_), v));
315 llvm::ConstantFP*
llFp(
const double v)
const {
316 return static_cast<llvm::ConstantFP*
>(
317 llvm::ConstantFP::get(llvm::Type::getDoubleTy(
context_), v));
331 bool always_clone =
false);
456 std::vector<std::unique_ptr<const StringDictionaryTranslationMgr>>
475 switch (lit.which()) {
505 static size_t addAligned(
const size_t off_in,
const size_t alignment) {
507 if (off % alignment != 0) {
508 off += (alignment - off % alignment);
510 return off + alignment;
519 size_t literal_found_off{0};
521 for (
const auto& literal : literals) {
523 literal_found_off =
addAligned(literal_found_off, lit_bytes);
524 if (literal == var_val) {
525 return {literal_found_off - lit_bytes, lit_bytes};
528 literals.emplace_back(val);
std::vector< llvm::Function * > helper_functions_
const std::list< std::shared_ptr< Analyzer::Expr > > & get_value_list() const
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
llvm::Value * emitEntryCall(const std::string &fname, const std::vector< llvm::Value * > &args)
std::vector< llvm::Value * > outer_join_match_found_per_level_
std::unordered_map< size_t, std::vector< llvm::Value * > > fetch_cache_
llvm::LLVMContext & getExecutorContext() const
std::shared_ptr< Executor > getExecutor() const
std::map< std::pair< llvm::Value *, llvm::Value * >, ArrayLoadCodegen > array_load_cache_
const Analyzer::FunctionOper * foper
llvm::Value * addStringConstant(const std::string &str)
void maybeCloneFunctionRecursive(llvm::Function *fn)
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)
llvm::Function * query_func_
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
std::unordered_map< llvm::Value *, HoistedLiteralLoadLocator > row_func_hoisted_literals_
llvm::IRBuilder ir_builder_
int offset_in_literal_buffer
void moveInValuesBitmap(std::unique_ptr< const InValuesBitmap > &in_values_bitmap)
std::vector< llvm::Value * > str_constants_
llvm::ConstantInt * llBool(const bool v) const
std::unordered_map< int, std::vector< llvm::Value * > > query_func_literal_loads_
InsertionOrderedMap filter_func_args_
const bool contains_left_deep_outer_join_
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
const std::unordered_map< int, LiteralValues > & getLiterals() const
double inline_fp_null_val(const SQL_TYPE_INFO &ti)
std::unordered_map< std::string, llvm::Value * > geo_target_cache_
llvm::ConstantFP * llFp(const double v) const
static size_t literalBytes(const CgenState::LiteralValue &lit)
std::vector< FunctionOperValue > ext_call_cache_
llvm::Function * row_func_
std::vector< llvm::Value * > group_by_expr_cache_
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
llvm::LLVMContext & context_
llvm::Function * current_func_
static size_t addAligned(const size_t off_in, const size_t alignment)
llvm::CallInst * filter_func_call_
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
std::vector< LiteralValue > LiteralValues
const InValuesBitmap * addInValuesBitmap(std::unique_ptr< InValuesBitmap > &in_values_bitmap)
void replaceFunctionForGpu(const std::string &fcn_to_replace, llvm::Function *fn)
std::unordered_map< int, size_t > literal_bytes_
std::unordered_map< int, llvm::Value * > scan_idx_to_hash_pos_
llvm::ConstantFP * llFp(const float v) const
std::vector< std::string > gpuFunctionsToReplace(llvm::Function *fn)
llvm::IRBuilder query_func_entry_ir_builder_
llvm::BasicBlock * filter_func_bb_
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
llvm::Constant * inlineNull(const SQLTypeInfo &)
void set_module_shallow_copy(const std::unique_ptr< llvm::Module > &module, bool always_clone=false)
std::vector< std::unique_ptr< const InValuesBitmap > > in_values_bitmaps_
llvm::Function * filter_func_
std::unordered_map< int, LiteralValues > literals_
std::vector< llvm::Value * > frag_offsets_
size_t getLiteralBufferUsage(const int device_id)
Datum get_constval() const
void emitErrorCheck(llvm::Value *condition, llvm::Value *errorCode, std::string label)
llvm::ConstantInt * llInt(const T v) const
int index_of_literal_load
llvm::ValueToValueMapTy vmap_
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
llvm::ConstantInt * ll_bool(const bool v, llvm::LLVMContext &context)
const StringDictionaryTranslationMgr * moveStringDictionaryTranslationMgr(std::unique_ptr< const StringDictionaryTranslationMgr > &&str_dict_translation_mgr)
std::vector< std::unique_ptr< const StringDictionaryTranslationMgr > > str_dict_translation_mgrs_
std::tuple< size_t, size_t > getOrAddLiteral(const T &val, const int device_id)
std::tuple< size_t, size_t > getOrAddLiteral(const Analyzer::Constant *constant, const EncodingType enc_type, const int dict_id, const int device_id)
llvm::CallInst * row_func_call_
CgenState(const size_t num_query_infos, const bool contains_left_deep_outer_join, Executor *executor)
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
llvm::BasicBlock * row_func_bb_
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)