mesa: Micro-optimize _mesa_is_valid_prim_mode
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 7 Nov 2014 06:51:45 +0000 (22:51 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 15 Jan 2015 01:09:50 +0000 (17:09 -0800)
You would not believe the mess GCC 4.8.3 generated for the old
switch-statement.

On Bay Trail-D using Fedora 20 compile flags (-m64 -O2 -mtune=generic
for 64-bit and -m32 -march=i686 -mtune=atom for 32-bit), affects
Gl32Batch7:

32-bit: Difference at 95.0% confidence -0.37374% +/- 0.184057% (n=40)
64-bit: Difference at 95.0% confidence 0.966722% +/- 0.338442% (n=40)

The regression on 32-bit is odd.  Callgrind says the caller,
_mesa_is_valid_prim_mode is faster.  Before it says 2,293,760
cycles, and after it says 917,504.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/main/api_validate.c

index b882f0e837d194a190ccd251fcc3c325d8cbf0c5..9c2e29e6472272a1285f7fe734aff8af7c924b29 100644 (file)
@@ -113,27 +113,21 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
 bool
 _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode)
 {
-   switch (mode) {
-   case GL_POINTS:
-   case GL_LINES:
-   case GL_LINE_LOOP:
-   case GL_LINE_STRIP:
-   case GL_TRIANGLES:
-   case GL_TRIANGLE_STRIP:
-   case GL_TRIANGLE_FAN:
+   /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN).  Test that
+    * first and exit.  You would think that a switch-statement would be the
+    * right approach, but at least GCC 4.7.2 generates some pretty dire code
+    * for the common case.
+    */
+   if (likely(mode <= GL_TRIANGLE_FAN))
       return true;
-   case GL_QUADS:
-   case GL_QUAD_STRIP:
-   case GL_POLYGON:
+
+   if (mode <= GL_POLYGON)
       return (ctx->API == API_OPENGL_COMPAT);
-   case GL_LINES_ADJACENCY:
-   case GL_LINE_STRIP_ADJACENCY:
-   case GL_TRIANGLES_ADJACENCY:
-   case GL_TRIANGLE_STRIP_ADJACENCY:
+
+   if (mode <= GL_TRIANGLE_STRIP_ADJACENCY)
       return _mesa_has_geometry_shaders(ctx);
-   default:
-      return false;
-   }
+
+   return false;
 }