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:
parent
8d99ad36b3
commit
bcb21886b9
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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_"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
16
gcc/ira.c
16
gcc/ira.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 } */
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user