nir: Add nir_foreach_function_impl helper

Most users of nir_foreach_function actually want the nir_function_impl, not the
nir_function, and want to skip empty functions (though some graphics-specific
passes sometimes fail to do that part). Add a nir_foreach_function_impl macro
to make that case more ergonomic.

   nir_foreach_function_impl(impl, shader) {
      ...
      foo(impl)
   }

is equivalent to:

   nir_foreach_function(func, shader) {
      if (func->impl) {
         ...
         foo(func->impl);
      }
   }

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23807>
This commit is contained in:
Alyssa Rosenzweig 2023-06-22 12:38:16 -04:00 committed by Marge Bot
parent a8044110bf
commit 19daa9283c

View file

@ -3995,6 +3995,50 @@ typedef struct nir_shader {
#define nir_foreach_function(func, shader) \
foreach_list_typed(nir_function, func, node, &(shader)->functions)
static inline nir_function *
nir_first_function_with_impl(const nir_shader *shader)
{
foreach_list_typed(nir_function, func, node, &shader->functions) {
if (func->impl != NULL)
return func;
}
return NULL;
}
static inline nir_function_impl *
_nir_foreach_function_impl_next(const nir_function **it)
{
foreach_list_typed_from(nir_function, func, node, _, (*it)->node.next) {
if (func->impl != NULL) {
*it = func;
return func->impl;
}
}
return NULL;
}
/* Equivalent to
*
* nir_foreach_function(func, shader) {
* if (func->impl != NULL) {
* ...
* }
* }
*
* Carefully written to ensure break/continue work in the user code.
*/
#define nir_foreach_function_impl(it, shader) \
for (const nir_function *_func_##it = nir_first_function_with_impl(shader); \
_func_##it != NULL; \
_func_##it = NULL) \
\
for (nir_function_impl *it = (_func_##it)->impl; \
it != NULL; \
it = _nir_foreach_function_impl_next(&_func_##it)) \
static inline nir_function_impl *
nir_shader_get_entrypoint(const nir_shader *shader)
{