summaryrefslogtreecommitdiff
path: root/patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch
diff options
context:
space:
mode:
authorAlexey Neyman <stilor@att.net>2017-02-28 08:57:53 (GMT)
committerAlexey Neyman <stilor@att.net>2017-02-28 08:57:53 (GMT)
commit99283866cc84102f22324a751a2ba3afb9221cb6 (patch)
treeee8b04c33cf0797e985d0f5476d310e9abb8ba78 /patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch
parent439cab379e169f505494376f55f1438d12de94fa (diff)
Add patches to Linaro GCC
Same as the base release as long as they applied. MUSL patches didn't, removed. Also, unobsolete Linaro GCC5 now that they rolled out a new release. Signed-off-by: Alexey Neyman <stilor@att.net>
Diffstat (limited to 'patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch')
-rw-r--r--patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch318
1 files changed, 318 insertions, 0 deletions
diff --git a/patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch b/patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch
new file mode 100644
index 0000000..c6ae103
--- /dev/null
+++ b/patches/gcc/linaro-6.3-2017.02/871-xtensa-Fix-PR-target-78118.patch
@@ -0,0 +1,318 @@
+From bdda1689faf608ad7c83b5bd2e21a236b0047579 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Wed, 26 Oct 2016 08:02:51 +0000
+Subject: [PATCH] xtensa: Fix PR target/78118
+
+It started failing after the following commit: 32e90dc6a0cda45 ("PR
+rtl-optimization/61047").
+
+The change that made xtensa backend go ICE looks completely unrelated,
+and indeed, the issue is caused by the side effect of
+compute_frame_size() function call hidden in the
+INITIAL_ELIMINATION_OFFSET macro. This call updates the value of the
+xtensa_current_frame_size static variable, used in "return" instruction
+predicate. Prior to the change the value of xtensa_current_frame_size was
+set to 0 after the end of epilogue generation, which enabled the "return"
+instruction for the CALL0 ABI, but after the change the additional
+INITIAL_ELIMINATION_OFFSET calls make xtensa_current_frame_size non-zero
+and "return" pattern unavailable.
+
+Get rid of the global xtensa_current_frame_size and
+xtensa_callee_save_size variables by moving them into the
+machine_function structure. Implement predicate for the "return" pattern
+as a function. Don't communicate completion of epilogue generation
+through zeroing of xtensa_current_frame_size, add explicit epilogue_done
+variable to the machine_function structure. Don't update stack frame
+layout after the completion of reload.
+
+2016-10-26 Max Filippov <jcmvbkbc@gmail.com>
+gcc/
+ * config/xtensa/xtensa-protos.h
+ (xtensa_use_return_instruction_p): New prototype.
+ * config/xtensa/xtensa.c (xtensa_current_frame_size,
+ xtensa_callee_save_size): Remove.
+ (struct machine_function): Add new fields: current_frame_size,
+ callee_save_size, frame_laid_out and epilogue_done.
+ (compute_frame_size, xtensa_expand_prologue,
+ xtensa_expand_epilogue): Replace xtensa_callee_save_size with
+ cfun->machine->callee_save_size and xtensa_current_frame_size
+ with cfun->machine->current_frame_size.
+ (compute_frame_size): Update cfun->machine->frame_laid_out and
+ don't update frame layout after reload completion.
+ (xtensa_expand_epilogue): Set cfun->machine->epilogue_done
+ instead of zeroing xtensa_current_frame_size.
+ (xtensa_use_return_instruction_p): New function.
+ * config/xtensa/xtensa.h (xtensa_current_frame_size): Remove
+ declaration.
+ (INITIAL_ELIMINATION_OFFSET): Use return value of
+ compute_frame_size instead of xtensa_current_frame_size value.
+ * config/xtensa/xtensa.md ("return" pattern): Use new predicate
+ function xtensa_use_return_instruction_p instead of inline code.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+ gcc/config/xtensa/xtensa-protos.h | 1 +
+ gcc/config/xtensa/xtensa.c | 82 ++++++++++++++++++++++++---------------
+ gcc/config/xtensa/xtensa.h | 6 +--
+ gcc/config/xtensa/xtensa.md | 2 +-
+ 4 files changed, 55 insertions(+), 36 deletions(-)
+
+diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
+index f2ca526..873557f 100644
+--- a/gcc/config/xtensa/xtensa-protos.h
++++ b/gcc/config/xtensa/xtensa-protos.h
+@@ -68,6 +68,7 @@ extern rtx xtensa_return_addr (int, rtx);
+ extern void xtensa_setup_frame_addresses (void);
+ extern int xtensa_dbx_register_number (int);
+ extern long compute_frame_size (int);
++extern bool xtensa_use_return_instruction_p (void);
+ extern void xtensa_expand_prologue (void);
+ extern void xtensa_expand_epilogue (void);
+ extern void order_regs_for_local_alloc (void);
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index 64d089b..e49f784 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -78,11 +78,6 @@ enum internal_test
+ can support a given mode. */
+ char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
+
+-/* Current frame size calculated by compute_frame_size. */
+-unsigned xtensa_current_frame_size;
+-/* Callee-save area size in the current frame calculated by compute_frame_size. */
+-int xtensa_callee_save_size;
+-
+ /* Largest block move to handle in-line. */
+ #define LARGEST_MOVE_RATIO 15
+
+@@ -94,6 +89,13 @@ struct GTY(()) machine_function
+ bool vararg_a7;
+ rtx vararg_a7_copy;
+ rtx_insn *set_frame_ptr_insn;
++ /* Current frame size calculated by compute_frame_size. */
++ unsigned current_frame_size;
++ /* Callee-save area size in the current frame calculated by
++ compute_frame_size. */
++ int callee_save_size;
++ bool frame_laid_out;
++ bool epilogue_done;
+ };
+
+ /* Vector, indexed by hard register number, which contains 1 for a
+@@ -2628,24 +2630,29 @@ compute_frame_size (int size)
+ {
+ int regno;
+
++ if (reload_completed && cfun->machine->frame_laid_out)
++ return cfun->machine->current_frame_size;
++
+ /* Add space for the incoming static chain value. */
+ if (cfun->static_chain_decl != NULL)
+ size += (1 * UNITS_PER_WORD);
+
+- xtensa_callee_save_size = 0;
++ cfun->machine->callee_save_size = 0;
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
+ {
+ if (xtensa_call_save_reg(regno))
+- xtensa_callee_save_size += UNITS_PER_WORD;
++ cfun->machine->callee_save_size += UNITS_PER_WORD;
+ }
+
+- xtensa_current_frame_size =
++ cfun->machine->current_frame_size =
+ XTENSA_STACK_ALIGN (size
+- + xtensa_callee_save_size
++ + cfun->machine->callee_save_size
+ + crtl->outgoing_args_size
+ + (WINDOW_SIZE * UNITS_PER_WORD));
+- xtensa_callee_save_size = XTENSA_STACK_ALIGN (xtensa_callee_save_size);
+- return xtensa_current_frame_size;
++ cfun->machine->callee_save_size =
++ XTENSA_STACK_ALIGN (cfun->machine->callee_save_size);
++ cfun->machine->frame_laid_out = true;
++ return cfun->machine->current_frame_size;
+ }
+
+
+@@ -2696,6 +2703,7 @@ xtensa_expand_prologue (void)
+ {
+ int regno;
+ HOST_WIDE_INT offset = 0;
++ int callee_save_size = cfun->machine->callee_save_size;
+
+ /* -128 is a limit of single addi instruction. */
+ if (total_size > 0 && total_size <= 128)
+@@ -2709,7 +2717,7 @@ xtensa_expand_prologue (void)
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
+ offset = total_size - UNITS_PER_WORD;
+ }
+- else if (xtensa_callee_save_size)
++ else if (callee_save_size)
+ {
+ /* 1020 is maximal s32i offset, if the frame is bigger than that
+ * we move sp to the end of callee-saved save area, save and then
+@@ -2717,13 +2725,13 @@ xtensa_expand_prologue (void)
+ if (total_size > 1024)
+ {
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+- GEN_INT (-xtensa_callee_save_size)));
++ GEN_INT (-callee_save_size)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ note_rtx = gen_rtx_SET (stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+- -xtensa_callee_save_size));
++ -callee_save_size));
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
+- offset = xtensa_callee_save_size - UNITS_PER_WORD;
++ offset = callee_save_size - UNITS_PER_WORD;
+ }
+ else
+ {
+@@ -2759,13 +2767,13 @@ xtensa_expand_prologue (void)
+ {
+ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
+ emit_move_insn (tmp_reg, GEN_INT (total_size -
+- xtensa_callee_save_size));
++ callee_save_size));
+ insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, tmp_reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ note_rtx = gen_rtx_SET (stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+- xtensa_callee_save_size -
++ callee_save_size -
+ total_size));
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
+ }
+@@ -2833,21 +2841,21 @@ xtensa_expand_epilogue (void)
+ int regno;
+ HOST_WIDE_INT offset;
+
+- if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024))
++ if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024))
+ {
+ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
+- emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size -
+- xtensa_callee_save_size));
++ emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size -
++ cfun->machine->callee_save_size));
+ emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ?
+ hard_frame_pointer_rtx : stack_pointer_rtx,
+ tmp_reg));
+- offset = xtensa_callee_save_size - UNITS_PER_WORD;
++ offset = cfun->machine->callee_save_size - UNITS_PER_WORD;
+ }
+ else
+ {
+ if (frame_pointer_needed)
+ emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
+- offset = xtensa_current_frame_size - UNITS_PER_WORD;
++ offset = cfun->machine->current_frame_size - UNITS_PER_WORD;
+ }
+
+ /* Prevent reordering of saved a0 update and loading it back from
+@@ -2867,16 +2875,16 @@ xtensa_expand_epilogue (void)
+ }
+ }
+
+- if (xtensa_current_frame_size > 0)
++ if (cfun->machine->current_frame_size > 0)
+ {
+ if (frame_pointer_needed || /* always reachable with addi */
+- xtensa_current_frame_size > 1024 ||
+- xtensa_current_frame_size <= 127)
++ cfun->machine->current_frame_size > 1024 ||
++ cfun->machine->current_frame_size <= 127)
+ {
+- if (xtensa_current_frame_size <= 127)
+- offset = xtensa_current_frame_size;
++ if (cfun->machine->current_frame_size <= 127)
++ offset = cfun->machine->current_frame_size;
+ else
+- offset = xtensa_callee_save_size;
++ offset = cfun->machine->callee_save_size;
+
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+@@ -2885,7 +2893,8 @@ xtensa_expand_epilogue (void)
+ else
+ {
+ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
+- emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size));
++ emit_move_insn (tmp_reg,
++ GEN_INT (cfun->machine->current_frame_size));
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ tmp_reg));
+ }
+@@ -2896,11 +2905,22 @@ xtensa_expand_epilogue (void)
+ stack_pointer_rtx,
+ EH_RETURN_STACKADJ_RTX));
+ }
+- xtensa_current_frame_size = 0;
+- xtensa_callee_save_size = 0;
++ cfun->machine->epilogue_done = true;
+ emit_jump_insn (gen_return ());
+ }
+
++bool
++xtensa_use_return_instruction_p (void)
++{
++ if (!reload_completed)
++ return false;
++ if (TARGET_WINDOWED_ABI)
++ return true;
++ if (compute_frame_size (get_frame_size ()) == 0)
++ return true;
++ return cfun->machine->epilogue_done;
++}
++
+ void
+ xtensa_set_return_address (rtx address, rtx scratch)
+ {
+diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
+index 82e9900..58eb1b2 100644
+--- a/gcc/config/xtensa/xtensa.h
++++ b/gcc/config/xtensa/xtensa.h
+@@ -23,8 +23,6 @@ along with GCC; see the file COPYING3. If not see
+
+ /* External variables defined in xtensa.c. */
+
+-extern unsigned xtensa_current_frame_size;
+-
+ /* Macros used in the machine description to select various Xtensa
+ configuration options. */
+ #ifndef XCHAL_HAVE_MUL32_HIGH
+@@ -477,14 +475,14 @@ enum reg_class
+ /* Specify the initial difference between the specified pair of registers. */
+ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ do { \
+- compute_frame_size (get_frame_size ()); \
++ long frame_size = compute_frame_size (get_frame_size ()); \
+ switch (FROM) \
+ { \
+ case FRAME_POINTER_REGNUM: \
+ (OFFSET) = 0; \
+ break; \
+ case ARG_POINTER_REGNUM: \
+- (OFFSET) = xtensa_current_frame_size; \
++ (OFFSET) = frame_size; \
+ break; \
+ default: \
+ gcc_unreachable (); \
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index db54a12..fcdb6c8 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -1663,7 +1663,7 @@
+ (define_insn "return"
+ [(return)
+ (use (reg:SI A0_REG))]
+- "(TARGET_WINDOWED_ABI || !xtensa_current_frame_size) && reload_completed"
++ "xtensa_use_return_instruction_p ()"
+ {
+ return TARGET_WINDOWED_ABI ?
+ (TARGET_DENSITY ? "retw.n" : "retw") :
+--
+2.1.4
+