Mesa (main): gallivm: move to new pass manager to handle coroutines change.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 9 07:52:43 UTC 2022


Module: Mesa
Branch: main
Commit: 2037c34f245e72de4fd58224c0aa7ae3a7427620
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2037c34f245e72de4fd58224c0aa7ae3a7427620

Author: Dave Airlie <airlied at redhat.com>
Date:   Tue May  3 11:42:24 2022 +1000

gallivm: move to new pass manager to handle coroutines change.

LLVM 15 ripped out the legacy coroutine passes. This means moving
to the new pass manager is the best option to move forward and is
long overdue.

I've tried to recreate the same set of passes in the new pass mgr
as the old, but I expect some tweaking may be needed to confirm this.

Acked-by: Kai Wasserbäch <kai at dev.carbon-project.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16289>

---

 src/gallium/auxiliary/gallivm/lp_bld.h      |  9 ++++-
 src/gallium/auxiliary/gallivm/lp_bld_init.c | 62 +++++++++++++++++++++--------
 src/gallium/auxiliary/gallivm/lp_bld_init.h |  4 ++
 src/gallium/drivers/llvmpipe/lp_screen.c    |  4 +-
 4 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld.h b/src/gallium/auxiliary/gallivm/lp_bld.h
index 5846afa3ce0..e1f6200ac94 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld.h
@@ -81,12 +81,19 @@
 #define LLVMInsertBasicBlock ILLEGAL_LLVM_FUNCTION
 #define LLVMCreateBuilder ILLEGAL_LLVM_FUNCTION
 
-#if LLVM_VERSION_MAJOR >= 8
+#if LLVM_VERSION_MAJOR >= 15
+#define GALLIVM_HAVE_CORO 0
+#define GALLIVM_USE_NEW_PASS 1
+#elif LLVM_VERSION_MAJOR >= 8
 #define GALLIVM_HAVE_CORO 1
+#define GALLIVM_USE_NEW_PASS 0
 #else
 #define GALLIVM_HAVE_CORO 0
+#define GALLIVM_USE_NEW_PASS 0
 #endif
 
+#define GALLIVM_COROUTINES (GALLIVM_HAVE_CORO || GALLIVM_USE_NEW_PASS)
+
 /* LLVM is transitioning to "opaque pointers", and as such deprecates
  * LLVMBuildGEP, LLVMBuildCall, LLVMBuildLoad, replacing them with
  * LLVMBuildGEP2, LLVMBuildCall2, LLVMBuildLoad2 respectivelly.
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 10aa312d472..2ed81d9ae5d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -44,7 +44,9 @@
 #include <llvm-c/Transforms/Utils.h>
 #endif
 #include <llvm-c/BitWriter.h>
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_USE_NEW_PASS == 1
+#include <llvm-c/Transforms/PassBuilder.h>
+#elif GALLIVM_HAVE_CORO == 1
 #if LLVM_VERSION_MAJOR <= 8 && (defined(PIPE_ARCH_AARCH64) || defined (PIPE_ARCH_ARM) || defined(PIPE_ARCH_S390) || defined(PIPE_ARCH_MIPS64))
 #include <llvm-c/Transforms/IPO.h>
 #endif
@@ -109,6 +111,7 @@ enum LLVM_CodeGenOpt_Level {
 static boolean
 create_pass_manager(struct gallivm_state *gallivm)
 {
+#if GALLIVM_USE_NEW_PASS == 0
    assert(!gallivm->passmgr);
    assert(gallivm->target);
 
@@ -116,7 +119,7 @@ create_pass_manager(struct gallivm_state *gallivm)
    if (!gallivm->passmgr)
       return FALSE;
 
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_HAVE_CORO == 1
    gallivm->cgpassmgr = LLVMCreatePassManager();
 #endif
    /*
@@ -133,7 +136,7 @@ create_pass_manager(struct gallivm_state *gallivm)
       free(td_str);
    }
 
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_HAVE_CORO == 1
 #if LLVM_VERSION_MAJOR <= 8 && (defined(PIPE_ARCH_AARCH64) || defined (PIPE_ARCH_ARM) || defined(PIPE_ARCH_S390) || defined(PIPE_ARCH_MIPS64))
    LLVMAddArgumentPromotionPass(gallivm->cgpassmgr);
    LLVMAddFunctionAttrsPass(gallivm->cgpassmgr);
@@ -180,14 +183,13 @@ create_pass_manager(struct gallivm_state *gallivm)
        */
       LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
    }
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_HAVE_CORO == 1
    LLVMAddCoroCleanupPass(gallivm->passmgr);
 #endif
-
+#endif
    return TRUE;
 }
 
-
 /**
  * Free gallivm object's LLVM allocations, but not any generated code
  * nor the gallivm object itself.
@@ -195,14 +197,16 @@ create_pass_manager(struct gallivm_state *gallivm)
 void
 gallivm_free_ir(struct gallivm_state *gallivm)
 {
+#if GALLIVM_USE_NEW_PASS == 0
    if (gallivm->passmgr) {
       LLVMDisposePassManager(gallivm->passmgr);
    }
 
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_HAVE_CORO == 1
    if (gallivm->cgpassmgr) {
       LLVMDisposePassManager(gallivm->cgpassmgr);
    }
+#endif
 #endif
 
    if (gallivm->engine) {
@@ -231,8 +235,12 @@ gallivm_free_ir(struct gallivm_state *gallivm)
    gallivm->target = NULL;
    gallivm->module = NULL;
    gallivm->module_name = NULL;
+#if GALLIVM_USE_NEW_PASS == 0
+#if GALLIVM_HAVE_CORO == 1
    gallivm->cgpassmgr = NULL;
+#endif
    gallivm->passmgr = NULL;
+#endif
    gallivm->context = NULL;
    gallivm->builder = NULL;
    gallivm->cache = NULL;
@@ -568,7 +576,6 @@ gallivm_verify_function(struct gallivm_state *gallivm,
 void
 gallivm_compile_module(struct gallivm_state *gallivm)
 {
-   LLVMValueRef func;
    int64_t time_begin = 0;
 
    assert(!gallivm->compiled);
@@ -578,6 +585,13 @@ gallivm_compile_module(struct gallivm_state *gallivm)
       gallivm->builder = NULL;
    }
 
+   LLVMSetDataLayout(gallivm->module, "");
+   assert(!gallivm->engine);
+   if (!init_gallivm_engine(gallivm)) {
+      assert(0);
+   }
+   assert(gallivm->engine);
+
    if (gallivm->cache && gallivm->cache->data_size) {
       goto skip_cached;
    }
@@ -601,11 +615,33 @@ gallivm_compile_module(struct gallivm_state *gallivm)
    if (gallivm_debug & GALLIVM_DEBUG_PERF)
       time_begin = os_time_get();
 
-#if GALLIVM_HAVE_CORO
+#if GALLIVM_USE_NEW_PASS == 1
+   char passes[1024];
+   passes[0] = 0;
+
+   /*
+    * there should be some way to combine these two pass runs but I'm not seeing it,
+    * at the time of writing.
+    */
+   strcpy(passes, "default<O0>");
+
+   LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions();
+   LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
+
+   if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
+      strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,constprop,instcombine,");
+   else
+      strcpy(passes, "mem2reg");
+
+   LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
+   LLVMDisposePassBuilderOptions(opts);
+#else
+#if GALLIVM_HAVE_CORO == 1
    LLVMRunPassManager(gallivm->cgpassmgr, gallivm->module);
 #endif
    /* Run optimization passes */
    LLVMInitializeFunctionPassManager(gallivm->passmgr);
+   LLVMValueRef func;
    func = LLVMGetFirstFunction(gallivm->module);
    while (func) {
       if (0) {
@@ -623,7 +659,7 @@ gallivm_compile_module(struct gallivm_state *gallivm)
       func = LLVMGetNextFunction(func);
    }
    LLVMFinalizeFunctionPassManager(gallivm->passmgr);
-
+#endif
    if (gallivm_debug & GALLIVM_DEBUG_PERF) {
       int64_t time_end = os_time_get();
       int time_msec = (int)((time_end - time_begin) / 1000);
@@ -650,12 +686,6 @@ gallivm_compile_module(struct gallivm_state *gallivm)
     * lp_build_create_jit_compiler_for_module()
     */
  skip_cached:
-   LLVMSetDataLayout(gallivm->module, "");
-   assert(!gallivm->engine);
-   if (!init_gallivm_engine(gallivm)) {
-      assert(0);
-   }
-   assert(gallivm->engine);
 
    ++gallivm->compiled;
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h
index 7eaaa31745b..81f0a1f31ba 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h
@@ -46,8 +46,12 @@ struct gallivm_state
    LLVMModuleRef module;
    LLVMExecutionEngineRef engine;
    LLVMTargetDataRef target;
+#if GALLIVM_USE_NEW_PASS == 0
    LLVMPassManagerRef passmgr;
+#if GALLIVM_HAVE_CORO == 1
    LLVMPassManagerRef cgpassmgr;
+#endif
+#endif
    LLVMContextRef context;
    LLVMBuilderRef builder;
    LLVMMCJITMemoryManagerRef memorymgr;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 7ee715bf380..69b82e984ec 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -215,7 +215,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return lscreen->use_tgsi ? 330 : 450;
    }
    case PIPE_CAP_COMPUTE:
-      return GALLIVM_HAVE_CORO;
+      return GALLIVM_COROUTINES;
    case PIPE_CAP_USER_VERTEX_BUFFERS:
       return 1;
    case PIPE_CAP_TGSI_TEXCOORD:
@@ -394,7 +394,7 @@ llvmpipe_get_shader_param(struct pipe_screen *screen,
    case PIPE_SHADER_TESS_CTRL:
    case PIPE_SHADER_TESS_EVAL:
       /* Tessellation shader needs llvm coroutines support */
-      if (!GALLIVM_HAVE_CORO || lscreen->use_tgsi)
+      if (!GALLIVM_COROUTINES || lscreen->use_tgsi)
          return 0;
       FALLTHROUGH;
    case PIPE_SHADER_VERTEX:



More information about the mesa-commit mailing list