aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2004-01-01 14:59:02 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2004-01-01 13:59:02 +0000
commitb684a3df8e33898816611f1cefbd0068ca22beca (patch)
treefe1b65729ca0a43eccd94abb9e3c03c5e01a6e20 /gcc
parent74aa338ad540b76f8d8566c996642b02810f5c14 (diff)
downloadgcc-b684a3df8e33898816611f1cefbd0068ca22beca.zip
gcc-b684a3df8e33898816611f1cefbd0068ca22beca.tar.gz
gcc-b684a3df8e33898816611f1cefbd0068ca22beca.tar.bz2
re PR rtl-optimization/13473 (cc1 segfault w/-march=pentium4)
PR opt/13473 * recog.c (validate_replace_rtx_1): Take care for RTL sharing inside ASM input operands PR opt/12617 * toplev.c (dump_file_index): Reorder ce3 and bbro. (dump_file): Likewise. (rest_of_compilation): Likewise. PR debug/13367 * cgraph.c (cgraph_function_possibly_inlined): Even with flag_really_no_inline we inline always_inline functions. * cgraphunit.c (cgraph_analyze_function): Clear inlinable flag for non-always_inline functions when there is flag_really_no_inline. (cgraph_decide_inlining): Limit work done when not inlining. (cgraph_decide_inlining_incrementally): Likewise. (cgraph_optimize_function): Check whether something got inlined. * c-objc-common.c (c_disregard_inline_limits): Do not always inline extern inline functions when not inlining. * opts.c (decode_options): Disable crossjumping at -O1 * invoke.texi (-O1): Document change. * gcc.dg/debug/20031231-1.c: New. * gcc.c-torture/compile/20040101-1.c: New. * gcc.dg/dwarf-die-[1-7].c: New. From-SVN: r75303
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/c-decl.c3
-rw-r--r--gcc/c-objc-common.c5
-rw-r--r--gcc/cgraph.c6
-rw-r--r--gcc/cgraphunit.c173
-rw-r--r--gcc/doc/invoke.texi6
-rw-r--r--gcc/opts.c4
-rw-r--r--gcc/recog.c38
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040101-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/debug/20031231-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die1.c8
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die2.c7
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die3.c11
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die5.c12
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die6.c12
-rw-r--r--gcc/testsuite/gcc.dg/dwarf-die7.c14
-rw-r--r--gcc/toplev.c48
18 files changed, 307 insertions, 120 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3680afd..9db27a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,2 +1,26 @@
+2003-12-31 Jan Hubicka <jh@suse.cz>
+
+ PR opt/13473
+ * recog.c (validate_replace_rtx_1): Take care for RTL sharing inside
+ ASM input operands
+
+ PR opt/12617
+ * toplev.c (dump_file_index): Reorder ce3 and bbro.
+ (dump_file): Likewise.
+ (rest_of_compilation): Likewise.
+
+ PR debug/13367
+ * cgraph.c (cgraph_function_possibly_inlined): Even with
+ flag_really_no_inline we inline always_inline functions.
+ * cgraphunit.c (cgraph_analyze_function): Clear inlinable flag
+ for non-always_inline functions when there is flag_really_no_inline.
+ (cgraph_decide_inlining): Limit work done when not inlining.
+ (cgraph_decide_inlining_incrementally): Likewise.
+ (cgraph_optimize_function): Check whether something got inlined.
+ * c-objc-common.c (c_disregard_inline_limits): Do not always inline
+ extern inline functions when not inlining.
+
+ * opts.c (decode_options): Disable crossjumping at -O1
+ * invoke.texi (-O1): Document change.
See ChangeLog.10 for earlier changes.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index db04a87..ee2db9e 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1426,7 +1426,8 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
if (TREE_USED (olddecl)
/* In unit-at-a-time mode we never inline re-defined extern
inline functions. */
- && !flag_unit_at_a_time)
+ && !flag_unit_at_a_time
+ && cgraph_function_possibly_inlined_p (olddecl))
(*debug_hooks->outlining_inline_function) (olddecl);
/* The new defn must not be inline. */
diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c
index e9a4a09..5a57aa4 100644
--- a/gcc/c-objc-common.c
+++ b/gcc/c-objc-common.c
@@ -1,5 +1,5 @@
/* Some code common to C and ObjC front ends.
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -61,7 +61,8 @@ c_disregard_inline_limits (tree fn)
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
- return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
+ return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn)
+ && DECL_EXTERNAL (fn));
}
int
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 91b08a6..26cbd27 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1,5 +1,5 @@
/* Callgraph handling code.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
@@ -613,7 +613,9 @@ bool
cgraph_function_possibly_inlined_p (tree decl)
{
if (!cgraph_global_info_ready)
- return (DECL_INLINE (decl) && !flag_really_no_inline);
+ return (DECL_INLINE (decl)
+ && (!flag_really_no_inline
+ || (*lang_hooks.tree_inlining.disregard_inline_limits) (decl)));
return cgraph_node (decl)->global.inlined;
}
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index d2d4d4c..dfe4c71 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1,5 +1,5 @@
/* Callgraph based intraprocedural optimizations.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
@@ -325,7 +325,8 @@ cgraph_analyze_function (struct cgraph_node *node)
if (node->local.inlinable)
node->local.disregard_inline_limits
= (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
-
+ if (flag_really_no_inline && !node->local.disregard_inline_limits)
+ node->local.inlinable = 0;
/* Inlining characteristics are maintained by the cgraph_mark_inline. */
node->global.insns = node->local.self_insns;
if (!DECL_EXTERNAL (decl))
@@ -471,7 +472,15 @@ cgraph_optimize_function (struct cgraph_node *node)
/* optimize_inline_calls avoids inlining of current_function_decl. */
current_function_decl = decl;
if (flag_inline_trees)
- optimize_inline_calls (decl);
+ {
+ struct cgraph_edge *e;
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->inline_call)
+ break;
+ if (e)
+ optimize_inline_calls (decl);
+ }
if (node->nested)
{
for (node = node->nested; node; node = node->next_nested)
@@ -1137,80 +1146,84 @@ cgraph_decide_inlining (void)
inlined[y]->output = 0, node->aux = 0;
}
- cgraph_decide_inlining_of_small_functions (inlined, inlined_callees);
-
- if (cgraph_dump_file)
- fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
+ if (!flag_really_no_inline)
+ {
+ cgraph_decide_inlining_of_small_functions (inlined, inlined_callees);
- /* And finally decide what functions are called once. */
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
- for (i = nnodes - 1; i >= 0; i--)
- {
- node = order[i];
+ /* And finally decide what functions are called once. */
- if (node->callers && !node->callers->next_caller && !node->needed
- && node->local.inlinable && !node->callers->inline_call
- && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
+ for (i = nnodes - 1; i >= 0; i--)
{
- bool ok = true;
- struct cgraph_node *node1;
-
- /* Verify that we won't duplicate the caller. */
- for (node1 = node->callers->caller;
- node1->callers && node1->callers->inline_call
- && ok; node1 = node1->callers->caller)
- if (node1->callers->next_caller || node1->needed)
- ok = false;
- if (ok)
+ node = order[i];
+
+ if (node->callers && !node->callers->next_caller && !node->needed
+ && node->local.inlinable && !node->callers->inline_call
+ && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
{
- if (cgraph_dump_file)
- fprintf (cgraph_dump_file,
- "\nConsidering %s %i insns.\n"
- " Called once from %s %i insns.\n",
- cgraph_node_name (node), node->global.insns,
- cgraph_node_name (node->callers->caller),
- node->callers->caller->global.insns);
- ninlined = cgraph_inlined_into (node->callers->caller, inlined);
- old_insns = overall_insns;
- if (cgraph_check_inline_limits
- (node->callers->caller, node, inlined, ninlined))
+ bool ok = true;
+ struct cgraph_node *node1;
+
+ /* Verify that we won't duplicate the caller. */
+ for (node1 = node->callers->caller;
+ node1->callers && node1->callers->inline_call
+ && ok; node1 = node1->callers->caller)
+ if (node1->callers->next_caller || node1->needed)
+ ok = false;
+ if (ok)
{
- ninlined_callees =
- cgraph_inlined_callees (node, inlined_callees);
- cgraph_mark_inline (node->callers->caller, node, inlined,
- ninlined, inlined_callees,
- ninlined_callees);
- for (y = 0; y < ninlined_callees; y++)
- inlined_callees[y]->output = 0, node->aux = 0;
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
- " Inlined into %s which now has %i insns"
- " for a net change of %+i insns.\n",
+ "\nConsidering %s %i insns.\n"
+ " Called once from %s %i insns.\n",
+ cgraph_node_name (node), node->global.insns,
cgraph_node_name (node->callers->caller),
- node->callers->caller->global.insns,
- overall_insns - old_insns);
+ node->callers->caller->global.insns);
+ ninlined = cgraph_inlined_into (node->callers->caller,
+ inlined);
+ old_insns = overall_insns;
+ if (cgraph_check_inline_limits
+ (node->callers->caller, node, inlined, ninlined))
+ {
+ ninlined_callees =
+ cgraph_inlined_callees (node, inlined_callees);
+ cgraph_mark_inline (node->callers->caller, node, inlined,
+ ninlined, inlined_callees,
+ ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, node->aux = 0;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined into %s which now has %i insns"
+ " for a net change of %+i insns.\n",
+ cgraph_node_name (node->callers->caller),
+ node->callers->caller->global.insns,
+ overall_insns - old_insns);
+ }
+ else
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inline limit reached, not inlined.\n");
+ }
+ for (y = 0; y < ninlined; y++)
+ inlined[y]->output = 0, node->aux = 0;
}
- else
- {
- if (cgraph_dump_file)
- fprintf (cgraph_dump_file,
- " Inline limit reached, not inlined.\n");
- }
- for (y = 0; y < ninlined; y++)
- inlined[y]->output = 0, node->aux = 0;
}
}
- }
- if (cgraph_dump_file)
- fprintf (cgraph_dump_file,
- "\nInlined %i calls, eliminated %i functions, "
- "%i insns turned to %i insns.\n\n",
- ncalls_inlined, nfunctions_inlined, initial_insns,
- overall_insns);
- free (order);
- free (inlined);
- free (inlined_callees);
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nInlined %i calls, eliminated %i functions, "
+ "%i insns turned to %i insns.\n\n",
+ ncalls_inlined, nfunctions_inlined, initial_insns,
+ overall_insns);
+ free (order);
+ free (inlined);
+ free (inlined_callees);
+ }
}
/* Decide on the inlining. We do so in the topological order to avoid
@@ -1242,20 +1255,24 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node)
inlined_callees[y]->output = 0, node->aux = 0;
}
- /* Now do the automatic inlining. */
- for (e = node->callees; e; e = e->next_callee)
- if (e->callee->local.inlinable && !e->callee->output
- && e->callee != node && !e->inline_call
- && cgraph_default_inline_p (e->callee)
- && cgraph_check_inline_limits (node, e->callee, inlined,
- ninlined))
- {
- ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
- cgraph_mark_inline (node, e->callee, inlined, ninlined,
- inlined_callees, ninlined_callees);
- for (y = 0; y < ninlined_callees; y++)
- inlined_callees[y]->output = 0, node->aux = 0;
- }
+ if (!flag_really_no_inline)
+ {
+ /* Now do the automatic inlining. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.inlinable && !e->callee->output
+ && e->callee != node && !e->inline_call
+ && cgraph_default_inline_p (e->callee)
+ && cgraph_check_inline_limits (node, e->callee, inlined,
+ ninlined))
+ {
+ ninlined_callees = cgraph_inlined_callees (e->callee,
+ inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, node->aux = 0;
+ }
+ }
/* Clear the flags set by cgraph_inlined_into. */
for (y = 0; y < ninlined; y++)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8c7863a..874e83c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-@c 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+@c 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -3626,7 +3626,6 @@ compilation time.
-fmerge-constants @gol
-fthread-jumps @gol
-floop-optimize @gol
--fcrossjumping @gol
-fif-conversion @gol
-fif-conversion2 @gol
-fdelayed-branch @gol
@@ -3663,7 +3662,8 @@ also turns on the following optimization flags:
-fstrict-aliasing @gol
-funit-at-a-time @gol
-falign-functions -falign-jumps @gol
--falign-loops -falign-labels}
+-falign-loops -falign-labels @gol
+-fcrossjumping}
Please note the warning under @option{-fgcse} about
invoking @option{-O2} on programs that use computed gotos.
diff --git a/gcc/opts.c b/gcc/opts.c
index e058369..e87acce 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1,5 +1,5 @@
/* Command line option handling.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Neil Booth.
This file is part of GCC.
@@ -536,13 +536,13 @@ decode_options (unsigned int argc, const char **argv)
flag_guess_branch_prob = 1;
flag_cprop_registers = 1;
flag_loop_optimize = 1;
- flag_crossjumping = 1;
flag_if_conversion = 1;
flag_if_conversion2 = 1;
}
if (optimize >= 2)
{
+ flag_crossjumping = 1;
flag_optimize_sibling_calls = 1;
flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1;
diff --git a/gcc/recog.c b/gcc/recog.c
index 7df8d33..f366e39 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1,6 +1,6 @@
/* Subroutines used by or related to instruction recognition.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -476,16 +476,38 @@ validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object)
return;
}
- /* Call ourself recursively to perform the replacements. */
+ /* Call ourself recursively to perform the replacements.
+ We must not replace inside already replaced expression, otherwise we
+ get infinite recursion for replacements like (reg X)->(subreg (reg X))
+ done by regmove, so we must special case shared ASM_OPERANDS. */
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ if (GET_CODE (x) == PARALLEL)
{
- if (fmt[i] == 'e')
- validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+ for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
+ {
+ if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
+ {
+ /* Verify that operands are really shared. */
+ if (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0))) !=
+ ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, j))))
+ abort ();
+ validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
+ from, to, object);
+ }
+ else
+ validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object);
+ }
}
+ else
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+ }
/* If we didn't substitute, there is nothing more to do. */
if (num_changes == prev_changes)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 17e5580..9a5e726 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2004-01-01 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/debug/20031231-1.c: New.
+ * gcc.c-torture/compile/20040101-1.c: New.
+ * gcc.dg/dwarf-die-[1-7].c: New.
+
2004-01-01 Jakub Jelinek <jakub@redhat.com>
PR optimization/13521
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c
new file mode 100644
index 0000000..7ddef7d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c
@@ -0,0 +1,28 @@
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+#define CF (1<<0)
+#define PF (1<<2)
+#define AF (1<<4)
+#define ZF (1<<6)
+#define SF (1<<7)
+#define OF (1<<11)
+
+#define EFLAGS_BITS (CF|PF|AF|ZF|SF|OF)
+
+void test16(uint16_t x, uint32_t eflags)
+{
+ uint16_t bsr_result;
+ uint32_t bsr_eflags;
+ uint16_t bsf_result;
+ uint32_t bsf_eflags;
+
+ __asm volatile(""
+ : "=&r" (bsr_result), "=&r" (bsr_eflags)
+ : "r" (x), "i" (~EFLAGS_BITS), "r" (eflags));
+ __asm volatile(""
+ : "=&r" (bsf_result), "=&r" (bsf_eflags)
+ : "r" (x), "i" (~EFLAGS_BITS), "r" (eflags));
+ printf("%08x %04x bsrw %02x %08x bsfw %02x %08x\n",
+ x, eflags, bsr_result, bsr_eflags, bsf_result, bsf_eflags);
+}
diff --git a/gcc/testsuite/gcc.dg/debug/20031231-1.c b/gcc/testsuite/gcc.dg/debug/20031231-1.c
new file mode 100644
index 0000000..08e7ac4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/20031231-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+/* We used to fail because GCC didn't expect always inline to be inlined at
+ -O0. */
+typedef union tree_node *tree;
+typedef struct c_pretty_print_info c_pretty_printer;
+
+
+void pp_c_string_literal (c_pretty_printer *, tree);
+
+
+static __inline__ __attribute__((always_inline)) void
+pp_c_shift_expression (c_pretty_printer *pp, tree e)
+{
+ pp_c_shift_expression (pp,e);
+}
+
+static void
+pp_c_relational_expression (c_pretty_printer *pp, tree e)
+{
+ pp_c_shift_expression (pp, e);
+}
diff --git a/gcc/testsuite/gcc.dg/dwarf-die1.c b/gcc/testsuite/gcc.dg/dwarf-die1.c
new file mode 100644
index 0000000..39f0bf2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die1.c
@@ -0,0 +1,8 @@
+/* Verify that inline function never actually inlined has no abstract DIE. */
+/* { dg-do compile */
+/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
+inline int t()
+{
+}
+int (*q)()=t;
diff --git a/gcc/testsuite/gcc.dg/dwarf-die2.c b/gcc/testsuite/gcc.dg/dwarf-die2.c
new file mode 100644
index 0000000..48bce24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die2.c
@@ -0,0 +1,7 @@
+/* Verify that inline function never actually emit has no DIE. */
+/* { dg-do compile */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler-not "CIE Version" } } */
+static inline int t()
+{
+}
diff --git a/gcc/testsuite/gcc.dg/dwarf-die3.c b/gcc/testsuite/gcc.dg/dwarf-die3.c
new file mode 100644
index 0000000..34fddfa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die3.c
@@ -0,0 +1,11 @@
+/* Verify that extern inline function never actually inlined has no abstract DIE. */
+/* { dg-do compile */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
+extern inline int t()
+{
+}
+int (*q)()=t;
+int t()
+{
+}
diff --git a/gcc/testsuite/gcc.dg/dwarf-die5.c b/gcc/testsuite/gcc.dg/dwarf-die5.c
new file mode 100644
index 0000000..b3a245d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die5.c
@@ -0,0 +1,12 @@
+/* Inlined inline function must have abstract DIE */
+/* { dg-do compile */
+/* { dg-options "-O2 -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-final { scan-assembler "3.*DW_AT_inline" } } */
+#1 "test.h"
+inline int t()
+{
+}
+int q()
+{
+ t();
+}
diff --git a/gcc/testsuite/gcc.dg/dwarf-die6.c b/gcc/testsuite/gcc.dg/dwarf-die6.c
new file mode 100644
index 0000000..40cdc8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die6.c
@@ -0,0 +1,12 @@
+/* not inline inline function must not have abstract DIE */
+/* { dg-do compile */
+/* { dg-options "-O2 -fno-inline -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
+#1 "test.h"
+inline int t()
+{
+}
+int q()
+{
+ t();
+}
diff --git a/gcc/testsuite/gcc.dg/dwarf-die7.c b/gcc/testsuite/gcc.dg/dwarf-die7.c
new file mode 100644
index 0000000..d8d013a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dwarf-die7.c
@@ -0,0 +1,14 @@
+/* Inlined non-inline function must have abstract DIE */
+/* { dg-do compile */
+/* { dg-options "-O2 -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-final { scan-assembler "1.*DW_AT_inline" } } */
+#1 "test.h"
+void f(void);
+static int t()
+{
+ f();
+}
+int q()
+{
+ t();
+}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 6e34c6d..2219fe8 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1,6 +1,6 @@
/* Top level of GCC compilers (cc1, cc1plus, etc.)
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -277,8 +277,8 @@ enum dump_file_index
DFI_flow2,
DFI_peephole2,
DFI_rnreg,
- DFI_bbro,
DFI_ce3,
+ DFI_bbro,
DFI_branch_target_load,
DFI_sched2,
DFI_stack,
@@ -328,8 +328,8 @@ static struct dump_file_info dump_file[DFI_MAX] =
{ "flow2", 'w', 1, 0, 0 },
{ "peephole2", 'z', 1, 0, 0 },
{ "rnreg", 'n', 1, 0, 0 },
- { "bbro", 'B', 1, 0, 0 },
{ "ce3", 'E', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
{ "btl", 'd', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "sched2", 'R', 1, 0, 0 },
{ "stack", 'k', 1, 0, 0 },
@@ -3463,14 +3463,6 @@ rest_of_compilation (tree decl)
}
#endif
- if (optimize > 0)
- {
- if (flag_rename_registers || flag_cprop_registers)
- rest_of_handle_regrename (decl, insns);
-
- rest_of_handle_reorder_blocks (decl, insns);
- }
-
if (flag_if_conversion2)
{
timevar_push (TV_IFCVT2);
@@ -3482,23 +3474,31 @@ rest_of_compilation (tree decl)
timevar_pop (TV_IFCVT2);
}
- if (flag_branch_target_load_optimize2)
- {
- /* Leave this a warning for now so that it is possible to experiment
- with running this pass twice. In 3.6, we should either make this
- an error, or use separate dump files. */
- if (flag_branch_target_load_optimize)
- warning ("branch target register load optimization is not intended "
- "to be run twice");
+ if (optimize > 0)
+ {
+ if (flag_rename_registers || flag_cprop_registers)
+ rest_of_handle_regrename (decl, insns);
- open_dump_file (DFI_branch_target_load, decl);
+ rest_of_handle_reorder_blocks (decl, insns);
+ }
+
+ if (flag_branch_target_load_optimize2)
+ {
+ /* Leave this a warning for now so that it is possible to experiment
+ with running this pass twice. In 3.6, we should either make this
+ an error, or use separate dump files. */
+ if (flag_branch_target_load_optimize)
+ warning ("branch target register load optimization is not intended "
+ "to be run twice");
- branch_target_load_optimize (insns, true);
+ open_dump_file (DFI_branch_target_load, decl);
- close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
+ branch_target_load_optimize (insns, true);
- ggc_collect ();
- }
+ close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
+
+ ggc_collect ();
+ }
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)