25 const auto window_func_context =
29 switch (window_func->getKind()) {
34 return cgen_state_->emitCall(
"row_number_window_func",
35 {cgen_state_->llInt(reinterpret_cast<const int64_t>(
36 window_func_context->output())),
37 code_generator.posArg(
nullptr)});
41 return cgen_state_->emitCall(
"percent_window_func",
42 {cgen_state_->llInt(reinterpret_cast<const int64_t>(
43 window_func_context->output())),
44 code_generator.posArg(
nullptr)});
51 const auto&
args = window_func->getArgs();
53 const auto arg_lvs = code_generator.codegen(
args.front().get(),
true, co);
55 return arg_lvs.front();
62 return codegenWindowFunctionAggregate(co);
65 LOG(
FATAL) <<
"Invalid window function kind";
91 agg_name =
"agg_count";
95 LOG(
FATAL) <<
"Invalid window function kind";
100 agg_name +=
"_float";
104 agg_name +=
"_double";
118 ?
args.front()->get_type_info()
126 const auto window_func_context =
128 const auto window_func = window_func_context->getWindowFunction();
131 arg_ti.get_type() ==
kFLOAT
132 ? llvm::PointerType::get(
get_int_type(32, cgen_state_->context_), 0)
133 : llvm::PointerType::get(
get_int_type(64, cgen_state_->context_), 0);
134 const auto aggregate_state_i64 = cgen_state_->llInt(
135 reinterpret_cast<const int64_t>(window_func_context->aggregateState()));
136 return cgen_state_->ir_builder_.CreateIntToPtr(aggregate_state_i64,
137 aggregate_state_type);
142 const auto reset_state_false_bb = codegenWindowResetStateControlFlow();
143 auto aggregate_state = aggregateWindowStatePtr();
144 llvm::Value* aggregate_state_count =
nullptr;
145 const auto window_func_context =
147 const auto window_func = window_func_context->getWindowFunction();
149 const auto aggregate_state_count_i64 = cgen_state_->llInt(
150 reinterpret_cast<const int64_t>(window_func_context->aggregateStateCount()));
151 const auto pi64_type =
152 llvm::PointerType::get(
get_int_type(64, cgen_state_->context_), 0);
153 aggregate_state_count =
154 cgen_state_->ir_builder_.CreateIntToPtr(aggregate_state_count_i64, pi64_type);
156 codegenWindowFunctionStateInit(aggregate_state);
158 const auto count_zero = cgen_state_->llInt(int64_t(0));
159 cgen_state_->emitCall(
"agg_id", {aggregate_state_count, count_zero});
161 cgen_state_->ir_builder_.CreateBr(reset_state_false_bb);
162 cgen_state_->ir_builder_.SetInsertPoint(reset_state_false_bb);
164 return codegenWindowFunctionAggregateCalls(aggregate_state, co);
169 const auto window_func_context =
171 const auto bitset = cgen_state_->llInt(
172 reinterpret_cast<const int64_t>(window_func_context->partitionStart()));
173 const auto min_val = cgen_state_->llInt(int64_t(0));
174 const auto max_val = cgen_state_->llInt(window_func_context->elementCount() - 1);
175 const auto null_val = cgen_state_->llInt(inline_int_null_value<int64_t>());
176 const auto null_bool_val = cgen_state_->llInt<int8_t>(inline_int_null_value<int8_t>());
178 const auto reset_state =
179 code_generator.
toBool(cgen_state_->emitCall(
"bit_is_set",
181 code_generator.
posArg(
nullptr),
186 const auto reset_state_true_bb = llvm::BasicBlock::Create(
187 cgen_state_->context_,
"reset_state.true", cgen_state_->current_func_);
188 const auto reset_state_false_bb = llvm::BasicBlock::Create(
189 cgen_state_->context_,
"reset_state.false", cgen_state_->current_func_);
190 cgen_state_->ir_builder_.CreateCondBr(
191 reset_state, reset_state_true_bb, reset_state_false_bb);
192 cgen_state_->ir_builder_.SetInsertPoint(reset_state_true_bb);
193 return reset_state_false_bb;
198 const auto window_func_context =
200 const auto window_func = window_func_context->getWindowFunction();
202 const auto window_func_null_val =
203 window_func_ti.is_fp()
204 ? cgen_state_->inlineFpNull(window_func_ti)
205 : cgen_state_->castToTypeIn(cgen_state_->inlineIntNull(window_func_ti), 64);
206 llvm::Value* window_func_init_val;
207 if (window_func_context->getWindowFunction()->getKind() ==
209 switch (window_func_ti.get_type()) {
211 window_func_init_val = cgen_state_->llFp(
float(0));
215 window_func_init_val = cgen_state_->llFp(
double(0));
219 window_func_init_val = cgen_state_->llInt(int64_t(0));
224 window_func_init_val = window_func_null_val;
226 const auto pi32_type =
227 llvm::PointerType::get(
get_int_type(32, cgen_state_->context_), 0);
228 switch (window_func_ti.get_type()) {
230 cgen_state_->emitCall(
"agg_id_double", {aggregate_state, window_func_init_val});
235 cgen_state_->ir_builder_.CreateBitCast(aggregate_state, pi32_type);
236 cgen_state_->emitCall(
"agg_id_float", {aggregate_state, window_func_init_val});
240 cgen_state_->emitCall(
"agg_id", {aggregate_state, window_func_init_val});
249 const auto window_func_context =
251 const auto window_func = window_func_context->getWindowFunction();
253 const auto window_func_null_val =
254 window_func_ti.is_fp()
255 ? cgen_state_->inlineFpNull(window_func_ti)
256 : cgen_state_->castToTypeIn(cgen_state_->inlineIntNull(window_func_ti), 64);
257 const auto&
args = window_func->getArgs();
258 llvm::Value* crt_val;
261 crt_val = cgen_state_->llInt(int64_t(1));
264 const auto arg_lvs = code_generator.
codegen(
args.front().get(),
true, co);
265 CHECK_EQ(arg_lvs.size(), size_t(1));
268 arg_lvs.front(),
args.front()->get_type_info(), window_func_ti,
false);
270 crt_val = window_func_ti.get_type() ==
kFLOAT
272 : cgen_state_->castToTypeIn(arg_lvs.front(), 64);
276 llvm::Value* multiplicity_lv =
nullptr;
278 cgen_state_->emitCall(agg_name, {aggregate_state, crt_val});
280 cgen_state_->emitCall(agg_name +
"_skip_val",
281 {aggregate_state, crt_val, window_func_null_val});
284 codegenWindowAvgEpilogue(crt_val, window_func_null_val, multiplicity_lv);
286 return codegenAggregateWindowState();
290 llvm::Value* window_func_null_val,
291 llvm::Value* multiplicity_lv) {
293 const auto window_func_context =
295 const auto window_func = window_func_context->getWindowFunction();
297 const auto pi32_type =
298 llvm::PointerType::get(
get_int_type(32, cgen_state_->context_), 0);
299 const auto pi64_type =
300 llvm::PointerType::get(
get_int_type(64, cgen_state_->context_), 0);
301 const auto aggregate_state_type =
302 window_func_ti.get_type() ==
kFLOAT ? pi32_type : pi64_type;
303 const auto aggregate_state_count_i64 = cgen_state_->llInt(
304 reinterpret_cast<const int64_t>(window_func_context->aggregateStateCount()));
305 auto aggregate_state_count = cgen_state_->ir_builder_.CreateIntToPtr(
306 aggregate_state_count_i64, aggregate_state_type);
307 std::string agg_count_func_name =
"agg_count";
308 switch (window_func_ti.get_type()) {
310 agg_count_func_name +=
"_float";
314 agg_count_func_name +=
"_double";
321 agg_count_func_name +=
"_skip_val";
322 cgen_state_->emitCall(agg_count_func_name,
323 {aggregate_state_count, crt_val, window_func_null_val});
328 const auto pi32_type =
329 llvm::PointerType::get(
get_int_type(32, cgen_state_->context_), 0);
330 const auto pi64_type =
331 llvm::PointerType::get(
get_int_type(64, cgen_state_->context_), 0);
332 const auto window_func_context =
336 const auto aggregate_state_type =
337 window_func_ti.get_type() ==
kFLOAT ? pi32_type : pi64_type;
338 auto aggregate_state = aggregateWindowStatePtr();
340 const auto aggregate_state_count_i64 = cgen_state_->llInt(
341 reinterpret_cast<const int64_t>(window_func_context->aggregateStateCount()));
342 auto aggregate_state_count = cgen_state_->ir_builder_.CreateIntToPtr(
343 aggregate_state_count_i64, aggregate_state_type);
345 switch (window_func_ti.get_type()) {
347 return cgen_state_->emitCall(
348 "load_avg_float", {aggregate_state, aggregate_state_count, double_null_lv});
351 return cgen_state_->emitCall(
352 "load_avg_double", {aggregate_state, aggregate_state_count, double_null_lv});
355 return cgen_state_->emitCall(
358 aggregate_state_count,
360 cgen_state_->llInt<int32_t>(window_func_ti.get_scale())});
363 return cgen_state_->emitCall(
364 "load_avg_int", {aggregate_state, aggregate_state_count, double_null_lv});
369 return cgen_state_->ir_builder_.CreateLoad(aggregate_state);
371 switch (window_func_ti.get_type()) {
373 return cgen_state_->emitCall(
"load_float", {aggregate_state});
376 return cgen_state_->emitCall(
"load_double", {aggregate_state});
379 return cgen_state_->ir_builder_.CreateLoad(aggregate_state);
SqlWindowFunctionKind getKind() const
llvm::Value * posArg(const Analyzer::Expr *) const
llvm::Value * aggregateWindowStatePtr()
HOST DEVICE SQLTypes get_type() const
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
static WindowFunctionContext * getActiveWindowFunctionContext(Executor *executor)
std::string get_window_agg_name(const SqlWindowFunctionKind kind, const SQLTypeInfo &window_func_ti)
void codegenWindowAvgEpilogue(llvm::Value *crt_val, llvm::Value *window_func_null_val, llvm::Value *multiplicity_lv)
static const WindowProjectNodeContext * get(Executor *executor)
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs() const
const WindowFunctionContext * activateWindowFunctionContext(Executor *executor, const size_t target_index) const
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
const SQLTypeInfo & get_type_info() const
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
void codegenWindowFunctionStateInit(llvm::Value *aggregate_state)
llvm::Value * toBool(llvm::Value *)
llvm::Value * codegenAggregateWindowState()
llvm::Value * codegenWindowFunctionAggregate(const CompilationOptions &co)
const Analyzer::WindowFunction * getWindowFunction() const
llvm::Value * codegenWindowFunctionAggregateCalls(llvm::Value *aggregate_state, const CompilationOptions &co)
llvm::Value * codegenWindowFunction(const size_t target_index, const CompilationOptions &co)
llvm::BasicBlock * codegenWindowResetStateControlFlow()
SQLTypeInfo get_adjusted_window_type_info(const Analyzer::WindowFunction *window_func)