vc4: Make sure we recompile when sample_mask changes.
[mesa.git] / src / gallium / drivers / vc4 / vc4_opt_cse.c
index 33e17d73401cd141267b6ef7b5589782f1ffe336..8b4d429074c3e3234c8db7fe0093635baecef1d1 100644 (file)
@@ -45,9 +45,8 @@ struct inst_key {
         enum qop op;
         struct qreg src[4];
         /**
-         * If the instruction depends on the flags, how many QOP_SFs have been
-         * seen before this instruction, or if it depends on r4, how many r4
-         * writes have been seen.
+         * If the instruction depends on the flags, how many SFs have been
+         * seen before this instruction.
          */
         uint32_t implicit_arg_update_count;
 };
@@ -62,10 +61,11 @@ inst_key_equals(const void *a, const void *b)
 }
 
 static struct qinst *
-vc4_find_cse(struct hash_table *ht, struct qinst *inst, uint32_t sf_count,
-             uint32_t r4_count)
+vc4_find_cse(struct vc4_compile *c, struct hash_table *ht,
+             struct qinst *inst, uint32_t sf_count)
 {
         if (inst->dst.file != QFILE_TEMP ||
+            !c->defs[inst->dst.index] ||
             inst->op == QOP_MOV ||
             qir_get_op_nsrc(inst->op) > 4) {
                 return NULL;
@@ -78,23 +78,21 @@ vc4_find_cse(struct hash_table *ht, struct qinst *inst, uint32_t sf_count,
                qir_get_op_nsrc(inst->op) * sizeof(key.src[0]));
         if (qir_depends_on_flags(inst))
                 key.implicit_arg_update_count = sf_count;
-        if (qir_reads_r4(inst))
-                key.implicit_arg_update_count = r4_count;
 
         uint32_t hash = _mesa_hash_data(&key, sizeof(key));
         struct hash_entry *entry =
-                _mesa_hash_table_search(ht, hash, &key);
+                _mesa_hash_table_search_pre_hashed(ht, hash, &key);
 
         if (entry) {
                 if (debug) {
                         fprintf(stderr, "CSE found match:\n");
 
                         fprintf(stderr, "  Original inst: ");
-                        qir_dump_inst(entry->data);
+                        qir_dump_inst(c, entry->data);
                         fprintf(stderr, "\n");
 
                         fprintf(stderr, "  Our inst:      ");
-                        qir_dump_inst(inst);
+                        qir_dump_inst(c, inst);
                         fprintf(stderr, "\n");
                 }
 
@@ -105,11 +103,11 @@ vc4_find_cse(struct hash_table *ht, struct qinst *inst, uint32_t sf_count,
         if (!alloc_key)
                 return NULL;
         memcpy(alloc_key, &key, sizeof(*alloc_key));
-        _mesa_hash_table_insert(ht, hash, alloc_key, inst);
+        _mesa_hash_table_insert_pre_hashed(ht, hash, alloc_key, inst);
 
         if (debug) {
                 fprintf(stderr, "Added to CSE HT: ");
-                qir_dump_inst(inst);
+                qir_dump_inst(c, inst);
                 fprintf(stderr, "\n");
         }
 
@@ -120,43 +118,24 @@ bool
 qir_opt_cse(struct vc4_compile *c)
 {
         bool progress = false;
-        struct simple_node *node, *t;
-        struct qinst *last_sf = NULL;
-        uint32_t sf_count = 0, r4_count = 0;
+        uint32_t sf_count = 0;
 
-        return false;
-        struct hash_table *ht = _mesa_hash_table_create(NULL, inst_key_equals);
+        struct hash_table *ht = _mesa_hash_table_create(NULL, NULL,
+                                                        inst_key_equals);
         if (!ht)
                 return false;
 
-        foreach_s(node, t, &c->instructions) {
-                struct qinst *inst = (struct qinst *)node;
-
-                if (qir_has_side_effects(inst)) {
-                        if (inst->op == QOP_TLB_DISCARD_SETUP)
-                                last_sf = NULL;
+        list_for_each_entry(struct qinst, inst, &c->instructions, link) {
+                if (qir_has_side_effects(c, inst) ||
+                    qir_has_side_effect_reads(c, inst) ||
+                    inst->op == QOP_TLB_COLOR_READ) {
                         continue;
                 }
 
-                if (inst->op == QOP_SF) {
-                        if (last_sf &&
-                            qir_reg_equals(last_sf->src[0], inst->src[0])) {
-                                if (debug) {
-                                        fprintf(stderr,
-                                                "Removing redundant SF: ");
-                                        qir_dump_inst(inst);
-                                        fprintf(stderr, "\n");
-                                }
-                                qir_remove_instruction(inst);
-                                progress = true;
-                                continue;
-                        } else {
-                                last_sf = inst;
-                                sf_count++;
-                        }
+                if (inst->sf) {
+                        sf_count++;
                 } else {
-                        struct qinst *cse = vc4_find_cse(ht, inst,
-                                                         sf_count, r4_count);
+                        struct qinst *cse = vc4_find_cse(c, ht, inst, sf_count);
                         if (cse) {
                                 inst->src[0] = cse->dst;
                                 for (int i = 1; i < qir_get_op_nsrc(inst->op);
@@ -167,14 +146,11 @@ qir_opt_cse(struct vc4_compile *c)
 
                                 if (debug) {
                                         fprintf(stderr, "  Turned into:   ");
-                                        qir_dump_inst(inst);
+                                        qir_dump_inst(c, inst);
                                         fprintf(stderr, "\n");
                                 }
                         }
                 }
-
-                if (qir_writes_r4(inst))
-                        r4_count++;
         }
 
         ralloc_free(ht);