static uint32_t reg(struct ir3_register *reg, struct ir3_info *info,
                uint32_t repeat, uint32_t valid_flags)
 {
+       struct ir3_shader_variant *v = info->data;
+       bool mergedregs = v->shader->compiler->gpu_id >= 600;
        reg_t val = { .dummy32 = 0 };
 
        if (reg->flags & ~valid_flags) {
                        /* ignore writes to dummy register r63.x */
                } else if (max < regid(48, 0)) {
                        if (reg->flags & IR3_REG_HALF) {
-                               if (info->gpu_id >= 600) {
+                               if (mergedregs) {
                                        /* starting w/ a6xx, half regs conflict with full regs: */
                                        info->max_reg = MAX2(info->max_reg, max >> 3);
                                } else {
 static int emit_cat0(struct ir3_instruction *instr, void *ptr,
                struct ir3_info *info)
 {
+       struct ir3_shader_variant *v = info->data;
        instr_cat0_t *cat0 = ptr;
 
-       if (info->gpu_id >= 500) {
+       if (v->shader->compiler->gpu_id >= 500) {
                cat0->a5xx.immed = instr->cat0.immed;
-       } else if (info->gpu_id >= 400) {
+       } else if (v->shader->compiler->gpu_id >= 400) {
                cat0->a4xx.immed = instr->cat0.immed;
        } else {
                cat0->a3xx.immed = instr->cat0.immed;
 static int emit_cat6(struct ir3_instruction *instr, void *ptr,
                struct ir3_info *info)
 {
+       struct ir3_shader_variant *v = info->data;
        struct ir3_register *dst, *src1, *src2;
        instr_cat6_t *cat6 = ptr;
 
        /* In a6xx we start using a new instruction encoding for some of
         * these instructions:
         */
-       if (info->gpu_id >= 600) {
+       if (v->shader->compiler->gpu_id >= 600) {
                switch (instr->opc) {
                case OPC_ATOMIC_ADD:
                case OPC_ATOMIC_SUB:
        emit_cat7,
 };
 
-void * ir3_assemble(struct ir3 *shader, struct ir3_info *info,
-               uint32_t gpu_id)
+void * ir3_assemble(struct ir3_shader_variant *v)
 {
        uint32_t *ptr, *dwords;
+       struct ir3_info *info = &v->info;
+       struct ir3 *shader = v->ir;
 
        memset(info, 0, sizeof(*info));
-       info->gpu_id        = gpu_id;
+       info->data          = v;
        info->max_reg       = -1;
        info->max_half_reg  = -1;
        info->max_const     = -1;
         * instructions on a4xx or sets of 4 instructions on a3xx),
         * so pad out w/ NOPs if needed: (NOTE each instruction is 64bits)
         */
-       if (gpu_id >= 400) {
+       if (v->shader->compiler->gpu_id >= 400) {
                info->sizedwords = align(info->sizedwords, 16 * 2);
        } else {
                info->sizedwords = align(info->sizedwords, 4 * 2);
 
 struct ir3_block;
 
 struct ir3_info {
-       uint32_t gpu_id;
+       void *data;              /* used internally in ir3 assembler */
        uint16_t sizedwords;
        uint16_t instrs_count;   /* expanded to account for rpt's */
        uint16_t nops_count;     /* # of nop instructions, including nopN */
 
 struct ir3 * ir3_create(struct ir3_compiler *compiler, gl_shader_stage type);
 void ir3_destroy(struct ir3 *shader);
-void * ir3_assemble(struct ir3 *shader,
-               struct ir3_info *info, uint32_t gpu_id);
+
+struct ir3_shader_variant;
+void * ir3_assemble(struct ir3_shader_variant *v);
 void * ir3_alloc(struct ir3 *shader, int sz);
 
 struct ir3_block * ir3_block_create(struct ir3 *shader);
 
 /* wrapper for ir3_assemble() which does some info fixup based on
  * shader state.  Non-static since used by ir3_cmdline too.
  */
-void * ir3_shader_assemble(struct ir3_shader_variant *v, uint32_t gpu_id)
+void * ir3_shader_assemble(struct ir3_shader_variant *v)
 {
+       unsigned gpu_id = v->shader->compiler->gpu_id;
        void *bin;
 
-       bin = ir3_assemble(v->ir, &v->info, gpu_id);
+       bin = ir3_assemble(v);
        if (!bin)
                return NULL;
 
 static void
 assemble_variant(struct ir3_shader_variant *v)
 {
-       struct ir3_compiler *compiler = v->shader->compiler;
-       uint32_t gpu_id = compiler->gpu_id;
-
-       v->bin = ir3_shader_assemble(v, gpu_id);
+       v->bin = ir3_shader_assemble(v);
 
        if (shader_debug_enabled(v->shader->type)) {
                fprintf(stdout, "Native code for unnamed %s shader %s:\n",
 
        struct ir3_shader_key key_mask;
 };
 
-void * ir3_shader_assemble(struct ir3_shader_variant *v, uint32_t gpu_id);
+void * ir3_shader_assemble(struct ir3_shader_variant *v);
 struct ir3_shader_variant * ir3_shader_get_variant(struct ir3_shader *shader,
                struct ir3_shader_key *key, bool binning_pass, bool *created);
 struct ir3_shader * ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,