#include "compiler.h"
#include "midgard_ops.h"
#include "util/u_memory.h"
-#include "util/register_allocate.h"
/* Scheduling for Midgard is complicated, to say the least. ALU instructions
* must be grouped into VLIW bundles according to following model:
if (!ins->has_constants)
return true;
- if (ins->alu.reg_mode == midgard_reg_mode_16) {
+ if (ins->alu.reg_mode != midgard_reg_mode_32) {
/* TODO: 16-bit constant combining */
if (pred->constant_count)
return false;
return temp;
}
-/* Reassigns numbering to get rid of gaps in the indices */
+/* Reassigns numbering to get rid of gaps in the indices and to prioritize
+ * smaller register classes */
static void
mir_squeeze_index(compiler_context *ctx)
/* TODO don't leak old hash_to_temp */
ctx->hash_to_temp = _mesa_hash_table_u64_create(NULL);
+ /* We need to prioritize texture registers on older GPUs so we don't
+ * fail RA trying to assign to work registers r0/r1 when a work
+ * register is already there */
+
+ mir_foreach_instr_global(ctx, ins) {
+ if (ins->type == TAG_TEXTURE_4)
+ ins->dest = find_or_allocate_temp(ctx, ins->dest);
+ }
+
mir_foreach_instr_global(ctx, ins) {
- ins->dest = find_or_allocate_temp(ctx, ins->dest);
+ if (ins->type != TAG_TEXTURE_4)
+ ins->dest = find_or_allocate_temp(ctx, ins->dest);
for (unsigned i = 0; i < ARRAY_SIZE(ins->src); ++i)
ins->src[i] = find_or_allocate_temp(ctx, ins->src[i]);
/* For register spilling - to thread local storage */
.arg_1 = 0xEA,
.arg_2 = 0x1E,
-
- /* Splattered across, TODO combine logically */
- .varying_parameters = (byte & 0x1FF) << 1,
- .address = (byte >> 9)
},
/* If we spill an unspill, RA goes into an infinite loop */
.no_spill = true
};
+ ins.constants[0] = byte;
+
if (is_store) {
/* r0 = r26, r1 = r27 */
assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
* spill node. All nodes are equal in spill cost, but we can't spill
* nodes written to from an unspill */
- for (unsigned i = 0; i < ctx->temp_count; ++i) {
- lcra_set_node_spill_cost(l, i, 1);
+ unsigned *cost = calloc(ctx->temp_count, sizeof(cost[0]));
+
+ mir_foreach_instr_global(ctx, ins) {
+ if (ins->dest < ctx->temp_count)
+ cost[ins->dest]++;
+
+ mir_foreach_src(ins, s) {
+ if (ins->src[s] < ctx->temp_count)
+ cost[ins->src[s]]++;
+ }
}
+ for (unsigned i = 0; i < ctx->temp_count; ++i)
+ lcra_set_node_spill_cost(l, i, cost[i]);
+
/* We can't spill any bundles that contain unspills. This could be
* optimized to allow use of r27 to spill twice per bundle, but if
* you're at the point of optimizing spilling, it's too late.