- struct qreg temp = qir_get_temp(c);
- struct qreg unif = qir_reg(QFILE_UNIF, max_index);
- struct qinst *mov = qir_inst(QOP_MOV, temp, unif, c->undef);
- list_add(&mov->link, &c->instructions);
- c->defs[temp.index] = mov;
- qir_for_each_inst_inorder(inst, c) {
- uint32_t nsrc = qir_get_op_nsrc(inst->op);
-
- uint32_t count = qir_get_instruction_uniform_count(inst);
-
- if (count <= 1)
- continue;
-
- bool removed = false;
- for (int i = 0; i < nsrc; i++) {
- if (is_lowerable_uniform(inst, i) &&
- inst->src[i].index == max_index) {
- inst->src[i] = temp;
- remove_uniform(ht, unif);
- removed = true;
+ qir_for_each_block(block, c) {
+ struct qinst *mov = NULL;
+
+ qir_for_each_inst(inst, block) {
+ uint32_t nsrc = qir_get_nsrc(inst);
+
+ uint32_t count = qir_get_instruction_uniform_count(inst);
+
+ if (count <= 1)
+ continue;
+
+ /* If the block doesn't have a load of hte
+ * uniform yet, add it. We could potentially
+ * do better and CSE MOVs from multiple blocks
+ * into dominating blocks, except that may
+ * cause troubles for register allocation.
+ */
+ if (!mov) {
+ mov = qir_inst(QOP_MOV, qir_get_temp(c),
+ unif, c->undef);
+ list_add(&mov->link,
+ &block->instructions);
+ c->defs[mov->dst.index] = mov;