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

Method CodegenWriteSlot

be/src/exec/text-converter.cc:110–352  ·  view source on GitHub ↗

Codegen for a function to parse one slot. The IR for a int slot looks like: define i1 @WriteSlot(<{ i32, i8 }>* %tuple_arg, i8* %data, i32 %len) #38 { entry: %parse_result = alloca i32 %0 = call i1 @IrIsNullString(i8* %data, i32 %len) br i1 %0, label %set_null, label %check_zero set_null: ; preds = %check_zero, %entry %1 = bitcast <{ i32, i8 }>* %tuple_arg

Source from the content-addressed store, hash-verified

108// TODO: convert this function to use cross-compilation + constant substitution in whole
109// or part. It is currently too complex and doesn't implement the full functionality.
110Status TextConverter::CodegenWriteSlot(LlvmCodeGen* codegen, TupleDescriptor* tuple_desc,
111 SlotDescriptor* slot_desc, llvm::Function** fn, const char* null_col_val, int len,
112 bool check_null, bool strict_mode) {
113 DCHECK(fn != nullptr);
114 DCHECK(SupportsCodegenWriteSlot(slot_desc->type()));
115
116 // Codegen is_null_string
117 bool is_default_null = (len == 2 && null_col_val[0] == '\\' && null_col_val[1] == 'N');
118 llvm::Function* is_null_string_fn;
119 if (is_default_null) {
120 is_null_string_fn = codegen->GetFunction(IRFunction::IS_NULL_STRING, false);
121 } else {
122 is_null_string_fn = codegen->GetFunction(IRFunction::GENERIC_IS_NULL_STRING, false);
123 }
124
125 DCHECK(is_null_string_fn != NULL);
126
127 llvm::StructType* tuple_type = tuple_desc->GetLlvmStruct(codegen);
128 if (tuple_type == NULL) {
129 return Status("TextConverter::CodegenWriteSlot(): Failed to generate "
130 "tuple type");
131 }
132 llvm::PointerType* tuple_ptr_type = tuple_type->getPointerTo();
133
134 LlvmCodeGen::FnPrototype prototype(
135 codegen, "WriteSlot", codegen->bool_type());
136 prototype.AddArgument(LlvmCodeGen::NamedVariable("tuple_arg", tuple_ptr_type));
137 prototype.AddArgument(LlvmCodeGen::NamedVariable("data", codegen->ptr_type()));
138 prototype.AddArgument(LlvmCodeGen::NamedVariable("len", codegen->i32_type()));
139
140 LlvmBuilder builder(codegen->context());
141 llvm::Value* args[3];
142 *fn = prototype.GeneratePrototype(&builder, &args[0]);
143
144 llvm::BasicBlock *set_null_block, *parse_slot_block, *check_zero_block = NULL;
145 codegen->CreateIfElseBlocks(*fn, "set_null", "parse_slot",
146 &set_null_block, &parse_slot_block);
147
148 if (!slot_desc->type().IsVarLenStringType()) {
149 check_zero_block = llvm::BasicBlock::Create(codegen->context(), "check_zero", *fn);
150 }
151
152 // Check if the data matches the configured NULL string.
153 llvm::Value* is_null;
154 if (check_null) {
155 if (is_default_null) {
156 is_null = builder.CreateCall(
157 is_null_string_fn, llvm::ArrayRef<llvm::Value*>({args[1], args[2]}));
158 } else {
159 llvm::Value* const null_col_ir_str =
160 codegen->GetStringConstant(&builder, null_col_val, len);
161 is_null = builder.CreateCall(is_null_string_fn,
162 llvm::ArrayRef<llvm::Value*>(
163 {args[1], args[2], null_col_ir_str, codegen->GetI32Constant(len)}));
164 }
165 } else {
166 // Constant FALSE as branch condition. We rely on later optimization passes
167 // to remove the branch and THEN block.

Callers

nothing calls this directly

Calls 15

NamedVariableClass · 0.85
CreateClass · 0.85
OKFunction · 0.85
GetLlvmStructMethod · 0.80
bool_typeMethod · 0.80
AddArgumentMethod · 0.80
ptr_typeMethod · 0.80
i32_typeMethod · 0.80
contextMethod · 0.80
GeneratePrototypeMethod · 0.80
CreateIfElseBlocksMethod · 0.80
IsVarLenStringTypeMethod · 0.80

Tested by

no test coverage detected