sorry, totally forgot about that. Seems fine as it is and I have the same within my CL branch (except the last nir_lower_constant_initializers).
as I don't really know if all that is actually true, but because it makes sense to me: Acked-by: Karol Herbst <kher...@redhat.com> I kind of wished we would have a helper function for this though like "nir_convert_to_single_function(nir_shader *shader, nir_function *entry_point)" which would do all of that already and we could just call. Hopefully you can come up with a better name. On Wed, Dec 12, 2018 at 4:34 AM Jason Ekstrand <ja...@jlekstrand.net> wrote: > > ping > > On Mon, Oct 29, 2018 at 12:14 PM Jason Ekstrand <ja...@jlekstrand.net> wrote: >> >> This has thrown a few people off recently and it's good to have the >> process and all the rational for it documented somewhere. A comment at >> the top of nir_inline_functions seems as good a place as any. >> >> Cc: Matt Turner <matts...@gmail.com> >> Cc: Karol Herbst <kher...@redhat.com> >> --- >> src/compiler/nir/nir_inline_functions.c | 68 +++++++++++++++++++++++++ >> 1 file changed, 68 insertions(+) >> >> diff --git a/src/compiler/nir/nir_inline_functions.c >> b/src/compiler/nir/nir_inline_functions.c >> index 06c90d93956..29474bb417b 100644 >> --- a/src/compiler/nir/nir_inline_functions.c >> +++ b/src/compiler/nir/nir_inline_functions.c >> @@ -132,6 +132,74 @@ inline_function_impl(nir_function_impl *impl, struct >> set *inlined) >> return progress; >> } >> >> +/** A pass to inline all functions in a shader into their callers >> + * >> + * For most use-cases, function inlining is a multi-step process. The >> general >> + * pattern employed by SPIR-V consumers and others is as follows: >> + * >> + * 1. nir_lower_constant_initializers(shader, nir_var_local) >> + * >> + * This is needed because local variables from the callee are simply >> added >> + * to the locals list for the caller and the information about where the >> + * constant initializer logically happens is lost. If the callee is >> + * called in a loop, this can cause the variable to go from being >> + * initialized once per loop iteration to being initialized once at the >> + * top of the caller and values to persist from one invocation of the >> + * callee to the next. The simple solution to this problem is to get >> rid >> + * of constant initializers before function inlining. >> + * >> + * 2. nir_lower_returns(shader) >> + * >> + * nir_inline_functions assumes that all functions end "naturally" by >> + * execution reaching the end of the function without any return >> + * instructions causing instant jumps to the end. Thanks to NIR being >> + * structured, we can't represent arbitrary jumps to various points in >> the >> + * program which is what an early return in the callee would have to >> turn >> + * into when we inline it into the caller. Instead, we require returns >> to >> + * be lowered which lets us just copy+paste the callee directly into the >> + * caller. >> + * >> + * 3. nir_inline_functions(shader) >> + * >> + * This does the actual function inlining and the resulting shader will >> + * contain no call instructions. >> + * >> + * 4. nir_copy_prop(shader) >> + * >> + * Most functions contain pointer parameters where the result of a deref >> + * instruction is passed in as a parameter, loaded via a load_param >> + * intrinsic, and then turned back into a deref via a cast. Running >> copy >> + * propagation gets rid of the intermediate steps and results in a whole >> + * deref chain again. This is currently required by a number of >> + * optimizations and lowering passes at least for certain variable >> modes. >> + * >> + * 5. Loop over the functions and delete all but the main entrypoint. >> + * >> + * In the Intel Vulkan driver this looks like this: >> + * >> + * foreach_list_typed_safe(nir_function, func, node, >> &nir->functions) { >> + * if (func != entry_point) >> + * exec_node_remove(&func->node); >> + * } >> + * assert(exec_list_length(&nir->functions) == 1); >> + * >> + * While nir_inline_functions does get rid of all call instructions, it >> + * doesn't get rid of any functions because it doesn't know what the >> "root >> + * function" is. Instead, it's up to the individual driver to know how >> to >> + * decide on a root function and delete the rest. With SPIR-V, >> + * spirv_to_nir returns the root function and so we can just use == >> whereas >> + * with GL, you may have to look for a function named "main". >> + * >> + * 6. nir_lower_constant_initializers(shader, ~nir_var_local) >> + * >> + * Lowering constant initializers on inputs, outputs, global variables, >> + * etc. requires that we know the main entrypoint so that we know where >> to >> + * initialize them. Otherwise, we would have to assume that anything >> + * could be a main entrypoint and initialize them at the start of every >> + * function but that would clearly be wrong if any of those functions >> were >> + * ever called within another function. Simply requiring a single- >> + * entrypoint function shader is the best way to make it well-defined. >> + */ >> bool >> nir_inline_functions(nir_shader *shader) >> { >> -- >> 2.19.1 >> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev