Sample IR: define i16 @TupleIsNullPredicate(%"class.impala::ScalarExprEvaluator"* %eval, %"class.impala::TupleRow"* %row) #51 { entry: br label %check_null check_null: ; preds = %entry %tuple_is_null_fn = call i1 @_ZN6impala19TupleRowTupleIsNullEPKNS_8TupleRowEi( %"class.impala::TupleRow"* %row, i32 0) %0 = select i1 %tuple_is_null_fn, i32 1, i32 0 %count = a
| 137 | /// ret i16 %ret_val |
| 138 | /// } |
| 139 | void TupleIsNullPredicate::FillCodegendComputeFnNonConstant( |
| 140 | LlvmCodeGen* codegen, llvm::Function* function, llvm::Value* args[2]) const { |
| 141 | llvm::LLVMContext& context = codegen->context(); |
| 142 | LlvmBuilder builder(context); |
| 143 | |
| 144 | llvm::BasicBlock* entry_block = |
| 145 | llvm::BasicBlock::Create(context, "entry", function); |
| 146 | builder.SetInsertPoint(entry_block); |
| 147 | |
| 148 | // Signature: |
| 149 | // bool TupleRowTupleIsNull(const TupleRow* row, int index); |
| 150 | // Returns whether row->GetTuple(index) is nullptr. |
| 151 | llvm::Function* tuple_is_null_fn = |
| 152 | codegen->GetFunction(IRFunction::TUPLE_ROW_GET_TUPLE_IS_NULL, false); |
| 153 | |
| 154 | llvm::Value* current_count_val = codegen->GetI32Constant(0); |
| 155 | for (int i = 0; i < tuple_idxs_.size(); i++) { |
| 156 | // We create the next block that checks whether the next tuple is null and increases |
| 157 | // 'count' if it is. While the builder's insertion point is still in the previous |
| 158 | // block we insert a branch to the new block. |
| 159 | llvm::BasicBlock* check_null_block |
| 160 | = llvm::BasicBlock::Create(context, "check_null", function); |
| 161 | builder.CreateBr(check_null_block); |
| 162 | |
| 163 | builder.SetInsertPoint(check_null_block); |
| 164 | llvm::Value* tuple_is_null = builder.CreateCall(tuple_is_null_fn, |
| 165 | {args[1], codegen->GetI32Constant(tuple_idxs_[i])}, "tuple_is_null_fn"); |
| 166 | llvm::Value* tuple_is_null_int = builder.CreateSelect(tuple_is_null, |
| 167 | codegen->GetI32Constant(1), codegen->GetI32Constant(0)); |
| 168 | current_count_val = builder.CreateAdd(current_count_val, tuple_is_null_int, "count"); |
| 169 | } |
| 170 | |
| 171 | // Create the last block that will compare 'count' with the original number of tuples. |
| 172 | // If they are equal, return a true value, otherwise a false value. While the builder's |
| 173 | // insertion point is still in the previous block we insert a branch to the new block. |
| 174 | llvm::BasicBlock* compare_count_block |
| 175 | = llvm::BasicBlock::Create(context, "compare_count", function); |
| 176 | builder.CreateBr(compare_count_block); |
| 177 | |
| 178 | builder.SetInsertPoint(compare_count_block); |
| 179 | llvm::Constant* tuple_ids_size = codegen->GetI32Constant(tuple_ids_.size()); |
| 180 | llvm::Value* cmp = |
| 181 | builder.CreateICmpEQ(current_count_val, tuple_ids_size, "count_eq_col_num"); |
| 182 | CodegenAnyVal ret_val = CodegenAnyVal::GetNonNullVal( |
| 183 | codegen, &builder, ColumnType(TYPE_BOOLEAN), "ret_val"); |
| 184 | ret_val.SetVal(cmp); |
| 185 | builder.CreateRet(ret_val.GetLoweredValue()); |
| 186 | } |
| 187 | |
| 188 | string TupleIsNullPredicate::DebugString() const { |
| 189 | stringstream out; |
nothing calls this directly
no test coverage detected