/* In liveness analysis, these are live masks (per-component) for
* indices for the block. Scalar compilers have the luxury of using
- * simple bit fields, but for us, liveness is a vector idea. We use
- * 8-bit to allow finegrained tracking up to vec8. If you're
- * implementing vec16 on Panfrost... I'm sorry. */
- uint8_t *live_in;
- uint8_t *live_out;
+ * simple bit fields, but for us, liveness is a vector idea. */
+ uint16_t *live_in;
+ uint16_t *live_out;
} midgard_block;
typedef struct midgard_bundle {
void mir_lower_special_reads(compiler_context *ctx);
struct ra_graph* allocate_registers(compiler_context *ctx, bool *spilled);
void install_registers(compiler_context *ctx, struct ra_graph *g);
-void mir_liveness_ins_update(uint8_t *live, midgard_instruction *ins, unsigned max);
+void mir_liveness_ins_update(uint16_t *live, midgard_instruction *ins, unsigned max);
void mir_compute_liveness(compiler_context *ctx);
void mir_invalidate_liveness(compiler_context *ctx);
bool mir_is_live_after(compiler_context *ctx, midgard_block *block, midgard_instruction *start, int src);
#include "compiler.h"
#include "util/u_memory.h"
-/* Routines for liveness analysis */
+/* Routines for liveness analysis. Liveness is tracked per byte per node. Per
+ * byte granularity is necessary for proper handling of int8 */
static void
-liveness_gen(uint8_t *live, unsigned node, unsigned max, unsigned mask)
+liveness_gen(uint16_t *live, unsigned node, unsigned max, uint16_t mask)
{
if (node >= max)
return;
}
static void
-liveness_kill(uint8_t *live, unsigned node, unsigned max, unsigned mask)
+liveness_kill(uint16_t *live, unsigned node, unsigned max, uint16_t mask)
{
if (node >= max)
return;
}
static bool
-liveness_get(uint8_t *live, unsigned node, unsigned max) {
+liveness_get(uint16_t *live, unsigned node, uint16_t max) {
if (node >= max)
return false;
/* Updates live_in for a single instruction */
void
-mir_liveness_ins_update(uint8_t *live, midgard_instruction *ins, unsigned max)
+mir_liveness_ins_update(uint16_t *live, midgard_instruction *ins, unsigned max)
{
/* live_in[s] = GEN[s] + (live_out[s] - KILL[s]) */
liveness_block_live_out(ctx, blk);
- uint8_t *live = mem_dup(blk->live_out, ctx->temp_count);
+ uint16_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint16_t));
mir_foreach_instr_in_block_rev(blk, ins)
mir_liveness_ins_update(live, ins, ctx->temp_count);
/* Allocate */
mir_foreach_block(ctx, block) {
- block->live_in = calloc(ctx->temp_count, 1);
- block->live_out = calloc(ctx->temp_count, 1);
+ block->live_in = calloc(ctx->temp_count, sizeof(uint16_t));
+ block->live_out = calloc(ctx->temp_count, sizeof(uint16_t));
}
/* Initialize the work list with the exit block */
* end of each block and walk the block backwards. */
mir_foreach_block(ctx, blk) {
- uint8_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint8_t));
+ uint16_t *live = mem_dup(blk->live_out, ctx->temp_count * sizeof(uint16_t));
mir_foreach_instr_in_block_rev(blk, ins) {
/* Mark all registers live after the instruction as