Example IR for setting the first null bit to a non-constant 'is_null' value: %14 = bitcast { i8, [7 x i8], %"class.impala::TimestampValue" }* %agg_tuple to i8 %null_byte_ptr3 = getelementptr i8, i8* %14, i32 0 %null_byte4 = load i8, i8* %null_byte_ptr3 %null_bit_cleared = and i8 %null_byte4, -2 %15 = sext i1 %result_is_null to i8 %null_bit = and i8 %15, 1 %null_bit_set = or i8 %null_bit_cleared, %
| 839 | // %null_bit_set = or i8 %null_bit_cleared, %null_bit |
| 840 | // store i8 %null_bit_set, i8* %null_byte_ptr3 |
| 841 | void SlotDescriptor::CodegenSetNullIndicator( |
| 842 | LlvmCodeGen* codegen, LlvmBuilder* builder, llvm::Value* tuple, llvm::Value* is_null) |
| 843 | const { |
| 844 | DCHECK_EQ(is_null->getType(), codegen->bool_type()); |
| 845 | llvm::Value* null_byte_ptr; |
| 846 | llvm::Value* null_byte = |
| 847 | CodegenGetNullByte(codegen, builder, null_indicator_offset_, tuple, &null_byte_ptr); |
| 848 | llvm::Constant* mask = codegen->GetI8Constant(null_indicator_offset_.bit_mask); |
| 849 | llvm::Constant* not_mask = codegen->GetI8Constant(~null_indicator_offset_.bit_mask); |
| 850 | |
| 851 | llvm::ConstantInt* constant_is_null = llvm::dyn_cast<llvm::ConstantInt>(is_null); |
| 852 | llvm::Value* result = nullptr; |
| 853 | if (constant_is_null != nullptr) { |
| 854 | if (constant_is_null->isOne()) { |
| 855 | result = builder->CreateOr(null_byte, mask, "null_bit_set"); |
| 856 | } else { |
| 857 | DCHECK(constant_is_null->isZero()); |
| 858 | result = builder->CreateAnd(null_byte, not_mask, "null_bit_cleared"); |
| 859 | } |
| 860 | } else { |
| 861 | // Avoid branching by computing the new byte as: |
| 862 | // (null_byte & ~mask) | (-null & mask); |
| 863 | llvm::Value* byte_with_cleared_bit = |
| 864 | builder->CreateAnd(null_byte, not_mask, "null_bit_cleared"); |
| 865 | llvm::Value* sign_extended_null = |
| 866 | builder->CreateSExt(is_null, codegen->i8_type()); |
| 867 | llvm::Value* bit_only = builder->CreateAnd(sign_extended_null, mask, "null_bit"); |
| 868 | result = builder->CreateOr(byte_with_cleared_bit, bit_only, "null_bit_set"); |
| 869 | } |
| 870 | |
| 871 | builder->CreateStore(result, null_byte_ptr); |
| 872 | } |
| 873 | |
| 874 | // Example IR for materializing a string column with non-NULL 'pool'. Includes the part |
| 875 | // that is generated by CodegenAnyVal::ToReadWriteInfo(). |
no test coverage detected