summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@chromium.org>2020-12-15 13:22:37 -0800
committerMarge Bot <eric+marge@anholt.net>2021-01-13 18:32:47 +0000
commit704e49bae06ba98c435c311ffd64d79658fd654e (patch)
treefa9298e15aec18e2b3a17b6b060158dffa8daf31
parent6d94f575d2137f6f31353df6b0d6279e9d206ea8 (diff)
downloadmesa-704e49bae06ba98c435c311ffd64d79658fd654e.tar.gz
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@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7997>
-rw-r--r--src/freedreno/isa/decode.c29
1 files changed, 29 insertions, 0 deletions
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;
}