tcg: Reorg TCGOp chaining
Instead of using -1 as end of chain, use 0, and link through the 0 entry as a fully circular double-linked list. Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
		
							parent
							
								
									a1b3c48d2b
								
							
						
					
					
						commit
						dcb8e75870
					
				| 
						 | 
				
			
			@ -59,7 +59,7 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Terminate the linked list.  */
 | 
			
		||||
    tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1;
 | 
			
		||||
    tcg_ctx.gen_op_buf[tcg_ctx.gen_op_buf[0].prev].next = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void gen_io_start(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,11 +103,7 @@ static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
 | 
			
		|||
        .prev = prev,
 | 
			
		||||
        .next = next
 | 
			
		||||
    };
 | 
			
		||||
    if (prev >= 0) {
 | 
			
		||||
        s->gen_op_buf[prev].next = oi;
 | 
			
		||||
    } else {
 | 
			
		||||
        s->gen_first_op_idx = oi;
 | 
			
		||||
    }
 | 
			
		||||
    s->gen_op_buf[prev].next = oi;
 | 
			
		||||
    old_op->prev = oi;
 | 
			
		||||
 | 
			
		||||
    return new_op;
 | 
			
		||||
| 
						 | 
				
			
			@ -583,7 +579,7 @@ void tcg_optimize(TCGContext *s)
 | 
			
		|||
    nb_globals = s->nb_globals;
 | 
			
		||||
    reset_all_temps(nb_temps);
 | 
			
		||||
 | 
			
		||||
    for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) {
 | 
			
		||||
    for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
 | 
			
		||||
        tcg_target_ulong mask, partmask, affected;
 | 
			
		||||
        int nb_oargs, nb_iargs, i;
 | 
			
		||||
        TCGArg tmp;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args)
 | 
			
		|||
    int pi = oi - 1;
 | 
			
		||||
 | 
			
		||||
    tcg_debug_assert(oi < OPC_BUF_SIZE);
 | 
			
		||||
    ctx->gen_last_op_idx = oi;
 | 
			
		||||
    ctx->gen_op_buf[0].prev = oi;
 | 
			
		||||
    ctx->gen_next_op_idx = ni;
 | 
			
		||||
 | 
			
		||||
    ctx->gen_op_buf[oi] = (TCGOp){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								tcg/tcg.c
								
								
								
								
							
							
						
						
									
										35
									
								
								tcg/tcg.c
								
								
								
								
							| 
						 | 
				
			
			@ -438,9 +438,9 @@ void tcg_func_start(TCGContext *s)
 | 
			
		|||
    s->goto_tb_issue_mask = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    s->gen_first_op_idx = 0;
 | 
			
		||||
    s->gen_last_op_idx = -1;
 | 
			
		||||
    s->gen_next_op_idx = 0;
 | 
			
		||||
    s->gen_op_buf[0].next = 1;
 | 
			
		||||
    s->gen_op_buf[0].prev = 0;
 | 
			
		||||
    s->gen_next_op_idx = 1;
 | 
			
		||||
    s->gen_next_parm_idx = 0;
 | 
			
		||||
 | 
			
		||||
    s->be = tcg_malloc(sizeof(TCGBackendData));
 | 
			
		||||
| 
						 | 
				
			
			@ -869,7 +869,7 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
 | 
			
		|||
    /* Make sure the calli field didn't overflow.  */
 | 
			
		||||
    tcg_debug_assert(s->gen_op_buf[i].calli == real_args);
 | 
			
		||||
 | 
			
		||||
    s->gen_last_op_idx = i;
 | 
			
		||||
    s->gen_op_buf[0].prev = i;
 | 
			
		||||
    s->gen_next_op_idx = i + 1;
 | 
			
		||||
    s->gen_next_parm_idx = pi;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1021,7 +1021,7 @@ void tcg_dump_ops(TCGContext *s)
 | 
			
		|||
    TCGOp *op;
 | 
			
		||||
    int oi;
 | 
			
		||||
 | 
			
		||||
    for (oi = s->gen_first_op_idx; oi >= 0; oi = op->next) {
 | 
			
		||||
    for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) {
 | 
			
		||||
        int i, k, nb_oargs, nb_iargs, nb_cargs;
 | 
			
		||||
        const TCGOpDef *def;
 | 
			
		||||
        const TCGArg *args;
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,7 +1033,7 @@ void tcg_dump_ops(TCGContext *s)
 | 
			
		|||
        args = &s->gen_opparam_buf[op->args];
 | 
			
		||||
 | 
			
		||||
        if (c == INDEX_op_insn_start) {
 | 
			
		||||
            qemu_log("%s ----", oi != s->gen_first_op_idx ? "\n" : "");
 | 
			
		||||
            qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : "");
 | 
			
		||||
 | 
			
		||||
            for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
 | 
			
		||||
                target_ulong a;
 | 
			
		||||
| 
						 | 
				
			
			@ -1298,18 +1298,13 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
 | 
			
		|||
    int next = op->next;
 | 
			
		||||
    int prev = op->prev;
 | 
			
		||||
 | 
			
		||||
    if (next >= 0) {
 | 
			
		||||
        s->gen_op_buf[next].prev = prev;
 | 
			
		||||
    } else {
 | 
			
		||||
        s->gen_last_op_idx = prev;
 | 
			
		||||
    }
 | 
			
		||||
    if (prev >= 0) {
 | 
			
		||||
        s->gen_op_buf[prev].next = next;
 | 
			
		||||
    } else {
 | 
			
		||||
        s->gen_first_op_idx = next;
 | 
			
		||||
    }
 | 
			
		||||
    /* We should never attempt to remove the list terminator.  */
 | 
			
		||||
    tcg_debug_assert(op != &s->gen_op_buf[0]);
 | 
			
		||||
 | 
			
		||||
    memset(op, -1, sizeof(*op));
 | 
			
		||||
    s->gen_op_buf[next].prev = prev;
 | 
			
		||||
    s->gen_op_buf[prev].next = next;
 | 
			
		||||
 | 
			
		||||
    memset(op, 0, sizeof(*op));
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PROFILER
 | 
			
		||||
    s->del_op_count++;
 | 
			
		||||
| 
						 | 
				
			
			@ -1356,7 +1351,7 @@ static void tcg_liveness_analysis(TCGContext *s)
 | 
			
		|||
    mem_temps = tcg_malloc(s->nb_temps);
 | 
			
		||||
    tcg_la_func_end(s, dead_temps, mem_temps);
 | 
			
		||||
 | 
			
		||||
    for (oi = s->gen_last_op_idx; oi >= 0; oi = oi_prev) {
 | 
			
		||||
    for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) {
 | 
			
		||||
        int i, nb_iargs, nb_oargs;
 | 
			
		||||
        TCGOpcode opc_new, opc_new2;
 | 
			
		||||
        bool have_opc_new2;
 | 
			
		||||
| 
						 | 
				
			
			@ -2351,7 +2346,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
 | 
			
		|||
    {
 | 
			
		||||
        int n;
 | 
			
		||||
 | 
			
		||||
        n = s->gen_last_op_idx + 1;
 | 
			
		||||
        n = s->gen_op_buf[0].prev + 1;
 | 
			
		||||
        s->op_count += n;
 | 
			
		||||
        if (n > s->op_count_max) {
 | 
			
		||||
            s->op_count_max = n;
 | 
			
		||||
| 
						 | 
				
			
			@ -2410,7 +2405,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
 | 
			
		|||
    tcg_out_tb_init(s);
 | 
			
		||||
 | 
			
		||||
    num_insns = -1;
 | 
			
		||||
    for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) {
 | 
			
		||||
    for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
 | 
			
		||||
        TCGOp * const op = &s->gen_op_buf[oi];
 | 
			
		||||
        TCGArg * const args = &s->gen_opparam_buf[op->args];
 | 
			
		||||
        TCGOpcode opc = op->opc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								tcg/tcg.h
								
								
								
								
							
							
						
						
									
										22
									
								
								tcg/tcg.h
								
								
								
								
							| 
						 | 
				
			
			@ -590,17 +590,21 @@ typedef struct TCGOp {
 | 
			
		|||
    unsigned callo  : 2;
 | 
			
		||||
    unsigned calli  : 6;
 | 
			
		||||
 | 
			
		||||
    /* Index of the arguments for this op, or -1 for zero-operand ops.  */
 | 
			
		||||
    signed args     : 16;
 | 
			
		||||
    /* Index of the arguments for this op, or 0 for zero-operand ops.  */
 | 
			
		||||
    unsigned args   : 16;
 | 
			
		||||
 | 
			
		||||
    /* Index of the prex/next op, or -1 for the end of the list.  */
 | 
			
		||||
    signed prev     : 16;
 | 
			
		||||
    signed next     : 16;
 | 
			
		||||
    /* Index of the prev/next op, or 0 for the end of the list.  */
 | 
			
		||||
    unsigned prev   : 16;
 | 
			
		||||
    unsigned next   : 16;
 | 
			
		||||
} TCGOp;
 | 
			
		||||
 | 
			
		||||
QEMU_BUILD_BUG_ON(NB_OPS > 0xff);
 | 
			
		||||
QEMU_BUILD_BUG_ON(OPC_BUF_SIZE >= 0x7fff);
 | 
			
		||||
QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE >= 0x7fff);
 | 
			
		||||
/* Make sure operands fit in the bitfields above.  */
 | 
			
		||||
QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
 | 
			
		||||
QEMU_BUILD_BUG_ON(OPC_BUF_SIZE > (1 << 16));
 | 
			
		||||
QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE > (1 << 16));
 | 
			
		||||
 | 
			
		||||
/* Make sure that we don't overflow 64 bits without noticing.  */
 | 
			
		||||
QEMU_BUILD_BUG_ON(sizeof(TCGOp) > 8);
 | 
			
		||||
 | 
			
		||||
struct TCGContext {
 | 
			
		||||
    uint8_t *pool_cur, *pool_end;
 | 
			
		||||
| 
						 | 
				
			
			@ -653,8 +657,6 @@ struct TCGContext {
 | 
			
		|||
    int goto_tb_issue_mask;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    int gen_first_op_idx;
 | 
			
		||||
    int gen_last_op_idx;
 | 
			
		||||
    int gen_next_op_idx;
 | 
			
		||||
    int gen_next_parm_idx;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue