diff --git a/.travis.yml b/.travis.yml index dc1c2091e0808..f6071cdb94e37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,10 +46,103 @@ before_install: matrix: fast_finish: true + allow_failures: + - jdk: oraclejdk9 include: + # C++ & Python w/ clang 6.0 + - compiler: gcc + language: cpp + os: linux + jdk: openjdk8 + env: + - ARROW_TRAVIS_USE_TOOLCHAIN=1 + - ARROW_TRAVIS_VALGRIND=1 + - ARROW_TRAVIS_PLASMA=1 + - ARROW_TRAVIS_ORC=1 + - ARROW_TRAVIS_CLANG_FORMAT=1 + - ARROW_TRAVIS_COVERAGE=1 + - ARROW_TRAVIS_PARQUET=1 + - ARROW_TRAVIS_PYTHON_DOCS=1 + - ARROW_BUILD_WARNING_LEVEL=CHECKIN + - ARROW_TRAVIS_PYTHON_JVM=1 + - ARROW_TRAVIS_JAVA_BUILD_ONLY=1 + # ARROW-2999 Benchmarks are disabled in Travis CI for the time being + # - ARROW_TRAVIS_PYTHON_BENCHMARKS=1 + - CC="clang-6.0" + - CXX="clang++-6.0" + before_script: + # Always run RAT checks, in case another build in matrix breaks RAT + - $TRAVIS_BUILD_DIR/ci/travis_release_audit.sh + # (ARROW_CI_CPP_AFFECTED implies ARROW_CI_PYTHON_AFFECTED) + - if [ $ARROW_CI_PYTHON_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_install_clang_tools.sh + - $TRAVIS_BUILD_DIR/ci/travis_lint.sh + # If either C++ or Python changed, we must install the C++ libraries + - git submodule update --init + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh + script: + # All test steps are required for accurate C++ coverage info + - $TRAVIS_BUILD_DIR/ci/travis_script_cpp.sh + # Build Arrow Java to test the pyarrow<->JVM in-process bridge + - $TRAVIS_BUILD_DIR/ci/travis_script_java.sh + # Only run Plasma tests with valgrind in one of the Python builds because + # they are slow + - export PLASMA_VALGRIND=0 + - $TRAVIS_BUILD_DIR/ci/travis_script_python.sh 2.7 + - export PLASMA_VALGRIND=1 + - $TRAVIS_BUILD_DIR/ci/travis_script_python.sh 3.6 + - $TRAVIS_BUILD_DIR/ci/travis_upload_cpp_coverage.sh + # Gandiva C++ w/ gcc 4.9 and Java + - compiler: gcc + language: cpp + os: linux + jdk: openjdk8 + env: + - ARROW_TRAVIS_GANDIVA=1 + - ARROW_TRAVIS_USE_TOOLCHAIN=1 + - ARROW_TRAVIS_VALGRIND=1 + - ARROW_TRAVIS_CLANG_FORMAT=1 + - ARROW_BUILD_WARNING_LEVEL=CHECKIN + - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9" + before_script: + # Run if something changed in CPP or Java. + - if [ $ARROW_CI_CPP_AFFECTED != "1" ] && [ $ARROW_CI_JAVA_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_install_clang_tools.sh + - $TRAVIS_BUILD_DIR/ci/travis_lint.sh + # If either C++ or Python changed, we must install the C++ libraries + - git submodule update --init + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh --only-library + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_gandiva_cpp.sh + - $TRAVIS_BUILD_DIR/ci/travis_script_gandiva_java.sh + # [OS X] C++ & Python w/ XCode 6.4 + - compiler: clang + language: cpp + osx_image: xcode6.4 + os: osx + cache: + addons: + env: + - ARROW_TRAVIS_USE_TOOLCHAIN=1 + - ARROW_TRAVIS_PLASMA=1 + - ARROW_TRAVIS_ORC=1 + - ARROW_TRAVIS_PARQUET=1 + - ARROW_BUILD_WARNING_LEVEL=CHECKIN + before_script: + - if [ $ARROW_CI_PYTHON_AFFECTED != "1" ]; then exit; fi + # If either C++ or Python changed, we must install the C++ libraries + - git submodule update --init + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh + script: + - if [ $ARROW_CI_CPP_AFFECTED == "1" ]; then $TRAVIS_BUILD_DIR/ci/travis_script_cpp.sh; fi + - $TRAVIS_BUILD_DIR/ci/travis_script_python.sh 2.7 + - $TRAVIS_BUILD_DIR/ci/travis_script_python.sh 3.6 # [OS X] Gandiva C++ w/ XCode 8.3 & Java - compiler: clang language: cpp + # xcode 7.3 has a bug in strptime. osx_image: xcode8.3 os: osx cache: @@ -67,6 +160,160 @@ matrix: script: - $TRAVIS_BUILD_DIR/ci/travis_script_gandiva_cpp.sh - $TRAVIS_BUILD_DIR/ci/travis_script_gandiva_java.sh + # [manylinux1] Python + - language: cpp + before_script: + - if [ $ARROW_CI_PYTHON_AFFECTED == "1" ]; then docker pull quay.io/xhochy/arrow_manylinux1_x86_64_base:latest; fi + script: + - if [ $ARROW_CI_PYTHON_AFFECTED == "1" ]; then $TRAVIS_BUILD_DIR/ci/travis_script_manylinux.sh; fi + # Java w/ OpenJDK 8 + - language: java + os: linux + jdk: openjdk8 + before_script: + - if [ $ARROW_CI_JAVA_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_java.sh + - $TRAVIS_BUILD_DIR/ci/travis_script_javadoc.sh + # Java w/ Oracle JDK 9 + - language: java + os: linux + jdk: oraclejdk9 + before_script: + - if [ $ARROW_CI_JAVA_AFFECTED != "1" ]; then exit; fi + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_java.sh + addons: + apt: + packages: + - oracle-java9-installer + # Integration w/ OpenJDK 8 + - language: java + os: linux + env: ARROW_TEST_GROUP=integration + jdk: openjdk8 + env: + - ARROW_TRAVIS_PLASMA=1 + - ARROW_TRAVIS_PLASMA_JAVA_CLIENT=1 + - CC="clang-6.0" + - CXX="clang++-6.0" + before_script: + - if [ $ARROW_CI_INTEGRATION_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_install_clang_tools.sh + - nvm install 10.1 + - $TRAVIS_BUILD_DIR/ci/travis_before_script_js.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_integration.sh + - $TRAVIS_BUILD_DIR/ci/travis_script_plasma_java_client.sh + # NodeJS + - language: node_js + os: linux + node_js: + - '10.1' + before_script: + - if [ $ARROW_CI_JS_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_js.sh + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_js.sh + # C++ & GLib & Ruby w/ gcc 4.9 + - compiler: gcc + language: cpp + os: linux + env: + - ARROW_TRAVIS_ORC=1 + - ARROW_TRAVIS_PARQUET=1 + - BUILD_TORCH_EXAMPLE=no + - CC="gcc-4.9" + - CXX="g++-4.9" + before_script: + - if [ $ARROW_CI_RUBY_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh --only-library + - $TRAVIS_BUILD_DIR/ci/travis_before_script_c_glib.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_ruby.sh + script: + - if [ $ARROW_CI_C_GLIB_AFFECTED = "1" ]; then $TRAVIS_BUILD_DIR/ci/travis_script_c_glib.sh; fi + - $TRAVIS_BUILD_DIR/ci/travis_script_ruby.sh + # [OS X] C++ & GLib & Ruby w/ XCode 8.3 & homebrew + - compiler: clang + osx_image: xcode8.3 + os: osx + env: + - ARROW_TRAVIS_ORC=1 + cache: + addons: + rvm: 2.2 + before_script: + - if [ $ARROW_CI_RUBY_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_osx.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh --only-library --homebrew + - $TRAVIS_BUILD_DIR/ci/travis_before_script_c_glib.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_ruby.sh + script: + - if [ $ARROW_CI_C_GLIB_AFFECTED = "1" ]; then $TRAVIS_BUILD_DIR/ci/travis_script_c_glib.sh; fi + - $TRAVIS_BUILD_DIR/ci/travis_script_ruby.sh + # Rust + - language: rust + cache: cargo + addons: + apt: + packages: + - libcurl4-openssl-dev + - libelf-dev + - libdw-dev + - binutils-dev + - cmake + before_script: + - if [ $ARROW_CI_RUST_AFFECTED != "1" ]; then exit; fi + - $TRAVIS_BUILD_DIR/ci/travis_install_cargo.sh + script: + - RUSTUP_TOOLCHAIN=stable $TRAVIS_BUILD_DIR/ci/travis_script_rust.sh + - RUSTUP_TOOLCHAIN=nightly $TRAVIS_BUILD_DIR/ci/travis_script_rust.sh || true + after_success: + - pushd ${TRAVIS_BUILD_DIR}/rust + # Run coverage for codecov.io + - mkdir -p target/kcov + - RUST_BACKTRACE=1 RUSTUP_TOOLCHAIN=stable cargo coverage --verbose + - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports" + # Go + - language: go + go_import_path: github.com/apache/arrow + os: linux + go: + - 1.11.x + before_script: + - if [ $ARROW_CI_GO_AFFECTED != "1" ]; then exit; fi + script: + - $TRAVIS_BUILD_DIR/ci/travis_script_go.sh + after_success: + - pushd ${TRAVIS_BUILD_DIR}/go/arrow + - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports" + # R + - language: r + cache: packages + latex: false + before_install: + # Have to copy-paste this here because of how R's build steps work + - eval `python $TRAVIS_BUILD_DIR/ci/detect-changes.py` + - if [ $ARROW_CI_R_AFFECTED != "1" ]; then exit; fi + - | + if [ $TRAVIS_OS_NAME == "linux" ]; then + sudo bash -c "echo -e 'Acquire::Retries 10; Acquire::http::Timeout \"20\";' > /etc/apt/apt.conf.d/99-travis-retry" + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update -qq + fi + - $TRAVIS_BUILD_DIR/ci/travis_install_linux.sh + - $TRAVIS_BUILD_DIR/ci/travis_before_script_cpp.sh --only-library + - $TRAVIS_BUILD_DIR/ci/travis_install_clang_tools.sh + - $TRAVIS_BUILD_DIR/ci/travis_lint.sh + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TRAVIS_BUILD_DIR/cpp-install/lib + - export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$TRAVIS_BUILD_DIR/cpp-install/lib/pkgconfig + - pushd ${TRAVIS_BUILD_DIR}/r + after_failure: - | diff --git a/cpp/cmake_modules/SetupCxxFlags.cmake b/cpp/cmake_modules/SetupCxxFlags.cmake index 13d586b427516..b0865fb0347c7 100644 --- a/cpp/cmake_modules/SetupCxxFlags.cmake +++ b/cpp/cmake_modules/SetupCxxFlags.cmake @@ -113,8 +113,6 @@ if ("${UPPERCASE_BUILD_WARNING_LEVEL}" STREQUAL "CHECKIN") if ("${COMPILER_VERSION}" VERSION_GREATER "3.6") set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-reserved-id-macro") set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-range-loop-analysis") - endif() - if ("${COMPILER_VERSION}" VERSION_GREATER "3.7") set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-double-promotion") endif() if ("${COMPILER_VERSION}" VERSION_GREATER "3.8") diff --git a/cpp/src/gandiva/context_helper.cc b/cpp/src/gandiva/context_helper.cc index 78cb383bd0021..6d5ca1b5d4236 100644 --- a/cpp/src/gandiva/context_helper.cc +++ b/cpp/src/gandiva/context_helper.cc @@ -25,16 +25,17 @@ namespace gandiva { -void ExportedContextFunctions::AddMappings(Engine& engine) const { +void ExportedContextFunctions::AddMappings(Engine* engine) const { std::vector args; - auto types = engine.types(); + auto types = engine->types(); // gdv_fn_context_set_error_msg - args = {types.i64_type(), // int64_t context_ptr - types.i8_ptr_type()}; // char const* err_msg + args = {types->i64_type(), // int64_t context_ptr + types->i8_ptr_type()}; // char const* err_msg - engine.AddGlobalMappingForFunc("gdv_fn_context_set_error_msg", types.void_type(), args, - reinterpret_cast(gdv_fn_context_set_error_msg)); + engine->AddGlobalMappingForFunc("gdv_fn_context_set_error_msg", types->void_type(), + args, + reinterpret_cast(gdv_fn_context_set_error_msg)); } } // namespace gandiva diff --git a/cpp/src/gandiva/engine.cc b/cpp/src/gandiva/engine.cc index 306ad2209837a..78cc84a3dec7d 100644 --- a/cpp/src/gandiva/engine.cc +++ b/cpp/src/gandiva/engine.cc @@ -221,7 +221,7 @@ void Engine::AddGlobalMappingForFunc(const std::string& name, llvm::Type* ret_ty execution_engine_->addGlobalMapping(fn, function_ptr); } -void Engine::AddGlobalMappings() { ExportedFuncsRegistry::AddMappings(*this); } +void Engine::AddGlobalMappings() { ExportedFuncsRegistry::AddMappings(this); } void Engine::DumpIR(std::string prefix) { std::string str; diff --git a/cpp/src/gandiva/engine.h b/cpp/src/gandiva/engine.h index 8746024c447ad..485447bd7d2f4 100644 --- a/cpp/src/gandiva/engine.h +++ b/cpp/src/gandiva/engine.h @@ -41,8 +41,8 @@ namespace gandiva { class Engine { public: llvm::LLVMContext* context() { return context_.get(); } - llvm::IRBuilder<>& ir_builder() { return *ir_builder_.get(); } - + llvm::IRBuilder<>* ir_builder() { return ir_builder_.get(); } + LLVMTypes* types() { return types_.get(); } llvm::Module* module() { return module_; } /// factory method to create and initialize the engine object. @@ -64,8 +64,6 @@ class Engine { /// Get the compiled function corresponding to the irfunction. void* CompiledFunction(llvm::Function* irFunction); - LLVMTypes& types() { return *types_; } - // Create and add a mapping for the cpp function to make it accessible from LLVM. void AddGlobalMappingForFunc(const std::string& name, llvm::Type* ret_type, const std::vector& args, void* func); diff --git a/cpp/src/gandiva/engine_llvm_test.cc b/cpp/src/gandiva/engine_llvm_test.cc index 48eee232e2597..424b258fd70d7 100644 --- a/cpp/src/gandiva/engine_llvm_test.cc +++ b/cpp/src/gandiva/engine_llvm_test.cc @@ -30,7 +30,7 @@ class TestEngine : public ::testing::Test { }; llvm::Function* TestEngine::BuildVecAdd(Engine* engine, LLVMTypes* types) { - llvm::IRBuilder<>& builder = engine->ir_builder(); + llvm::IRBuilder<>* builder = engine->ir_builder(); llvm::LLVMContext* context = engine->context(); // Create fn prototype : @@ -62,39 +62,39 @@ llvm::Function* TestEngine::BuildVecAdd(Engine* engine, LLVMTypes* types) { llvm::BasicBlock* loop_exit = llvm::BasicBlock::Create(*context, "exit", fn); // Loop entry - builder.SetInsertPoint(loop_entry); - builder.CreateBr(loop_body); + builder->SetInsertPoint(loop_entry); + builder->CreateBr(loop_body); // Loop body - builder.SetInsertPoint(loop_body); + builder->SetInsertPoint(loop_body); - llvm::PHINode* loop_var = builder.CreatePHI(types->i32_type(), 2, "loop_var"); - llvm::PHINode* sum = builder.CreatePHI(types->i64_type(), 2, "sum"); + llvm::PHINode* loop_var = builder->CreatePHI(types->i32_type(), 2, "loop_var"); + llvm::PHINode* sum = builder->CreatePHI(types->i64_type(), 2, "sum"); loop_var->addIncoming(types->i32_constant(0), loop_entry); sum->addIncoming(types->i64_constant(0), loop_entry); // setup loop PHI llvm::Value* loop_update = - builder.CreateAdd(loop_var, types->i32_constant(1), "loop_var+1"); + builder->CreateAdd(loop_var, types->i32_constant(1), "loop_var+1"); loop_var->addIncoming(loop_update, loop_body); // get the current value - llvm::Value* offset = builder.CreateGEP(arg_elements, loop_var, "offset"); - llvm::Value* current_value = builder.CreateLoad(offset, "value"); + llvm::Value* offset = builder->CreateGEP(arg_elements, loop_var, "offset"); + llvm::Value* current_value = builder->CreateLoad(offset, "value"); // setup sum PHI - llvm::Value* sum_update = builder.CreateAdd(sum, current_value, "sum+ith"); + llvm::Value* sum_update = builder->CreateAdd(sum, current_value, "sum+ith"); sum->addIncoming(sum_update, loop_body); // check loop_var llvm::Value* loop_var_check = - builder.CreateICmpSLT(loop_update, arg_nelements, "loop_var < nrec"); - builder.CreateCondBr(loop_var_check, loop_body, loop_exit); + builder->CreateICmpSLT(loop_update, arg_nelements, "loop_var < nrec"); + builder->CreateCondBr(loop_var_check, loop_body, loop_exit); // Loop exit - builder.SetInsertPoint(loop_exit); - builder.CreateRet(sum_update); + builder->SetInsertPoint(loop_exit); + builder->CreateRet(sum_update); return fn; } diff --git a/cpp/src/gandiva/exported_funcs.h b/cpp/src/gandiva/exported_funcs.h index 2f767fb594094..0ca28c2b5b188 100644 --- a/cpp/src/gandiva/exported_funcs.h +++ b/cpp/src/gandiva/exported_funcs.h @@ -30,18 +30,18 @@ class ExportedFuncsBase { public: virtual ~ExportedFuncsBase() = default; - virtual void AddMappings(Engine& engine) const = 0; + virtual void AddMappings(Engine* engine) const = 0; }; // Class for exporting Stub functions class ExportedStubFunctions : public ExportedFuncsBase { - void AddMappings(Engine& engine) const override; + void AddMappings(Engine* engine) const override; }; REGISTER_EXPORTED_FUNCS(ExportedStubFunctions); // Class for exporting Context functions class ExportedContextFunctions : public ExportedFuncsBase { - void AddMappings(Engine& engine) const override; + void AddMappings(Engine* engine) const override; }; REGISTER_EXPORTED_FUNCS(ExportedContextFunctions); diff --git a/cpp/src/gandiva/exported_funcs_registry.cc b/cpp/src/gandiva/exported_funcs_registry.cc index 2ed72d73d4f01..4c87c4d40764b 100644 --- a/cpp/src/gandiva/exported_funcs_registry.cc +++ b/cpp/src/gandiva/exported_funcs_registry.cc @@ -21,7 +21,7 @@ namespace gandiva { -void ExportedFuncsRegistry::AddMappings(Engine& engine) { +void ExportedFuncsRegistry::AddMappings(Engine* engine) { for (auto entry : registered()) { entry->AddMappings(engine); } diff --git a/cpp/src/gandiva/exported_funcs_registry.h b/cpp/src/gandiva/exported_funcs_registry.h index 63de29d4e7274..511ec9c212468 100644 --- a/cpp/src/gandiva/exported_funcs_registry.h +++ b/cpp/src/gandiva/exported_funcs_registry.h @@ -33,7 +33,7 @@ class ExportedFuncsRegistry { using list_type = std::vector; // Add functions from all the registered classes to the engine. - static void AddMappings(Engine& engine); + static void AddMappings(Engine* engine); static bool Register(ExportedFuncsBase* entry) { registered().push_back(entry); diff --git a/cpp/src/gandiva/expr_validator.cc b/cpp/src/gandiva/expr_validator.cc index 849583f97ed0d..5dfa2448d3963 100644 --- a/cpp/src/gandiva/expr_validator.cc +++ b/cpp/src/gandiva/expr_validator.cc @@ -45,7 +45,7 @@ Status ExprValidator::Validate(const ExpressionPtr& expr) { } Status ExprValidator::Visit(const FieldNode& node) { - auto llvm_type = types_.IRType(node.return_type()->id()); + auto llvm_type = types_->IRType(node.return_type()->id()); if (llvm_type == nullptr) { std::stringstream ss; ss << "Field " << node.field()->name() << " has unsupported data type " @@ -120,7 +120,7 @@ Status ExprValidator::Visit(const IfNode& node) { } Status ExprValidator::Visit(const LiteralNode& node) { - auto llvm_type = types_.IRType(node.return_type()->id()); + auto llvm_type = types_->IRType(node.return_type()->id()); if (llvm_type == nullptr) { std::stringstream ss; ss << "Value " << node.holder() << " has unsupported data type " diff --git a/cpp/src/gandiva/expr_validator.h b/cpp/src/gandiva/expr_validator.h index 86239f29ce6f6..ea686afe4da0e 100644 --- a/cpp/src/gandiva/expr_validator.h +++ b/cpp/src/gandiva/expr_validator.h @@ -38,7 +38,7 @@ class FunctionRegistry; /// data types, signatures and return types class ExprValidator : public NodeVisitor { public: - explicit ExprValidator(LLVMTypes& types, SchemaPtr schema) + explicit ExprValidator(LLVMTypes* types, SchemaPtr schema) : types_(types), schema_(schema) { for (auto& field : schema_->fields()) { field_map_[field->name()] = field; @@ -62,7 +62,7 @@ class ExprValidator : public NodeVisitor { FunctionRegistry registry_; - LLVMTypes& types_; + LLVMTypes* types_; SchemaPtr schema_; diff --git a/cpp/src/gandiva/gdv_function_stubs.cc b/cpp/src/gandiva/gdv_function_stubs.cc index 4a590183289f5..1f4bb6312c3a9 100644 --- a/cpp/src/gandiva/gdv_function_stubs.cc +++ b/cpp/src/gandiva/gdv_function_stubs.cc @@ -48,36 +48,37 @@ int64_t gdv_fn_to_date_utf8_utf8_int32(int64_t ptr, const char* data, int data_l namespace gandiva { -void ExportedStubFunctions::AddMappings(Engine& engine) const { +void ExportedStubFunctions::AddMappings(Engine* engine) const { std::vector args; - auto types = engine.types(); + auto types = engine->types(); // gdv_fn_like_utf8_utf8 - args = {types.i64_type(), // int64_t ptr - types.i8_ptr_type(), // const char* data - types.i32_type(), // int data_len - types.i8_ptr_type(), // const char* pattern - types.i32_type()}; // int pattern_len + args = {types->i64_type(), // int64_t ptr + types->i8_ptr_type(), // const char* data + types->i32_type(), // int data_len + types->i8_ptr_type(), // const char* pattern + types->i32_type()}; // int pattern_len - engine.AddGlobalMappingForFunc("gdv_fn_like_utf8_utf8", types.i1_type() /*return_type*/, - args, reinterpret_cast(gdv_fn_like_utf8_utf8)); + engine->AddGlobalMappingForFunc("gdv_fn_like_utf8_utf8", + types->i1_type() /*return_type*/, args, + reinterpret_cast(gdv_fn_like_utf8_utf8)); // gdv_fn_to_date_utf8_utf8_int32 - args = {types.i64_type(), // int64_t ptr - types.i8_ptr_type(), // const char* data - types.i32_type(), // int data_len - types.i1_type(), // bool in1_validity - types.i8_ptr_type(), // const char* pattern - types.i32_type(), // int pattern_len - types.i1_type(), // bool in2_validity - types.i32_type(), // int32_t suppress_errors - types.i1_type(), // bool in3_validity - types.i64_type(), // int64_t execution_context - types.ptr_type(types.i8_type())}; // bool* out_valid + args = {types->i64_type(), // int64_t ptr + types->i8_ptr_type(), // const char* data + types->i32_type(), // int data_len + types->i1_type(), // bool in1_validity + types->i8_ptr_type(), // const char* pattern + types->i32_type(), // int pattern_len + types->i1_type(), // bool in2_validity + types->i32_type(), // int32_t suppress_errors + types->i1_type(), // bool in3_validity + types->i64_type(), // int64_t execution_context + types->ptr_type(types->i8_type())}; // bool* out_valid - engine.AddGlobalMappingForFunc("gdv_fn_to_date_utf8_utf8_int32", - types.i64_type() /*return_type*/, args, - reinterpret_cast(gdv_fn_to_date_utf8_utf8_int32)); + engine->AddGlobalMappingForFunc( + "gdv_fn_to_date_utf8_utf8_int32", types->i64_type() /*return_type*/, args, + reinterpret_cast(gdv_fn_to_date_utf8_utf8_int32)); } } // namespace gandiva diff --git a/cpp/src/gandiva/llvm_generator.cc b/cpp/src/gandiva/llvm_generator.cc index d8f857897ff79..c675bf3fc7c7a 100644 --- a/cpp/src/gandiva/llvm_generator.cc +++ b/cpp/src/gandiva/llvm_generator.cc @@ -118,10 +118,10 @@ Status LLVMGenerator::Execute(const arrow::RecordBatch& record_batch, llvm::Value* LLVMGenerator::LoadVectorAtIndex(llvm::Value* arg_addrs, int idx, const std::string& name) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); llvm::Value* offset = - builder.CreateGEP(arg_addrs, types().i32_constant(idx), name + "_mem_addr"); - return builder.CreateLoad(offset, name + "_mem"); + builder->CreateGEP(arg_addrs, types()->i32_constant(idx), name + "_mem_addr"); + return builder->CreateLoad(offset, name + "_mem"); } /// Get reference to validity array at specified index in the args list. @@ -129,7 +129,7 @@ llvm::Value* LLVMGenerator::GetValidityReference(llvm::Value* arg_addrs, int idx FieldPtr field) { const std::string& name = field->name(); llvm::Value* load = LoadVectorAtIndex(arg_addrs, idx, name); - return ir_builder().CreateIntToPtr(load, types().i64_ptr_type(), name + "_varray"); + return ir_builder()->CreateIntToPtr(load, types()->i64_ptr_type(), name + "_varray"); } /// Get reference to data array at specified index in the args list. @@ -137,13 +137,13 @@ llvm::Value* LLVMGenerator::GetDataReference(llvm::Value* arg_addrs, int idx, FieldPtr field) { const std::string& name = field->name(); llvm::Value* load = LoadVectorAtIndex(arg_addrs, idx, name); - llvm::Type* base_type = types().DataVecType(field->type()); + llvm::Type* base_type = types()->DataVecType(field->type()); llvm::Value* ret; if (base_type->isPointerTy()) { - ret = ir_builder().CreateIntToPtr(load, base_type, name + "_darray"); + ret = ir_builder()->CreateIntToPtr(load, base_type, name + "_darray"); } else { - llvm::Type* pointer_type = types().ptr_type(base_type); - ret = ir_builder().CreateIntToPtr(load, pointer_type, name + "_darray"); + llvm::Type* pointer_type = types()->ptr_type(base_type); + ret = ir_builder()->CreateIntToPtr(load, pointer_type, name + "_darray"); } return ret; } @@ -153,14 +153,14 @@ llvm::Value* LLVMGenerator::GetOffsetsReference(llvm::Value* arg_addrs, int idx, FieldPtr field) { const std::string& name = field->name(); llvm::Value* load = LoadVectorAtIndex(arg_addrs, idx, name); - return ir_builder().CreateIntToPtr(load, types().i32_ptr_type(), name + "_oarray"); + return ir_builder()->CreateIntToPtr(load, types()->i32_ptr_type(), name + "_oarray"); } /// Get reference to local bitmap array at specified index in the args list. llvm::Value* LLVMGenerator::GetLocalBitMapReference(llvm::Value* arg_bitmaps, int idx) { llvm::Value* load = LoadVectorAtIndex(arg_bitmaps, idx, ""); - return ir_builder().CreateIntToPtr(load, types().i64_ptr_type(), - std::to_string(idx) + "_lbmap"); + return ir_builder()->CreateIntToPtr(load, types()->i64_ptr_type(), + std::to_string(idx) + "_lbmap"); } /// \brief Generate code for one expression. @@ -215,17 +215,17 @@ llvm::Value* LLVMGenerator::GetLocalBitMapReference(llvm::Value* arg_bitmaps, in Status LLVMGenerator::CodeGenExprValue(DexPtr value_expr, FieldDescriptorPtr output, int suffix_idx, llvm::Function** fn) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); // Create fn prototype : // int expr_1 (long **addrs, long **bitmaps, long *context_ptr, long nrec) std::vector arguments; - arguments.push_back(types().i64_ptr_type()); - arguments.push_back(types().i64_ptr_type()); - arguments.push_back(types().i64_type()); - arguments.push_back(types().i64_type()); + arguments.push_back(types()->i64_ptr_type()); + arguments.push_back(types()->i64_ptr_type()); + arguments.push_back(types()->i64_type()); + arguments.push_back(types()->i64_type()); llvm::FunctionType* prototype = - llvm::FunctionType::get(types().i32_type(), arguments, false /*isVarArg*/); + llvm::FunctionType::get(types()->i32_type(), arguments, false /*isVarArg*/); // Create fn std::string func_name = "expr_" + std::to_string(suffix_idx); @@ -248,20 +248,20 @@ Status LLVMGenerator::CodeGenExprValue(DexPtr value_expr, FieldDescriptorPtr out llvm::Value* arg_nrecords = &*args; arg_nrecords->setName("nrecords"); - llvm::BasicBlock* loop_entry = llvm::BasicBlock::Create(context(), "entry", *fn); - llvm::BasicBlock* loop_body = llvm::BasicBlock::Create(context(), "loop", *fn); - llvm::BasicBlock* loop_exit = llvm::BasicBlock::Create(context(), "exit", *fn); + llvm::BasicBlock* loop_entry = llvm::BasicBlock::Create(*context(), "entry", *fn); + llvm::BasicBlock* loop_body = llvm::BasicBlock::Create(*context(), "loop", *fn); + llvm::BasicBlock* loop_exit = llvm::BasicBlock::Create(*context(), "exit", *fn); // Add reference to output vector (in entry block) - builder.SetInsertPoint(loop_entry); + builder->SetInsertPoint(loop_entry); llvm::Value* output_ref = GetDataReference(arg_addrs, output->data_idx(), output->field()); // Loop body - builder.SetInsertPoint(loop_body); + builder->SetInsertPoint(loop_body); // define loop_var : start with 0, +1 after each iter - llvm::PHINode* loop_var = builder.CreatePHI(types().i64_type(), 2, "loop_var"); + llvm::PHINode* loop_var = builder->CreatePHI(types()->i64_type(), 2, "loop_var"); // The visitor can add code to both the entry/loop blocks. Visitor visitor(this, *fn, loop_entry, arg_addrs, arg_local_bitmaps, arg_context_ptr, @@ -270,35 +270,35 @@ Status LLVMGenerator::CodeGenExprValue(DexPtr value_expr, FieldDescriptorPtr out LValuePtr output_value = visitor.result(); // The "current" block may have changed due to code generation in the visitor. - llvm::BasicBlock* loop_body_tail = builder.GetInsertBlock(); + llvm::BasicBlock* loop_body_tail = builder->GetInsertBlock(); // add jump to "loop block" at the end of the "setup block". - builder.SetInsertPoint(loop_entry); - builder.CreateBr(loop_body); + builder->SetInsertPoint(loop_entry); + builder->CreateBr(loop_body); // save the value in the output vector. - builder.SetInsertPoint(loop_body_tail); + builder->SetInsertPoint(loop_body_tail); if (output->Type()->id() == arrow::Type::BOOL) { SetPackedBitValue(output_ref, loop_var, output_value->data()); } else { - llvm::Value* slot_offset = builder.CreateGEP(output_ref, loop_var); - builder.CreateStore(output_value->data(), slot_offset); + llvm::Value* slot_offset = builder->CreateGEP(output_ref, loop_var); + builder->CreateStore(output_value->data(), slot_offset); } ADD_TRACE("saving result " + output->Name() + " value %T", output_value->data()); // check loop_var - loop_var->addIncoming(types().i64_constant(0), loop_entry); + loop_var->addIncoming(types()->i64_constant(0), loop_entry); llvm::Value* loop_update = - builder.CreateAdd(loop_var, types().i64_constant(1), "loop_var+1"); + builder->CreateAdd(loop_var, types()->i64_constant(1), "loop_var+1"); loop_var->addIncoming(loop_update, loop_body_tail); llvm::Value* loop_var_check = - builder.CreateICmpSLT(loop_update, arg_nrecords, "loop_var < nrec"); - builder.CreateCondBr(loop_var_check, loop_body, loop_exit); + builder->CreateICmpSLT(loop_update, arg_nrecords, "loop_var < nrec"); + builder->CreateCondBr(loop_var_check, loop_body, loop_exit); // Loop exit - builder.SetInsertPoint(loop_exit); - builder.CreateRet(types().i32_constant(0)); + builder->SetInsertPoint(loop_exit); + builder->CreateRet(types()->i32_constant(0)); return Status::OK(); } @@ -307,9 +307,9 @@ llvm::Value* LLVMGenerator::GetPackedBitValue(llvm::Value* bitmap, llvm::Value* position) { ADD_TRACE("fetch bit at position %T", position); - llvm::Value* bitmap8 = ir_builder().CreateBitCast( - bitmap, types().ptr_type(types().i8_type()), "bitMapCast"); - return AddFunctionCall("bitMapGetBit", types().i1_type(), {bitmap8, position}); + llvm::Value* bitmap8 = ir_builder()->CreateBitCast( + bitmap, types()->ptr_type(types()->i8_type()), "bitMapCast"); + return AddFunctionCall("bitMapGetBit", types()->i1_type(), {bitmap8, position}); } /// Set the value of a bit in bitMap. @@ -318,9 +318,9 @@ void LLVMGenerator::SetPackedBitValue(llvm::Value* bitmap, llvm::Value* position ADD_TRACE("set bit at position %T", position); ADD_TRACE(" to value %T ", value); - llvm::Value* bitmap8 = ir_builder().CreateBitCast( - bitmap, types().ptr_type(types().i8_type()), "bitMapCast"); - AddFunctionCall("bitMapSetBit", types().void_type(), {bitmap8, position, value}); + llvm::Value* bitmap8 = ir_builder()->CreateBitCast( + bitmap, types()->ptr_type(types()->i8_type()), "bitMapCast"); + AddFunctionCall("bitMapSetBit", types()->void_type(), {bitmap8, position, value}); } /// Clear the bit in bitMap if value = false. @@ -329,9 +329,9 @@ void LLVMGenerator::ClearPackedBitValueIfFalse(llvm::Value* bitmap, llvm::Value* ADD_TRACE("ClearIfFalse bit at position %T", position); ADD_TRACE(" value %T ", value); - llvm::Value* bitmap8 = ir_builder().CreateBitCast( - bitmap, types().ptr_type(types().i8_type()), "bitMapCast"); - AddFunctionCall("bitMapClearBitIfFalse", types().void_type(), + llvm::Value* bitmap8 = ir_builder()->CreateBitCast( + bitmap, types()->ptr_type(types()->i8_type()), "bitMapCast"); + AddFunctionCall("bitMapClearBitIfFalse", types()->void_type(), {bitmap8, position, value}); } @@ -371,9 +371,9 @@ llvm::Value* LLVMGenerator::AddFunctionCall(const std::string& full_name, llvm::Value* value; if (ret_type->isVoidTy()) { // void functions can't have a name for the call. - value = ir_builder().CreateCall(fn, args); + value = ir_builder()->CreateCall(fn, args); } else { - value = ir_builder().CreateCall(fn, args, full_name); + value = ir_builder()->CreateCall(fn, args, full_name); DCHECK(value->getType() == ret_type); } return value; @@ -400,7 +400,7 @@ LLVMGenerator::Visitor::Visitor(LLVMGenerator* generator, llvm::Function* functi } void LLVMGenerator::Visitor::Visit(const VectorReadFixedLenValueDex& dex) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); llvm::Value* slot_ref = GetBufferReference(dex.DataIdx(), kBufferTypeData, dex.Field()); @@ -408,8 +408,8 @@ void LLVMGenerator::Visitor::Visit(const VectorReadFixedLenValueDex& dex) { if (dex.FieldType()->id() == arrow::Type::BOOL) { slot_value = generator_->GetPackedBitValue(slot_ref, loop_var_); } else { - llvm::Value* slot_offset = builder.CreateGEP(slot_ref, loop_var_); - slot_value = builder.CreateLoad(slot_offset, dex.FieldName()); + llvm::Value* slot_offset = builder->CreateGEP(slot_ref, loop_var_); + slot_value = builder->CreateLoad(slot_offset, dex.FieldName()); } ADD_VISITOR_TRACE("visit fixed-len data vector " + dex.FieldName() + " value %T", @@ -418,7 +418,7 @@ void LLVMGenerator::Visitor::Visit(const VectorReadFixedLenValueDex& dex) { } void LLVMGenerator::Visitor::Visit(const VectorReadVarLenValueDex& dex) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); llvm::Value* slot; // compute len from the offsets array. @@ -426,23 +426,23 @@ void LLVMGenerator::Visitor::Visit(const VectorReadVarLenValueDex& dex) { GetBufferReference(dex.OffsetsIdx(), kBufferTypeOffsets, dex.Field()); // => offset_start = offsets[loop_var] - slot = builder.CreateGEP(offsets_slot_ref, loop_var_); - llvm::Value* offset_start = builder.CreateLoad(slot, "offset_start"); + slot = builder->CreateGEP(offsets_slot_ref, loop_var_); + llvm::Value* offset_start = builder->CreateLoad(slot, "offset_start"); // => offset_end = offsets[loop_var + 1] llvm::Value* loop_var_next = - builder.CreateAdd(loop_var_, generator_->types().i64_constant(1), "loop_var+1"); - slot = builder.CreateGEP(offsets_slot_ref, loop_var_next); - llvm::Value* offset_end = builder.CreateLoad(slot, "offset_end"); + builder->CreateAdd(loop_var_, generator_->types()->i64_constant(1), "loop_var+1"); + slot = builder->CreateGEP(offsets_slot_ref, loop_var_next); + llvm::Value* offset_end = builder->CreateLoad(slot, "offset_end"); // => len_value = offset_end - offset_start llvm::Value* len_value = - builder.CreateSub(offset_end, offset_start, dex.FieldName() + "Len"); + builder->CreateSub(offset_end, offset_start, dex.FieldName() + "Len"); // get the data from the data array, at offset 'offset_start'. llvm::Value* data_slot_ref = GetBufferReference(dex.DataIdx(), kBufferTypeData, dex.Field()); - llvm::Value* data_value = builder.CreateGEP(data_slot_ref, offset_start); + llvm::Value* data_value = builder->CreateGEP(data_slot_ref, offset_start); ADD_VISITOR_TRACE("visit var-len data vector " + dex.FieldName() + " len %T", len_value); result_.reset(new LValue(data_value, len_value)); @@ -468,87 +468,87 @@ void LLVMGenerator::Visitor::Visit(const LocalBitMapValidityDex& dex) { } void LLVMGenerator::Visitor::Visit(const TrueDex& dex) { - result_.reset(new LValue(generator_->types().true_constant())); + result_.reset(new LValue(generator_->types()->true_constant())); } void LLVMGenerator::Visitor::Visit(const FalseDex& dex) { - result_.reset(new LValue(generator_->types().false_constant())); + result_.reset(new LValue(generator_->types()->false_constant())); } void LLVMGenerator::Visitor::Visit(const LiteralDex& dex) { - LLVMTypes& types = generator_->types(); + LLVMTypes* types = generator_->types(); llvm::Value* value = nullptr; llvm::Value* len = nullptr; switch (dex.type()->id()) { case arrow::Type::BOOL: - value = types.i1_constant(boost::get(dex.holder())); + value = types->i1_constant(boost::get(dex.holder())); break; case arrow::Type::UINT8: - value = types.i8_constant(boost::get(dex.holder())); + value = types->i8_constant(boost::get(dex.holder())); break; case arrow::Type::UINT16: - value = types.i16_constant(boost::get(dex.holder())); + value = types->i16_constant(boost::get(dex.holder())); break; case arrow::Type::UINT32: - value = types.i32_constant(boost::get(dex.holder())); + value = types->i32_constant(boost::get(dex.holder())); break; case arrow::Type::UINT64: - value = types.i64_constant(boost::get(dex.holder())); + value = types->i64_constant(boost::get(dex.holder())); break; case arrow::Type::INT8: - value = types.i8_constant(boost::get(dex.holder())); + value = types->i8_constant(boost::get(dex.holder())); break; case arrow::Type::INT16: - value = types.i16_constant(boost::get(dex.holder())); + value = types->i16_constant(boost::get(dex.holder())); break; case arrow::Type::INT32: - value = types.i32_constant(boost::get(dex.holder())); + value = types->i32_constant(boost::get(dex.holder())); break; case arrow::Type::INT64: - value = types.i64_constant(boost::get(dex.holder())); + value = types->i64_constant(boost::get(dex.holder())); break; case arrow::Type::FLOAT: - value = types.float_constant(boost::get(dex.holder())); + value = types->float_constant(boost::get(dex.holder())); break; case arrow::Type::DOUBLE: - value = types.double_constant(boost::get(dex.holder())); + value = types->double_constant(boost::get(dex.holder())); break; case arrow::Type::STRING: case arrow::Type::BINARY: { const std::string& str = boost::get(dex.holder()); - llvm::Constant* str_int_cast = types.i64_constant((int64_t)str.c_str()); - value = llvm::ConstantExpr::getIntToPtr(str_int_cast, types.i8_ptr_type()); - len = types.i32_constant(static_cast(str.length())); + llvm::Constant* str_int_cast = types->i64_constant((int64_t)str.c_str()); + value = llvm::ConstantExpr::getIntToPtr(str_int_cast, types->i8_ptr_type()); + len = types->i32_constant(static_cast(str.length())); break; } case arrow::Type::DATE64: - value = types.i64_constant(boost::get(dex.holder())); + value = types->i64_constant(boost::get(dex.holder())); break; case arrow::Type::TIME32: - value = types.i32_constant(boost::get(dex.holder())); + value = types->i32_constant(boost::get(dex.holder())); break; case arrow::Type::TIME64: - value = types.i64_constant(boost::get(dex.holder())); + value = types->i64_constant(boost::get(dex.holder())); break; case arrow::Type::TIMESTAMP: - value = types.i64_constant(boost::get(dex.holder())); + value = types->i64_constant(boost::get(dex.holder())); break; default: @@ -561,7 +561,7 @@ void LLVMGenerator::Visitor::Visit(const LiteralDex& dex) { void LLVMGenerator::Visitor::Visit(const NonNullableFuncDex& dex) { ADD_VISITOR_TRACE("visit NonNullableFunc base function " + dex.func_descriptor()->name()); - LLVMTypes& types = generator_->types(); + LLVMTypes* types = generator_->types(); const NativeFunction* native_function = dex.native_function(); @@ -569,7 +569,7 @@ void LLVMGenerator::Visitor::Visit(const NonNullableFuncDex& dex) { auto params = BuildParams(dex.function_holder().get(), dex.args(), false, native_function->needs_context()); - llvm::Type* ret_type = types.IRType(native_function->signature().ret_type()->id()); + llvm::Type* ret_type = types->IRType(native_function->signature().ret_type()->id()); llvm::Value* value = generator_->AddFunctionCall(native_function->pc_name(), ret_type, params); @@ -578,7 +578,7 @@ void LLVMGenerator::Visitor::Visit(const NonNullableFuncDex& dex) { void LLVMGenerator::Visitor::Visit(const NullableNeverFuncDex& dex) { ADD_VISITOR_TRACE("visit NullableNever base function " + dex.func_descriptor()->name()); - LLVMTypes& types = generator_->types(); + LLVMTypes* types = generator_->types(); const NativeFunction* native_function = dex.native_function(); @@ -586,7 +586,7 @@ void LLVMGenerator::Visitor::Visit(const NullableNeverFuncDex& dex) { auto params = BuildParams(dex.function_holder().get(), dex.args(), true, native_function->needs_context()); - llvm::Type* ret_type = types.IRType(native_function->signature().ret_type()->id()); + llvm::Type* ret_type = types->IRType(native_function->signature().ret_type()->id()); llvm::Value* value = generator_->AddFunctionCall(native_function->pc_name(), ret_type, params); result_.reset(new LValue(value)); @@ -595,8 +595,8 @@ void LLVMGenerator::Visitor::Visit(const NullableNeverFuncDex& dex) { void LLVMGenerator::Visitor::Visit(const NullableInternalFuncDex& dex) { ADD_VISITOR_TRACE("visit NullableInternal base function " + dex.func_descriptor()->name()); - llvm::IRBuilder<>& builder = ir_builder(); - LLVMTypes& types = generator_->types(); + llvm::IRBuilder<>* builder = ir_builder(); + LLVMTypes* types = generator_->types(); const NativeFunction* native_function = dex.native_function(); @@ -606,16 +606,16 @@ void LLVMGenerator::Visitor::Visit(const NullableInternalFuncDex& dex) { // add an extra arg for validity (alloced on stack). llvm::AllocaInst* result_valid_ptr = - new llvm::AllocaInst(types.i8_type(), 0, "result_valid", entry_block_); + new llvm::AllocaInst(types->i8_type(), 0, "result_valid", entry_block_); params.push_back(result_valid_ptr); - llvm::Type* ret_type = types.IRType(native_function->signature().ret_type()->id()); + llvm::Type* ret_type = types->IRType(native_function->signature().ret_type()->id()); llvm::Value* value = generator_->AddFunctionCall(native_function->pc_name(), ret_type, params); // load the result validity and truncate to i1. - llvm::Value* result_valid_i8 = builder.CreateLoad(result_valid_ptr); - llvm::Value* result_valid = builder.CreateTrunc(result_valid_i8, types.i1_type()); + llvm::Value* result_valid_i8 = builder->CreateLoad(result_valid_ptr); + llvm::Value* result_valid = builder->CreateTrunc(result_valid_i8, types->i1_type()); // set validity bit in the local bitmap. ClearLocalBitMapIfNotValid(dex.local_bitmap_idx(), result_valid); @@ -625,38 +625,38 @@ void LLVMGenerator::Visitor::Visit(const NullableInternalFuncDex& dex) { void LLVMGenerator::Visitor::Visit(const IfDex& dex) { ADD_VISITOR_TRACE("visit IfExpression"); - llvm::IRBuilder<>& builder = ir_builder(); - LLVMTypes& types = generator_->types(); + llvm::IRBuilder<>* builder = ir_builder(); + LLVMTypes* types = generator_->types(); // Evaluate condition. LValuePtr if_condition = BuildValueAndValidity(dex.condition_vv()); // Check if the result is valid, and there is match. llvm::Value* validAndMatched = - builder.CreateAnd(if_condition->data(), if_condition->validity(), "validAndMatch"); + builder->CreateAnd(if_condition->data(), if_condition->validity(), "validAndMatch"); // Create blocks for the then, else and merge cases. - llvm::LLVMContext& context = generator_->context(); - llvm::BasicBlock* then_bb = llvm::BasicBlock::Create(context, "then", function_); - llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(context, "else", function_); - llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(context, "merge", function_); + llvm::LLVMContext* context = generator_->context(); + llvm::BasicBlock* then_bb = llvm::BasicBlock::Create(*context, "then", function_); + llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(*context, "else", function_); + llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(*context, "merge", function_); - builder.CreateCondBr(validAndMatched, then_bb, else_bb); + builder->CreateCondBr(validAndMatched, then_bb, else_bb); // Emit the then block. - builder.SetInsertPoint(then_bb); + builder->SetInsertPoint(then_bb); ADD_VISITOR_TRACE("branch to then block"); LValuePtr then_lvalue = BuildValueAndValidity(dex.then_vv()); ClearLocalBitMapIfNotValid(dex.local_bitmap_idx(), then_lvalue->validity()); ADD_VISITOR_TRACE("IfExpression result validity %T in matching then", then_lvalue->validity()); - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); // refresh then_bb for phi (could have changed due to code generation of then_vv). - then_bb = builder.GetInsertBlock(); + then_bb = builder->GetInsertBlock(); // Emit the else block. - builder.SetInsertPoint(else_bb); + builder->SetInsertPoint(else_bb); LValuePtr else_lvalue; if (dex.is_terminal_else()) { ADD_VISITOR_TRACE("branch to terminal else block"); @@ -674,21 +674,21 @@ void LLVMGenerator::Visitor::Visit(const IfDex& dex) { value_expr->Accept(*this); else_lvalue = result(); } - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); // refresh else_bb for phi (could have changed due to code generation of else_vv). - else_bb = builder.GetInsertBlock(); + else_bb = builder->GetInsertBlock(); // Emit the merge block. - builder.SetInsertPoint(merge_bb); - llvm::Type* result_llvm_type = types.DataVecType(dex.result_type()); - llvm::PHINode* result_value = builder.CreatePHI(result_llvm_type, 2, "res_value"); + builder->SetInsertPoint(merge_bb); + llvm::Type* result_llvm_type = types->DataVecType(dex.result_type()); + llvm::PHINode* result_value = builder->CreatePHI(result_llvm_type, 2, "res_value"); result_value->addIncoming(then_lvalue->data(), then_bb); result_value->addIncoming(else_lvalue->data(), else_bb); llvm::PHINode* result_length = nullptr; if (then_lvalue->length() != nullptr) { - result_length = builder.CreatePHI(types.i32_type(), 2, "res_length"); + result_length = builder->CreatePHI(types->i32_type(), 2, "res_length"); result_length->addIncoming(then_lvalue->length(), then_bb); result_length->addIncoming(else_lvalue->length(), else_bb); @@ -709,18 +709,18 @@ void LLVMGenerator::Visitor::Visit(const IfDex& dex) { void LLVMGenerator::Visitor::Visit(const BooleanAndDex& dex) { ADD_VISITOR_TRACE("visit BooleanAndExpression"); - llvm::IRBuilder<>& builder = ir_builder(); - LLVMTypes& types = generator_->types(); - llvm::LLVMContext& context = generator_->context(); + llvm::IRBuilder<>* builder = ir_builder(); + LLVMTypes* types = generator_->types(); + llvm::LLVMContext* context = generator_->context(); // Create blocks for short-circuit. llvm::BasicBlock* short_circuit_bb = - llvm::BasicBlock::Create(context, "short_circuit", function_); + llvm::BasicBlock::Create(*context, "short_circuit", function_); llvm::BasicBlock* non_short_circuit_bb = - llvm::BasicBlock::Create(context, "non_short_circuit", function_); - llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(context, "merge", function_); + llvm::BasicBlock::Create(*context, "non_short_circuit", function_); + llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(*context, "merge", function_); - llvm::Value* all_exprs_valid = types.true_constant(); + llvm::Value* all_exprs_valid = types->true_constant(); for (auto& pair : dex.args()) { LValuePtr current = BuildValueAndValidity(*pair); @@ -728,41 +728,41 @@ void LLVMGenerator::Visitor::Visit(const BooleanAndDex& dex) { ADD_VISITOR_TRACE("BooleanAndExpression arg valdity %T", current->validity()); // short-circuit if valid and false - llvm::Value* is_false = builder.CreateNot(current->data()); + llvm::Value* is_false = builder->CreateNot(current->data()); llvm::Value* valid_and_false = - builder.CreateAnd(is_false, current->validity(), "valid_and_false"); + builder->CreateAnd(is_false, current->validity(), "valid_and_false"); - llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(context, "else", function_); - builder.CreateCondBr(valid_and_false, short_circuit_bb, else_bb); + llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(*context, "else", function_); + builder->CreateCondBr(valid_and_false, short_circuit_bb, else_bb); // Emit the else block. - builder.SetInsertPoint(else_bb); + builder->SetInsertPoint(else_bb); // remember if any nulls were encountered. all_exprs_valid = - builder.CreateAnd(all_exprs_valid, current->validity(), "validityBitAnd"); + builder->CreateAnd(all_exprs_valid, current->validity(), "validityBitAnd"); // continue to evaluate the next pair in list. } - builder.CreateBr(non_short_circuit_bb); + builder->CreateBr(non_short_circuit_bb); // Short-circuit case (atleast one of the expressions is valid and false). // No need to set validity bit (valid by default). - builder.SetInsertPoint(short_circuit_bb); + builder->SetInsertPoint(short_circuit_bb); ADD_VISITOR_TRACE("BooleanAndExpression result value false"); ADD_VISITOR_TRACE("BooleanAndExpression result valdity true"); - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); // non short-circuit case (All expressions are either true or null). // result valid if all of the exprs are non-null. - builder.SetInsertPoint(non_short_circuit_bb); + builder->SetInsertPoint(non_short_circuit_bb); ClearLocalBitMapIfNotValid(dex.local_bitmap_idx(), all_exprs_valid); ADD_VISITOR_TRACE("BooleanAndExpression result value true"); ADD_VISITOR_TRACE("BooleanAndExpression result valdity %T", all_exprs_valid); - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); - builder.SetInsertPoint(merge_bb); - llvm::PHINode* result_value = builder.CreatePHI(types.i1_type(), 2, "res_value"); - result_value->addIncoming(types.false_constant(), short_circuit_bb); - result_value->addIncoming(types.true_constant(), non_short_circuit_bb); + builder->SetInsertPoint(merge_bb); + llvm::PHINode* result_value = builder->CreatePHI(types->i1_type(), 2, "res_value"); + result_value->addIncoming(types->false_constant(), short_circuit_bb); + result_value->addIncoming(types->true_constant(), non_short_circuit_bb); result_.reset(new LValue(result_value)); } @@ -776,18 +776,18 @@ void LLVMGenerator::Visitor::Visit(const BooleanAndDex& dex) { void LLVMGenerator::Visitor::Visit(const BooleanOrDex& dex) { ADD_VISITOR_TRACE("visit BooleanOrExpression"); - llvm::IRBuilder<>& builder = ir_builder(); - LLVMTypes& types = generator_->types(); - llvm::LLVMContext& context = generator_->context(); + llvm::IRBuilder<>* builder = ir_builder(); + LLVMTypes* types = generator_->types(); + llvm::LLVMContext* context = generator_->context(); // Create blocks for short-circuit. llvm::BasicBlock* short_circuit_bb = - llvm::BasicBlock::Create(context, "short_circuit", function_); + llvm::BasicBlock::Create(*context, "short_circuit", function_); llvm::BasicBlock* non_short_circuit_bb = - llvm::BasicBlock::Create(context, "non_short_circuit", function_); - llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(context, "merge", function_); + llvm::BasicBlock::Create(*context, "non_short_circuit", function_); + llvm::BasicBlock* merge_bb = llvm::BasicBlock::Create(*context, "merge", function_); - llvm::Value* all_exprs_valid = types.true_constant(); + llvm::Value* all_exprs_valid = types->true_constant(); for (auto& pair : dex.args()) { LValuePtr current = BuildValueAndValidity(*pair); @@ -796,39 +796,39 @@ void LLVMGenerator::Visitor::Visit(const BooleanOrDex& dex) { // short-circuit if valid and true. llvm::Value* valid_and_true = - builder.CreateAnd(current->data(), current->validity(), "valid_and_true"); + builder->CreateAnd(current->data(), current->validity(), "valid_and_true"); - llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(context, "else", function_); - builder.CreateCondBr(valid_and_true, short_circuit_bb, else_bb); + llvm::BasicBlock* else_bb = llvm::BasicBlock::Create(*context, "else", function_); + builder->CreateCondBr(valid_and_true, short_circuit_bb, else_bb); // Emit the else block. - builder.SetInsertPoint(else_bb); + builder->SetInsertPoint(else_bb); // remember if any nulls were encountered. all_exprs_valid = - builder.CreateAnd(all_exprs_valid, current->validity(), "validityBitAnd"); + builder->CreateAnd(all_exprs_valid, current->validity(), "validityBitAnd"); // continue to evaluate the next pair in list. } - builder.CreateBr(non_short_circuit_bb); + builder->CreateBr(non_short_circuit_bb); // Short-circuit case (atleast one of the expressions is valid and true). // No need to set validity bit (valid by default). - builder.SetInsertPoint(short_circuit_bb); + builder->SetInsertPoint(short_circuit_bb); ADD_VISITOR_TRACE("BooleanOrExpression result value true"); ADD_VISITOR_TRACE("BooleanOrExpression result valdity true"); - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); // non short-circuit case (All expressions are either false or null). // result valid if all of the exprs are non-null. - builder.SetInsertPoint(non_short_circuit_bb); + builder->SetInsertPoint(non_short_circuit_bb); ClearLocalBitMapIfNotValid(dex.local_bitmap_idx(), all_exprs_valid); ADD_VISITOR_TRACE("BooleanOrExpression result value false"); ADD_VISITOR_TRACE("BooleanOrExpression result valdity %T", all_exprs_valid); - builder.CreateBr(merge_bb); + builder->CreateBr(merge_bb); - builder.SetInsertPoint(merge_bb); - llvm::PHINode* result_value = builder.CreatePHI(types.i1_type(), 2, "res_value"); - result_value->addIncoming(types.true_constant(), short_circuit_bb); - result_value->addIncoming(types.false_constant(), non_short_circuit_bb); + builder->SetInsertPoint(merge_bb); + llvm::PHINode* result_value = builder->CreatePHI(types->i1_type(), 2, "res_value"); + result_value->addIncoming(types->true_constant(), short_circuit_bb); + result_value->addIncoming(types->false_constant(), non_short_circuit_bb); result_.reset(new LValue(result_value)); } @@ -848,12 +848,12 @@ LValuePtr LLVMGenerator::Visitor::BuildValueAndValidity(const ValueValidityPair& std::vector LLVMGenerator::Visitor::BuildParams( FunctionHolder* holder, const ValueValidityPairVector& args, bool with_validity, bool with_context) { - LLVMTypes& types = generator_->types(); + LLVMTypes* types = generator_->types(); std::vector params; // if the function has holder, add the holder pointer first. if (holder != nullptr) { - auto ptr = types.i64_constant((int64_t)holder); + auto ptr = types->i64_constant((int64_t)holder); params.push_back(ptr); } @@ -887,13 +887,13 @@ std::vector LLVMGenerator::Visitor::BuildParams( // Bitwise-AND of a vector of bits to get the combined validity. llvm::Value* LLVMGenerator::Visitor::BuildCombinedValidity(const DexVector& validities) { - llvm::IRBuilder<>& builder = ir_builder(); - LLVMTypes& types = generator_->types(); + llvm::IRBuilder<>* builder = ir_builder(); + LLVMTypes* types = generator_->types(); - llvm::Value* isValid = types.true_constant(); + llvm::Value* isValid = types->true_constant(); for (auto& dex : validities) { dex->Accept(*this); - isValid = builder.CreateAnd(isValid, result()->data(), "validityBitAnd"); + isValid = builder->CreateAnd(isValid, result()->data(), "validityBitAnd"); } ADD_VISITOR_TRACE("combined validity is %T", isValid); return isValid; @@ -901,11 +901,11 @@ llvm::Value* LLVMGenerator::Visitor::BuildCombinedValidity(const DexVector& vali llvm::Value* LLVMGenerator::Visitor::GetBufferReference(int idx, BufferType buffer_type, FieldPtr field) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); // Switch to the entry block to create a reference. - llvm::BasicBlock* saved_block = builder.GetInsertBlock(); - builder.SetInsertPoint(entry_block_); + llvm::BasicBlock* saved_block = builder->GetInsertBlock(); + builder->SetInsertPoint(entry_block_); llvm::Value* slot_ref = nullptr; switch (buffer_type) { @@ -923,21 +923,21 @@ llvm::Value* LLVMGenerator::Visitor::GetBufferReference(int idx, BufferType buff } // Revert to the saved block. - builder.SetInsertPoint(saved_block); + builder->SetInsertPoint(saved_block); return slot_ref; } llvm::Value* LLVMGenerator::Visitor::GetLocalBitMapReference(int idx) { - llvm::IRBuilder<>& builder = ir_builder(); + llvm::IRBuilder<>* builder = ir_builder(); // Switch to the entry block to create a reference. - llvm::BasicBlock* saved_block = builder.GetInsertBlock(); - builder.SetInsertPoint(entry_block_); + llvm::BasicBlock* saved_block = builder->GetInsertBlock(); + builder->SetInsertPoint(entry_block_); llvm::Value* slot_ref = generator_->GetLocalBitMapReference(arg_local_bitmaps_, idx); // Revert to the saved block. - builder.SetInsertPoint(saved_block); + builder->SetInsertPoint(saved_block); return slot_ref; } @@ -1003,16 +1003,16 @@ void LLVMGenerator::AddTrace(const std::string& msg, llvm::Value* value) { // cast this to an llvm pointer. const char* str = trace_strings_.back().c_str(); - llvm::Constant* str_int_cast = types().i64_constant((int64_t)str); + llvm::Constant* str_int_cast = types()->i64_constant((int64_t)str); llvm::Constant* str_ptr_cast = - llvm::ConstantExpr::getIntToPtr(str_int_cast, types().i8_ptr_type()); + llvm::ConstantExpr::getIntToPtr(str_int_cast, types()->i8_ptr_type()); std::vector args; args.push_back(str_ptr_cast); if (value != nullptr) { args.push_back(value); } - AddFunctionCall(print_fn_name, types().i32_type(), args); + AddFunctionCall(print_fn_name, types()->i32_type(), args); } } // namespace gandiva diff --git a/cpp/src/gandiva/llvm_generator.h b/cpp/src/gandiva/llvm_generator.h index 66c7115eef9a3..d8e8df88481f3 100644 --- a/cpp/src/gandiva/llvm_generator.h +++ b/cpp/src/gandiva/llvm_generator.h @@ -58,7 +58,7 @@ class LLVMGenerator { Status Execute(const arrow::RecordBatch& record_batch, const ArrayDataVector& output_vector); - LLVMTypes& types() { return engine_->types(); } + LLVMTypes* types() { return engine_->types(); } llvm::Module* module() { return engine_->module(); } private: @@ -68,8 +68,8 @@ class LLVMGenerator { FRIEND_TEST(TestLLVMGenerator, TestAdd); FRIEND_TEST(TestLLVMGenerator, TestNullInternal); - llvm::LLVMContext& context() { return *(engine_->context()); } - llvm::IRBuilder<>& ir_builder() { return engine_->ir_builder(); } + llvm::LLVMContext* context() { return engine_->context(); } + llvm::IRBuilder<>* ir_builder() { return engine_->ir_builder(); } /// Visitor to generate the code for a decomposed expression. class Visitor : public DexVisitor { @@ -98,7 +98,7 @@ class LLVMGenerator { private: enum BufferType { kBufferTypeValidity = 0, kBufferTypeData, kBufferTypeOffsets }; - llvm::IRBuilder<>& ir_builder() { return generator_->ir_builder(); } + llvm::IRBuilder<>* ir_builder() { return generator_->ir_builder(); } llvm::Module* module() { return generator_->module(); } // Generate the code to build the combined validity (bitwise and) from the diff --git a/cpp/src/gandiva/precompiled/extended_math_ops.cc b/cpp/src/gandiva/precompiled/extended_math_ops.cc index 1021a294e5d50..cee369ed189e2 100644 --- a/cpp/src/gandiva/precompiled/extended_math_ops.cc +++ b/cpp/src/gandiva/precompiled/extended_math_ops.cc @@ -33,38 +33,30 @@ extern "C" { INNER(float64, OUT_TYPE) // Cubic root -#define CBRT(IN_TYPE, OUT_TYPE) \ - FORCE_INLINE \ - OUT_TYPE cbrt_##IN_TYPE(IN_TYPE in) { \ - return static_cast((cbrt(static_cast(in)))); \ - } +#define CBRT(IN_TYPE, OUT_TYPE) \ + FORCE_INLINE \ + OUT_TYPE cbrt_##IN_TYPE(IN_TYPE in) { return static_cast(cbrtl(in)); } ENUMERIC_TYPES_UNARY(CBRT, float64) // Exponent -#define EXP(IN_TYPE, OUT_TYPE) \ - FORCE_INLINE \ - OUT_TYPE exp_##IN_TYPE(IN_TYPE in) { \ - return static_cast(exp(static_cast(in))); \ - } +#define EXP(IN_TYPE, OUT_TYPE) \ + FORCE_INLINE \ + OUT_TYPE exp_##IN_TYPE(IN_TYPE in) { return static_cast(expl(in)); } ENUMERIC_TYPES_UNARY(EXP, float64) // log -#define LOG(IN_TYPE, OUT_TYPE) \ - FORCE_INLINE \ - OUT_TYPE log_##IN_TYPE(IN_TYPE in) { \ - return static_cast(log(static_cast(in))); \ - } +#define LOG(IN_TYPE, OUT_TYPE) \ + FORCE_INLINE \ + OUT_TYPE log_##IN_TYPE(IN_TYPE in) { return static_cast(logl(in)); } ENUMERIC_TYPES_UNARY(LOG, float64) // log base 10 -#define LOG10(IN_TYPE, OUT_TYPE) \ - FORCE_INLINE \ - OUT_TYPE log10_##IN_TYPE(IN_TYPE in) { \ - return static_cast(log10(static_cast(in))); \ - } +#define LOG10(IN_TYPE, OUT_TYPE) \ + FORCE_INLINE \ + OUT_TYPE log10_##IN_TYPE(IN_TYPE in) { return static_cast(log10l(in)); } ENUMERIC_TYPES_UNARY(LOG10, float64) @@ -79,23 +71,22 @@ void set_error_for_logbase(int64_t execution_context, double base) { } // log with base -#define LOG_WITH_BASE(IN_TYPE1, IN_TYPE2, OUT_TYPE) \ - FORCE_INLINE \ - OUT_TYPE log_##IN_TYPE1##_##IN_TYPE2(IN_TYPE1 base, boolean is_base_valid, \ - IN_TYPE2 value, boolean is_value_valid, \ - int64 context, boolean* out_valid) { \ - *out_valid = false; \ - if (!is_base_valid || !is_value_valid) { \ - return 0; \ - } \ - OUT_TYPE log_of_base = static_cast(log(static_cast(base))); \ - if (log_of_base == 0) { \ - set_error_for_logbase(context, static_cast(base)); \ - return 0; \ - } \ - *out_valid = true; \ - return static_cast(log(static_cast(value)) / \ - log(static_cast(base))); \ +#define LOG_WITH_BASE(IN_TYPE1, IN_TYPE2, OUT_TYPE) \ + FORCE_INLINE \ + OUT_TYPE log_##IN_TYPE1##_##IN_TYPE2(IN_TYPE1 base, boolean is_base_valid, \ + IN_TYPE2 value, boolean is_value_valid, \ + int64 context, boolean* out_valid) { \ + *out_valid = false; \ + if (!is_base_valid || !is_value_valid) { \ + return 0; \ + } \ + OUT_TYPE log_of_base = static_cast(logl(base)); \ + if (log_of_base == 0) { \ + set_error_for_logbase(context, static_cast(base)); \ + return 0; \ + } \ + *out_valid = true; \ + return static_cast(logl(value) / logl(base)); \ } LOG_WITH_BASE(int32, int32, float64) @@ -109,8 +100,7 @@ LOG_WITH_BASE(float64, float64, float64) #define POWER(IN_TYPE1, IN_TYPE2, OUT_TYPE) \ FORCE_INLINE \ OUT_TYPE power_##IN_TYPE1##_##IN_TYPE2(IN_TYPE1 in1, IN_TYPE2 in2) { \ - return static_cast( \ - pow(static_cast(in1), static_cast(in2))); \ + return static_cast(powl(in1, in2)); \ } POWER(float64, float64, float64) diff --git a/cpp/src/gandiva/tests/projector_test.cc b/cpp/src/gandiva/tests/projector_test.cc index 988841765255b..e97c3a461eb4a 100644 --- a/cpp/src/gandiva/tests/projector_test.cc +++ b/cpp/src/gandiva/tests/projector_test.cc @@ -366,12 +366,12 @@ TEST_F(TestProjector, TestExtendedMath) { std::vector logb_vals; std::vector power_vals; for (int i = 0; i < num_records; i++) { - cbrt_vals.push_back(cbrt(input0[i])); - exp_vals.push_back(exp(input0[i])); - log_vals.push_back(log(input0[i])); - log10_vals.push_back(log10(input0[i])); - logb_vals.push_back(log(input1[i]) / log(input0[i])); - power_vals.push_back(pow(input0[i], input1[i])); + cbrt_vals.push_back(static_cast(cbrtl(input0[i]))); + exp_vals.push_back(static_cast(expl(input0[i]))); + log_vals.push_back(static_cast(logl(input0[i]))); + log10_vals.push_back(static_cast(log10l(input0[i]))); + logb_vals.push_back(static_cast(logl(input1[i]) / logl(input0[i]))); + power_vals.push_back(static_cast(powl(input0[i], input1[i]))); } auto expected_cbrt = MakeArrowArray(cbrt_vals, validity); auto expected_exp = MakeArrowArray(exp_vals, validity); diff --git a/java/pom.xml b/java/pom.xml index d8e1944bb2255..f6847ae7ac5e1 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -368,7 +368,7 @@ maven-surefire-plugin - 2.19 + 2.20 true true