Commit a373fa1f authored by Dave Airlie's avatar Dave Airlie
Browse files

WIP: don't inline libclc functions

parent aeb267d5
Pipeline #737130 waiting for manual action with stages
......@@ -31,6 +31,31 @@
#include "nir_builder.h"
#include "nir_spirv.h"
static nir_function *
clone_function(const nir_function *fxn, nir_shader *ns)
{
nir_function *nfxn = nir_function_create(ns, fxn->name);
nfxn->num_params = fxn->num_params;
if (fxn->num_params) {
nfxn->params = ralloc_array(ns, nir_parameter, fxn->num_params);
memcpy(nfxn->params, fxn->params, sizeof(nir_parameter) * fxn->num_params);
}
nfxn->is_entrypoint = fxn->is_entrypoint;
nfxn->is_preamble = fxn->is_preamble;
nfxn->should_inline = fxn->should_inline;
nfxn->dont_inline = fxn->dont_inline;
/* At first glance, it looks like we should clone the function_impl here.
* However, call instructions need to be able to reference at least the
* function and those will get processed as we clone the function_impls.
* We stop here and do function_impls as a second pass.
*/
return nfxn;
}
static bool
lower_clc_call_instr(nir_instr *instr, nir_builder *b,
const nir_shader *clc_shader,
......@@ -39,6 +64,74 @@ lower_clc_call_instr(nir_instr *instr, nir_builder *b,
nir_call_instr *call = nir_instr_as_call(instr);
nir_function *func = NULL;
if (!call->callee->name)
return false;
if (call->callee->impl)
return false;
nir_foreach_function(function, clc_shader) {
if (strcmp(function->name, call->callee->name) == 0) {
func = function;
break;
}
}
if (!func || !func->impl) {
return false;
}
nir_function_impl *copy = nir_function_impl_clone(b->shader, func->impl);
copy->function = call->callee;
call->callee->impl = copy;
fprintf(stderr, "cloned %s\n", copy->function->name);
nir_foreach_block_safe(block, copy) {
nir_foreach_instr_safe(n_instr, block) {
if (n_instr->type == nir_instr_type_call) {
nir_call_instr *ncall = nir_instr_as_call(n_instr);
if (!ncall->callee->name)
continue;
fprintf(stderr, "copy calls %s\n", ncall->callee->name);
bool found = false;
nir_foreach_function(function, b->shader) {
if (strcmp(function->name, ncall->callee->name) == 0) {
if (ncall->callee != function)
ncall->callee = function;
found = true;
break;
}
}
if (found) {
continue;
}
nir_function *new_func = NULL;
nir_foreach_function(clc_function, clc_shader) {
if (strcmp(clc_function->name, ncall->callee->name) == 0) {
new_func = clone_function(clc_function, b->shader);
fprintf(stderr, "copy clone %s to %p\n", clc_function->name, new_func);
break;
}
}
if (!new_func)
continue;
ncall->callee = new_func;
}
}
}
return true;
}
static bool
lower_clc_call_inline_instr(nir_instr *instr, nir_builder *b,
const nir_shader *clc_shader,
struct hash_table *copy_vars)
{
nir_call_instr *call = nir_instr_as_call(instr);
nir_function *func = NULL;
if (!call->callee->name)
return false;
......@@ -48,6 +141,7 @@ lower_clc_call_instr(nir_instr *instr, nir_builder *b,
break;
}
}
if (!func || !func->impl) {
return false;
}
......@@ -63,7 +157,6 @@ lower_clc_call_instr(nir_instr *instr, nir_builder *b,
nir_inline_function_impl(b, func->impl, params, copy_vars);
ralloc_free(params);
return true;
}
......@@ -78,8 +171,12 @@ nir_lower_libclc_impl(nir_function_impl *impl,
bool progress = false;
nir_foreach_block_safe(block, impl) {
nir_foreach_instr_safe(instr, block) {
if (instr->type == nir_instr_type_call)
progress |= lower_clc_call_instr(instr, &b, clc_shader, copy_vars);
if (instr->type == nir_instr_type_call) {
if (b.shader->options->driver_functions)
progress |= lower_clc_call_instr(instr, &b, clc_shader, copy_vars);
else
progress |= lower_clc_call_inline_instr(instr, &b, clc_shader, copy_vars);
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment