diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2019-04-21 13:34:35 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2019-04-24 13:05:21 -0700 |
commit | 7ecd02a06f8f4c0bbf872ecc15e37035b7e1df5f (patch) | |
tree | 256d78a31338de5ca775b6529409d3d6d7ae6bb2 /tcg/tcg.h | |
parent | 6e6c4efed995d9eca6ae0cfdb2252df830262f50 (diff) |
tcg: Restart TB generation after relocation overflow
If the TB generates too much code, such that backend relocations
overflow, try again with a smaller TB. In support of this, move
relocation processing from a random place within tcg_out_op, in
the handling of branch opcodes, to a new function at the end of
tcg_gen_code.
This is not a complete solution, as there are additional relocs
generated for out-of-line ldst handling and constant pools.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg.h')
-rw-r--r-- | tcg/tcg.h | 15 |
1 files changed, 7 insertions, 8 deletions
@@ -238,12 +238,13 @@ typedef uint64_t tcg_insn_unit; do { if (!(X)) { __builtin_unreachable(); } } while (0) #endif -typedef struct TCGRelocation { - struct TCGRelocation *next; - int type; +typedef struct TCGRelocation TCGRelocation; +struct TCGRelocation { + QSIMPLEQ_ENTRY(TCGRelocation) next; tcg_insn_unit *ptr; intptr_t addend; -} TCGRelocation; + int type; +}; typedef struct TCGLabel TCGLabel; struct TCGLabel { @@ -254,11 +255,9 @@ struct TCGLabel { union { uintptr_t value; tcg_insn_unit *value_ptr; - TCGRelocation *first_reloc; } u; -#ifdef CONFIG_DEBUG_TCG + QSIMPLEQ_HEAD(, TCGRelocation) relocs; QSIMPLEQ_ENTRY(TCGLabel) next; -#endif }; typedef struct TCGPool { @@ -691,7 +690,6 @@ struct TCGContext { #endif #ifdef CONFIG_DEBUG_TCG - QSIMPLEQ_HEAD(, TCGLabel) labels; int temps_in_use; int goto_tb_issue_mask; #endif @@ -729,6 +727,7 @@ struct TCGContext { TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ QTAILQ_HEAD(, TCGOp) ops, free_ops; + QSIMPLEQ_HEAD(, TCGLabel) labels; /* Tells which temporary holds a given register. It does not take into account fixed registers */ |