[Mesa-dev] [PATCH] mesa: Make ffs/ffsl conditions match popcount ones.

Alexander von Gluck kallisti5 at unixzen.com
Tue Jan 10 21:08:51 PST 2012


- Ensure mesa code uses the _mesa_ffs(l) functions
   consistantly instead of jumping around between ffs
   and _mesa_ffs
- This makes ffs/ffsl behave more like the popcount code
- Better detects and handles edge cases of missing ffs/ffsl
- Use builtin ffs/ffsl more often as it may provide
   performance improvements
---
  src/mesa/drivers/dri/i915/i915_program.c    |    6 +++---
  src/mesa/drivers/dri/i965/brw_draw_upload.c |    2 +-
  src/mesa/drivers/dri/i965/brw_vs_state.c    |    2 +-
  src/mesa/drivers/dri/i965/brw_wm_state.c    |    2 +-
  src/mesa/main/imports.c                     |    3 ++-
  src/mesa/main/imports.h                     |   18 +++++++++++-------
  6 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_program.c 
b/src/mesa/drivers/dri/i915/i915_program.c
index 0a600d3..0a544c7 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -75,7 +75,7 @@
  GLuint
  i915_get_temp(struct i915_fragment_program *p)
  {
-   int bit = ffs(~p->temp_flag);
+   int bit = _mesa_ffs(~p->temp_flag);
     if (!bit) {
        fprintf(stderr, "%s: out of temporaries\n", __FILE__);
        exit(1);
@@ -89,7 +89,7 @@ i915_get_temp(struct i915_fragment_program *p)
  GLuint
  i915_get_utemp(struct i915_fragment_program * p)
  {
-   int bit = ffs(~p->utemp_flag);
+   int bit = _mesa_ffs(~p->utemp_flag);
     if (!bit) {
        fprintf(stderr, "%s: out of temporaries\n", __FILE__);
        exit(1);
@@ -206,7 +206,7 @@ i915_emit_arith(struct i915_fragment_program * p,
  static GLuint get_free_rreg (struct i915_fragment_program *p,
                               GLuint live_regs)
  {
-    int bit = ffs(~live_regs);
+    int bit = _mesa_ffs(~live_regs);
      if (!bit) {
          i915_program_error(p, "Can't find free R reg");
          return UREG_BAD;
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c 
b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 331f2a0..b4fd220 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -373,7 +373,7 @@ static void brw_prepare_vertices(struct brw_context 
*brw)
     /* Accumulate the list of enabled arrays. */
     brw->vb.nr_enabled = 0;
     while (vs_inputs) {
-      GLuint i = ffsll(vs_inputs) - 1;
+      GLuint i = _mesa_ffsll(vs_inputs) - 1;
        struct brw_vertex_element *input = &brw->vb.inputs[i];

        vs_inputs &= ~BITFIELD64_BIT(i);
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c 
b/src/mesa/drivers/dri/i965/brw_vs_state.c
index f572123..1283b73 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -77,7 +77,7 @@ brw_upload_vs_unit(struct brw_context *brw)
        vs->thread2.scratch_space_base_pointer =
  	 brw->vs.scratch_bo->offset >> 10; /* reloc */
        vs->thread2.per_thread_scratch_space =
-	 ffs(brw->vs.prog_data->total_scratch) - 11;
+	 _mesa_ffs(brw->vs.prog_data->total_scratch) - 11;
     } else {
        vs->thread2.scratch_space_base_pointer = 0;
        vs->thread2.per_thread_scratch_space = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c 
b/src/mesa/drivers/dri/i965/brw_wm_state.c
index e1791c2..fca4d0c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -119,7 +119,7 @@ brw_upload_wm_unit(struct brw_context *brw)
        wm->thread2.scratch_space_base_pointer =
  	 brw->wm.scratch_bo->offset >> 10; /* reloc */
        wm->thread2.per_thread_scratch_space =
-	 ffs(brw->wm.prog_data->total_scratch) - 11;
+	 _mesa_ffs(brw->wm.prog_data->total_scratch) - 11;
     } else {
        wm->thread2.scratch_space_base_pointer = 0;
        wm->thread2.per_thread_scratch_space = 0;
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 2469e42..9e5f631 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -453,7 +453,8 @@ _mesa_inv_sqrtf(float n)
  #endif
  }

-#ifndef __GNUC__
+#if !defined(__GNUC__) ||\
+   ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
  /**
   * Find the first bit set in a word.
   */
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index b7e8743..fab8b43 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -568,14 +568,16 @@ _mesa_init_sqrt_table(void);

  #ifdef __GNUC__

-#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(ANDROID) || 
defined(__APPLE__)
-#define ffs __builtin_ffs
-#define ffsll __builtin_ffsll
+#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#define _mesa_ffs __builtin_ffs
+#define _mesa_ffsll __builtin_ffsll
+#else /* older GCC, no builtin */
+extern int
+_mesa_ffs(int32_t i);
+extern int
+_mesa_ffsll(int64_t i);
  #endif

-#define _mesa_ffs(i)  ffs(i)
-#define _mesa_ffsll(i)  ffsll(i)
-
  #if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
  #define _mesa_bitcount(i) __builtin_popcount(i)
  #define _mesa_bitcount_64(i) __builtin_popcountll(i)
@@ -586,7 +588,9 @@ extern unsigned int
  _mesa_bitcount_64(uint64_t n);
  #endif

-#else
+#else /* non-GNUC */
+#include <strings.h> /* for ffs */
+
  extern int
  _mesa_ffs(int32_t i);

-- 
1.7.7.2


More information about the mesa-dev mailing list