gallivm: add coroutine pass manager support
authorDave Airlie <airlied@redhat.com>
Tue, 25 Jun 2019 21:37:20 +0000 (07:37 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 4 Sep 2019 05:22:20 +0000 (15:22 +1000)
coroutines require a proper pass manager, so add the passes
to the correct places

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld.h
src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_init.h

index ca23005b808229a733a5d092cffab660b8e2dff9..a6a6c1add0a7b1a857af110a193b488edab8a39b 100644 (file)
@@ -95,6 +95,11 @@ typedef void *LLVMMCJITMemoryManagerRef;
 #define LLVMInsertBasicBlock ILLEGAL_LLVM_FUNCTION
 #define LLVMCreateBuilder ILLEGAL_LLVM_FUNCTION
 
+#if HAVE_LLVM >= 0x0800
+#define GALLIVM_HAVE_CORO 1
+#else
+#define GALLIVM_HAVE_CORO 0
+#endif
 
 /*
  * Before LLVM 3.4 LLVMSetAlignment only supported GlobalValue, not
index 544c23ee96dbcc9c0efc5b492458354c904f8a87..b0781eb97c2d6e7d2fea75bb4c2ae91ece42d735 100644 (file)
@@ -44,7 +44,9 @@
 #include <llvm-c/Transforms/Utils.h>
 #endif
 #include <llvm-c/BitWriter.h>
-
+#if GALLIVM_HAVE_CORO
+#include <llvm-c/Transforms/Coroutines.h>
+#endif
 
 /* Only MCJIT is available as of LLVM SVN r216982 */
 #if HAVE_LLVM >= 0x0306
@@ -125,6 +127,10 @@ create_pass_manager(struct gallivm_state *gallivm)
    gallivm->passmgr = LLVMCreateFunctionPassManagerForModule(gallivm->module);
    if (!gallivm->passmgr)
       return FALSE;
+
+#if GALLIVM_HAVE_CORO
+   gallivm->cgpassmgr = LLVMCreatePassManager();
+#endif
    /*
     * TODO: some per module pass manager with IPO passes might be helpful -
     * the generated texture functions may benefit from inlining if they are
@@ -144,6 +150,12 @@ create_pass_manager(struct gallivm_state *gallivm)
       free(td_str);
    }
 
+#if GALLIVM_HAVE_CORO
+   LLVMAddCoroEarlyPass(gallivm->cgpassmgr);
+   LLVMAddCoroSplitPass(gallivm->cgpassmgr);
+   LLVMAddCoroElidePass(gallivm->cgpassmgr);
+#endif
+
    if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) {
       /*
        * TODO: Evaluate passes some more - keeping in mind
@@ -170,6 +182,9 @@ create_pass_manager(struct gallivm_state *gallivm)
       LLVMAddConstantPropagationPass(gallivm->passmgr);
       LLVMAddInstructionCombiningPass(gallivm->passmgr);
       LLVMAddGVNPass(gallivm->passmgr);
+#if GALLIVM_HAVE_CORO
+      LLVMAddCoroCleanupPass(gallivm->passmgr);
+#endif
    }
    else {
       /* We need at least this pass to prevent the backends to fail in
@@ -193,6 +208,12 @@ gallivm_free_ir(struct gallivm_state *gallivm)
       LLVMDisposePassManager(gallivm->passmgr);
    }
 
+#if GALLIVM_HAVE_CORO
+   if (gallivm->cgpassmgr) {
+      LLVMDisposePassManager(gallivm->cgpassmgr);
+   }
+#endif
+
    if (gallivm->engine) {
       /* This will already destroy any associated module */
       LLVMDisposeExecutionEngine(gallivm->engine);
@@ -219,6 +240,7 @@ gallivm_free_ir(struct gallivm_state *gallivm)
    gallivm->target = NULL;
    gallivm->module = NULL;
    gallivm->module_name = NULL;
+   gallivm->cgpassmgr = NULL;
    gallivm->passmgr = NULL;
    gallivm->context = NULL;
    gallivm->builder = NULL;
@@ -610,6 +632,9 @@ gallivm_compile_module(struct gallivm_state *gallivm)
    if (gallivm_debug & GALLIVM_DEBUG_PERF)
       time_begin = os_time_get();
 
+#if GALLIVM_HAVE_CORO
+   LLVMRunPassManager(gallivm->cgpassmgr, gallivm->module);
+#endif
    /* Run optimization passes */
    LLVMInitializeFunctionPassManager(gallivm->passmgr);
    func = LLVMGetFirstFunction(gallivm->module);
index 62ca0c7faa47057db3e35426bc8817809ca185d1..56279ce1aac2bc6ecff24a94302cafad88725d4c 100644 (file)
@@ -46,6 +46,7 @@ struct gallivm_state
    LLVMExecutionEngineRef engine;
    LLVMTargetDataRef target;
    LLVMPassManagerRef passmgr;
+   LLVMPassManagerRef cgpassmgr;
    LLVMContextRef context;
    LLVMBuilderRef builder;
    LLVMMCJITMemoryManagerRef memorymgr;