From 3d8ec9676261740404a06afe992adbffd0123a00 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 27 Apr 2020 16:58:54 -0700 Subject: [PATCH] freedreno/ir3/ra: split out helper for array assignment Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/ir3_ra.c | 106 ++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index d55753085a5..656fa01193e 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -1267,6 +1267,62 @@ ra_block_alloc(struct ir3_ra_ctx *ctx, struct ir3_block *block) } } +static void +assign_arr_base(struct ir3_ra_ctx *ctx, struct ir3_array *arr, + struct ir3_instruction **precolor, unsigned nprecolor) +{ + unsigned base = 0; + + /* figure out what else we conflict with which has already + * been assigned: + */ +retry: + foreach_array (arr2, &ctx->ir->array_list) { + if (arr2 == arr) + break; + if (arr2->end_ip == 0) + continue; + /* if it intersects with liverange AND register range.. */ + if (intersects(arr->start_ip, arr->end_ip, + arr2->start_ip, arr2->end_ip) && + intersects(base, base + reg_size_for_array(arr), + arr2->reg, arr2->reg + reg_size_for_array(arr2))) { + base = MAX2(base, arr2->reg + reg_size_for_array(arr2)); + goto retry; + } + } + + /* also need to not conflict with any pre-assigned inputs: */ + for (unsigned i = 0; i < nprecolor; i++) { + struct ir3_instruction *instr = precolor[i]; + + if (!instr || (instr->flags & IR3_INSTR_UNUSED)) + continue; + + struct ir3_ra_instr_data *id = &ctx->instrd[instr->ip]; + + /* only consider the first component: */ + if (id->off > 0) + continue; + + unsigned name = ra_name(ctx, id); + unsigned regid = instr->regs[0]->num; + + /* Check if array intersects with liverange AND register + * range of the input: + */ + if (intersects(arr->start_ip, arr->end_ip, + ctx->def[name], ctx->use[name]) && + intersects(base, base + reg_size_for_array(arr), + regid, regid + class_sizes[id->cls])) { + base = MAX2(base, regid + class_sizes[id->cls]); + goto retry; + } + } + + arr->reg = base; +} + /* handle pre-colored registers. This includes "arrays" (which could be of * length 1, used for phi webs lowered to registers in nir), as well as * special shader input values that need to be pinned to certain registers. @@ -1323,59 +1379,13 @@ ra_precolor(struct ir3_ra_ctx *ctx, struct ir3_instruction **precolor, unsigned * But on a5xx and earlier it will need to track two bases. */ foreach_array (arr, &ctx->ir->array_list) { - unsigned base = 0; if (arr->end_ip == 0) continue; - /* figure out what else we conflict with which has already - * been assigned: - */ -retry: - foreach_array (arr2, &ctx->ir->array_list) { - if (arr2 == arr) - break; - if (arr2->end_ip == 0) - continue; - /* if it intersects with liverange AND register range.. */ - if (intersects(arr->start_ip, arr->end_ip, - arr2->start_ip, arr2->end_ip) && - intersects(base, base + reg_size_for_array(arr), - arr2->reg, arr2->reg + reg_size_for_array(arr2))) { - base = MAX2(base, arr2->reg + reg_size_for_array(arr2)); - goto retry; - } - } - - /* also need to not conflict with any pre-assigned inputs: */ - for (unsigned i = 0; i < nprecolor; i++) { - struct ir3_instruction *instr = precolor[i]; - - if (!instr || (instr->flags & IR3_INSTR_UNUSED)) - continue; - - struct ir3_ra_instr_data *id = &ctx->instrd[instr->ip]; - - /* only consider the first component: */ - if (id->off > 0) - continue; - - unsigned name = ra_name(ctx, id); - unsigned regid = instr->regs[0]->num; - - /* Check if array intersects with liverange AND register - * range of the input: - */ - if (intersects(arr->start_ip, arr->end_ip, - ctx->def[name], ctx->use[name]) && - intersects(base, base + reg_size_for_array(arr), - regid, regid + class_sizes[id->cls])) { - base = MAX2(base, regid + class_sizes[id->cls]); - goto retry; - } - } + assign_arr_base(ctx, arr, precolor, nprecolor); - arr->reg = base; + unsigned base = arr->reg; for (unsigned i = 0; i < arr->length; i++) { unsigned name, reg; -- 2.30.2