re PR target/8340 (ICE on x86 inline asm w/ -fPIC)

gcc/
	PR target/8340
	PR middle-end/47602
	PR rtl-optimization/55458
	* config/i386/i386.c (ix86_use_pseudo_pic_reg): New.
	(ix86_init_pic_reg): New.
	(ix86_select_alt_pic_regnum): Add check on pseudo register.
	(ix86_save_reg): Likewise.
	(ix86_expand_prologue): Remove PIC register initialization
	now performed in ix86_init_pic_reg.
	(ix86_output_function_epilogue): Add check on pseudo register.
	(set_pic_reg_ever_alive): New.
	(legitimize_pic_address): Replace df_set_regs_ever_live with new
	set_pic_reg_ever_alive.
	(legitimize_tls_address): Likewise.
	(ix86_pic_register_p): New check.
	(ix86_delegitimize_address): Add check on pseudo register.
	(ix86_expand_call): Insert move from pseudo PIC register to ABI
	defined REAL_PIC_OFFSET_TABLE_REGNUM.
	(TARGET_INIT_PIC_REG): New.
	(TARGET_USE_PSEUDO_PIC_REG): New.
	* config/i386/i386.h (PIC_OFFSET_TABLE_REGNUM): Return INVALID_REGNUM
	if pic_offset_table_rtx exists.
	* doc/tm.texi.in (TARGET_USE_PSEUDO_PIC_REG, TARGET_INIT_PIC_REG):
	Document.
	* doc/tm.texi: Regenerate.
	* function.c (assign_parms): Generate pseudo register for PIC.
	* init-regs.c (initialize_uninitialized_regs): Ignor pseudo PIC
	register.
	* ira-color.c (color_pass): Add check on pseudo register.
	* ira-emit.c (change_loop): Don't create copies for PIC pseudo
	register.
	* ira.c (split_live_ranges_for_shrink_wrap): Add check on pseudo
	register.
	(ira): Add target specific PIC register initialization.
	(do_reload): Keep PIC pseudo register.
	* lra-assigns.c (spill_for): Add checks on pseudo register.
	* lra-constraints.c (contains_symbol_ref_p): New.
	(lra_constraints): Enable lra risky transformations when PIC is pseudo
	register.
	* shrink-wrap.c (try_shrink_wrapping): Add check on pseudo register.
	* target.def (use_pseudo_pic_reg): New.
	(init_pic_reg): New.

gcc/testsuite/
	PR target/8340
	PR middle-end/47602
	PR rtl-optimization/55458
	* gcc.target/i386/pic-1.c: Remove dg-error as test should pass now.
	* gcc.target/i386/pr55458.c: Likewise.
	* gcc.target/i386/pr47602.c: New.
	* gcc.target/i386/pr23098.c: Move to XFAIL.

From-SVN: r216154
This commit is contained in:
Kirill Yukhin 2014-10-13 17:26:49 +00:00
parent 8d99ad36b3
commit bcb21886b9
18 changed files with 289 additions and 92 deletions

View File

@ -1,3 +1,49 @@
2014-10-13 Ilya Enkovich <ilya.enkovich@intel.com>
Vladimir Makarov <vmakarov@redhat.com>
PR target/8340
PR middle-end/47602
PR rtl-optimization/55458
* config/i386/i386.c (ix86_use_pseudo_pic_reg): New.
(ix86_init_pic_reg): New.
(ix86_select_alt_pic_regnum): Add check on pseudo register.
(ix86_save_reg): Likewise.
(ix86_expand_prologue): Remove PIC register initialization
now performed in ix86_init_pic_reg.
(ix86_output_function_epilogue): Add check on pseudo register.
(set_pic_reg_ever_alive): New.
(legitimize_pic_address): Replace df_set_regs_ever_live with new
set_pic_reg_ever_alive.
(legitimize_tls_address): Likewise.
(ix86_pic_register_p): New check.
(ix86_delegitimize_address): Add check on pseudo register.
(ix86_expand_call): Insert move from pseudo PIC register to ABI
defined REAL_PIC_OFFSET_TABLE_REGNUM.
(TARGET_INIT_PIC_REG): New.
(TARGET_USE_PSEUDO_PIC_REG): New.
* config/i386/i386.h (PIC_OFFSET_TABLE_REGNUM): Return INVALID_REGNUM
if pic_offset_table_rtx exists.
* doc/tm.texi.in (TARGET_USE_PSEUDO_PIC_REG, TARGET_INIT_PIC_REG):
Document.
* doc/tm.texi: Regenerate.
* function.c (assign_parms): Generate pseudo register for PIC.
* init-regs.c (initialize_uninitialized_regs): Ignor pseudo PIC
register.
* ira-color.c (color_pass): Add check on pseudo register.
* ira-emit.c (change_loop): Don't create copies for PIC pseudo
register.
* ira.c (split_live_ranges_for_shrink_wrap): Add check on pseudo
register.
(ira): Add target specific PIC register initialization.
(do_reload): Keep PIC pseudo register.
* lra-assigns.c (spill_for): Add checks on pseudo register.
* lra-constraints.c (contains_symbol_ref_p): New.
(lra_constraints): Enable lra risky transformations when PIC is pseudo
register.
* shrink-wrap.c (try_shrink_wrapping): Add check on pseudo register.
* target.def (use_pseudo_pic_reg): New.
(init_pic_reg): New.
2014-10-13 Evgeny Stupachenko <evstupac@gmail.com>
* config/i386/x86-tune.def (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY):

View File

@ -6141,6 +6141,68 @@ ix86_maybe_switch_abi (void)
reinit_regs ();
}
/* Return 1 if pseudo register should be created and used to hold
GOT address for PIC code. */
static bool
ix86_use_pseudo_pic_reg (void)
{
if ((TARGET_64BIT
&& (ix86_cmodel == CM_SMALL_PIC
|| TARGET_PECOFF))
|| !flag_pic)
return false;
return true;
}
/* Create and initialize PIC register if required. */
static void
ix86_init_pic_reg (void)
{
edge entry_edge;
rtx_insn *seq;
if (!ix86_use_pseudo_pic_reg ())
return;
start_sequence ();
if (TARGET_64BIT)
{
if (ix86_cmodel == CM_LARGE_PIC)
{
rtx_code_label *label;
rtx tmp_reg;
gcc_assert (Pmode == DImode);
label = gen_label_rtx ();
emit_label (label);
LABEL_PRESERVE_P (label) = 1;
tmp_reg = gen_rtx_REG (Pmode, R11_REG);
gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
label));
emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
pic_offset_table_rtx, tmp_reg));
}
else
emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
}
else
{
rtx insn = emit_insn (gen_set_got (pic_offset_table_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
}
seq = get_insns ();
end_sequence ();
entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
insert_insn_on_edge (seq, entry_edge);
commit_one_edge_insertion (entry_edge);
}
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
@ -9383,6 +9445,9 @@ gen_pop (rtx arg)
static unsigned int
ix86_select_alt_pic_regnum (void)
{
if (ix86_use_pseudo_pic_reg ())
return INVALID_REGNUM;
if (crtl->is_leaf
&& !crtl->profile
&& !ix86_current_function_calls_tls_descriptor)
@ -9407,6 +9472,7 @@ static bool
ix86_save_reg (unsigned int regno, bool maybe_eh_return)
{
if (pic_offset_table_rtx
&& !ix86_use_pseudo_pic_reg ()
&& regno == REAL_PIC_OFFSET_TABLE_REGNUM
&& (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
|| crtl->profile
@ -10759,7 +10825,6 @@ ix86_expand_prologue (void)
{
struct machine_function *m = cfun->machine;
rtx insn, t;
bool pic_reg_used;
struct ix86_frame frame;
HOST_WIDE_INT allocate;
bool int_registers_saved;
@ -11206,60 +11271,6 @@ ix86_expand_prologue (void)
if (!sse_registers_saved)
ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
pic_reg_used = false;
/* We don't use pic-register for pe-coff target. */
if (pic_offset_table_rtx
&& !TARGET_PECOFF
&& (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
|| crtl->profile))
{
unsigned int alt_pic_reg_used = ix86_select_alt_pic_regnum ();
if (alt_pic_reg_used != INVALID_REGNUM)
SET_REGNO (pic_offset_table_rtx, alt_pic_reg_used);
pic_reg_used = true;
}
if (pic_reg_used)
{
if (TARGET_64BIT)
{
if (ix86_cmodel == CM_LARGE_PIC)
{
rtx_code_label *label;
rtx tmp_reg;
gcc_assert (Pmode == DImode);
label = gen_label_rtx ();
emit_label (label);
LABEL_PRESERVE_P (label) = 1;
tmp_reg = gen_rtx_REG (Pmode, R11_REG);
gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
insn = emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
label));
insn = emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
insn = emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
pic_offset_table_rtx, tmp_reg));
}
else
insn = emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
}
else
{
insn = emit_insn (gen_set_got (pic_offset_table_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
}
}
/* In the pic_reg_used case, make sure that the got load isn't deleted
when mcount needs it. Blockage to avoid call movement across mcount
call is emitted in generic code after the NOTE_INSN_PROLOGUE_END
note. */
if (crtl->profile && !flag_fentry && pic_reg_used)
emit_insn (gen_prologue_use (pic_offset_table_rtx));
if (crtl->drap_reg && !crtl->stack_realign_needed)
{
/* vDRAP is setup but after reload it turns out stack realign
@ -11800,7 +11811,8 @@ ix86_expand_epilogue (int style)
static void
ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED, HOST_WIDE_INT)
{
if (pic_offset_table_rtx)
if (pic_offset_table_rtx
&& !ix86_use_pseudo_pic_reg ())
SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
#if TARGET_MACHO
/* Mach-O doesn't support labels at the end of objects, so if
@ -13120,6 +13132,15 @@ ix86_GOT_alias_set (void)
return set;
}
/* Set regs_ever_live for PIC base address register
to true if required. */
static void
set_pic_reg_ever_live ()
{
if (reload_in_progress)
df_set_regs_ever_live (REGNO (pic_offset_table_rtx), true);
}
/* Return a legitimate reference for ORIG (an address) using the
register REG. If REG is 0, a new pseudo is generated.
@ -13170,8 +13191,7 @@ legitimize_pic_address (rtx orig, rtx reg)
/* This symbol may be referenced via a displacement from the PIC
base address (@GOTOFF). */
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
set_pic_reg_ever_live ();
if (GET_CODE (addr) == CONST)
addr = XEXP (addr, 0);
if (GET_CODE (addr) == PLUS)
@ -13203,8 +13223,7 @@ legitimize_pic_address (rtx orig, rtx reg)
/* This symbol may be referenced via a displacement from the PIC
base address (@GOTOFF). */
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
set_pic_reg_ever_live ();
if (GET_CODE (addr) == CONST)
addr = XEXP (addr, 0);
if (GET_CODE (addr) == PLUS)
@ -13265,8 +13284,7 @@ legitimize_pic_address (rtx orig, rtx reg)
/* This symbol must be referenced via a load from the
Global Offset Table (@GOT). */
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
set_pic_reg_ever_live ();
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
if (TARGET_64BIT)
@ -13318,8 +13336,7 @@ legitimize_pic_address (rtx orig, rtx reg)
{
if (!TARGET_64BIT)
{
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
set_pic_reg_ever_live ();
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
UNSPEC_GOTOFF);
new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
@ -13615,8 +13632,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
}
else if (flag_pic)
{
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
set_pic_reg_ever_live ();
pic = pic_offset_table_rtx;
type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
}
@ -14247,6 +14263,8 @@ ix86_pic_register_p (rtx x)
if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
return (pic_offset_table_rtx
&& rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
else if (pic_offset_table_rtx)
return REG_P (x) && REGNO (x) == REGNO (pic_offset_table_rtx);
else
return REG_P (x) && REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
}
@ -14421,8 +14439,12 @@ ix86_delegitimize_address (rtx x)
leal (%ebx, %ecx, 4), %ecx
...
movl foo@GOTOFF(%ecx), %edx
in which case we return (%ecx - %ebx) + foo. */
if (pic_offset_table_rtx)
in which case we return (%ecx - %ebx) + foo.
Note that when pseudo_pic_reg is used we can generate it only
before reload_completed. */
if (pic_offset_table_rtx
&& (!reload_completed || !ix86_use_pseudo_pic_reg ()))
result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
pic_offset_table_rtx),
result);
@ -24899,7 +24921,12 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
&& DEFAULT_ABI != MS_ABI))
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
&& ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
use_reg (&use, pic_offset_table_rtx);
{
use_reg (&use, gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM));
if (ix86_use_pseudo_pic_reg ())
emit_move_insn (gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM),
pic_offset_table_rtx);
}
}
if (TARGET_64BIT && INTVAL (callarg2) >= 0)
@ -47413,6 +47440,10 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
#define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG ix86_function_arg
#undef TARGET_INIT_PIC_REG
#define TARGET_INIT_PIC_REG ix86_init_pic_reg
#undef TARGET_USE_PSEUDO_PIC_REG
#define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
#undef TARGET_PASS_BY_REFERENCE

View File

@ -1233,12 +1233,14 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define REAL_PIC_OFFSET_TABLE_REGNUM BX_REG
#define PIC_OFFSET_TABLE_REGNUM \
((TARGET_64BIT && (ix86_cmodel == CM_SMALL_PIC \
|| TARGET_PECOFF)) \
|| !flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM)
#define PIC_OFFSET_TABLE_REGNUM \
((TARGET_64BIT && (ix86_cmodel == CM_SMALL_PIC \
|| TARGET_PECOFF)) \
|| !flag_pic \
? INVALID_REGNUM \
: pic_offset_table_rtx \
? INVALID_REGNUM \
: REAL_PIC_OFFSET_TABLE_REGNUM)
#define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"

View File

@ -3902,6 +3902,16 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,
@code{TARGET_FUNCTION_ARG} serves both purposes.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_USE_PSEUDO_PIC_REG (void)
This hook should return 1 in case pseudo register should be created
for pic_offset_table_rtx during function expand.
@end deftypefn
@deftypefn {Target Hook} void TARGET_INIT_PIC_REG (void)
Perform a target dependent initialization of pic_offset_table_rtx.
This hook is called at the start of register allocation.
@end deftypefn
@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
This target hook returns the number of bytes at the beginning of an
argument that must be put in registers. The value must be zero for

View File

@ -3348,6 +3348,10 @@ the stack.
@hook TARGET_FUNCTION_INCOMING_ARG
@hook TARGET_USE_PSEUDO_PIC_REG
@hook TARGET_INIT_PIC_REG
@hook TARGET_ARG_PARTIAL_BYTES
@hook TARGET_PASS_BY_REFERENCE

View File

@ -3453,6 +3453,11 @@ assign_parms (tree fndecl)
fnargs.release ();
/* Initialize pic_offset_table_rtx with a pseudo register
if required. */
if (targetm.use_pseudo_pic_reg ())
pic_offset_table_rtx = gen_reg_rtx (Pmode);
/* Output all parameter conversion instructions (possibly including calls)
now that all parameters have been copied out of hard registers. */
emit_insn (all.first_conversion_insn);

View File

@ -80,6 +80,11 @@ initialize_uninitialized_regs (void)
if (regno < FIRST_PSEUDO_REGISTER)
continue;
/* Ignore pseudo PIC register. */
if (pic_offset_table_rtx
&& regno == REGNO (pic_offset_table_rtx))
continue;
/* Do not generate multiple moves for the same regno.
This is common for sequences of subreg operations.
They would be deleted during combine but there is no

View File

@ -3245,9 +3245,11 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
ALLOCNO_NUM (subloop_allocno)));
if ((flag_ira_region == IRA_REGION_MIXED)
&& (loop_tree_node->reg_pressure[pclass]
<= ira_class_hard_regs_num[pclass]))
if ((flag_ira_region == IRA_REGION_MIXED
&& (loop_tree_node->reg_pressure[pclass]
<= ira_class_hard_regs_num[pclass]))
|| (pic_offset_table_rtx != NULL
&& regno == (int) REGNO (pic_offset_table_rtx)))
{
if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
{

View File

@ -620,7 +620,10 @@ change_loop (ira_loop_tree_node_t node)
/* don't create copies because reload can spill an
allocno set by copy although the allocno will not
get memory slot. */
|| ira_equiv_no_lvalue_p (regno)))
|| ira_equiv_no_lvalue_p (regno)
|| (pic_offset_table_rtx != NULL
&& (ALLOCNO_REGNO (allocno)
== (int) REGNO (pic_offset_table_rtx)))))
continue;
original_reg = allocno_emit_reg (allocno);
if (parent_allocno == NULL

View File

@ -4896,7 +4896,7 @@ split_live_ranges_for_shrink_wrap (void)
FOR_BB_INSNS (first, insn)
{
rtx dest = interesting_dest_for_shprep (insn, call_dom);
if (!dest)
if (!dest || dest == pic_offset_table_rtx)
continue;
rtx newreg = NULL_RTX;
@ -5048,6 +5048,9 @@ ira (FILE *f)
bool saved_flag_caller_saves = flag_caller_saves;
enum ira_region saved_flag_ira_region = flag_ira_region;
/* Perform target specific PIC register initialization. */
targetm.init_pic_reg ();
ira_conflicts_p = optimize > 0;
ira_use_lra_p = targetm.lra_p ();
@ -5299,10 +5302,18 @@ do_reload (void)
{
basic_block bb;
bool need_dce;
unsigned pic_offset_table_regno = INVALID_REGNUM;
if (flag_ira_verbose < 10)
ira_dump_file = dump_file;
/* If pic_offset_table_rtx is a pseudo register, then keep it so
after reload to avoid possible wrong usages of hard reg assigned
to it. */
if (pic_offset_table_rtx
&& REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
pic_offset_table_regno = REGNO (pic_offset_table_rtx);
timevar_push (TV_RELOAD);
if (ira_use_lra_p)
{
@ -5407,6 +5418,9 @@ do_reload (void)
inform (DECL_SOURCE_LOCATION (decl), "for %qD", decl);
}
if (pic_offset_table_regno != INVALID_REGNUM)
pic_offset_table_rtx = gen_rtx_REG (Pmode, pic_offset_table_regno);
timevar_pop (TV_IRA);
}

View File

@ -879,11 +879,13 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
}
/* Spill pseudos. */
EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
if ((int) spill_regno >= lra_constraint_new_regno_start
&& ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
&& ! bitmap_bit_p (&lra_split_regs, spill_regno)
&& ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
&& ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))
if ((pic_offset_table_rtx != NULL
&& spill_regno == REGNO (pic_offset_table_rtx))
|| ((int) spill_regno >= lra_constraint_new_regno_start
&& ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
&& ! bitmap_bit_p (&lra_split_regs, spill_regno)
&& ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
&& ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)))
goto fail;
insn_pseudos_num = 0;
if (lra_dump_file != NULL)
@ -1053,9 +1055,15 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap
return;
}
for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
if ((pic_offset_table_rtx == NULL_RTX
|| i != (int) REGNO (pic_offset_table_rtx))
&& reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
sorted_pseudos[n++] = i;
qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
if (pic_offset_table_rtx != NULL_RTX
&& (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] >= 0 && lra_reg_info[regno].nrefs > 0)
sorted_pseudos[n++] = regno;
for (i = n - 1; i >= 0; i--)
{
regno = sorted_pseudos[i];

View File

@ -3798,6 +3798,35 @@ contains_reg_p (rtx x, bool hard_reg_p, bool spilled_p)
return false;
}
/* Return true if X contains a symbol reg. */
static bool
contains_symbol_ref_p (rtx x)
{
int i, j;
const char *fmt;
enum rtx_code code;
code = GET_CODE (x);
if (code == SYMBOL_REF)
return true;
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if (contains_symbol_ref_p (XEXP (x, i)))
return true;
}
else if (fmt[i] == 'E')
{
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if (contains_symbol_ref_p (XVECEXP (x, i, j)))
return true;
}
}
return false;
}
/* Process all regs in location *LOC and change them on equivalent
substitution. Return true if any change was done. */
static bool
@ -4020,7 +4049,11 @@ lra_constraints (bool first_p)
("Maximum number of LRA constraint passes is achieved (%d)\n",
LRA_MAX_CONSTRAINT_ITERATION_NUMBER);
changed_p = false;
lra_risky_transformations_p = false;
if (pic_offset_table_rtx
&& REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
lra_risky_transformations_p = true;
else
lra_risky_transformations_p = false;
new_insn_uid_start = get_max_uid ();
new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
/* Mark used hard regs for target stack size calulations. */
@ -4088,7 +4121,12 @@ lra_constraints (bool first_p)
paradoxical subregs. */
|| (MEM_P (x)
&& (GET_MODE_SIZE (lra_reg_info[i].biggest_mode)
> GET_MODE_SIZE (GET_MODE (x)))))
> GET_MODE_SIZE (GET_MODE (x))))
|| (pic_offset_table_rtx
&& ((CONST_POOL_OK_P (PSEUDO_REGNO_MODE (i), x)
&& (targetm.preferred_reload_class
(x, lra_get_allocno_class (i)) == NO_REGS))
|| contains_symbol_ref_p (x))))
ira_reg_equiv[i].defined_p = false;
if (contains_reg_p (x, false, true))
ira_reg_equiv[i].profitable_p = false;

View File

@ -579,7 +579,8 @@ try_shrink_wrapping (edge *entry_edge, edge orig_entry_edge,
if (frame_pointer_needed)
add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
HARD_FRAME_POINTER_REGNUM);
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
if (pic_offset_table_rtx
&& (unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
PIC_OFFSET_TABLE_REGNUM);
if (crtl->drap_reg)

View File

@ -4274,6 +4274,20 @@ DEFHOOK
HOOK_VECTOR_END (calls)
DEFHOOK
(use_pseudo_pic_reg,
"This hook should return 1 in case pseudo register should be created\n\
for pic_offset_table_rtx during function expand.",
bool, (void),
hook_bool_void_false)
DEFHOOK
(init_pic_reg,
"Perform a target dependent initialization of pic_offset_table_rtx.\n\
This hook is called at the start of register allocation.",
void, (void),
hook_void_void)
/* Return the diagnostic message string if conversion from FROMTYPE
to TOTYPE is not allowed, NULL otherwise. */
DEFHOOK

View File

@ -1,3 +1,13 @@
2014-10-13 Evgeny Stupachenko <evstupac@gmail.com>
PR target/8340
PR middle-end/47602
PR rtl-optimization/55458
* gcc.target/i386/pic-1.c: Remove dg-error as test should pass now.
* gcc.target/i386/pr55458.c: Likewise.
* gcc.target/i386/pr47602.c: New.
* gcc.target/i386/pr23098.c: Move to XFAIL.
2014-10-13 Jan Hubicka <hubicka@ucw.cz>
PR tree-optimization/62127

View File

@ -5,11 +5,13 @@
/* { dg-skip-if "No Windows PIC" { *-*-mingw* *-*-cygwin } { "*" } { "" } } */
/* { dg-options "-fPIC" } */
/* Test verifies that %ebx is no longer fixed when generating PIC code on i686. */
int foo ()
{
static int a;
__asm__ __volatile__ ( /* { dg-error "PIC register" } */
__asm__ __volatile__ (
"xorl %%ebx, %%ebx\n"
"movl %%ebx, %0\n"
: "=m" (a)

View File

@ -1,7 +1,7 @@
/* PR rtl-optimization/23098 */
/* { dg-do compile } */
/* { dg-options "-O2 -fPIC" } */
/* { dg-final { scan-assembler-not "\.LC\[0-9\]" { xfail *-*-vxworks* } } } */
/* { dg-final { scan-assembler-not "\.LC\[0-9\]" { xfail *-*-* } } } */
/* { dg-require-effective-target ia32 } */
/* { dg-require-effective-target fpic } */

View File

@ -2,10 +2,12 @@
/* { dg-require-effective-target ia32 } */
/* { dg-options "-fPIC" } */
/* Test verifies that %ebx is no longer fixed when generating PIC code on i686. */
int a, b, c;
void
foo (void)
{
asm volatile ("":"+m" (a), "+m" (b), "+m" (c)); /* { dg-error "operand has impossible constraints" } */
asm volatile ("":"+m" (a), "+m" (b), "+m" (c));
}