diff --git a/dbms/src/Common/ProfileEvents.cpp b/dbms/src/Common/ProfileEvents.cpp index 027f52b2f37..7151b6eab38 100644 --- a/dbms/src/Common/ProfileEvents.cpp +++ b/dbms/src/Common/ProfileEvents.cpp @@ -79,6 +79,8 @@ M(CompileAttempt) \ M(CompileSuccess) \ \ + M(CompileFunction) \ + \ M(ExternalSortWritePart) \ M(ExternalSortMerge) \ M(ExternalAggregationWritePart) \ diff --git a/dbms/src/Functions/IFunction.cpp b/dbms/src/Functions/IFunction.cpp index d271e3e9744..f9727c3b3ce 100644 --- a/dbms/src/Functions/IFunction.cpp +++ b/dbms/src/Functions/IFunction.cpp @@ -31,6 +31,7 @@ namespace ErrorCodes extern const int ILLEGAL_COLUMN; } + namespace { diff --git a/dbms/src/Interpreters/ExpressionJIT.cpp b/dbms/src/Interpreters/ExpressionJIT.cpp index 2a0984728c1..17fc97b77eb 100644 --- a/dbms/src/Interpreters/ExpressionJIT.cpp +++ b/dbms/src/Interpreters/ExpressionJIT.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,11 @@ __attribute__((__weak__)) int _ZTIN4llvm12MemoryBufferE = 0; } +namespace ProfileEvents +{ + extern const Event CompileFunction; +} + namespace DB { @@ -176,6 +182,7 @@ struct LLVMContext std::string mangled_name; llvm::raw_string_ostream mangled_name_stream(mangled_name); llvm::Mangler::getNameWithPrefix(mangled_name_stream, function.getName(), layout); + mangled_name_stream.flush(); function_names.emplace_back(function.getName(), mangled_name); } @@ -187,8 +194,13 @@ struct LLVMContext #endif for (const auto & names : function_names) - if (auto symbol = compileLayer.findSymbol(names.second, false).getAddress()) - symbols[names.first] = reinterpret_cast(*symbol); + { + if (auto symbol = compileLayer.findSymbol(names.second, false)) + { + if (auto address_or_error = symbol.getAddress()) + symbols[names.first] = reinterpret_cast(*address_or_error); + } + } } }; @@ -231,6 +243,8 @@ public: static void compileFunction(std::shared_ptr & context, const IFunctionBase & f) { + ProfileEvents::increment(ProfileEvents::CompileFunction); + auto & arg_types = f.getArgumentTypes(); auto & b = context->builder; auto * size_type = b.getIntNTy(sizeof(size_t) * 8); @@ -548,6 +562,7 @@ void compileFunctions(ExpressionActions::Actions & actions, const Names & output { if (actions[i].type != ExpressionAction::APPLY_FUNCTION || !isCompilable(context->builder, *actions[i].function)) continue; + fused[i].push_back(actions[i]); if (dependents[i].find({}) != dependents[i].end()) { @@ -559,10 +574,12 @@ void compileFunctions(ExpressionActions::Actions & actions, const Names & output actions[i].argument_names = fn->getArgumentNames(); continue; } + /// TODO: determine whether it's profitable to inline the function if there's more than one dependent. for (const auto & dep : dependents[i]) fused[*dep].insert(fused[*dep].end(), fused[i].begin(), fused[i].end()); } + context->finalize(); }