From 99cf25d08b422ccf718a05f484e1be90f533ab63 Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 1 Jan 2004 13:59:02 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75303 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 24 ++++ gcc/c-decl.c | 3 +- gcc/c-objc-common.c | 5 +- gcc/cgraph.c | 6 +- gcc/cgraphunit.c | 173 +++++++++++++---------- gcc/doc/invoke.texi | 6 +- gcc/opts.c | 4 +- gcc/recog.c | 38 +++-- gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.c-torture/compile/20040101-1.c | 28 ++++ gcc/testsuite/gcc.dg/debug/20031231-1.c | 22 +++ gcc/testsuite/gcc.dg/dwarf-die1.c | 8 ++ gcc/testsuite/gcc.dg/dwarf-die2.c | 7 + gcc/testsuite/gcc.dg/dwarf-die3.c | 11 ++ gcc/testsuite/gcc.dg/dwarf-die5.c | 12 ++ gcc/testsuite/gcc.dg/dwarf-die6.c | 12 ++ gcc/testsuite/gcc.dg/dwarf-die7.c | 14 ++ gcc/toplev.c | 48 +++---- 18 files changed, 307 insertions(+), 120 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20040101-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/20031231-1.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die1.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die2.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die3.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die5.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die6.c create mode 100644 gcc/testsuite/gcc.dg/dwarf-die7.c 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 + + 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 + + * 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 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) -- 2.7.4