add some optimizations
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 18 Aug 2017 23:50:57 +0000 (16:50 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 18 Aug 2017 23:50:57 +0000 (16:50 -0700)
src/llvm_wrapper/CMakeLists.txt
src/llvm_wrapper/llvm_wrapper.h
src/pipeline/pipeline.cpp
src/spirv_to_llvm/spirv_to_llvm.cpp

index 203275105672d38c26d0478842d04724645f9e1f..d4c54089a6fa6229d14ffcff54f4c37c83b4416e 100644 (file)
@@ -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()
index e3555f8fb2ef603e93f6a05dd4a55f9aa903fef4..62a5e040c84cd12c9c927db9d14b27377f48cab8 100644 (file)
@@ -28,6 +28,9 @@
 #include <llvm-c/TargetMachine.h>
 #include <llvm-c/OrcBindings.h>
 #include <llvm-c/Analysis.h>
+#include <llvm-c/Transforms/IPO.h>
+#include <llvm-c/Transforms/Scalar.h>
+#include <llvm-c/Transforms/Vectorize.h>
 #include <memory>
 #include <type_traits>
 #include <utility>
@@ -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)
index 70cae74dbcc5b3463bd911a86a081136a0efc6cb..38827882b879bd955794edafd4349f55501dcb1d 100644 (file)
@@ -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;
index 9e7eadc14cac43818bcf61e3d18d77ab54ef16c5..7c6fc64af7835652da5cdbcfed43b92d1fbd6251 100644 (file)
@@ -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,