From 6a7d1ca2c49ae06bbb323936f1e1c17ba7e2c9a1 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 29 Jan 2018 05:24:00 -0700 Subject: [PATCH] mesa/st/glsl_to_tgsi: Mark first write as unconditional when appropriate In the register lifetime estimation if the first write is unconditional or conditional but not within a loop then this is an unconditional dominant write in the sense of register life time estimation. Add a test case and record the write accordingly. Fixes: 807e2539e512ca6c96f059da855473eb7be99ba1 ("mesa/st/glsl_to_tgsi: Add tracking of ifelse writes in register merging") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104803 Signed-off-by: Gert Wollny Reviewed-by: Brian Paul --- .../st_glsl_to_tgsi_temprename.cpp | 24 ++++++++++++++++++- .../tests/test_glsl_to_tgsi_lifetime.cpp | 24 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp index 3a00b337496..6921a643b74 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi_temprename.cpp @@ -197,6 +197,7 @@ private: static const int write_is_conditional = -1; static const int conditionality_unresolved = 0; static const int conditionality_untouched; + static const int write_is_unconditional; /* A bit field tracking the nexting levels of if-else clauses where the * temporary has (so far) been written to in the if branch, but not in the @@ -220,6 +221,9 @@ private: const int temp_comp_access::conditionality_untouched = numeric_limits::max(); +const int +temp_comp_access::write_is_unconditional = numeric_limits::max() - 1; + /* Class to track the access to all components of a temporary register. */ class temp_access { public: @@ -566,6 +570,13 @@ void temp_comp_access::record_read(int line, prog_scope *scope) first_read_scope = scope; } + /* If the conditionality of the first write is already resolved then + * no further checks are required. + */ + if (conditionality_in_loop_id == write_is_unconditional || + conditionality_in_loop_id == write_is_conditional) + return; + /* Check whether we are in a condition within a loop */ const prog_scope *ifelse_scope = scope->in_ifelse_scope(); const prog_scope *enclosing_loop; @@ -612,9 +623,20 @@ void temp_comp_access::record_write(int line, prog_scope *scope) if (first_write < 0) { first_write = line; first_write_scope = scope; + + /* If the first write we encounter is not in a conditional branch, or + * the conditional write is not within a loop, then this is to be + * considered an unconditional dominant write. + */ + const prog_scope *conditional = scope->enclosing_conditional(); + if (!conditional || !conditional->innermost_loop()) { + conditionality_in_loop_id = write_is_unconditional; + } } - if (conditionality_in_loop_id == write_is_conditional) + /* The conditionality of the first write is already resolved. */ + if (conditionality_in_loop_id == write_is_unconditional || + conditionality_in_loop_id == write_is_conditional) return; /* If the nesting depth is larger than the supported level, diff --git a/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp b/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp index a3b0f0e02f9..acebfb82935 100644 --- a/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp +++ b/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp @@ -794,6 +794,30 @@ TEST_F(LifetimeEvaluatorExactTest, WriteInIfElseBranchSecondIfInLoop) run (code, temp_lt_expect({{-1,-1}, {2,9}})); } +/** Regression test for bug #104803, + * Read and write in if/else path outside loop and later read in conditional + * within a loop. The first write is to be considered the dominant write. + */ +TEST_F(LifetimeEvaluatorExactTest, IfElseWriteInBothOutsideLoopReadInElseInLoop) +{ + const vector code = { + { TGSI_OPCODE_IF, {}, {in0}, {} }, + { TGSI_OPCODE_MOV, {1}, {in0}, {} }, + { TGSI_OPCODE_ELSE, {}, {}, {} }, + { TGSI_OPCODE_MOV, {1}, {in1}, {} }, + { TGSI_OPCODE_ENDIF, {}, {}, {} }, + { TGSI_OPCODE_BGNLOOP }, + { TGSI_OPCODE_IF, {}, {in0}, {} }, + { TGSI_OPCODE_MOV, {2}, {in1}, {} }, + { TGSI_OPCODE_ELSE, {}, {}, {} }, + { TGSI_OPCODE_MOV, {2}, {1}, {} }, + { TGSI_OPCODE_ENDIF, {}, {}, {} }, + { TGSI_OPCODE_ENDLOOP }, + { TGSI_OPCODE_MOV, {out0}, {2}, {}}, + { TGSI_OPCODE_END} + }; + run (code, temp_lt_expect({{-1,-1}, {1,11}, {7, 12}})); +} /* A continue in the loop is not relevant */ TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterContinue) -- 2.30.2