From 5abb19a69e4b877ba9ae96c62d7d052bf6cd4782 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 18 Aug 2017 16:50:57 -0700 Subject: [PATCH] add some optimizations --- src/llvm_wrapper/CMakeLists.txt | 4 +-- src/llvm_wrapper/llvm_wrapper.h | 32 ++++++++++++++++++++++ src/pipeline/pipeline.cpp | 42 +++++++++++++++++++++++++++++ src/spirv_to_llvm/spirv_to_llvm.cpp | 26 ++++++++++++++---- 4 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/llvm_wrapper/CMakeLists.txt b/src/llvm_wrapper/CMakeLists.txt index 2032751..d4c5408 100644 --- a/src/llvm_wrapper/CMakeLists.txt +++ b/src/llvm_wrapper/CMakeLists.txt @@ -23,8 +23,8 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) set(sources llvm_wrapper.cpp orc_compile_stack.cpp) add_library(vulkan_cpu_llvm_wrapper STATIC ${sources}) -if(0) -llvm_map_components_to_libnames(llvm_libraries core native analysis orcjit mcjit nativecodegen) +if(1) +llvm_map_components_to_libnames(llvm_libraries core native analysis orcjit mcjit nativecodegen ipo scalaropts vectorize) else() set(llvm_libraries LLVM) endif() diff --git a/src/llvm_wrapper/llvm_wrapper.h b/src/llvm_wrapper/llvm_wrapper.h index e3555f8..62a5e04 100644 --- a/src/llvm_wrapper/llvm_wrapper.h +++ b/src/llvm_wrapper/llvm_wrapper.h @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -365,6 +368,14 @@ struct Builder : public Wrapper<::LLVMBuilderRef, Builder_deleter> ::LLVMValueRef rhs, const char *result_name) { + if(::LLVMGetValueKind(rhs) == ::LLVMConstantIntValueKind) + { + unsigned long long value = ::LLVMConstIntGetZExtValue(rhs); + if(value == 0) + return ::LLVMGetUndef(::LLVMTypeOf(rhs)); + if((value & (value - 1)) == 0) + return ::LLVMBuildAnd(builder, lhs, ::LLVMConstInt(::LLVMTypeOf(rhs), value - 1, false), result_name); + } auto srem_result = ::LLVMBuildSRem(builder, lhs, rhs, ""); auto zero_constant = ::LLVMConstInt(::LLVMTypeOf(lhs), 0, false); auto different_signs = ::LLVMBuildICmp( @@ -385,6 +396,27 @@ struct Builder : public Wrapper<::LLVMBuilderRef, Builder_deleter> } }; +struct Pass_manager_deleter +{ + void operator()(::LLVMPassManagerRef v) const noexcept + { + ::LLVMDisposePassManager(v); + } +}; + +struct Pass_manager : public Wrapper<::LLVMPassManagerRef, Pass_manager_deleter> +{ + using Wrapper::Wrapper; + static Pass_manager create_module_pass_manager() + { + return Pass_manager(::LLVMCreatePassManager()); + } + static Pass_manager create_function_pass_manager(::LLVMModuleRef module) + { + return Pass_manager(::LLVMCreateFunctionPassManagerForModule(module)); + } +}; + inline ::LLVMTypeRef get_scalar_or_vector_element_type(::LLVMTypeRef type) { if(::LLVMGetTypeKind(type) == ::LLVMTypeKind::LLVMVectorTypeKind) diff --git a/src/pipeline/pipeline.cpp b/src/pipeline/pipeline.cpp index 70cae74..3882788 100644 --- a/src/pipeline/pipeline.cpp +++ b/src/pipeline/pipeline.cpp @@ -91,6 +91,48 @@ llvm_wrapper::Module Pipeline::optimize_module(llvm_wrapper::Module module, case ::LLVMCodeGenLevelAggressive: { #warning finish implementing module optimizations + { + auto manager = llvm_wrapper::Pass_manager::create_function_pass_manager(module.get()); + ::LLVMAddPromoteMemoryToRegisterPass(manager.get()); + ::LLVMAddScalarReplAggregatesPass(manager.get()); + ::LLVMAddScalarizerPass(manager.get()); + ::LLVMAddEarlyCSEMemSSAPass(manager.get()); + ::LLVMAddSCCPPass(manager.get()); + ::LLVMAddAggressiveDCEPass(manager.get()); + ::LLVMAddLICMPass(manager.get()); + ::LLVMAddCFGSimplificationPass(manager.get()); + ::LLVMAddReassociatePass(manager.get()); + ::LLVMAddInstructionCombiningPass(manager.get()); + ::LLVMAddNewGVNPass(manager.get()); + ::LLVMAddCorrelatedValuePropagationPass(manager.get()); + ::LLVMInitializeFunctionPassManager(manager.get()); + for(auto fn = ::LLVMGetFirstFunction(module.get()); fn; fn = ::LLVMGetNextFunction(fn)) + ::LLVMRunFunctionPassManager(manager.get(), fn); + ::LLVMFinalizeFunctionPassManager(manager.get()); + } + { + auto manager = llvm_wrapper::Pass_manager::create_module_pass_manager(); + ::LLVMAddIPSCCPPass(manager.get()); + ::LLVMAddFunctionInliningPass(manager.get()); + ::LLVMAddDeadArgEliminationPass(manager.get()); + ::LLVMAddGlobalDCEPass(manager.get()); + ::LLVMRunPassManager(manager.get(), module.get()); + } + { + auto manager = llvm_wrapper::Pass_manager::create_function_pass_manager(module.get()); + ::LLVMAddCFGSimplificationPass(manager.get()); + ::LLVMAddPromoteMemoryToRegisterPass(manager.get()); + ::LLVMAddScalarReplAggregatesPass(manager.get()); + ::LLVMAddReassociatePass(manager.get()); + ::LLVMAddInstructionCombiningPass(manager.get()); + ::LLVMAddLoopUnrollPass(manager.get()); + ::LLVMAddSLPVectorizePass(manager.get()); + ::LLVMAddAggressiveDCEPass(manager.get()); + ::LLVMInitializeFunctionPassManager(manager.get()); + for(auto fn = ::LLVMGetFirstFunction(module.get()); fn; fn = ::LLVMGetNextFunction(fn)) + ::LLVMRunFunctionPassManager(manager.get(), fn); + ::LLVMFinalizeFunctionPassManager(manager.get()); + } std::cerr << "optimized module:" << std::endl; ::LLVMDumpModule(module.get()); break; diff --git a/src/spirv_to_llvm/spirv_to_llvm.cpp b/src/spirv_to_llvm/spirv_to_llvm.cpp index 9e7eadc..7c6fc64 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.cpp +++ b/src/spirv_to_llvm/spirv_to_llvm.cpp @@ -5255,11 +5255,27 @@ void Spirv_to_llvm::handle_instruction_op_u_mod(Op_u_mod instruction, void Spirv_to_llvm::handle_instruction_op_s_rem(Op_s_rem instruction, std::size_t instruction_start_index) { -#warning finish - throw Parser_error(instruction_start_index, - instruction_start_index, - "instruction not implemented: " - + std::string(get_enumerant_name(instruction.get_operation()))); + switch(stage) + { + case Stage::calculate_types: + break; + case Stage::generate_code: + { + auto &state = get_id_state(instruction.result); + if(!state.decorations.empty()) + throw Parser_error(instruction_start_index, + instruction_start_index, + "decorations on instruction not implemented: " + + std::string(get_enumerant_name(instruction.get_operation()))); + auto result_type = get_type(instruction.result_type, instruction_start_index); + state.value = Value(::LLVMBuildSRem(builder.get(), + get_id_state(instruction.operand_1).value.value().value, + get_id_state(instruction.operand_2).value.value().value, + get_name(instruction.result).c_str()), + result_type); + break; + } + } } void Spirv_to_llvm::handle_instruction_op_s_mod(Op_s_mod instruction, -- 2.30.2