tcg: Re-order tcg_region_init vs tcg_prologue_init

Instead of delaying tcg_region_init until after tcg_prologue_init
is complete, do tcg_region_init first and let tcg_prologue_init
shrink the first region by the size of the generated prologue.

Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-03-09 08:45:58 -08:00
parent c634754172
commit b0a0794a0f
5 changed files with 22 additions and 46 deletions

View File

@ -111,17 +111,6 @@ static int tcg_init(MachineState *ms)
tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
mttcg_enabled = s->mttcg_enabled;
/*
* Initialize TCG regions only for softmmu.
*
* This needs to be done later for user mode, because the prologue
* generation needs to be delayed so that GUEST_BASE is already set.
*/
#ifndef CONFIG_USER_ONLY
tcg_region_init();
#endif /* !CONFIG_USER_ONLY */
return 0;
}

View File

@ -1339,6 +1339,9 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
splitwx, &error_fatal);
assert(ok);
/* TODO: allocating regions is hand-in-glove with code_gen_buffer. */
tcg_region_init();
#if defined(CONFIG_SOFTMMU)
/* There's no guest base to take into account, so go ahead and
initialize the prologue now. */

View File

@ -879,7 +879,6 @@ int main(int argc, char **argv)
* the real value of GUEST_BASE into account.
*/
tcg_prologue_init(tcg_ctx);
tcg_region_init();
/* build Task State */
memset(ts, 0, sizeof(TaskState));

View File

@ -868,7 +868,6 @@ int main(int argc, char **argv, char **envp)
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account. */
tcg_prologue_init(tcg_ctx);
tcg_region_init();
target_cpu_copy_regs(env, regs);

View File

@ -1206,32 +1206,18 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
void tcg_prologue_init(TCGContext *s)
{
size_t prologue_size, total_size;
void *buf0, *buf1;
size_t prologue_size;
/* Put the prologue at the beginning of code_gen_buffer. */
buf0 = s->code_gen_buffer;
total_size = s->code_gen_buffer_size;
s->code_ptr = buf0;
s->code_buf = buf0;
tcg_region_assign(s, 0);
s->code_ptr = s->code_gen_ptr;
s->code_buf = s->code_gen_ptr;
s->data_gen_ptr = NULL;
/*
* The region trees are not yet configured, but tcg_splitwx_to_rx
* needs the bounds for an assert.
*/
region.start = buf0;
region.end = buf0 + total_size;
#ifndef CONFIG_TCG_INTERPRETER
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
#endif
/* Compute a high-water mark, at which we voluntarily flush the buffer
and start over. The size here is arbitrary, significantly larger
than we expect the code generation for any one opcode to require. */
s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
#ifdef TCG_TARGET_NEED_POOL_LABELS
s->pool_labels = NULL;
#endif
@ -1248,32 +1234,32 @@ void tcg_prologue_init(TCGContext *s)
}
#endif
buf1 = s->code_ptr;
prologue_size = tcg_current_code_size(s);
#ifndef CONFIG_TCG_INTERPRETER
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
tcg_ptr_byte_diff(buf1, buf0));
flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
(uintptr_t)s->code_buf, prologue_size);
#endif
/* Deduct the prologue from the buffer. */
prologue_size = tcg_current_code_size(s);
s->code_gen_ptr = buf1;
s->code_gen_buffer = buf1;
s->code_buf = buf1;
total_size -= prologue_size;
s->code_gen_buffer_size = total_size;
/* Deduct the prologue from the first region. */
region.start = s->code_ptr;
tcg_register_jit(tcg_splitwx_to_rx(s->code_gen_buffer), total_size);
/* Recompute boundaries of the first region. */
tcg_region_assign(s, 0);
tcg_register_jit(tcg_splitwx_to_rx(region.start),
region.end - region.start);
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
FILE *logfile = qemu_log_lock();
qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
if (s->data_gen_ptr) {
size_t code_size = s->data_gen_ptr - buf0;
size_t code_size = s->data_gen_ptr - s->code_gen_ptr;
size_t data_size = prologue_size - code_size;
size_t i;
log_disas(buf0, code_size);
log_disas(s->code_gen_ptr, code_size);
for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
if (sizeof(tcg_target_ulong) == 8) {
@ -1287,7 +1273,7 @@ void tcg_prologue_init(TCGContext *s)
}
}
} else {
log_disas(buf0, prologue_size);
log_disas(s->code_gen_ptr, prologue_size);
}
qemu_log("\n");
qemu_log_flush();