blob: 7cf02ea1459826ab34640cc9e6ddf3717c9406bc [file]
// 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