| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| #include "codegen/codegen-anyval-read-write-info.h" | |
| #include "codegen/codegen-anyval.h" | |
| #include "codegen/llvm-codegen.h" | |
| #include "llvm/IR/LLVMContext.h" | |
| namespace impala { | |
| void NonWritableBasicBlock::BranchTo(LlvmBuilder* builder) const { | |
| DCHECK(builder != nullptr); | |
| builder->CreateBr(basic_block_); | |
| } | |
| void NonWritableBasicBlock::BranchToIf(LlvmBuilder* builder, | |
| llvm::Value* condition, const NonWritableBasicBlock& else_block) const { | |
| DCHECK(builder != nullptr); | |
| builder->CreateCondBr(condition, basic_block_, else_block.basic_block_); | |
| } | |
| void NonWritableBasicBlock::BranchToIfNot(LlvmBuilder* builder, | |
| llvm::Value* condition, const NonWritableBasicBlock& then_block) const { | |
| DCHECK(builder != nullptr); | |
| builder->CreateCondBr(condition, then_block.basic_block_, basic_block_); | |
| } | |
| llvm::BasicBlock* NonWritableBasicBlock::CreateBasicBlockBefore( | |
| llvm::LLVMContext& context, const std::string& name, llvm::Function* fn) const { | |
| return llvm::BasicBlock::Create(context, name, fn, basic_block_); | |
| } | |
| llvm::Value* CodegenAnyValReadWriteInfo::GetSimpleVal() const { | |
| llvm::Value* const * val = std::get_if<llvm::Value*>(&data_); | |
| DCHECK(val != nullptr); | |
| return *val; | |
| } | |
| const CodegenAnyValReadWriteInfo::PtrLenStruct& CodegenAnyValReadWriteInfo::GetPtrAndLen() | |
| const { | |
| const PtrLenStruct* ptr_len_struct = std::get_if<PtrLenStruct>(&data_); | |
| DCHECK(ptr_len_struct != nullptr); | |
| return *ptr_len_struct; | |
| } | |
| const CodegenAnyValReadWriteInfo::TimestampStruct& | |
| CodegenAnyValReadWriteInfo::GetTimeAndDate() const { | |
| const TimestampStruct* timestamp_struct = std::get_if<TimestampStruct>(&data_); | |
| DCHECK(timestamp_struct != nullptr); | |
| return *timestamp_struct; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetSimpleVal(llvm::Value* val) { | |
| DCHECK(val != nullptr); | |
| DCHECK(!is_data_initialized() || holds_simple_val()); | |
| data_ = val; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetPtrAndLen(llvm::Value* ptr, llvm::Value* len) { | |
| DCHECK(ptr != nullptr); | |
| DCHECK(len != nullptr); | |
| DCHECK(!is_data_initialized() || holds_ptr_and_len()); | |
| PtrLenStruct val; | |
| val.ptr = ptr; | |
| val.len = len; | |
| data_ = val; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetTimeAndDate(llvm::Value* time_of_day, | |
| llvm::Value* date) { | |
| DCHECK(time_of_day != nullptr); | |
| DCHECK(date != nullptr); | |
| DCHECK(!is_data_initialized() || holds_timestamp()); | |
| TimestampStruct val; | |
| val.time_of_day = time_of_day; | |
| val.date = date; | |
| data_ = val; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetEval(llvm::Value* eval) { | |
| DCHECK(eval != nullptr); | |
| eval_ = eval; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetFnCtxIdx(int fn_ctx_idx) { | |
| DCHECK_GE(fn_ctx_idx, -1); | |
| fn_ctx_idx_ = fn_ctx_idx; | |
| } | |
| void CodegenAnyValReadWriteInfo::SetBlocks(llvm::BasicBlock* entry_block, | |
| llvm::BasicBlock* null_block, llvm::BasicBlock* non_null_block) { | |
| DCHECK(entry_block != nullptr); | |
| DCHECK(null_block != nullptr); | |
| DCHECK(non_null_block != nullptr); | |
| entry_block_ = entry_block; | |
| null_block_ = null_block; | |
| non_null_block_ = non_null_block; | |
| } | |
| llvm::ConstantStruct* CodegenAnyValReadWriteInfo::GetIrType() const { | |
| // Delete the vectors in 'type_copy' because they are not used here and because they | |
| // cannot be converted to IR. | |
| // TODO IMPALA-11643: Revisit this. | |
| ColumnType type_copy = type_; | |
| type_copy.children.clear(); | |
| type_copy.field_names.clear(); | |
| type_copy.field_ids.clear(); | |
| return type_copy.ToIR(codegen_); | |
| } | |
| void CodegenAnyValReadWriteInfo::CodegenConvertToCanonicalForm() { | |
| switch(type_.type) { | |
| case TYPE_FLOAT: | |
| case TYPE_DOUBLE: { | |
| llvm::Value* new_val = CodegenAnyVal::ConvertToCanonicalForm(codegen_, builder_, | |
| type_, GetSimpleVal()); | |
| SetSimpleVal(new_val); | |
| break; | |
| } | |
| default: | |
| ; | |
| } | |
| } | |
| llvm::Value* CodegenAnyValReadWriteInfo::CodegenGetFnCtx() const { | |
| llvm::Function* const get_func_ctx_fn = | |
| codegen_->GetFunction(IRFunction::GET_FUNCTION_CTX, false); | |
| return builder_->CreateCall(get_func_ctx_fn, | |
| {eval_, codegen_->GetI32Constant(fn_ctx_idx_)}, "fn_ctx"); | |
| } | |
| llvm::PHINode* CodegenAnyValReadWriteInfo::CodegenNullPhiNode( | |
| llvm::Value* non_null_value, llvm::Value* null_value, const std::string& name) { | |
| return LlvmCodeGen::CreateBinaryPhiNode( | |
| builder_, non_null_value, null_value, non_null_block_, null_block_, name); | |
| } | |
| llvm::PHINode* CodegenAnyValReadWriteInfo::CodegenIsNullPhiNode(const std::string& name) { | |
| return CodegenNullPhiNode(codegen_->false_value(), codegen_->true_value(), name); | |
| } | |
| bool CodegenAnyValReadWriteInfo::is_data_initialized() const { | |
| return std::get_if<std::monostate>(&data_) == nullptr; | |
| } | |
| bool CodegenAnyValReadWriteInfo::holds_simple_val() const { | |
| return std::get_if<llvm::Value*>(&data_) != nullptr; | |
| } | |
| bool CodegenAnyValReadWriteInfo::holds_ptr_and_len() const { | |
| return std::get_if<PtrLenStruct>(&data_) != nullptr; | |
| } | |
| bool CodegenAnyValReadWriteInfo::holds_timestamp() const { | |
| return std::get_if<TimestampStruct>(&data_) != nullptr; | |
| } | |
| } // namespace impala |