summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8907aed2c3f..e319b26755c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -28446,11 +28446,15 @@ rs6000_output_function_epilogue (FILE *file,
{
#if TARGET_MACHO
macho_branch_islands ();
- /* Mach-O doesn't support labels at the end of objects, so if
- it looks like we might want one, insert a NOP. */
+
{
rtx_insn *insn = get_last_insn ();
rtx_insn *deleted_debug_label = NULL;
+
+ /* Mach-O doesn't support labels at the end of objects, so if
+ it looks like we might want one, take special action.
+
+ First, collect any sequence of deleted debug labels. */
while (insn
&& NOTE_P (insn)
&& NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
@@ -28463,11 +28467,40 @@ rs6000_output_function_epilogue (FILE *file,
deleted_debug_label = insn;
insn = PREV_INSN (insn);
}
- if (insn
- && (LABEL_P (insn)
+
+ /* Second, if we have:
+ label:
+ barrier
+ then this needs to be detected, so skip past the barrier. */
+
+ if (insn && BARRIER_P (insn))
+ insn = PREV_INSN (insn);
+
+ /* Up to now we've only seen notes or barriers. */
+ if (insn)
+ {
+ if (LABEL_P (insn)
|| (NOTE_P (insn)
- && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
- fputs ("\tnop\n", file);
+ && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
+ /* Trailing label: <barrier>. */
+ fputs ("\tnop\n", file);
+ else
+ {
+ /* Lastly, see if we have a completely empty function body. */
+ while (insn && ! INSN_P (insn))
+ insn = PREV_INSN (insn);
+ /* If we don't find any insns, we've got an empty function body;
+ I.e. completely empty - without a return or branch. This is
+ taken as the case where a function body has been removed
+ because it contains an inline __builtin_unreachable(). GCC
+ states that reaching __builtin_unreachable() means UB so we're
+ not obliged to do anything special; however, we want
+ non-zero-sized function bodies. To meet this, and help the
+ user out, let's trap the case. */
+ if (insn == NULL)
+ fputs ("\ttrap\n", file);
+ }
+ }
else if (deleted_debug_label)
for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)