MCPcopy Create free account
hub / github.com/apache/impala / GetCodegendComputeFnImpl

Method GetCodegendComputeFnImpl

be/src/exprs/case-expr.cc:180–280  ·  view source on GitHub ↗

Sample IR output when there is a case expression and else expression define i16 @CaseExpr(%"class.impala::ScalarExprEvaluator"* %context, %"class.impala::TupleRow"* %row) #20 { eval_case_expr: %case_val = call i64 @GetSlotRef(%"class.impala::ScalarExprEvaluator"* %context, %"class.impala::TupleRow"* %row) %is_null = trunc i64 %case_val to i1 br i1 %is_null, label %return_else_expr, label %eval_fir

Source from the content-addressed store, hash-verified

178// ret i16 %else_val
179// }
180Status CaseExpr::GetCodegendComputeFnImpl(LlvmCodeGen* codegen, llvm::Function** fn) {
181 const int num_children = GetNumChildren();
182 vector<llvm::Function*> child_fns(num_children, nullptr);
183 for (int i = 0; i < num_children; ++i) {
184 RETURN_IF_ERROR(GetChild(i)->GetCodegendComputeFn(codegen, false, &child_fns[i]));
185 }
186
187 llvm::LLVMContext& context = codegen->context();
188 LlvmBuilder builder(context);
189
190 llvm::Value* args[2];
191 llvm::Function* function = CreateIrFunctionPrototype("CaseExpr", codegen, &args);
192 llvm::BasicBlock* eval_case_expr_block = nullptr;
193
194 // This is the block immediately after the when/then exprs. It will either point to a
195 // block which returns the else expr, or returns NULL if no else expr is specified.
196 llvm::BasicBlock* default_value_block = llvm::BasicBlock::Create(
197 context, has_else_expr() ? "return_else_expr" : "return_null", function);
198
199 // If there is a case expression, create a block to evaluate it.
200 CodegenAnyVal case_val;
201 llvm::BasicBlock* eval_first_when_expr_block = llvm::BasicBlock::Create(
202 context, "eval_first_when_expr", function, default_value_block);
203 llvm::BasicBlock* current_when_expr_block = eval_first_when_expr_block;
204 if (has_case_expr()) {
205 // Need at least case, when and then expr, and optionally an else expr
206 DCHECK_GE(num_children, has_else_expr() ? 4 : 3);
207 // If there is a case expr, create block eval_case_expr to evaluate the
208 // case expr. Place this block before eval_first_when_expr_block
209 eval_case_expr_block = llvm::BasicBlock::Create(
210 context, "eval_case_expr", function, eval_first_when_expr_block);
211 builder.SetInsertPoint(eval_case_expr_block);
212 case_val = CodegenAnyVal::CreateCallWrapped(
213 codegen, &builder, children()[0]->type(), child_fns[0], args, "case_val");
214 builder.CreateCondBr(
215 case_val.GetIsNull(), default_value_block, eval_first_when_expr_block);
216 } else {
217 DCHECK_GE(num_children, has_else_expr() ? 3 : 2);
218 }
219
220 const int loop_end = has_else_expr() ? num_children - 1 : num_children;
221 const int last_loop_iter = loop_end - 2;
222 // The loop increments by two each time, because each iteration handles one when/then
223 // pair. Both when and then subexpressions are single children. If there is a case expr
224 // start loop at index 1. (case expr is GetChild(0) and has already be evaluated.
225 for (int i = has_case_expr() ? 1 : 0; i < loop_end; i += 2) {
226 llvm::BasicBlock* check_when_expr_block = llvm::BasicBlock::Create(
227 context, "check_when_expr_block", function, default_value_block);
228 llvm::BasicBlock* return_then_expr_block = llvm::BasicBlock::Create(
229 context, "return_then_expr", function, default_value_block);
230
231 // continue_or_exit_block either points to the next eval_next_when_expr block,
232 // or points to the defaut_value_block if there are no more when/then expressions.
233 llvm::BasicBlock* continue_or_exit_block = nullptr;
234 if (i == last_loop_iter) {
235 continue_or_exit_block = default_value_block;
236 } else {
237 continue_or_exit_block = llvm::BasicBlock::Create(

Callers

nothing calls this directly

Calls 11

CreateClass · 0.85
OKFunction · 0.85
GetCodegendComputeFnMethod · 0.80
contextMethod · 0.80
GetIsNullMethod · 0.80
FinalizeFunctionMethod · 0.80
StatusClass · 0.70
typeEnum · 0.50
typeMethod · 0.45
EqMethod · 0.45
GetValMethod · 0.45

Tested by

no test coverage detected