+ return progress;
+}
+
+static void
+apply_kills(struct vc4_compile *c, struct qinst **movs, struct qinst *inst)
+{
+ if (inst->dst.file != QFILE_TEMP)
+ return;
+
+ for (int i = 0; i < c->num_temps; i++) {
+ if (movs[i] &&
+ (movs[i]->dst.index == inst->dst.index ||
+ (movs[i]->src[0].file == QFILE_TEMP &&
+ movs[i]->src[0].index == inst->dst.index))) {
+ movs[i] = NULL;
+ }
+ }
+}
+
+bool
+qir_opt_copy_propagation(struct vc4_compile *c)
+{
+ bool progress = false;
+ struct qinst **movs;
+
+ movs = ralloc_array(c, struct qinst *, c->num_temps);
+ if (!movs)
+ return false;
+
+ qir_for_each_block(block, c) {
+ /* The MOVs array tracks only available movs within the
+ * block.
+ */
+ memset(movs, 0, sizeof(struct qinst *) * c->num_temps);
+
+ qir_for_each_inst(inst, block) {
+ progress = try_copy_prop(c, inst, movs) || progress;
+
+ apply_kills(c, movs, inst);
+
+ if (is_copy_mov(inst))
+ movs[inst->dst.index] = inst;
+ }
+ }
+
+ ralloc_free(movs);
+