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

Method CreateStructValFromReadWriteInfo

be/src/codegen/codegen-anyval.cc:854–927  ·  view source on GitHub ↗

Returns the last block generated so we can set it as a predecessor in PHI nodes.

Source from the content-addressed store, hash-verified

852
853// Returns the last block generated so we can set it as a predecessor in PHI nodes.
854llvm::BasicBlock* CodegenAnyVal::CreateStructValFromReadWriteInfo(
855 const CodegenAnyValReadWriteInfo& read_write_info,
856 llvm::Value** ptr, llvm::Value** len, llvm::BasicBlock* struct_produce_value_block) {
857 LlvmCodeGen* codegen = read_write_info.codegen();
858 LlvmBuilder* builder = read_write_info.builder();
859
860 DCHECK(read_write_info.type().IsStructType() && read_write_info.children().size() > 0);
861 DCHECK(read_write_info.GetEval() != nullptr);
862 DCHECK_GT(read_write_info.GetFnCtxIdx(), -1);
863
864 // Cross-compiled functions this hand-crafted function will call.
865 llvm::Function* const allocate_for_results_fn =
866 codegen->GetFunction(IRFunction::FN_CTX_ALLOCATE_FOR_RESULTS, false);
867 llvm::Function* const store_result_in_eval_fn =
868 codegen->GetFunction(IRFunction::STORE_RESULT_IN_EVALUATOR, false);
869
870 builder->SetInsertPoint(read_write_info.non_null_block());
871 std::size_t num_children = read_write_info.children().size();
872 DCHECK_GT(num_children, 0);
873 llvm::Value* fn_ctx = read_write_info.CodegenGetFnCtx();
874
875 // Allocate a buffer for the child pointers. If allocation fails, the struct will be
876 // null.
877 llvm::Value* children_ptrs_buffer = builder->CreateCall(allocate_for_results_fn,
878 {fn_ctx, codegen->GetI64Constant(num_children * sizeof(uint8_t*))},
879 "children_ptrs_buffer");
880 llvm::Value* cast_children_ptrs_buffer = builder->CreateBitCast(
881 children_ptrs_buffer, codegen->ptr_ptr_type(), "cast_children_ptrs_buffer");
882 llvm::Value* buffer_is_null = builder->CreateIsNull(
883 cast_children_ptrs_buffer, "buffer_is_null");
884
885 // Branch based on 'buffer_is_null'.
886 read_write_info.children()[0].entry_block().BranchToIfNot(builder, buffer_is_null,
887 NonWritableBasicBlock(read_write_info.null_block()));
888 for (std::size_t i = 0; i < num_children; ++i) {
889 const CodegenAnyValReadWriteInfo& child_codegen_value_read_write_info =
890 read_write_info.children()[i];
891 CodegenAnyVal child_any_val =
892 CreateFromReadWriteInfo(child_codegen_value_read_write_info);
893
894 llvm::ConstantStruct* child_type_ir =
895 child_codegen_value_read_write_info.GetIrType();
896 llvm::Value* child_type_ir_ptr = codegen->CreateEntryBlockAlloca(
897 *builder, child_type_ir->getType(), "child_type_ptr");
898 builder->CreateStore(child_type_ir, child_type_ir_ptr);
899
900 llvm::Value* child_any_val_ptr = child_any_val.GetAnyValPtr("child_ptr");
901
902 // Convert and store the child in the corresponding ScalarExprEvaluator - this takes
903 // care of the lifetime of the object.
904 llvm::Value* stored_child_ptr = builder->CreateCall(store_result_in_eval_fn,
905 {child_codegen_value_read_write_info.GetEval(), child_any_val_ptr,
906 child_type_ir_ptr},
907 "stored_value");
908
909 // The address where the child pointer should be written. This is in the pointer list
910 // of the StructVal.
911 llvm::Value* dst_child_ptr_addr = builder->CreateInBoundsGEP(

Callers

nothing calls this directly

Calls 15

IsStructTypeMethod · 0.80
childrenMethod · 0.80
GetEvalMethod · 0.80
GetFnCtxIdxMethod · 0.80
non_null_blockMethod · 0.80
CodegenGetFnCtxMethod · 0.80
CreateCallMethod · 0.80
GetI64ConstantMethod · 0.80
ptr_ptr_typeMethod · 0.80
BranchToIfNotMethod · 0.80
entry_blockMethod · 0.80

Tested by

no test coverage detected