Mesa (master): freedreno/hw/isa: Add expression caching

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 13 18:53:08 UTC 2021


Module: Mesa
Branch: master
Commit: 704e49bae06ba98c435c311ffd64d79658fd654e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=704e49bae06ba98c435c311ffd64d79658fd654e

Author: Rob Clark <robdclark at chromium.org>
Date:   Tue Dec 15 13:22:37 2020 -0800

freedreno/hw/isa: Add expression caching

Drops decoding an ~850KB collection of instructions from ~4min to ~1sec.

Granted for normal sized shaders, this probably doesn't matter.. but it
at reduces my cycle time for fixing things to match existing disasm
syntax using this massive collection of unique instructions.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7997>

---

 src/freedreno/isa/decode.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/src/freedreno/isa/decode.c b/src/freedreno/isa/decode.c
index 92d2664ee09..89575d17244 100644
--- a/src/freedreno/isa/decode.c
+++ b/src/freedreno/isa/decode.c
@@ -32,6 +32,7 @@
 #include "util/bitset.h"
 #include "util/compiler.h"
 #include "util/half_float.h"
+#include "util/hash_table.h"
 #include "util/ralloc.h"
 #include "util/u_debug.h"
 #include "util/u_math.h"
@@ -92,6 +93,21 @@ struct decode_scope {
 	 * Pointer back to decode state, for convenience.
 	 */
 	struct decode_state *state;
+
+	/**
+	 * Cache expression evaluation results.  Expressions for overrides can
+	 * be repeatedly evaluated for each field being resolved.  And each
+	 * field reference to a derived field (potentially from another expr)
+	 * would require re-evaluation.  But for a given scope, each evaluation
+	 * of an expression gives the same result.  So we can cache to speed
+	 * things up.
+	 *
+	 * TODO we could maybe be clever and assign a unique idx to each expr
+	 * and use a direct lookup table?  Would be a bit more clever if it was
+	 * smart enough to allow unrelated expressions that are never involved
+	 * in a given scope to have overlapping cache lookup idx's.
+	 */
+	struct hash_table *cache;
 };
 
 /**
@@ -225,6 +241,15 @@ pop_scope(struct decode_scope *scope)
 static uint64_t
 evaluate_expr(struct decode_scope *scope, isa_expr_t expr)
 {
+	if (scope->cache) {
+		struct hash_entry *entry = _mesa_hash_table_search(scope->cache, expr);
+		if (entry) {
+			return *(uint64_t *)entry->data;
+		}
+	} else {
+		scope->cache = _mesa_pointer_hash_table_create(scope);
+	}
+
 	if (!push_expr(scope->state, expr))
 		return 0;
 
@@ -232,6 +257,10 @@ evaluate_expr(struct decode_scope *scope, isa_expr_t expr)
 
 	pop_expr(scope->state);
 
+	uint64_t *retp = ralloc_size(scope->cache, sizeof(*retp));
+	*retp = ret;
+	_mesa_hash_table_insert(scope->cache, expr, retp);
+
 	return ret;
 }
 



More information about the mesa-commit mailing list