From 2859fd34f343657c790b6cabed1db2a80cf16854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Thu, 21 Nov 2024 20:49:45 +0100 Subject: [PATCH] r300: minor fix for backend writer/reader detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consider the following snippet from a Trine shader 20: RCP temp[40].z, temp[39].__w_; 21: MOV temp[40].xy, temp[34].-x-y__; 22: DP3 temp[41].x, temp[40].xyz_, temp[29].xyz_; ... 33: DP3 temp[52].x, temp[40].xyz_, temp[51].xyz_; 34: MAX temp[53].x, temp[52].x___, none.0___; 35: MUL temp[54].xy, temp[40].xy__, const[8].ww__; 36: MUL temp[55].xy, temp[54].xy__, temp[41].xx__; 37: MUL temp[56].x, temp[40].z___, const[8].w___; When we search for writers for temp[40] so that we can check if we can convert the MUL to omod, the corresponding variable actually contains the RCP temp[40].z first and the MOV temp[40].xy is marked as friend. However the current logic only checks the first instruction of variable, so we fail to find the writer. Just search recursivelly also the variable friends. Signed-off-by: Pavel Ondračka Part-of: --- .../drivers/r300/compiler/radeon_variable.c | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/r300/compiler/radeon_variable.c b/src/gallium/drivers/r300/compiler/radeon_variable.c index 5cd9485094e..615cd31ae89 100644 --- a/src/gallium/drivers/r300/compiler/radeon_variable.c +++ b/src/gallium/drivers/r300/compiler/radeon_variable.c @@ -486,21 +486,28 @@ rc_variable_list_get_writers(struct rc_list *var_list, unsigned int src_type, vo struct rc_list *writer_list = NULL; for (list_ptr = var_list; list_ptr; list_ptr = list_ptr->Next) { struct rc_variable *var = list_ptr->Item; - if (variable_writes_src(var, src_type, src)) { - struct rc_variable *friend; - rc_list_add(&writer_list, rc_list(&var->C->Pool, var)); - for (friend = var->Friend; friend; friend = friend->Friend) { - if (variable_writes_src(friend, src_type, src)) { - rc_list_add(&writer_list, rc_list(&var->C->Pool, friend)); + while (var) { + if (variable_writes_src(var, src_type, src)) { + struct rc_variable *friend; + rc_list_add(&writer_list, rc_list(&var->C->Pool, var)); + for (friend = var->Friend; friend; friend = friend->Friend) { + if (variable_writes_src(friend, src_type, src)) { + rc_list_add(&writer_list, rc_list(&var->C->Pool, friend)); + } } + /* Once we have identified the variable and its + * friends that write this source, we can stop + * stop searching, because we know none of the + * other variables in the list will write this source. + * If they did they would be friends of var. + */ + return writer_list; + } else { + if (var->Friend) + var = var->Friend; + else + break; } - /* Once we have identified the variable and its - * friends that write this source, we can stop - * stop searching, because we know none of the - * other variables in the list will write this source. - * If they did they would be friends of var. - */ - break; } } return writer_list;