i386.c (ix86_save_reg): Examine regs_ever_live...
* config/i386/i386.c (ix86_save_reg): Examine regs_ever_live, not current_function_uses_pic_offset_table and current_function_uses_const_pool; examine current_function_profile. (ix86_expand_prologue): Likewise. Add pic_offset_table_rtx as input to blockage if needed. (ix86_expand_call): Do not set current_function_uses_pic_offset_table. (legitimize_pic_address): Likewise. Set regs_ever_live for pic_offset_table_rtx when invoked during reload. * config/i386/i386.h (FINALIZE_PIC): Remove. * config/i386/i386.md (tablejump): Reformat. Do not set current_function_uses_pic_offset_table. (tls_global_dynamic, tls_local_dynamic_base): Likewise. (blockage): Accept anything as operand 0. From-SVN: r53981
This commit is contained in:
parent
52f4fff682
commit
66edd3b4ca
|
@ -1,3 +1,19 @@
|
|||
2002-05-28 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/i386/i386.c (ix86_save_reg): Examine regs_ever_live,
|
||||
not current_function_uses_pic_offset_table and
|
||||
current_function_uses_const_pool; examine current_function_profile.
|
||||
(ix86_expand_prologue): Likewise. Add pic_offset_table_rtx as
|
||||
input to blockage if needed.
|
||||
(ix86_expand_call): Do not set current_function_uses_pic_offset_table.
|
||||
(legitimize_pic_address): Likewise. Set regs_ever_live for
|
||||
pic_offset_table_rtx when invoked during reload.
|
||||
* config/i386/i386.h (FINALIZE_PIC): Remove.
|
||||
* config/i386/i386.md (tablejump): Reformat. Do not set
|
||||
current_function_uses_pic_offset_table.
|
||||
(tls_global_dynamic, tls_local_dynamic_base): Likewise.
|
||||
(blockage): Accept anything as operand 0.
|
||||
|
||||
2002-05-28 Jason Thorpe <thorpej@wasabisystems.com>
|
||||
|
||||
* config/netbsd-aout.h (NETBSD_OS_CPP_BUILTINS_AOUT): Define
|
||||
|
|
|
@ -4012,8 +4012,8 @@ ix86_save_reg (regno, maybe_eh_return)
|
|||
int maybe_eh_return;
|
||||
{
|
||||
if (regno == PIC_OFFSET_TABLE_REGNUM
|
||||
&& (current_function_uses_pic_offset_table
|
||||
|| current_function_uses_const_pool
|
||||
&& (regs_ever_live[regno]
|
||||
|| current_function_profile
|
||||
|| current_function_calls_eh_return))
|
||||
return 1;
|
||||
|
||||
|
@ -4235,9 +4235,9 @@ void
|
|||
ix86_expand_prologue ()
|
||||
{
|
||||
rtx insn;
|
||||
int pic_reg_used = (flag_pic && (current_function_uses_pic_offset_table
|
||||
|| current_function_uses_const_pool)
|
||||
&& !TARGET_64BIT);
|
||||
int pic_reg_used = (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
|
||||
&& (regs_ever_live[PIC_OFFSET_TABLE_REGNUM]
|
||||
|| current_function_profile));
|
||||
struct ix86_frame frame;
|
||||
int use_mov = 0;
|
||||
HOST_WIDE_INT allocate;
|
||||
|
@ -4320,18 +4320,19 @@ ix86_expand_prologue ()
|
|||
{
|
||||
insn = emit_insn (gen_set_got (pic_offset_table_rtx));
|
||||
|
||||
/* ??? The current_function_uses_pic_offset_table flag is woefully
|
||||
inaccurate, as it isn't updated as code gets deleted. Allow the
|
||||
thing to be removed. A better solution would be to actually get
|
||||
proper liveness for ebx, as then we won't save/restore it too. */
|
||||
/* Even with accurate pre-reload life analysis, we can wind up
|
||||
deleting all references to the pic register after reload.
|
||||
Consider if cross-jumping unifies two sides of a branch
|
||||
controled by a comparison vs the only read from a global.
|
||||
In which case, allow the set_got to be deleted, though we're
|
||||
too late to do anything about the ebx save in the prologue. */
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
|
||||
}
|
||||
|
||||
/* If we are profiling, make sure no instructions are scheduled before
|
||||
the call to mcount. However, if -fpic, the above call will have
|
||||
done that. */
|
||||
if (current_function_profile && ! pic_reg_used)
|
||||
emit_insn (gen_blockage ());
|
||||
/* Prevent function calls from be scheduled before the call to mcount.
|
||||
In the pic_reg_used case, make sure that the got load isn't deleted. */
|
||||
if (current_function_profile)
|
||||
emit_insn (gen_blockage (pic_reg_used ? pic_offset_table_rtx : const0_rtx));
|
||||
}
|
||||
|
||||
/* Emit code to restore saved registers using MOV insns. First register
|
||||
|
@ -5245,7 +5246,8 @@ legitimize_pic_address (orig, reg)
|
|||
/* This symbol may be referenced via a displacement from the PIC
|
||||
base address (@GOTOFF). */
|
||||
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
if (reload_in_progress)
|
||||
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
|
||||
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
|
||||
new = gen_rtx_CONST (Pmode, new);
|
||||
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
|
||||
|
@ -5261,7 +5263,6 @@ legitimize_pic_address (orig, reg)
|
|||
{
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
|
||||
new = gen_rtx_CONST (Pmode, new);
|
||||
new = gen_rtx_MEM (Pmode, new);
|
||||
|
@ -5281,7 +5282,8 @@ legitimize_pic_address (orig, reg)
|
|||
/* This symbol must be referenced via a load from the
|
||||
Global Offset Table (@GOT). */
|
||||
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
if (reload_in_progress)
|
||||
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
|
||||
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
|
||||
new = gen_rtx_CONST (Pmode, new);
|
||||
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
|
||||
|
@ -5322,7 +5324,8 @@ legitimize_pic_address (orig, reg)
|
|||
{
|
||||
if (!TARGET_64BIT)
|
||||
{
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
if (reload_in_progress)
|
||||
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
|
||||
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
|
||||
UNSPEC_GOTOFF);
|
||||
new = gen_rtx_PLUS (Pmode, new, op1);
|
||||
|
@ -5518,7 +5521,8 @@ legitimize_address (x, oldx, mode)
|
|||
case TLS_MODEL_INITIAL_EXEC:
|
||||
if (flag_pic)
|
||||
{
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
if (reload_in_progress)
|
||||
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
|
||||
pic = pic_offset_table_rtx;
|
||||
}
|
||||
else
|
||||
|
@ -10464,10 +10468,7 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
|
|||
if (! TARGET_64BIT && flag_pic
|
||||
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
|
||||
&& ! SYMBOL_REF_FLAG (XEXP (fnaddr, 0)))
|
||||
{
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
use_reg (&use, pic_offset_table_rtx);
|
||||
}
|
||||
use_reg (&use, pic_offset_table_rtx);
|
||||
|
||||
if (TARGET_64BIT && INTVAL (callarg2) >= 0)
|
||||
{
|
||||
|
|
|
@ -2406,17 +2406,6 @@ enum ix86_builtins
|
|||
fputs (user_label_prefix, FILE); \
|
||||
fputs (xname, FILE); \
|
||||
} while (0)
|
||||
|
||||
/* The `FINALIZE_PIC' macro serves as a hook to emit these special
|
||||
codes once the function is being compiled into assembly code, but
|
||||
not before. (It is not done before, because in the case of
|
||||
compiling an inline function, it would lead to multiple PIC
|
||||
prologues being included in functions which used inline functions
|
||||
and were compiled to assembly language.) */
|
||||
|
||||
#define FINALIZE_PIC \
|
||||
(current_function_uses_pic_offset_table |= current_function_profile)
|
||||
|
||||
|
||||
/* Max number of args passed in registers. If this is more than 3, we will
|
||||
have problems with ebx (register #4), since it is a caller save register and
|
||||
|
|
|
@ -12699,29 +12699,34 @@
|
|||
(use (label_ref (match_operand 1 "" "")))])]
|
||||
""
|
||||
{
|
||||
/* In PIC mode, the table entries are stored GOT-relative. Convert
|
||||
the relative address to an absolute address. */
|
||||
/* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
|
||||
relative. Convert the relative address to an absolute address. */
|
||||
if (flag_pic)
|
||||
{
|
||||
rtx op0, op1;
|
||||
enum rtx_code code;
|
||||
|
||||
if (TARGET_64BIT)
|
||||
operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
|
||||
gen_rtx_LABEL_REF (Pmode, operands[1]),
|
||||
NULL_RTX, 0,
|
||||
OPTAB_DIRECT);
|
||||
{
|
||||
code = PLUS;
|
||||
op0 = operands[0];
|
||||
op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
|
||||
}
|
||||
else if (HAVE_AS_GOTOFF_IN_DATA)
|
||||
{
|
||||
operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
|
||||
pic_offset_table_rtx, NULL_RTX,
|
||||
1, OPTAB_DIRECT);
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
code = PLUS;
|
||||
op0 = operands[0];
|
||||
op1 = pic_offset_table_rtx;
|
||||
}
|
||||
else
|
||||
{
|
||||
operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
|
||||
operands[0], NULL_RTX, 1,
|
||||
OPTAB_DIRECT);
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
code = MINUS;
|
||||
op0 = pic_offset_table_rtx;
|
||||
op1 = operands[0];
|
||||
}
|
||||
|
||||
operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 1,
|
||||
OPTAB_DIRECT);
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -13061,7 +13066,7 @@
|
|||
registers we stored in the result block. We avoid problems by
|
||||
claiming that all hard registers are used and clobbered at this
|
||||
point. */
|
||||
emit_insn (gen_blockage ());
|
||||
emit_insn (gen_blockage (const0_rtx));
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
@ -13072,7 +13077,7 @@
|
|||
;; all of memory. This blocks insns from being moved across this point.
|
||||
|
||||
(define_insn "blockage"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
|
||||
""
|
||||
""
|
||||
[(set_attr "length" "0")])
|
||||
|
@ -13391,7 +13396,6 @@
|
|||
{
|
||||
if (!flag_pic)
|
||||
abort ();
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
operands[2] = pic_offset_table_rtx;
|
||||
operands[3] = ix86_tls_get_addr ();
|
||||
})
|
||||
|
@ -13434,7 +13438,6 @@
|
|||
{
|
||||
if (!flag_pic)
|
||||
abort ();
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
operands[1] = pic_offset_table_rtx;
|
||||
operands[2] = ix86_tls_get_addr ();
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue