aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg.h
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2019-04-21 13:34:35 -0700
committerRichard Henderson <richard.henderson@linaro.org>2019-04-24 13:05:21 -0700
commit7ecd02a06f8f4c0bbf872ecc15e37035b7e1df5f (patch)
tree256d78a31338de5ca775b6529409d3d6d7ae6bb2 /tcg/tcg.h
parent6e6c4efed995d9eca6ae0cfdb2252df830262f50 (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.h15
1 files changed, 7 insertions, 8 deletions
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 50de1cdda3..cfc57110a1 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -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 */