From fb02bec3dc07c15450d265d4ae93b964ab62f7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Tue, 10 Dec 2024 12:22:51 +0100 Subject: [PATCH] Revert "Enable JIT compilation for more expressions" --- src/Core/AccurateComparison.h | 6 - src/DataTypes/IDataType.h | 4 - src/DataTypes/NumberTraits.h | 33 ---- src/Functions/DivisionUtils.h | 99 +--------- src/Functions/FunctionBinaryArithmetic.h | 121 ++++-------- src/Functions/FunctionUnaryArithmetic.h | 16 +- src/Functions/FunctionsComparison.h | 198 ++------------------ src/Functions/FunctionsConversion.h | 141 -------------- src/Functions/FunctionsLogical.cpp | 39 ---- src/Functions/FunctionsLogical.h | 101 +++------- src/Functions/abs.cpp | 57 +----- src/Functions/assumeNotNull.cpp | 21 --- src/Functions/bitCount.cpp | 25 +-- src/Functions/identity.h | 26 +-- src/Functions/isNotNull.cpp | 22 --- src/Functions/isNull.cpp | 20 -- src/Functions/sign.cpp | 45 +---- src/Interpreters/ActionsDAG.cpp | 12 +- src/Interpreters/ActionsDAG.h | 4 +- src/Interpreters/ExpressionActions.cpp | 9 - src/Interpreters/JIT/CHJIT.cpp | 4 - src/Interpreters/JIT/CompileDAG.cpp | 8 +- src/Processors/QueryPlan/ExpressionStep.cpp | 39 +--- 23 files changed, 112 insertions(+), 938 deletions(-) diff --git a/src/Core/AccurateComparison.h b/src/Core/AccurateComparison.h index 25937a61168..87ff14e40e7 100644 --- a/src/Core/AccurateComparison.h +++ b/src/Core/AccurateComparison.h @@ -209,14 +209,12 @@ template struct EqualsOp using SymmetricOp = EqualsOp; static UInt8 apply(A a, B b) { return accurate::equalsOp(a, b); } - static constexpr bool compilable = true; }; template struct NotEqualsOp { using SymmetricOp = NotEqualsOp; static UInt8 apply(A a, B b) { return accurate::notEqualsOp(a, b); } - static constexpr bool compilable = true; }; template struct GreaterOp; @@ -225,14 +223,12 @@ template struct LessOp { using SymmetricOp = GreaterOp; static UInt8 apply(A a, B b) { return accurate::lessOp(a, b); } - static constexpr bool compilable = true; }; template struct GreaterOp { using SymmetricOp = LessOp; static UInt8 apply(A a, B b) { return accurate::greaterOp(a, b); } - static constexpr bool compilable = true; }; template struct GreaterOrEqualsOp; @@ -241,14 +237,12 @@ template struct LessOrEqualsOp { using SymmetricOp = GreaterOrEqualsOp; static UInt8 apply(A a, B b) { return accurate::lessOrEqualsOp(a, b); } - static constexpr bool compilable = true; }; template struct GreaterOrEqualsOp { using SymmetricOp = LessOrEqualsOp; static UInt8 apply(A a, B b) { return accurate::greaterOrEqualsOp(a, b); } - static constexpr bool compilable = true; }; } diff --git a/src/DataTypes/IDataType.h b/src/DataTypes/IDataType.h index 2771d056e96..8f06526ddbb 100644 --- a/src/DataTypes/IDataType.h +++ b/src/DataTypes/IDataType.h @@ -555,7 +555,6 @@ inline bool isNullableOrLowCardinalityNullable(const DataTypePtr & data_type) template constexpr bool IsDataTypeDecimal = false; template constexpr bool IsDataTypeNumber = false; -template constexpr bool IsDataTypeNativeNumber = false; template constexpr bool IsDataTypeDateOrDateTime = false; template constexpr bool IsDataTypeDate = false; template constexpr bool IsDataTypeEnum = false; @@ -582,9 +581,6 @@ template constexpr bool IsDataTypeDecimal> = t template <> inline constexpr bool IsDataTypeDecimal = true; template constexpr bool IsDataTypeNumber> = true; -template -requires std::is_arithmetic_v -constexpr bool IsDataTypeNativeNumber> = true; template <> inline constexpr bool IsDataTypeDate = true; template <> inline constexpr bool IsDataTypeDate = true; diff --git a/src/DataTypes/NumberTraits.h b/src/DataTypes/NumberTraits.h index b4a322e1083..5f5962da5ee 100644 --- a/src/DataTypes/NumberTraits.h +++ b/src/DataTypes/NumberTraits.h @@ -205,39 +205,6 @@ struct ResultOfIf ConstructedType, Error>>>; }; -/** Type casting for `modulo` function: - * UInt, UInt -> UInt - * Int, Int -> Int - * UInt, Int -> Int - * UInt64, Int -> Error - * Float, Float -> Float64 - * Float, [U]Int -> Float64 - */ -template -struct ResultOfModuloNativePromotion -{ - static_assert(is_arithmetic_v && is_arithmetic_v); - - static constexpr bool has_float = std::is_floating_point_v || std::is_floating_point_v; - static constexpr bool has_integer = is_integer || is_integer; - static constexpr bool has_signed = is_signed_v || is_signed_v; - static constexpr bool has_unsigned = !is_signed_v || !is_signed_v; - - static constexpr size_t max_size_of_unsigned_integer = max(is_signed_v ? 0 : sizeof(A), is_signed_v ? 0 : sizeof(B)); - static constexpr size_t max_size_of_signed_integer = max(is_signed_v ? sizeof(A) : 0, is_signed_v ? sizeof(B) : 0); - static constexpr size_t max_size_of_integer = max(is_integer ? sizeof(A) : 0, is_integer ? sizeof(B) : 0); - - using ConstructedType = typename Construct< - has_signed, - false, - (has_signed ^ has_unsigned) ? max(max_size_of_unsigned_integer * 2, max_size_of_signed_integer) : max(sizeof(A), sizeof(B))>::Type; - - using Type = std::conditional_t< - std::is_same_v, - A, - std::conditional_t>>; -}; - /** Before applying operator `%` and bitwise operations, operands are cast to whole numbers. */ template struct ToInteger { diff --git a/src/Functions/DivisionUtils.h b/src/Functions/DivisionUtils.h index 69fa1437487..1d9c2ad7ccb 100644 --- a/src/Functions/DivisionUtils.h +++ b/src/Functions/DivisionUtils.h @@ -6,14 +6,8 @@ #include #include -#include "DataTypes/Native.h" #include "config.h" -#if USE_EMBEDDED_COMPILER -# include -# include -#endif - namespace DB { @@ -21,42 +15,8 @@ namespace DB namespace ErrorCodes { extern const int ILLEGAL_DIVISION; - extern const int LOGICAL_ERROR; } -#if USE_EMBEDDED_COMPILER - -template -static llvm::Value * compileWithNullableValues(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed, F && compile_func) -{ - auto * left_type = left->getType(); - auto * right_type = right->getType(); - - if (!left_type->isStructTy() && !right_type->isStructTy()) - { - // Both arguments are not nullable. - return compile_func(b, left, right, is_signed); - } - - auto * denull_left = left_type->isStructTy() ? b.CreateExtractValue(left, {1}) : left; - auto * denull_right = right_type->isStructTy() ? b.CreateExtractValue(right, {1}) : right; - auto * denull_result = compile_func(b, denull_left, denull_right, is_signed); - - auto * nullable_result_type = toNullableType(b, denull_result->getType()); - llvm::Value * nullable_result = llvm::Constant::getNullValue(nullable_result_type); - nullable_result = b.CreateInsertValue(nullable_result, denull_result, {0}); - - auto * result_is_null = b.CreateExtractValue(nullable_result, {1}); - if (left_type->isStructTy()) - result_is_null = b.CreateOr(result_is_null, b.CreateExtractValue(left, {1})); - if (right_type->isStructTy()) - result_is_null = b.CreateOr(result_is_null, b.CreateExtractValue(right, {1})); - - return b.CreateInsertValue(nullable_result, result_is_null, {1}); -} - -#endif - template inline void throwIfDivisionLeadsToFPE(A a, B b) { @@ -198,39 +158,14 @@ struct ModuloImpl } #if USE_EMBEDDED_COMPILER - static constexpr bool compilable = true; /// Ignore exceptions in LLVM IR - - static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed) - { - return compileWithNullableValues( - b, - left, - right, - is_signed, - [](auto & b_, auto * left_, auto * right_, auto is_signed_) { return compileImpl(b_, left_, right_, is_signed_); }); - } - - static llvm::Value * compileImpl(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed) - { - if (left->getType()->isFloatingPointTy()) - return b.CreateFRem(left, right); - else if (left->getType()->isIntegerTy()) - return is_signed ? b.CreateSRem(left, right) : b.CreateURem(left, right); - else - throw Exception(ErrorCodes::LOGICAL_ERROR, "ModuloImpl compilation expected native integer or floating point type"); - } - - #endif + static constexpr bool compilable = false; /// don't know how to throw from LLVM IR +#endif }; template struct ModuloLegacyImpl : ModuloImpl { using ResultType = typename NumberTraits::ResultOfModuloLegacy::Type; - -#if USE_EMBEDDED_COMPILER - static constexpr bool compilable = false; /// moduloLegacy is only used in partition key expression -#endif }; template @@ -259,36 +194,6 @@ struct PositiveModuloImpl : ModuloImpl } return static_cast(res); } - -#if USE_EMBEDDED_COMPILER - static constexpr bool compilable = true; /// Ignore exceptions in LLVM IR - - static llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed) - { - return compileWithNullableValues( - b, - left, - right, - is_signed, - [](auto & b_, auto * left_, auto * right_, auto is_signed_) { return compileImpl(b_, left_, right_, is_signed_); }); - } - - static llvm::Value * compileImpl(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed) - { - auto * result = ModuloImpl::compileImpl(b, left, right, is_signed); - if (is_signed) - { - /// If result is negative, result += abs(right). - auto * zero = llvm::Constant::getNullValue(result->getType()); - auto * is_negative = b.CreateICmpSLT(result, zero); - auto * abs_right = b.CreateSelect(b.CreateICmpSLT(right, zero), b.CreateNeg(right), right); - return b.CreateSelect(is_negative, b.CreateAdd(result, abs_right), result); - } - else - return result; - } -#endif - }; } diff --git a/src/Functions/FunctionBinaryArithmetic.h b/src/Functions/FunctionBinaryArithmetic.h index 528908b6f0f..91adf73b679 100644 --- a/src/Functions/FunctionBinaryArithmetic.h +++ b/src/Functions/FunctionBinaryArithmetic.h @@ -810,7 +810,6 @@ class FunctionBinaryArithmetic : public IFunction static constexpr bool is_division = IsOperation::division; static constexpr bool is_bit_hamming_distance = IsOperation::bit_hamming_distance; static constexpr bool is_modulo = IsOperation::modulo; - static constexpr bool is_positive_modulo = IsOperation::positive_modulo; static constexpr bool is_int_div = IsOperation::int_div; static constexpr bool is_int_div_or_zero = IsOperation::int_div_or_zero; @@ -2388,105 +2387,59 @@ ColumnPtr executeStringInteger(const ColumnsWithTypeAndName & arguments, const A if (!canBeNativeType(*arguments[0]) || !canBeNativeType(*arguments[1]) || !canBeNativeType(*result_type)) return false; - auto denull_left_type = removeNullable(arguments[0]); - auto denull_right_type = removeNullable(arguments[1]); - WhichDataType data_type_lhs(denull_left_type); - WhichDataType data_type_rhs(denull_right_type); + WhichDataType data_type_lhs(arguments[0]); + WhichDataType data_type_rhs(arguments[1]); if ((data_type_lhs.isDateOrDate32() || data_type_lhs.isDateTime()) || (data_type_rhs.isDateOrDate32() || data_type_rhs.isDateTime())) return false; - return castBothTypes( - denull_left_type.get(), - denull_right_type.get(), - [&](const auto & left, const auto & right) + return castBothTypes(arguments[0].get(), arguments[1].get(), [&](const auto & left, const auto & right) + { + using LeftDataType = std::decay_t; + using RightDataType = std::decay_t; + if constexpr (!std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v) { - using LeftDataType = std::decay_t; - using RightDataType = std::decay_t; - if constexpr ( - !std::is_same_v && !std::is_same_v - && !std::is_same_v && !std::is_same_v) - { - using ResultDataType = typename BinaryOperationTraits::ResultDataType; - using OpSpec = Op; - - if constexpr ( - !std::is_same_v && !IsDataTypeDecimal - && !IsDataTypeDecimal && !IsDataTypeDecimal && OpSpec::compilable) - { - if constexpr (is_modulo || is_positive_modulo) - { - using LeftType = typename LeftDataType::FieldType; - using RightType = typename RightDataType::FieldType; - using PromotedType = typename NumberTraits::ResultOfModuloNativePromotion::Type; - if constexpr (std::is_arithmetic_v) - { - return true; - } - } - else - return true; - } - } - return false; - }); + using ResultDataType = typename BinaryOperationTraits::ResultDataType; + using OpSpec = Op; + if constexpr (!std::is_same_v && !IsDataTypeDecimal && OpSpec::compilable) + return true; + } + return false; + }); } llvm::Value * compileImpl(llvm::IRBuilderBase & builder, const ValuesWithType & arguments, const DataTypePtr & result_type) const override { assert(2 == arguments.size()); - auto denull_left_type = removeNullable(arguments[0].type); - auto denull_right_type = removeNullable(arguments[1].type); llvm::Value * result = nullptr; - - castBothTypes( - denull_left_type.get(), - denull_right_type.get(), - [&](const auto & left, const auto & right) + castBothTypes(arguments[0].type.get(), arguments[1].type.get(), [&](const auto & left, const auto & right) + { + using LeftDataType = std::decay_t; + using RightDataType = std::decay_t; + if constexpr (!std::is_same_v && + !std::is_same_v && + !std::is_same_v && + !std::is_same_v) { - using LeftDataType = std::decay_t; - using RightDataType = std::decay_t; - if constexpr ( - !std::is_same_v && !std::is_same_v - && !std::is_same_v && !std::is_same_v) + using ResultDataType = typename BinaryOperationTraits::ResultDataType; + using OpSpec = Op; + if constexpr (!std::is_same_v && !IsDataTypeDecimal && OpSpec::compilable) { - using ResultDataType = typename BinaryOperationTraits::ResultDataType; - using OpSpec = Op; - if constexpr ( - !std::is_same_v && !IsDataTypeDecimal - && !IsDataTypeDecimal && !IsDataTypeDecimal && OpSpec::compilable) - { - auto & b = static_cast &>(builder); - if constexpr (is_modulo || is_positive_modulo) - { - using LeftType = typename LeftDataType::FieldType; - using RightType = typename RightDataType::FieldType; - using PromotedType = typename NumberTraits::ResultOfModuloNativePromotion::Type; - if constexpr (std::is_arithmetic_v) - { - DataTypePtr promoted_type = std::make_shared>(); - if (result_type->isNullable()) - promoted_type = std::make_shared(promoted_type); + auto & b = static_cast &>(builder); + auto * lval = nativeCast(b, arguments[0], result_type); + auto * rval = nativeCast(b, arguments[1], result_type); + result = OpSpec::compile(b, lval, rval, std::is_signed_v); - auto * lval = nativeCast(b, arguments[0], promoted_type); - auto * rval = nativeCast(b, arguments[1], promoted_type); - result = nativeCast( - b, promoted_type, OpSpec::compile(b, lval, rval, std::is_signed_v), result_type); - return true; - } - } - else - { - auto * lval = nativeCast(b, arguments[0], result_type); - auto * rval = nativeCast(b, arguments[1], result_type); - result = OpSpec::compile(b, lval, rval, std::is_signed_v); - return true; - } - } + return true; } - return false; - }); + } + + return false; + }); return result; } diff --git a/src/Functions/FunctionUnaryArithmetic.h b/src/Functions/FunctionUnaryArithmetic.h index 72f5e37e99e..cf79bb06430 100644 --- a/src/Functions/FunctionUnaryArithmetic.h +++ b/src/Functions/FunctionUnaryArithmetic.h @@ -489,7 +489,9 @@ public: { using DataType = std::decay_t; if constexpr (std::is_same_v || std::is_same_v) + { return false; + } else { using T0 = typename DataType::FieldType; @@ -511,7 +513,9 @@ public: { using DataType = std::decay_t; if constexpr (std::is_same_v || std::is_same_v) + { return false; + } else { using T0 = typename DataType::FieldType; @@ -519,16 +523,8 @@ public: if constexpr (!std::is_same_v && !IsDataTypeDecimal && Op::compilable) { auto & b = static_cast &>(builder); - if constexpr (std::is_same_v, AbsImpl> || std::is_same_v, BitCountImpl>) - { - /// We don't need to cast the argument to the result type if it's abs/bitcount function. - result = Op::compile(b, arguments[0].value, is_signed_v); - } - else - { - auto * v = nativeCast(b, arguments[0], result_type); - result = Op::compile(b, v, is_signed_v); - } + auto * v = nativeCast(b, arguments[0], result_type); + result = Op::compile(b, v, is_signed_v); return true; } diff --git a/src/Functions/FunctionsComparison.h b/src/Functions/FunctionsComparison.h index 5a4276e0d75..d8ff9b1699e 100644 --- a/src/Functions/FunctionsComparison.h +++ b/src/Functions/FunctionsComparison.h @@ -1,21 +1,17 @@ #pragma once -// Include this first, because `#define _asan_poison_address` from -// llvm/Support/Compiler.h conflicts with its forward declaration in -// sanitizer/asan_interface.h -#include -#include -#include +#include +#include +#include -#include +#include #include #include -#include #include +#include #include -#include -#include -#include +#include + #include #include #include @@ -28,23 +24,22 @@ #include #include #include -#include + +#include +#include + #include +#include #include + +#include +#include + #include #include -#include -#include -#include -#include -#include -#include "DataTypes/NumberTraits.h" -#if USE_EMBEDDED_COMPILER -# include -# include -# include -#endif +#include +#include namespace DB { @@ -635,61 +630,6 @@ struct GenericComparisonImpl } }; - -#if USE_EMBEDDED_COMPILER - -template