ClickHouse/src/Functions/FunctionIfBase.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

80 lines
2.4 KiB
C++
Raw Normal View History

#pragma once
2021-05-17 07:30:42 +00:00
#include <Functions/IFunction.h>
#include <DataTypes/Native.h>
#include "config.h"
namespace DB
{
class FunctionIfBase : public IFunction
{
#if USE_EMBEDDED_COMPILER
public:
bool isCompilableImpl(const DataTypes & types) const override
{
/// It's difficult to compare Date and DateTime - cannot use JIT compilation.
bool has_date = false;
bool has_datetime = false;
for (const auto & type : types)
{
auto type_removed_nullable = removeNullable(type);
WhichDataType which(type_removed_nullable);
if (which.isDate())
has_date = true;
if (which.isDateTime())
has_datetime = true;
if (has_date && has_datetime)
return false;
if (!isCompilableType(type_removed_nullable))
return false;
}
return true;
}
2021-05-03 22:34:40 +00:00
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, Values values) const override
{
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
2021-05-07 08:43:06 +00:00
auto return_type = getReturnTypeImpl(types);
auto * head = b.GetInsertBlock();
2021-05-07 08:43:06 +00:00
auto * join = llvm::BasicBlock::Create(head->getContext(), "join_block", head->getParent());
std::vector<std::pair<llvm::BasicBlock *, llvm::Value *>> returns;
for (size_t i = 0; i + 1 < types.size(); i += 2)
{
2021-05-07 08:43:06 +00:00
auto * then = llvm::BasicBlock::Create(head->getContext(), "then_" + std::to_string(i), head->getParent());
auto * next = llvm::BasicBlock::Create(head->getContext(), "next_" + std::to_string(i), head->getParent());
2021-05-03 22:34:40 +00:00
auto * cond = values[i];
2021-05-07 08:43:06 +00:00
b.CreateCondBr(nativeBoolCast(b, types[i], cond), then, next);
b.SetInsertPoint(then);
2021-05-07 08:43:06 +00:00
auto * value = nativeCast(b, types[i + 1], values[i + 1], return_type);
returns.emplace_back(b.GetInsertBlock(), value);
b.CreateBr(join);
b.SetInsertPoint(next);
}
2021-05-07 08:43:06 +00:00
auto * else_value = nativeCast(b, types.back(), values.back(), return_type);
returns.emplace_back(b.GetInsertBlock(), else_value);
b.CreateBr(join);
2021-05-07 08:43:06 +00:00
b.SetInsertPoint(join);
2021-05-07 08:43:06 +00:00
auto * phi = b.CreatePHI(toNativeType(b, return_type), returns.size());
for (const auto & [block, value] : returns)
phi->addIncoming(value, block);
return phi;
}
#endif
};
}