backport: re PR target/51784 (PIC register not correctly preserved in nested funcs / with non-local goto)

gcc:
	Backport from mainline:
	2013-07-22  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (nonlocal_goto_receiver): Delete insn if
	it is not needed after split.

	2013-07-20  Iain Sandoe  <iain@codesourcery.com>

	PR target/51784
	* config/i386/i386.c (output_set_got) [TARGET_MACHO]: Adjust to emit a
	second label for nonlocal goto receivers. Don't output pic base labels
	unless we're producing PIC; mark that action unreachable().
	(ix86_save_reg): If the function contains a nonlocal label, save the
	PIC base reg.
	* config/darwin-protos.h (machopic_should_output_picbase_label): New.
	* gcc/config/darwin.c (emitted_pic_label_num): New GTY.
	(update_pic_label_number_if_needed): New.
	(machopic_output_function_base_name): Adjust for nonlocal receiver
	case.
	(machopic_should_output_picbase_label): New.
	* config/i386/i386.md (enum unspecv): UNSPECV_NLGR: New.
	(nonlocal_goto_receiver): New insn and split.

From-SVN: r202147
This commit is contained in:
Iain Sandoe 2013-09-01 15:39:28 +00:00 committed by Iain Sandoe
parent 4709b71fdb
commit 73168547c7
5 changed files with 102 additions and 21 deletions

View File

@ -1,3 +1,28 @@
2013-09-01 Iain Sandoe <iain@codesourcery.com>
Backport from mainline:
2013-07-22 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (nonlocal_goto_receiver): Delete insn if
it is not needed after split.
2013-07-20 Iain Sandoe <iain@codesourcery.com>
PR target/51784
* config/i386/i386.c (output_set_got) [TARGET_MACHO]: Adjust to emit a
second label for nonlocal goto receivers. Don't output pic base labels
unless we're producing PIC; mark that action unreachable().
(ix86_save_reg): If the function contains a nonlocal label, save the
PIC base reg.
* config/darwin-protos.h (machopic_should_output_picbase_label): New.
* gcc/config/darwin.c (emitted_pic_label_num): New GTY.
(update_pic_label_number_if_needed): New.
(machopic_output_function_base_name): Adjust for nonlocal receiver
case.
(machopic_should_output_picbase_label): New.
* config/i386/i386.md (enum unspecv): UNSPECV_NLGR: New.
(nonlocal_goto_receiver): New insn and split.
2013-08-28 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline

View File

@ -26,6 +26,7 @@ extern void machopic_validate_stub_or_non_lazy_ptr (const char *);
extern void machopic_output_function_base_name (FILE *);
extern const char *machopic_indirection_name (rtx, bool);
extern const char *machopic_mcount_stub_name (void);
extern bool machopic_should_output_picbase_label (void);
#ifdef RTX_CODE

View File

@ -362,14 +362,13 @@ machopic_gen_offset (rtx orig)
static GTY(()) const char * function_base_func_name;
static GTY(()) int current_pic_label_num;
static GTY(()) int emitted_pic_label_num;
void
machopic_output_function_base_name (FILE *file)
static void
update_pic_label_number_if_needed (void)
{
const char *current_name;
/* If dynamic-no-pic is on, we should not get here. */
gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
/* When we are generating _get_pc thunks within stubs, there is no current
function. */
if (current_function_decl)
@ -387,7 +386,28 @@ machopic_output_function_base_name (FILE *file)
++current_pic_label_num;
function_base_func_name = "L_machopic_stub_dummy";
}
fprintf (file, "L%011d$pb", current_pic_label_num);
}
void
machopic_output_function_base_name (FILE *file)
{
/* If dynamic-no-pic is on, we should not get here. */
gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
update_pic_label_number_if_needed ();
fprintf (file, "L%d$pb", current_pic_label_num);
}
bool
machopic_should_output_picbase_label (void)
{
update_pic_label_number_if_needed ();
if (current_pic_label_num == emitted_pic_label_num)
return false;
emitted_pic_label_num = current_pic_label_num;
return true;
}
/* The suffix attached to non-lazy pointer symbols. */

View File

@ -8613,17 +8613,12 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
if (!flag_pic)
{
if (TARGET_MACHO)
/* We don't need a pic base, we're not producing pic. */
gcc_unreachable ();
xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
#if TARGET_MACHO
/* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
is what will be referenced by the Mach-O PIC subsystem. */
if (!label)
ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
#endif
targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
}
@ -8636,12 +8631,18 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
xops[2] = gen_rtx_MEM (QImode, xops[2]);
output_asm_insn ("call\t%X2", xops);
/* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
is what will be referenced by the Mach-O PIC subsystem. */
#if TARGET_MACHO
if (!label)
/* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
This is what will be referenced by the Mach-O PIC subsystem. */
if (machopic_should_output_picbase_label () || !label)
ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
else
/* When we are restoring the pic base at the site of a nonlocal label,
and we decided to emit the pic base above, we will still output a
local label used for calculating the correction offset (even though
the offset will be 0 in that case). */
if (label)
targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (label));
#endif
@ -8717,7 +8718,8 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return)
&& (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
|| crtl->profile
|| crtl->calls_eh_return
|| crtl->uses_const_pool))
|| crtl->uses_const_pool
|| cfun->has_nonlocal_label))
return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
if (crtl->calls_eh_return && maybe_eh_return)

View File

@ -202,7 +202,10 @@
;; For RDRAND support
UNSPECV_RDRAND
])
;; Non-local goto.
UNSPECV_NLGR
])
;; Constants to represent rounding modes in the ROUND instruction
(define_constants
@ -16801,7 +16804,37 @@
emit_insn (gen_set_got (pic_offset_table_rtx));
DONE;
})
(define_insn_and_split "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
"TARGET_MACHO && !TARGET_64BIT && flag_pic"
"#"
"&& reload_completed"
[(const_int 0)]
{
if (crtl->uses_pic_offset_table)
{
rtx xops[3];
rtx label_rtx = gen_label_rtx ();
rtx tmp;
/* Get a new pic base. */
emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
/* Correct this with the offset from the new to the old. */
xops[0] = xops[1] = pic_offset_table_rtx;
label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
UNSPEC_MACHOPIC_OFFSET);
xops[2] = gen_rtx_CONST (Pmode, tmp);
ix86_expand_binary_operator (MINUS, SImode, xops);
}
else
/* No pic reg restore needed. */
emit_note (NOTE_INSN_DELETED);
DONE;
})
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
(define_split