aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-05-28 18:37:22 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-05-28 18:37:22 -0700
commit66edd3b4ca7e6cc9a6d09fc4ba5d890f04c66ead (patch)
tree0ac9200a04b0ae4859b32189c21877c9a830da1a
parent52f4fff6829c14f4cdf754751566df0fb28f5ad5 (diff)
downloadgcc-66edd3b4ca7e6cc9a6d09fc4ba5d890f04c66ead.zip
gcc-66edd3b4ca7e6cc9a6d09fc4ba5d890f04c66ead.tar.gz
gcc-66edd3b4ca7e6cc9a6d09fc4ba5d890f04c66ead.tar.bz2
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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/i386/i386.c47
-rw-r--r--gcc/config/i386/i386.h11
-rw-r--r--gcc/config/i386/i386.md39
4 files changed, 61 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eb3f5f0..f391122 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 39831af..7e98741 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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)
{
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 5946370..970dfdf 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 2d19645..1c99f60 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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 ();
})