20 using namespace impala;
25 DCHECK_EQ(children_.size(), 2);
26 BooleanVal val1 = children_[0]->GetBooleanVal(context, row);
27 if (!val1.is_null && !val1.val)
return BooleanVal(
false);
29 BooleanVal val2 = children_[1]->GetBooleanVal(context, row);
32 if (val1.is_null || val2.
is_null)
return BooleanVal::null();
38 DCHECK_EQ(children_.size(), 2);
39 BooleanVal val1 = children_[0]->GetBooleanVal(context, row);
40 if (!val1.is_null && val1.val)
return BooleanVal(
true);
42 BooleanVal val2 = children_[1]->GetBooleanVal(context, row);
45 if (val1.is_null || val2.
is_null)
return BooleanVal::null();
103 if (ir_compute_fn_ != NULL) {
104 *fn = ir_compute_fn_;
108 DCHECK_EQ(GetNumChildren(), 2);
110 Function* lhs_function;
111 RETURN_IF_ERROR(children()[0]->GetCodegendComputeFn(state, &lhs_function));
112 Function* rhs_function;
113 RETURN_IF_ERROR(children()[1]->GetCodegendComputeFn(state, &rhs_function));
117 LLVMContext& context = codegen->
context();
120 Function*
function = CreateIrFunctionPrototype(codegen,
"CompoundPredicate", &args);
122 BasicBlock* entry_block = BasicBlock::Create(context,
"entry",
function);
123 builder.SetInsertPoint(entry_block);
126 BasicBlock* lhs_null_block = BasicBlock::Create(context,
"lhs_null",
function);
127 BasicBlock* lhs_not_null_block =
128 BasicBlock::Create(context,
"lhs_not_null",
function);
129 BasicBlock* lhs_null_rhs_not_null_block =
130 BasicBlock::Create(context,
"lhs_null_rhs_not_null",
function);
131 BasicBlock* lhs_not_null_rhs_null_block =
132 BasicBlock::Create(context,
"lhs_not_null_rhs_null",
function);
133 BasicBlock* null_block = BasicBlock::Create(context,
"null_block",
function);
134 BasicBlock* not_null_block = BasicBlock::Create(context,
"not_null_block",
function);
135 BasicBlock* ret_block = BasicBlock::Create(context,
"ret",
function);
139 codegen, &builder,
TYPE_BOOLEAN, lhs_function, args,
"lhs_call");
142 codegen, &builder,
TYPE_BOOLEAN, rhs_function, args,
"rhs_call");
144 Value* lhs_is_null = lhs_result.
GetIsNull();
145 Value* rhs_is_null = rhs_result.
GetIsNull();
146 Value* lhs_value = lhs_result.
GetVal();
147 Value* rhs_value = rhs_result.
GetVal();
150 Value* compare = NULL;
152 compare = builder.CreateAnd(lhs_value, rhs_value,
"tmp_and");
154 compare = builder.CreateOr(lhs_value, rhs_value,
"tmp_or");
158 builder.CreateCondBr(lhs_is_null, lhs_null_block, lhs_not_null_block);
161 builder.SetInsertPoint(lhs_null_block);
162 builder.CreateCondBr(rhs_is_null, null_block, lhs_null_rhs_not_null_block);
165 builder.SetInsertPoint(lhs_not_null_block);
166 builder.CreateCondBr(rhs_is_null, lhs_not_null_rhs_null_block, not_null_block);
169 builder.SetInsertPoint(lhs_not_null_rhs_null_block);
172 builder.CreateCondBr(lhs_value, null_block, not_null_block);
175 builder.CreateCondBr(lhs_value, not_null_block, null_block);
179 builder.SetInsertPoint(lhs_null_rhs_not_null_block);
182 builder.CreateCondBr(rhs_value, null_block, not_null_block);
185 builder.CreateCondBr(rhs_value, not_null_block, null_block);
189 builder.SetInsertPoint(null_block);
190 builder.CreateBr(ret_block);
193 builder.SetInsertPoint(not_null_block);
196 not_null_phi->addIncoming(codegen->
false_value(), lhs_null_rhs_not_null_block);
197 not_null_phi->addIncoming(codegen->
false_value(), lhs_not_null_rhs_null_block);
198 not_null_phi->addIncoming(compare, lhs_not_null_block);
200 not_null_phi->addIncoming(codegen->
true_value(), lhs_null_rhs_not_null_block);
201 not_null_phi->addIncoming(codegen->
true_value(), lhs_not_null_rhs_null_block);
202 not_null_phi->addIncoming(compare, lhs_not_null_block);
204 builder.CreateBr(ret_block);
207 builder.SetInsertPoint(ret_block);
208 PHINode* is_null_phi = builder.CreatePHI(codegen->
boolean_type(), 2,
"is_null");
209 is_null_phi->addIncoming(codegen->
true_value(), null_block);
210 is_null_phi->addIncoming(codegen->
false_value(), not_null_block);
212 PHINode* val_phi = builder.CreatePHI(codegen->
boolean_type(), 2,
"val");
213 val_phi->addIncoming(codegen->
false_value(), null_block);
214 val_phi->addIncoming(not_null_phi, not_null_block);
219 builder.CreateRet(ret.
value());
223 ir_compute_fn_ = *fn;
static CodegenAnyVal CreateCallWrapped(LlvmCodeGen *cg, LlvmCodeGen::LlvmBuilder *builder, const ColumnType &type, llvm::Function *fn, llvm::ArrayRef< llvm::Value * > args, const char *name="", llvm::Value *result_ptr=NULL)
Same as above but wraps the result in a CodegenAnyVal.
Status CodegenComputeFn(bool and_fn, RuntimeState *state, llvm::Function **fn)
void SetIsNull(llvm::Value *is_null)
Sets the 'is_null' field of the *Val.
#define RETURN_IF_ERROR(stmt)
some generally useful macros
void SetVal(llvm::Value *val)
llvm::Type * boolean_type()
Simple wrappers to reduce code verbosity.
LLVM code generator. This is the top level object to generate jitted code.
llvm::Value * true_value()
Returns true/false constants (bool type)
virtual impala_udf::BooleanVal GetBooleanVal(ExprContext *context, TupleRow *)
virtual impala_udf::BooleanVal GetBooleanVal(ExprContext *context, TupleRow *)
llvm::Value * value()
Returns the current type-lowered value.
llvm::Value * false_value()
llvm::Value * GetVal(const char *name="val")
llvm::Type * GetType(const ColumnType &type)
Returns llvm type for the column type.
Status GetCodegen(LlvmCodeGen **codegen, bool initialize=true)
llvm::Value * GetIsNull(const char *name="is_null")
Gets the 'is_null' field of the *Val.
llvm::Function * FinalizeFunction(llvm::Function *function)
llvm::LLVMContext & context()