| 1052 | } |
| 1053 | |
| 1054 | void CodegenAnyVal::StructChildToReadWriteInfo( |
| 1055 | CodegenAnyValReadWriteInfo* read_write_info, |
| 1056 | const ColumnType& type, llvm::Value* child_ptr) { |
| 1057 | LlvmCodeGen* codegen = read_write_info->codegen(); |
| 1058 | LlvmBuilder* builder = read_write_info->builder(); |
| 1059 | llvm::Type* slot_type = codegen->GetSlotType(type); |
| 1060 | |
| 1061 | // Children of struct-typed 'AnyVal's are stored in one of the members of an 'ExprValue' |
| 1062 | // belonging to the appropriate 'ScalarExprEvaluator'. These have the same type and |
| 1063 | // layout as the values stored in the slots, except for BOOLEANs, which are stored as i1 |
| 1064 | // in the slots but are stored as 'bool' variables in 'ExprValue' (as children of struct |
| 1065 | // 'AnyVal's). As this code deals with values in 'AnyVal's, for BOOLEANS we use i8, |
| 1066 | // which is the LLVM type corresponding to 'bool', and for other types we use the slot |
| 1067 | // type. |
| 1068 | llvm::Type* child_type = type.type == TYPE_BOOLEAN || type.type == TYPE_CHAR ? |
| 1069 | codegen->i8_type() : slot_type; |
| 1070 | llvm::Value* cast_child_ptr = builder->CreateBitCast(child_ptr, |
| 1071 | child_type->getPointerTo(), "cast_child_ptr"); |
| 1072 | |
| 1073 | switch (type.type) { |
| 1074 | case TYPE_CHAR: { |
| 1075 | llvm::Value* len = codegen->GetI32Constant(type.len); |
| 1076 | read_write_info->SetPtrAndLen(cast_child_ptr, len); |
| 1077 | break; |
| 1078 | } |
| 1079 | case TYPE_STRING: |
| 1080 | case TYPE_VARCHAR: { |
| 1081 | llvm::Function* str_ptr_fn = codegen->GetFunction( |
| 1082 | IRFunction::STRING_VALUE_PTR, false); |
| 1083 | llvm::Value* ptr = builder->CreateCall(str_ptr_fn, |
| 1084 | llvm::ArrayRef<llvm::Value*>({cast_child_ptr}), "ptr"); |
| 1085 | |
| 1086 | llvm::Function* str_len_fn = codegen->GetFunction( |
| 1087 | IRFunction::STRING_VALUE_LEN, false); |
| 1088 | llvm::Value* len = builder->CreateCall(str_len_fn, |
| 1089 | llvm::ArrayRef<llvm::Value*>({cast_child_ptr}), "len"); |
| 1090 | read_write_info->SetPtrAndLen(ptr, len); |
| 1091 | break; |
| 1092 | } |
| 1093 | case TYPE_ARRAY: |
| 1094 | case TYPE_MAP: { // Arrays and maps have the same memory layout. |
| 1095 | llvm::Value* ptr_addr = builder->CreateStructGEP( |
| 1096 | nullptr, cast_child_ptr, 0, "ptr_addr"); |
| 1097 | llvm::Value* ptr = builder->CreateLoad(ptr_addr, "ptr"); |
| 1098 | |
| 1099 | llvm::Value* len; |
| 1100 | llvm::Value* len_addr = builder->CreateStructGEP( |
| 1101 | nullptr, cast_child_ptr, 1, "len_addr"); |
| 1102 | len = builder->CreateLoad(len_addr, "len"); |
| 1103 | read_write_info->SetPtrAndLen(ptr, len); |
| 1104 | break; |
| 1105 | } |
| 1106 | case TYPE_FIXED_UDA_INTERMEDIATE: |
| 1107 | DCHECK(false) << "FIXED_UDA_INTERMEDIATE does not need to be copied: the " |
| 1108 | << "StringVal must be set up to point to the output slot"; |
| 1109 | break; |
| 1110 | case TYPE_TIMESTAMP: { |
| 1111 | llvm::Value* time_of_day_addr = builder->CreateStructGEP( |
nothing calls this directly
no test coverage detected