[Mesa-dev] [PATCH 00/11] nir: Add a pass management framework
Jason Ekstrand
jason at jlekstrand.net
Tue Nov 3 13:58:50 PST 2015
On Tue, Nov 3, 2015 at 12:16 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> On Wednesday, October 28, 2015 02:32:00 PM Jason Ekstrand wrote:
>> This series adds a nir_pass datastructure and some helpers for managing
>> optimization and lowering passes. I've been meaning to get around to this
>> for some time. There are a couple of primary benifits to this:
>>
>> First, this gives us a central place to put things such as validating the
>> shader, printing it if it changes, etc. Right now, the i965 backend calls
>> nir_validate_shader after each pass. We would also like to add something
>> like we have in the i965 backend where it can be set to dump the IR to a
>> file after every pass that changess it.
>>
>> Mor importantly, though, it moves metadata out of the passes them selves
>> and into the runner. In the process of putting this series together, I
>> found at least 3 or 4 optimization passes that don't properly invalidate
>> metadata. By putting a metadata_preserved field in nir_pass and handling
>> metadata in the pass runner, we make it much less likely that a pass will
>> get this wrong. LLVM has a similar optimization pass architecture for
>> precicely this reason.
>>
>> As a nice little side-benifit, we no longer have to iterate over all of the
>> overloads with non-NULL impl pointers in each pass.
>
> I read through the series today. Most of it seemed pretty reasonable,
> but when I got to patch 11 and saw the final result...I just wasn't a
> huge fan of how it turned out.
>
> There's something really nice about having passes simply be functions
> that manipulate the shader. They can easily take arguments. You can
> easily call them conditionally - which we do, based on scalar-vs-vec4,
> generation number, or shader stage. You can assemble passes into groups
> by using helper functions (i.e. brw_nir_lower_inputs). You can easily
> add breakpoints at arbitrary locations.
>
> While you can technically still do these things with the flat array of
> structs, I think it would be awkward in practice:
>
> - Packing a bunch of function arguments into a struct, passing them as
> a void *, and unpacking them is a bunch of boilerplate. Especially
> for passes that have a single parameter, i.e. "true"/"false" or "32".
>
> - For passes that don't have any arguments, adding the extra unused
> (void *closure) parameter also adds more boilerplate. Plus, it just
> seems unfortunate - they already had a nice clean API...
Yeah... arguments... I'll freely admit that that's the Achilles' heel
of my whole plan. Unfortunately, the C language doesn't really
provide good facilities for this. We could make it work less
painfully with some fun GCC builtins, but I don't know how to do it on
msvc or the like and even the builtins would be rather hackish. I
guess it's something where if the advantages of having automatic pass
management are high enough to offset the pain, we can switch then.
> - Conditionally calling passes means assembling a list of passes on the
> fly, dynamically, rather than using a static array. Would probably
> get messy. Hope the array sizes are right.
Yeah, I wasn't a fan of that either.
> Also, in order for INTEL_DEBUG=optimizer style output to work, *all*
> lowering/optimization passes need to participate. This lets you diff
> successive code dumps, seeing what each pass did. If some passes don't
> get printed, then the output is unintelligable. (I've had to fix that.)
>
> Notably, patch 11 doesn't convert any passes with arguments or
> conditional passes to the infrastructure - only the simple cases.
> Will this work okay for the more complex ones, or will we want
> something different? Is this a step toward that?
My initial reaction was "but most passes don't take arguments". While
I'd be ok with moving the bool from lower_vars_to_ssa into
nir_compiler_options, that's about the only pass argument I'd be ok
with moving there. Looking over things a bit more, it looks like
about half of the lowering passes take arguments. (Substantially more
than I was hoping) :-(
> I also tend to agree with Rob's reluctance toward meta-programming,
> FWIW...I'd at least like to be wowed by some nice benefits.
>
> It sounds like Jason and Connor have some ideas about how a pass
> manager could be helpful in the future. But for now, I only see
> two concrete benefits:
>
> 1. It ensures nir_metadata_preserve gets called appropriately.
> (this is *really* important!)
This is my #1 priority
> 2. It removes some boilerplate for looping over impls.
I like this, but it's not needed.
You forgot my #2 priority: Automatic validation.
> I have an alternate approach to suggest for #1. I don't think #2 is
> terribly important for now, since Jason may end up reworking functions
> a bit as part of his SPIR-V work...and it seems like we should defer
> tidying until we have more than one function.
>
> Also, we do need to fix missing nir_metadata_preserve calls on the
> stable branch, so we should fix those independently of implementing
> a new pass management scheme. I have patches for that.
I've reviewed most of those. Thanks for doing that.
So, I still kind of like my struct... but I understand that there are
problems with it that are, as of yet, unsolved.
The patches I just sent are a rework of the nir_pass struct to make it
basically just a helper for creating passes. In particular, I
completely dropped nir_shader_optimize. I don't know how worth-while
it is without that and without the function argument problems solved,
but there it is none the less.
--Jason
More information about the mesa-dev
mailing list