Codegens an unrolled version of MaterializeExprs(). Uses codegen'd exprs and slot writes. If 'pool' is non-NULL, string data is copied into it. Example IR for materializing a string column with non-NULL 'pool', produced by the following query: select l_comment from tpch.lineitem order by l_comment limit 10; define void @MaterializeExprs(%"class.impala::Tuple"* %opaque_tuple, %"class.impala::Tup
| 398 | // ret void |
| 399 | // } |
| 400 | Status Tuple::CodegenMaterializeExprs(LlvmCodeGen* codegen, bool collect_varlen_vals, |
| 401 | const TupleDescriptor& desc, const vector<ScalarExpr*>& slot_materialize_exprs, |
| 402 | bool use_mem_pool, llvm::Function** fn) { |
| 403 | // Only support 'collect_varlen_vals' == false for now. |
| 404 | // TODO IMPALA-12068: implement it for 'collect_varlen_vals' == true too. |
| 405 | if (collect_varlen_vals) { |
| 406 | return Status("CodegenMaterializeExprs() collect_varlen_vals == true NYI"); |
| 407 | } |
| 408 | llvm::LLVMContext& context = codegen->context(); |
| 409 | |
| 410 | // Codegen each compute function from slot_materialize_exprs |
| 411 | llvm::Function* materialize_expr_fns[slot_materialize_exprs.size()]; |
| 412 | for (int i = 0; i < slot_materialize_exprs.size(); ++i) { |
| 413 | Status status = slot_materialize_exprs[i]->GetCodegendComputeFn( |
| 414 | codegen, false, &materialize_expr_fns[i]); |
| 415 | if (!status.ok()) { |
| 416 | return Status::Expected(Substitute("Could not codegen CodegenMaterializeExprs: $0", |
| 417 | status.GetDetail())); |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | // Construct function signature (this must exactly match the actual signature since it's |
| 422 | // used in xcompiled IR). With 'pool': |
| 423 | // void MaterializeExprs(Tuple* opaque_tuple, TupleRow* row, |
| 424 | // const TupleDescriptor& desc, ScalarExprEvaluator* const* evals, MemPool* pool, |
| 425 | // CodegenTypes::StringValuePtrVecType* non_null_string_values, |
| 426 | // CodegenTypes::CollValuePtrAndSizeVecType* non_null_collection_values, |
| 427 | // int* total_varlen_lengths, int* num_non_null_string_values, |
| 428 | // int* num_non_null_collection_values); |
| 429 | llvm::PointerType* opaque_tuple_type = codegen->GetStructPtrType<Tuple>(); |
| 430 | llvm::PointerType* row_type = codegen->GetStructPtrType<TupleRow>(); |
| 431 | llvm::PointerType* desc_type = codegen->GetStructPtrType<TupleDescriptor>(); |
| 432 | llvm::PointerType* expr_evals_type = |
| 433 | codegen->GetStructPtrPtrType<ScalarExprEvaluator>(); |
| 434 | llvm::PointerType* pool_type = codegen->GetStructPtrType<MemPool>(); |
| 435 | llvm::Type* string_values_type = |
| 436 | CodegenTypes::getStringValuePtrVecType(codegen)->getPointerTo(); |
| 437 | llvm::Type* coll_values_and_sizes_type = |
| 438 | CodegenTypes::getCollValuePtrAndSizeVecType(codegen)->getPointerTo(); |
| 439 | llvm::PointerType* int_ptr_type = codegen->i32_ptr_type(); |
| 440 | |
| 441 | LlvmCodeGen::FnPrototype prototype(codegen, "MaterializeExprs", codegen->void_type()); |
| 442 | prototype.AddArgument("opaque_tuple", opaque_tuple_type); |
| 443 | prototype.AddArgument("row", row_type); |
| 444 | prototype.AddArgument("desc", desc_type); |
| 445 | prototype.AddArgument("slot_materialize_expr_evals", expr_evals_type); |
| 446 | prototype.AddArgument("pool", pool_type); |
| 447 | prototype.AddArgument("non_null_string_values", string_values_type); |
| 448 | prototype.AddArgument("non_null_collection_values", coll_values_and_sizes_type); |
| 449 | prototype.AddArgument("total_varlen_lengths", int_ptr_type); |
| 450 | prototype.AddArgument("num_non_null_string_values", int_ptr_type); |
| 451 | prototype.AddArgument("num_non_null_collection_values", int_ptr_type); |
| 452 | |
| 453 | LlvmBuilder builder(context); |
| 454 | llvm::Value* args[10]; |
| 455 | *fn = prototype.GeneratePrototype(&builder, args); |
| 456 | llvm::Value* opaque_tuple_arg = args[0]; |
| 457 | llvm::Value* row_arg = args[1]; |
nothing calls this directly
no test coverage detected