mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 01:22:04 +00:00
Implement jit for numeric if and multiIf
This commit is contained in:
parent
1433e6e849
commit
2d70d9d601
@ -6,6 +6,7 @@
|
||||
#include <DataTypes/DataTypeFixedString.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/Native.h>
|
||||
#include <Columns/ColumnVector.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
@ -113,7 +114,64 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class FunctionIf : public IFunction
|
||||
template <bool null_is_false>
|
||||
class FunctionIfBase : public IFunction
|
||||
{
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
public:
|
||||
bool isCompilableImpl(const DataTypes & types) const override
|
||||
{
|
||||
for (const auto & type : types)
|
||||
if (!removeNullable(type)->isValueRepresentedByNumber())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const DataTypes & types, ValuePlaceholders values) const override
|
||||
{
|
||||
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
|
||||
auto type = getReturnTypeImpl(types);
|
||||
llvm::Value * null = nullptr;
|
||||
if (!null_is_false && type->isNullable())
|
||||
null = b.CreateInsertValue(llvm::Constant::getNullValue(toNativeType(b, type)), b.getTrue(), {1});
|
||||
auto * head = b.GetInsertBlock();
|
||||
auto * join = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
std::vector<std::pair<llvm::BasicBlock *, llvm::Value *>> returns;
|
||||
for (size_t i = 0; i + 1 < types.size(); i += 2)
|
||||
{
|
||||
auto * then = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
auto * next = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
auto * cond = values[i]();
|
||||
if (!null_is_false && types[i]->isNullable())
|
||||
{
|
||||
returns.emplace_back(head, null);
|
||||
auto * nonnull = llvm::BasicBlock::Create(head->getContext(), "", head->getParent());
|
||||
b.CreateCondBr(b.CreateExtractValue(cond, {1}), join, nonnull);
|
||||
b.SetInsertPoint(nonnull);
|
||||
b.CreateCondBr(nativeBoolCast(b, removeNullable(types[i]), b.CreateExtractValue(cond, {0})), then, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.CreateCondBr(nativeBoolCast(b, types[i], cond), then, next);
|
||||
}
|
||||
b.SetInsertPoint(then);
|
||||
returns.emplace_back(then, nativeCast(b, types[i + 1], values[i + 1](), type));
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(next);
|
||||
head = next;
|
||||
}
|
||||
returns.emplace_back(head, nativeCast(b, types.back(), values.back()(), type));
|
||||
b.CreateBr(join);
|
||||
b.SetInsertPoint(join);
|
||||
auto * phi = b.CreatePHI(toNativeType(b, type), returns.size());
|
||||
for (const auto & r : returns)
|
||||
phi->addIncoming(r.second, r.first);
|
||||
return phi;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class FunctionIf : public FunctionIfBase</*null_is_false=*/false>
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "if";
|
||||
@ -916,8 +974,8 @@ public:
|
||||
/// - arrays of such types.
|
||||
///
|
||||
/// Additionally the arguments, conditions or branches, support nullable types
|
||||
/// and the NULL value.
|
||||
class FunctionMultiIf final : public IFunction
|
||||
/// and the NULL value, with a NULL condition treated as false.
|
||||
class FunctionMultiIf final : public FunctionIfBase</*null_is_false=*/true>
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "multiIf";
|
||||
|
Loading…
Reference in New Issue
Block a user