OSDN Git Service

* final.c (final_scan_insn): Handle NOTE_INSN_CALL_ARG_LOCATION.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Mar 2011 08:32:13 +0000 (08:32 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Mar 2011 08:32:13 +0000 (08:32 +0000)
Call var_location debug hook even on CALL_INSNs.
(rest_of_clean_state): Don't print NOTE_INSN_CALL_ARG_LOCATION.
* rtl.def (ENTRY_VALUE): New.
* dwarf2out.c: Include cfglayout.h.
(dwarf_stack_op_name, size_of_loc_descr, output_loc_operands,
output_loc_operands_raw): Handle DW_OP_GNU_entry_value.
(struct call_arg_loc_node): New type.
(call_arg_locations, call_arg_loc_last, block_map, call_site_count,
tail_call_site_count): New variables.
(dwarf_tag_name): Handle DW_TAG_GNU_call_site and
DW_TAG_GNU_call_site_parameter.
(dwarf_attr_name): Handle DW_AT_GNU_call_site_value,
DW_AT_GNU_call_site_data_value, DW_AT_GNU_call_site_target,
DW_AT_GNU_call_site_target_clobbered, DW_AT_GNU_tail_call,
DW_AT_GNU_all_tail_call_sites, DW_AT_GNU_all_call_sites
and DW_AT_GNU_all_source_call_sites.
(mem_loc_descriptor): Handle ENTRY_VALUE.
(add_src_coords_attributes): Don't add enything if
DECL_SOURCE_LOCATION is UNKNOWN_LOCATION.
(dwarf2out_abstract_function): Save and clear call_arg_location,
call_site_count and tail_call_site_count around dwarf2out_decl call.
(gen_call_site_die): New function.
(gen_subprogram_die): Emit DW_TAG_GNU_call_site DIEs for call sites.
(gen_lexical_block_die, gen_inlined_subroutine_die): Update block_map.
(dwarf2out_function_decl): Clear call_arg_locations,
call_arg_loc_last, set call_site_count and tail_call_site_count
to -1 and free block_map.
(dwarf2out_var_location): Handle NOTE_INSN_CALL_ARG_LOCATION and
CALL_INSNs.  Add NOTE_DURING_CALL_P var location notes even when not
followed by any real instructions.
(dwarf2out_begin_function): Set call_site_count and
tail_call_site_count to 0.
(resolve_addr): If DW_AT_abstract_origin of DW_TAG_GNU_call_site
is dw_val_class_addr, attempt to look it up again, for DECL_EXTERNAL
attempt to force a DIE for it and worst case remove the attribute.
(resolve_one_addr): For TREE_CONSTANT_POOL_ADDRESS_P SYMBOL_REFs
check TREE_ASM_WRITTEN of DECL_INITIAL of the decl instead of
the decl itself.
* var-tracking.c: Include tm_p.h.
(vt_stack_adjustments): For calls call note_register_arguments.
(argument_reg_set): New variable.
(add_stores): For MO_VAL_SET of non-tracked regs from argument_reg_set
ensure the VALUE is resolved.
(call_arguments): New variable.
(prepare_call_arguments): New function.
(add_with_sets): For MO_CALL set u.loc from call_arguments and clear it.
(struct expand_loc_callback_data): Add ignore_cur_loc field.
(vt_expand_loc_callback): If ignore_cur_loc, don't look at cur_loc and
always use the best expression.
(vt_expand_loc): Add ignore_cur_loc argument.
(vt_expand_loc_dummy): Clear ignore_cur_loc field.
(emit_note_insn_var_location): Adjust vt_expand_loc callers.
(emit_notes_in_bb) <case MO_CALL>: Add NOTE_INSN_CALL_ARG_LOCATION
note for all calls.
(vt_add_function_parameter): Use cselib_lookup_from_insn.
If dv is a VALUE, enter into hash table also ENTRY_VALUE for the
argument.  Don't call cselib_preserve_only_values and
cselib_reset_table.
(note_register_arguments): New function.
(vt_initialize): Compute argument_reg_set.  Call
vt_add_function_parameters before processing basic blocks instead of
afterwards.  For calls call prepare_call_arguments before calling
cselib_process_insn.
* print-rtl.c (print_rtx): Handle NOTE_INSN_CALL_ARG_LOCATION.
* Makefile.in (dwarf2out.o): Depend on $(CFGLAYOUT_H).
(var-tracking.o): Depend on $(TM_P_H).
* cfglayout.h (insn_scope): New prototype.
* gengtype.c (adjust_field_rtx_def): Handle NOTE_INSN_CALL_ARG_LOCATION.
* cfglayout.c (insn_scope): No longer static.
* insn-notes.def (CALL_ARG_LOCATION): New.
* calls.c (expand_call, emit_library_call_value_1): Put USEs for
MEM arguments into CALL_INSN_FUNCTION_USAGE unconditionally.
* integrate.c (set_block_origin_self, set_block_abstract_flags): Do
nothing for DECL_EXTERNAL BLOCK_VARS.
cp/
* cp-objcp-common.c (cp_function_decl_explicit_p): Don't crash if
DECL_LANG_SPECIFIC is NULL.
include/
* dwarf2.h (DW_TAG_GNU_call_site, DW_TAG_GNU_call_site_parameter,
DW_AT_GNU_call_site_value, DW_AT_GNU_call_site_data_value,
DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered,
DW_AT_GNU_tail_call, DW_AT_GNU_all_tail_call_sites,
DW_AT_GNU_all_call_sites,, DW_AT_GNU_all_source_call_sites,
DW_OP_GNU_entry_value): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171033 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/calls.c
gcc/cfglayout.c
gcc/cfglayout.h
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.c
gcc/dwarf2out.c
gcc/final.c
gcc/gengtype.c
gcc/insn-notes.def
gcc/integrate.c
gcc/print-rtl.c
gcc/rtl.def
gcc/var-tracking.c
include/ChangeLog
include/dwarf2.h

index 8762623..d42943d 100644 (file)
@@ -1,3 +1,81 @@
+2011-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * final.c (final_scan_insn): Handle NOTE_INSN_CALL_ARG_LOCATION.
+       Call var_location debug hook even on CALL_INSNs.
+       (rest_of_clean_state): Don't print NOTE_INSN_CALL_ARG_LOCATION.
+       * rtl.def (ENTRY_VALUE): New.
+       * dwarf2out.c: Include cfglayout.h.
+       (dwarf_stack_op_name, size_of_loc_descr, output_loc_operands,
+       output_loc_operands_raw): Handle DW_OP_GNU_entry_value.
+       (struct call_arg_loc_node): New type.
+       (call_arg_locations, call_arg_loc_last, block_map, call_site_count,
+       tail_call_site_count): New variables.
+       (dwarf_tag_name): Handle DW_TAG_GNU_call_site and
+       DW_TAG_GNU_call_site_parameter.
+       (dwarf_attr_name): Handle DW_AT_GNU_call_site_value,
+       DW_AT_GNU_call_site_data_value, DW_AT_GNU_call_site_target,
+       DW_AT_GNU_call_site_target_clobbered, DW_AT_GNU_tail_call,
+       DW_AT_GNU_all_tail_call_sites, DW_AT_GNU_all_call_sites
+       and DW_AT_GNU_all_source_call_sites.
+       (mem_loc_descriptor): Handle ENTRY_VALUE.
+       (add_src_coords_attributes): Don't add enything if
+       DECL_SOURCE_LOCATION is UNKNOWN_LOCATION.
+       (dwarf2out_abstract_function): Save and clear call_arg_location,
+       call_site_count and tail_call_site_count around dwarf2out_decl call.
+       (gen_call_site_die): New function.
+       (gen_subprogram_die): Emit DW_TAG_GNU_call_site DIEs for call sites.
+       (gen_lexical_block_die, gen_inlined_subroutine_die): Update block_map.
+       (dwarf2out_function_decl): Clear call_arg_locations,
+       call_arg_loc_last, set call_site_count and tail_call_site_count
+       to -1 and free block_map.
+       (dwarf2out_var_location): Handle NOTE_INSN_CALL_ARG_LOCATION and
+       CALL_INSNs.  Add NOTE_DURING_CALL_P var location notes even when not
+       followed by any real instructions.
+       (dwarf2out_begin_function): Set call_site_count and
+       tail_call_site_count to 0.
+       (resolve_addr): If DW_AT_abstract_origin of DW_TAG_GNU_call_site
+       is dw_val_class_addr, attempt to look it up again, for DECL_EXTERNAL
+       attempt to force a DIE for it and worst case remove the attribute.
+       (resolve_one_addr): For TREE_CONSTANT_POOL_ADDRESS_P SYMBOL_REFs
+       check TREE_ASM_WRITTEN of DECL_INITIAL of the decl instead of
+       the decl itself.
+       * var-tracking.c: Include tm_p.h.
+       (vt_stack_adjustments): For calls call note_register_arguments.
+       (argument_reg_set): New variable.
+       (add_stores): For MO_VAL_SET of non-tracked regs from argument_reg_set
+       ensure the VALUE is resolved.
+       (call_arguments): New variable.
+       (prepare_call_arguments): New function.
+       (add_with_sets): For MO_CALL set u.loc from call_arguments and clear it.
+       (struct expand_loc_callback_data): Add ignore_cur_loc field.
+       (vt_expand_loc_callback): If ignore_cur_loc, don't look at cur_loc and
+       always use the best expression.
+       (vt_expand_loc): Add ignore_cur_loc argument.
+       (vt_expand_loc_dummy): Clear ignore_cur_loc field.
+       (emit_note_insn_var_location): Adjust vt_expand_loc callers.
+       (emit_notes_in_bb) <case MO_CALL>: Add NOTE_INSN_CALL_ARG_LOCATION
+       note for all calls.
+       (vt_add_function_parameter): Use cselib_lookup_from_insn.
+       If dv is a VALUE, enter into hash table also ENTRY_VALUE for the
+       argument.  Don't call cselib_preserve_only_values and
+       cselib_reset_table.
+       (note_register_arguments): New function.
+       (vt_initialize): Compute argument_reg_set.  Call
+       vt_add_function_parameters before processing basic blocks instead of
+       afterwards.  For calls call prepare_call_arguments before calling
+       cselib_process_insn.
+       * print-rtl.c (print_rtx): Handle NOTE_INSN_CALL_ARG_LOCATION.
+       * Makefile.in (dwarf2out.o): Depend on $(CFGLAYOUT_H).
+       (var-tracking.o): Depend on $(TM_P_H).
+       * cfglayout.h (insn_scope): New prototype.
+       * gengtype.c (adjust_field_rtx_def): Handle NOTE_INSN_CALL_ARG_LOCATION.
+       * cfglayout.c (insn_scope): No longer static.
+       * insn-notes.def (CALL_ARG_LOCATION): New.
+       * calls.c (expand_call, emit_library_call_value_1): Put USEs for
+       MEM arguments into CALL_INSN_FUNCTION_USAGE unconditionally.
+       * integrate.c (set_block_origin_self, set_block_abstract_flags): Do
+       nothing for DECL_EXTERNAL BLOCK_VARS.
+
 2011-03-16  Alan Modra  <amodra@gmail.com>
 
        PR target/45844
 2011-03-16  Alan Modra  <amodra@gmail.com>
 
        PR target/45844
index 9a8262a..b4de74b 100644 (file)
@@ -3,7 +3,7 @@
 
 # Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
 # 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
 
 # Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
 # 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-# 2008, 2009, 2010 Free Software Foundation, Inc.
+# 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 #This file is part of GCC.
 
 
 #This file is part of GCC.
 
@@ -2933,7 +2933,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(LIBFUNCS_H) toplev.h $(DIAGNOSTIC_CORE_H) dwarf2out.h reload.h \
    $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
    gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \
    $(LIBFUNCS_H) toplev.h $(DIAGNOSTIC_CORE_H) dwarf2out.h reload.h \
    $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
    gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \
-   $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) tree-pretty-print.h
+   $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CFGLAYOUT_H) tree-pretty-print.h
 dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \
    gt-dwarf2asm.h $(DWARF2_H) $(SPLAY_TREE_H) $(TARGET_H)
 dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \
    gt-dwarf2asm.h $(DWARF2_H) $(SPLAY_TREE_H) $(TARGET_H)
@@ -3162,7 +3162,7 @@ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
    $(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
    cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) pointer-set.h \
    $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
    $(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
    cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) pointer-set.h \
-   $(RECOG_H) tree-pretty-print.h
+   $(RECOG_H) $(TM_P_H) tree-pretty-print.h
 profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
 profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
index f539f66..b15bfef 100644 (file)
@@ -1,7 +1,7 @@
 /* Convert function calls to rtl insns, for GNU C compiler.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Convert function calls to rtl insns, for GNU C compiler.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 
 This file is part of GCC.
 
@@ -2784,9 +2784,7 @@ expand_call (tree exp, rtx target, int ignore)
                sibcall_failure = 1;
              }
 
                sibcall_failure = 1;
              }
 
-         if (((flags & ECF_CONST)
-              || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
-             && args[i].stack)
+         if (args[i].stack)
            call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
                                             gen_rtx_USE (VOIDmode,
                                                          args[i].stack),
            call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
                                             gen_rtx_USE (VOIDmode,
                                                          args[i].stack),
@@ -3682,6 +3680,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
 
       if (! (reg != 0 && partial == 0))
        {
 
       if (! (reg != 0 && partial == 0))
        {
+         rtx use;
+
          if (ACCUMULATE_OUTGOING_ARGS)
            {
              /* If this is being stored into a pre-allocated, fixed-size,
          if (ACCUMULATE_OUTGOING_ARGS)
            {
              /* If this is being stored into a pre-allocated, fixed-size,
@@ -3752,28 +3752,22 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
 
          NO_DEFER_POP;
 
 
          NO_DEFER_POP;
 
-         if ((flags & ECF_CONST)
-             || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
-           {
-             rtx use;
-
-             /* Indicate argument access so that alias.c knows that these
-                values are live.  */
-             if (argblock)
-               use = plus_constant (argblock,
-                                    argvec[argnum].locate.offset.constant);
-             else
-               /* When arguments are pushed, trying to tell alias.c where
-                  exactly this argument is won't work, because the
-                  auto-increment causes confusion.  So we merely indicate
-                  that we access something with a known mode somewhere on
-                  the stack.  */
-               use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
-                                   gen_rtx_SCRATCH (Pmode));
-             use = gen_rtx_MEM (argvec[argnum].mode, use);
-             use = gen_rtx_USE (VOIDmode, use);
-             call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage);
-           }
+         /* Indicate argument access so that alias.c knows that these
+            values are live.  */
+         if (argblock)
+           use = plus_constant (argblock,
+                                argvec[argnum].locate.offset.constant);
+         else
+           /* When arguments are pushed, trying to tell alias.c where
+              exactly this argument is won't work, because the
+              auto-increment causes confusion.  So we merely indicate
+              that we access something with a known mode somewhere on
+              the stack.  */
+           use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
+                               gen_rtx_SCRATCH (Pmode));
+         use = gen_rtx_MEM (argvec[argnum].mode, use);
+         use = gen_rtx_USE (VOIDmode, use);
+         call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage);
        }
     }
 
        }
     }
 
index f7d4d10..76925a5 100644 (file)
@@ -1,6 +1,6 @@
 /* Basic block reordering routines for the GNU compiler.
 /* Basic block reordering routines for the GNU compiler.
-   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 
 This file is part of GCC.
 
@@ -54,7 +54,6 @@ static void change_scope (rtx, tree, tree);
 
 void verify_insn_chain (void);
 static void fixup_fallthru_exit_predecessor (void);
 
 void verify_insn_chain (void);
 static void fixup_fallthru_exit_predecessor (void);
-static tree insn_scope (const_rtx);
 \f
 rtx
 unlink_insn_chain (rtx first, rtx last)
 \f
 rtx
 unlink_insn_chain (rtx first, rtx last)
@@ -499,7 +498,7 @@ locator_scope (int loc)
 }
 
 /* Return lexical scope block insn belongs to.  */
 }
 
 /* Return lexical scope block insn belongs to.  */
-static tree
+tree
 insn_scope (const_rtx insn)
 {
   return locator_scope (INSN_LOCATOR (insn));
 insn_scope (const_rtx insn)
 {
   return locator_scope (INSN_LOCATOR (insn));
index 42b12dd..deb9856 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic block reordering routines for the GNU compiler.
 /* Basic block reordering routines for the GNU compiler.
-   Copyright (C) 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2003, 2004, 2007, 2011 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 
    This file is part of GCC.
 
@@ -27,6 +27,7 @@ extern GTY(()) rtx cfg_layout_function_header;
 
 extern void cfg_layout_initialize (unsigned int);
 extern void cfg_layout_finalize (void);
 
 extern void cfg_layout_initialize (unsigned int);
 extern void cfg_layout_finalize (void);
+extern tree insn_scope (const_rtx);
 extern void reemit_insn_block_notes (void);
 extern bool can_copy_bbs_p (basic_block *, unsigned);
 extern void copy_bbs (basic_block *, unsigned, basic_block *,
 extern void reemit_insn_block_notes (void);
 extern bool can_copy_bbs_p (basic_block *, unsigned);
 extern void copy_bbs (basic_block *, unsigned, basic_block *,
index f8249df..58ea1a5 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * cp-objcp-common.c (cp_function_decl_explicit_p): Don't crash if
+       DECL_LANG_SPECIFIC is NULL.
+
 2011-03-15  Jason Merrill  <jason@redhat.com>
 
        Core 1074
 2011-03-15  Jason Merrill  <jason@redhat.com>
 
        Core 1074
index f045d29..6e04269 100644 (file)
@@ -1,5 +1,6 @@
 /* Some code common to C++ and ObjC++ front ends.
 /* Some code common to C++ and ObjC++ front ends.
-   Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski@apple.com>
 
 This file is part of GCC.
    Contributed by Ziemowit Laski  <zlaski@apple.com>
 
 This file is part of GCC.
@@ -160,6 +161,7 @@ cp_function_decl_explicit_p (tree decl)
 {
   return (decl
          && FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node
 {
   return (decl
          && FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node
+         && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
          && DECL_NONCONVERTING_P (decl));
 }
 
          && DECL_NONCONVERTING_P (decl));
 }
 
index 3319c61..7e257c3 100644 (file)
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "tree-pass.h"
 #include "tree-flow.h"
 #include "gimple.h"
 #include "tree-pass.h"
 #include "tree-flow.h"
+#include "cfglayout.h"
 
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
 static rtx last_var_location_insn;
 
 static void dwarf2out_source_line (unsigned int, const char *, int, bool);
 static rtx last_var_location_insn;
@@ -4794,6 +4795,8 @@ dwarf_stack_op_name (unsigned int op)
       return "DW_OP_GNU_encoded_addr";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
       return "DW_OP_GNU_encoded_addr";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
 
     default:
       return "OP_<unknown>";
 
     default:
       return "OP_<unknown>";
@@ -4900,6 +4903,8 @@ loc_list_plus_const (dw_loc_list_ref list_head, HOST_WIDE_INT offset)
 #define DWARF_REF_SIZE \
   (dwarf_version == 2 ? DWARF2_ADDR_SIZE : DWARF_OFFSET_SIZE)
 
 #define DWARF_REF_SIZE \
   (dwarf_version == 2 ? DWARF2_ADDR_SIZE : DWARF_OFFSET_SIZE)
 
+static unsigned long size_of_locs (dw_loc_descr_ref);
+
 /* Return the size of a location descriptor.  */
 
 static unsigned long
 /* Return the size of a location descriptor.  */
 
 static unsigned long
@@ -5015,6 +5020,12 @@ size_of_loc_descr (dw_loc_descr_ref loc)
     case DW_OP_GNU_implicit_pointer:
       size += DWARF_REF_SIZE + size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
       break;
     case DW_OP_GNU_implicit_pointer:
       size += DWARF_REF_SIZE + size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
       break;
+    case DW_OP_GNU_entry_value:
+      {
+       unsigned long op_size = size_of_locs (loc->dw_loc_oprnd1.v.val_loc);
+       size += size_of_uleb128 (op_size) + op_size;
+       break;
+      }
     default:
       break;
     }
     default:
       break;
     }
@@ -5052,6 +5063,7 @@ size_of_locs (dw_loc_descr_ref loc)
 
 static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
 static void get_ref_die_offset_label (char *, dw_die_ref);
 
 static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
 static void get_ref_die_offset_label (char *, dw_die_ref);
+static void output_loc_sequence (dw_loc_descr_ref, int);
 
 /* Output location description stack opcode's operands (if any).
    The for_eh_or_skip parameter controls whether register numbers are
 
 /* Output location description stack opcode's operands (if any).
    The for_eh_or_skip parameter controls whether register numbers are
@@ -5301,6 +5313,11 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip)
       }
       break;
 
       }
       break;
 
+    case DW_OP_GNU_entry_value:
+      dw2_asm_output_data_uleb128 (size_of_locs (val1->v.val_loc), NULL);
+      output_loc_sequence (val1->v.val_loc, for_eh_or_skip);
+      break;
+
     default:
       /* Other codes have no operands.  */
       break;
     default:
       /* Other codes have no operands.  */
       break;
@@ -5477,6 +5494,7 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
       break;
 
     case DW_OP_GNU_implicit_pointer:
       break;
 
     case DW_OP_GNU_implicit_pointer:
+    case DW_OP_GNU_entry_value:
       gcc_unreachable ();
       break;
 
       gcc_unreachable ();
       break;
 
@@ -6115,10 +6133,33 @@ struct GTY (()) var_loc_list_def {
 };
 typedef struct var_loc_list_def var_loc_list;
 
 };
 typedef struct var_loc_list_def var_loc_list;
 
+/* Call argument location list.  */
+struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
+  rtx GTY (()) call_arg_loc_note;
+  const char * GTY (()) label;
+  tree GTY (()) block;
+  bool tail_call_p;
+  rtx GTY (()) symbol_ref;
+  struct call_arg_loc_node * GTY (()) next;
+};
+
 
 /* Table of decl location linked lists.  */
 static GTY ((param_is (var_loc_list))) htab_t decl_loc_table;
 
 
 /* Table of decl location linked lists.  */
 static GTY ((param_is (var_loc_list))) htab_t decl_loc_table;
 
+/* Head and tail of call_arg_loc chain.  */
+static GTY (()) struct call_arg_loc_node *call_arg_locations;
+static struct call_arg_loc_node *call_arg_loc_last;
+
+/* Number of call sites in the current function.  */
+static int call_site_count = -1;
+/* Number of tail call sites in the current function.  */
+static int tail_call_site_count = -1;
+
+/* Vector mapping block numbers to DW_TAG_{lexical_block,inlined_subroutine}
+   DIEs.  */
+static VEC (dw_die_ref, heap) *block_map;
+
 /* A pointer to the base of a list of references to DIE's that
    are uniquely identified by their tag, presence/absence of
    children DIE's, and list of attribute/value pairs.  */
 /* A pointer to the base of a list of references to DIE's that
    are uniquely identified by their tag, presence/absence of
    children DIE's, and list of attribute/value pairs.  */
@@ -6907,6 +6948,10 @@ dwarf_tag_name (unsigned int tag)
       return "DW_TAG_GNU_EINCL";
     case DW_TAG_GNU_template_template_param:
       return "DW_TAG_GNU_template_template_param";
       return "DW_TAG_GNU_EINCL";
     case DW_TAG_GNU_template_template_param:
       return "DW_TAG_GNU_template_template_param";
+    case DW_TAG_GNU_call_site:
+      return "DW_TAG_GNU_call_site";
+    case DW_TAG_GNU_call_site_parameter:
+      return "DW_TAG_GNU_call_site_parameter";
     default:
       return "DW_TAG_<unknown>";
     }
     default:
       return "DW_TAG_<unknown>";
     }
@@ -7151,6 +7196,22 @@ dwarf_attr_name (unsigned int attr)
       return "DW_AT_GNU_odr_signature";
     case DW_AT_GNU_template_name:
       return "DW_AT_GNU_template_name";
       return "DW_AT_GNU_odr_signature";
     case DW_AT_GNU_template_name:
       return "DW_AT_GNU_template_name";
+    case DW_AT_GNU_call_site_value:
+      return "DW_AT_GNU_call_site_value";
+    case DW_AT_GNU_call_site_data_value:
+      return "DW_AT_GNU_call_site_data_value";
+    case DW_AT_GNU_call_site_target:
+      return "DW_AT_GNU_call_site_target";
+    case DW_AT_GNU_call_site_target_clobbered:
+      return "DW_AT_GNU_call_site_target_clobbered";
+    case DW_AT_GNU_tail_call:
+      return "DW_AT_GNU_tail_call";
+    case DW_AT_GNU_all_tail_call_sites:
+      return "DW_AT_GNU_all_tail_call_sites";
+    case DW_AT_GNU_all_call_sites:
+      return "DW_AT_GNU_all_call_sites";
+    case DW_AT_GNU_all_source_call_sites:
+      return "DW_AT_GNU_all_source_call_sites";
 
     case DW_AT_VMS_rtnbeg_pd_address:
       return "DW_AT_VMS_rtnbeg_pd_address";
 
     case DW_AT_VMS_rtnbeg_pd_address:
       return "DW_AT_VMS_rtnbeg_pd_address";
@@ -13964,6 +14025,26 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
                        "CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
       return 0;
 
                        "CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
       return 0;
 
+    case ENTRY_VALUE:
+      mem_loc_result = new_loc_descr (DW_OP_GNU_entry_value, 0, 0);
+      mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_loc;
+      if (REG_P (XEXP (rtl, 0)))
+       mem_loc_result->dw_loc_oprnd1.v.val_loc
+         = one_reg_loc_descriptor (dbx_reg_number (XEXP (rtl, 0)),
+                                   VAR_INIT_STATUS_INITIALIZED);
+      else if (MEM_P (XEXP (rtl, 0)) && REG_P (XEXP (XEXP (rtl, 0), 0)))
+       {
+         dw_loc_descr_ref ref
+           = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
+                                 VAR_INIT_STATUS_INITIALIZED);
+         if (ref == NULL)
+           return NULL;
+         mem_loc_result->dw_loc_oprnd1.v.val_loc = ref;
+       }
+      else
+       gcc_unreachable ();
+      return mem_loc_result;
+
     case PRE_MODIFY:
       /* Extract the PLUS expression nested inside and fall into
         PLUS code below.  */
     case PRE_MODIFY:
       /* Extract the PLUS expression nested inside and fall into
         PLUS code below.  */
@@ -17842,8 +17923,11 @@ add_linkage_attr (dw_die_ref die, tree decl)
 static void
 add_src_coords_attributes (dw_die_ref die, tree decl)
 {
 static void
 add_src_coords_attributes (dw_die_ref die, tree decl)
 {
-  expanded_location s = expand_location (DECL_SOURCE_LOCATION (decl));
+  expanded_location s;
 
 
+  if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
+    return;
+  s = expand_location (DECL_SOURCE_LOCATION (decl));
   add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
   add_AT_unsigned (die, DW_AT_decl_line, s.line);
 }
   add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
   add_AT_unsigned (die, DW_AT_decl_line, s.line);
 }
@@ -18872,6 +18956,8 @@ dwarf2out_abstract_function (tree decl)
   tree context;
   int was_abstract;
   htab_t old_decl_loc_table;
   tree context;
   int was_abstract;
   htab_t old_decl_loc_table;
+  int old_call_site_count, old_tail_call_site_count;
+  struct call_arg_loc_node *old_call_arg_locations;
 
   /* Make sure we have the actual abstract inline, not a clone.  */
   decl = DECL_ORIGIN (decl);
 
   /* Make sure we have the actual abstract inline, not a clone.  */
   decl = DECL_ORIGIN (decl);
@@ -18886,6 +18972,12 @@ dwarf2out_abstract_function (tree decl)
      get locations in abstract instantces.  */
   old_decl_loc_table = decl_loc_table;
   decl_loc_table = NULL;
      get locations in abstract instantces.  */
   old_decl_loc_table = decl_loc_table;
   decl_loc_table = NULL;
+  old_call_arg_locations = call_arg_locations;
+  call_arg_locations = NULL;
+  old_call_site_count = call_site_count;
+  call_site_count = -1;
+  old_tail_call_site_count = tail_call_site_count;
+  tail_call_site_count = -1;
 
   /* Be sure we've emitted the in-class declaration DIE (if any) first, so
      we don't get confused by DECL_ABSTRACT.  */
 
   /* Be sure we've emitted the in-class declaration DIE (if any) first, so
      we don't get confused by DECL_ABSTRACT.  */
@@ -18910,6 +19002,9 @@ dwarf2out_abstract_function (tree decl)
 
   current_function_decl = save_fn;
   decl_loc_table = old_decl_loc_table;
 
   current_function_decl = save_fn;
   decl_loc_table = old_decl_loc_table;
+  call_arg_locations = old_call_arg_locations;
+  call_site_count = old_call_site_count;
+  tail_call_site_count = old_tail_call_site_count;
   pop_cfun ();
 }
 
   pop_cfun ();
 }
 
@@ -18985,6 +19080,43 @@ premark_types_used_by_global_vars (void)
                   premark_types_used_by_global_vars_helper, NULL);
 }
 
                   premark_types_used_by_global_vars_helper, NULL);
 }
 
+/* Generate a DW_TAG_GNU_call_site DIE in function DECL under SUBR_DIE
+   for CA_LOC call arg loc node.  */
+
+static dw_die_ref
+gen_call_site_die (tree decl, dw_die_ref subr_die,
+                  struct call_arg_loc_node *ca_loc)
+{
+  dw_die_ref stmt_die = NULL, die;
+  tree block = ca_loc->block;
+
+  while (block
+        && block != DECL_INITIAL (decl)
+        && TREE_CODE (block) == BLOCK)
+    {
+      if (VEC_length (dw_die_ref, block_map) > BLOCK_NUMBER (block))
+       stmt_die = VEC_index (dw_die_ref, block_map, BLOCK_NUMBER (block));
+      if (stmt_die)
+       break;
+      block = BLOCK_SUPERCONTEXT (block);
+    }
+  if (stmt_die == NULL)
+    stmt_die = subr_die;
+  die = new_die (DW_TAG_GNU_call_site, stmt_die, NULL_TREE);
+  add_AT_lbl_id (die, DW_AT_low_pc, ca_loc->label);
+  if (ca_loc->tail_call_p)
+    add_AT_flag (die, DW_AT_GNU_tail_call, 1);
+  if (ca_loc->symbol_ref)
+    {
+      dw_die_ref tdie = lookup_decl_die (SYMBOL_REF_DECL (ca_loc->symbol_ref));
+      if (tdie)
+       add_AT_die_ref (die, DW_AT_abstract_origin, tdie);
+      else
+       add_AT_addr (die, DW_AT_abstract_origin, ca_loc->symbol_ref);
+    }
+  return die;
+}
+
 /* Generate a DIE to represent a declared function (either file-scope or
    block-local).  */
 
 /* Generate a DIE to represent a declared function (either file-scope or
    block-local).  */
 
@@ -19467,12 +19599,113 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
      constructor function.  */
   if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK)
     {
      constructor function.  */
   if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK)
     {
+      int call_site_note_count = 0;
+      int tail_call_site_note_count = 0;
+
       /* Emit a DW_TAG_variable DIE for a named return value.  */
       if (DECL_NAME (DECL_RESULT (decl)))
        gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
 
       current_function_has_inlines = 0;
       decls_for_scope (outer_scope, subr_die, 0);
       /* Emit a DW_TAG_variable DIE for a named return value.  */
       if (DECL_NAME (DECL_RESULT (decl)))
        gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
 
       current_function_has_inlines = 0;
       decls_for_scope (outer_scope, subr_die, 0);
+
+      if (call_arg_locations)
+       {
+         struct call_arg_loc_node *ca_loc;
+         for (ca_loc = call_arg_locations; ca_loc; ca_loc = ca_loc->next)
+           {
+             dw_die_ref die = NULL;
+             rtx tloc = NULL_RTX;
+             rtx arg, next_arg;
+
+             for (arg = NOTE_VAR_LOCATION (ca_loc->call_arg_loc_note);
+                  arg; arg = next_arg)
+               {
+                 dw_loc_descr_ref reg, val;
+                 enum machine_mode mode = GET_MODE (XEXP (XEXP (arg, 0), 1));
+                 dw_die_ref cdie;
+
+                 next_arg = XEXP (arg, 1);
+                 if (REG_P (XEXP (XEXP (arg, 0), 0))
+                     && next_arg
+                     && MEM_P (XEXP (XEXP (next_arg, 0), 0))
+                     && REG_P (XEXP (XEXP (XEXP (next_arg, 0), 0), 0))
+                     && REGNO (XEXP (XEXP (arg, 0), 0))
+                        == REGNO (XEXP (XEXP (XEXP (next_arg, 0), 0), 0)))
+                   next_arg = XEXP (next_arg, 1);
+                 if (mode == VOIDmode)
+                   mode = GET_MODE (XEXP (XEXP (arg, 0), 0));
+                 if (GET_MODE_CLASS (mode) != MODE_INT
+                     || GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE)
+                   continue;
+                 if (XEXP (XEXP (arg, 0), 0) == pc_rtx)
+                   {
+                     gcc_assert (ca_loc->symbol_ref == NULL_RTX);
+                     tloc = XEXP (XEXP (arg, 0), 1);
+                     continue;
+                   }
+                 if (REG_P (XEXP (XEXP (arg, 0), 0)))
+                   reg = reg_loc_descriptor (XEXP (XEXP (arg, 0), 0),
+                                             VAR_INIT_STATUS_INITIALIZED);
+                 else if (MEM_P (XEXP (XEXP (arg, 0), 0)))
+                   reg = mem_loc_descriptor (XEXP (XEXP (XEXP (arg, 0),
+                                                         0), 0), mode,
+                                             VAR_INIT_STATUS_INITIALIZED);
+                 else
+                   continue;
+                 if (reg == NULL)
+                   continue;
+                 val = mem_loc_descriptor (XEXP (XEXP (arg, 0), 1), VOIDmode,
+                                           VAR_INIT_STATUS_INITIALIZED);
+                 if (val == NULL)
+                   continue;
+                 if (die == NULL)
+                   die = gen_call_site_die (decl, subr_die, ca_loc);
+                 cdie = new_die (DW_TAG_GNU_call_site_parameter, die,
+                                 NULL_TREE);           
+                 add_AT_loc (cdie, DW_AT_location, reg);
+                 add_AT_loc (cdie, DW_AT_GNU_call_site_value, val);
+                 if (next_arg != XEXP (arg, 1))
+                   {
+                     val = mem_loc_descriptor (XEXP (XEXP (XEXP (arg, 1),
+                                                           0), 1), VOIDmode,
+                                               VAR_INIT_STATUS_INITIALIZED);
+                     if (val != NULL)
+                       add_AT_loc (cdie, DW_AT_GNU_call_site_data_value, val);
+                   }
+               }
+             if (die == NULL
+                 && (ca_loc->symbol_ref || tloc))
+               die = gen_call_site_die (decl, subr_die, ca_loc);
+             if (die != NULL && tloc != NULL_RTX)
+               {
+                 dw_loc_descr_ref tval
+                   = mem_loc_descriptor (tloc, VOIDmode,
+                                         VAR_INIT_STATUS_INITIALIZED);
+                 if (tval)
+                   add_AT_loc (die, DW_AT_GNU_call_site_target, tval);
+               }
+             if (die != NULL)
+               {
+                 call_site_note_count++;
+                 if (ca_loc->tail_call_p)
+                   tail_call_site_note_count++;
+               }
+           }
+         call_arg_locations = NULL;
+         call_arg_loc_last = NULL;
+       }
+      if (tail_call_site_count >= 0
+         && tail_call_site_count == tail_call_site_note_count)
+       {
+         if (call_site_count >= 0
+             && call_site_count == call_site_note_count)
+           add_AT_flag (subr_die, DW_AT_GNU_all_call_sites, 1);
+         else
+           add_AT_flag (subr_die, DW_AT_GNU_all_tail_call_sites, 1);
+       }
+      call_site_count = -1;
+      tail_call_site_count = -1;
     }
   /* Add the calling convention attribute if requested.  */
   add_calling_convention_attribute (subr_die, decl);
     }
   /* Add the calling convention attribute if requested.  */
   add_calling_convention_attribute (subr_die, decl);
@@ -19861,6 +20094,14 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
 {
   dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
 
 {
   dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
 
+  if (call_arg_locations)
+    {
+      if (VEC_length (dw_die_ref, block_map) <= BLOCK_NUMBER (stmt))
+       VEC_safe_grow_cleared (dw_die_ref, heap, block_map,
+                              BLOCK_NUMBER (stmt) + 1);
+      VEC_replace (dw_die_ref, block_map, BLOCK_NUMBER (stmt), stmt_die);
+    }
+
   if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
     add_high_low_attributes (stmt, stmt_die);
 
   if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
     add_high_low_attributes (stmt, stmt_die);
 
@@ -19891,6 +20132,13 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
       dw_die_ref subr_die
        = new_die (DW_TAG_inlined_subroutine, context_die, stmt);
 
       dw_die_ref subr_die
        = new_die (DW_TAG_inlined_subroutine, context_die, stmt);
 
+      if (call_arg_locations)
+       {
+         if (VEC_length (dw_die_ref, block_map) <= BLOCK_NUMBER (stmt))
+           VEC_safe_grow_cleared (dw_die_ref, heap, block_map,
+                                  BLOCK_NUMBER (stmt) + 1);
+         VEC_replace (dw_die_ref, block_map, BLOCK_NUMBER (stmt), subr_die);
+       }
       add_abstract_origin_attribute (subr_die, decl);
       if (TREE_ASM_WRITTEN (stmt))
         add_high_low_attributes (stmt, subr_die);
       add_abstract_origin_attribute (subr_die, decl);
       if (TREE_ASM_WRITTEN (stmt))
         add_high_low_attributes (stmt, subr_die);
@@ -21502,7 +21750,11 @@ static void
 dwarf2out_function_decl (tree decl)
 {
   dwarf2out_decl (decl);
 dwarf2out_function_decl (tree decl)
 {
   dwarf2out_decl (decl);
-
+  call_arg_locations = NULL;
+  call_arg_loc_last = NULL;
+  call_site_count = -1;
+  tail_call_site_count = -1;
+  VEC_free (dw_die_ref, heap, block_map);
   htab_empty (decl_loc_table);
 }
 
   htab_empty (decl_loc_table);
 }
 
@@ -21899,16 +22151,35 @@ dwarf2out_var_location (rtx loc_note)
   static const char *last_postcall_label;
   static bool last_in_cold_section_p;
   tree decl;
   static const char *last_postcall_label;
   static bool last_in_cold_section_p;
   tree decl;
+  bool var_loc_p;
+
+  if (!NOTE_P (loc_note))
+    {
+      if (CALL_P (loc_note))
+       {
+         call_site_count++;
+         if (SIBLING_CALL_P (loc_note))
+           tail_call_site_count++;
+       }
+      return;
+    }
 
 
-  if (!DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
+  var_loc_p = NOTE_KIND (loc_note) == NOTE_INSN_VAR_LOCATION;
+  if (var_loc_p && !DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
     return;
 
   next_real = next_real_insn (loc_note);
     return;
 
   next_real = next_real_insn (loc_note);
+
   /* If there are no instructions which would be affected by this note,
      don't do anything.  */
   /* If there are no instructions which would be affected by this note,
      don't do anything.  */
-  if (next_real == NULL_RTX && !NOTE_DURING_CALL_P (loc_note))
+  if (var_loc_p
+      && next_real == NULL_RTX
+      && !NOTE_DURING_CALL_P (loc_note))
     return;
 
     return;
 
+  if (next_real == NULL_RTX)
+    next_real = get_last_insn ();
+
   /* If there were any real insns between note we processed last time
      and this note (or if it is the first note), clear
      last_{,postcall_}label so that they are not reused this time.  */
   /* If there were any real insns between note we processed last time
      and this note (or if it is the first note), clear
      last_{,postcall_}label so that they are not reused this time.  */
@@ -21920,12 +22191,20 @@ dwarf2out_var_location (rtx loc_note)
       last_postcall_label = NULL;
     }
 
       last_postcall_label = NULL;
     }
 
-  decl = NOTE_VAR_LOCATION_DECL (loc_note);
-  newloc = add_var_loc_to_decl (decl, loc_note,
-                               NOTE_DURING_CALL_P (loc_note)
-                               ? last_postcall_label : last_label);
-  if (newloc == NULL)
-    return;
+  if (var_loc_p)
+    {
+      decl = NOTE_VAR_LOCATION_DECL (loc_note);
+      newloc = add_var_loc_to_decl (decl, loc_note,
+                                   NOTE_DURING_CALL_P (loc_note)
+                                   ? last_postcall_label : last_label);
+      if (newloc == NULL)
+       return;
+    }
+  else
+    {
+      decl = NULL_TREE;
+      newloc = NULL;
+    }
 
   /* If there were no real insns between note we processed last time
      and this note, use the label we emitted last time.  Otherwise
 
   /* If there were no real insns between note we processed last time
      and this note, use the label we emitted last time.  Otherwise
@@ -21938,7 +22217,43 @@ dwarf2out_var_location (rtx loc_note)
       last_label = ggc_strdup (loclabel);
     }
 
       last_label = ggc_strdup (loclabel);
     }
 
-  if (!NOTE_DURING_CALL_P (loc_note))
+  if (!var_loc_p)
+    {
+      struct call_arg_loc_node *ca_loc
+       = ggc_alloc_cleared_call_arg_loc_node ();
+      rtx prev = prev_real_insn (loc_note), x;
+      ca_loc->call_arg_loc_note = loc_note;
+      ca_loc->next = NULL;
+      ca_loc->label = last_label;
+      gcc_assert (prev
+                 && (CALL_P (prev)
+                     || (NONJUMP_INSN_P (prev)
+                         && GET_CODE (PATTERN (prev)) == SEQUENCE
+                         && CALL_P (XVECEXP (PATTERN (prev), 0, 0)))));
+      if (!CALL_P (prev))
+       prev = XVECEXP (PATTERN (prev), 0, 0);
+      ca_loc->tail_call_p = SIBLING_CALL_P (prev);
+      x = PATTERN (prev);
+      if (GET_CODE (x) == PARALLEL)
+       x = XVECEXP (x, 0, 0);
+      if (GET_CODE (x) == SET)
+       x = SET_SRC (x);
+      if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
+       {
+         x = XEXP (XEXP (x, 0), 0);
+         if (GET_CODE (x) == SYMBOL_REF
+             && SYMBOL_REF_DECL (x)
+             && TREE_CODE (SYMBOL_REF_DECL (x)) == FUNCTION_DECL)
+           ca_loc->symbol_ref = x;
+       }
+      ca_loc->block = insn_scope (prev);
+      if (call_arg_locations)
+       call_arg_loc_last->next = ca_loc;
+      else
+       call_arg_locations = ca_loc;
+      call_arg_loc_last = ca_loc;
+    }
+  else if (!NOTE_DURING_CALL_P (loc_note))
     newloc->label = last_label;
   else
     {
     newloc->label = last_label;
   else
     {
@@ -21974,6 +22289,8 @@ dwarf2out_begin_function (tree fun)
     }
 
   dwarf2out_note_section_used ();
     }
 
   dwarf2out_note_section_used ();
+  call_site_count = 0;
+  tail_call_site_count = 0;
 }
 
 /* Output a label to mark the beginning of a source code line entry
 }
 
 /* Output a label to mark the beginning of a source code line entry
@@ -22804,9 +23121,16 @@ resolve_one_addr (rtx *addr, void *data ATTRIBUTE_UNUSED)
     }
 
   if (GET_CODE (rtl) == SYMBOL_REF
     }
 
   if (GET_CODE (rtl) == SYMBOL_REF
-      && SYMBOL_REF_DECL (rtl)
-      && !TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
-    return 1;
+      && SYMBOL_REF_DECL (rtl))
+    {
+      if (TREE_CONSTANT_POOL_ADDRESS_P (rtl))
+       {
+         if (!TREE_ASM_WRITTEN (DECL_INITIAL (SYMBOL_REF_DECL (rtl))))
+           return 1;
+       }
+      else if (!TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
+       return 1;
+    }
 
   if (GET_CODE (rtl) == CONST
       && for_each_rtx (&XEXP (rtl, 0), resolve_one_addr, NULL))
 
   if (GET_CODE (rtl) == CONST
       && for_each_rtx (&XEXP (rtl, 0), resolve_one_addr, NULL))
@@ -22898,6 +23222,28 @@ resolve_addr (dw_die_ref die)
            remove_AT (die, a->dw_attr);
            ix--;
          }
            remove_AT (die, a->dw_attr);
            ix--;
          }
+       if (die->die_tag == DW_TAG_GNU_call_site
+           && a->dw_attr == DW_AT_abstract_origin)
+         {
+           tree tdecl = SYMBOL_REF_DECL (a->dw_attr_val.v.val_addr);
+           dw_die_ref tdie = lookup_decl_die (tdecl);
+           if (tdie == NULL && DECL_EXTERNAL (tdecl))
+             {
+               force_decl_die (tdecl);
+               tdie = lookup_decl_die (tdecl);
+             }
+           if (tdie)
+             {
+               a->dw_attr_val.val_class = dw_val_class_die_ref;
+               a->dw_attr_val.v.val_die_ref.die = tdie;
+               a->dw_attr_val.v.val_die_ref.external = 0;
+             }
+           else
+             {
+               remove_AT (die, a->dw_attr);
+               ix--;
+             }
+         }
        break;
       default:
        break;
        break;
       default:
        break;
index 1e1424f..eb800c5 100644 (file)
@@ -1,6 +1,7 @@
 /* Convert RTL to assembler code and output it, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
 /* Convert RTL to assembler code and output it, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2005,6 +2006,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
          break;
 
        case NOTE_INSN_VAR_LOCATION:
          break;
 
        case NOTE_INSN_VAR_LOCATION:
+       case NOTE_INSN_CALL_ARG_LOCATION:
          if (!DECL_IGNORED_P (current_function_decl))
            debug_hooks->var_location (insn);
          break;
          if (!DECL_IGNORED_P (current_function_decl))
            debug_hooks->var_location (insn);
          break;
@@ -2671,6 +2673,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
                if (t)
                  assemble_external (t);
              }
                if (t)
                  assemble_external (t);
              }
+           if (!DECL_IGNORED_P (current_function_decl))
+             debug_hooks->var_location (insn);
          }
 
        /* Output assembler code from the template.  */
          }
 
        /* Output assembler code from the template.  */
@@ -4423,6 +4427,7 @@ rest_of_clean_state (void)
       if (final_output
          && (!NOTE_P (insn) ||
              (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
       if (final_output
          && (!NOTE_P (insn) ||
              (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
+              && NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION
               && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
               && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
               && NOTE_KIND (insn) != NOTE_INSN_CFA_RESTORE_STATE)))
               && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
               && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
               && NOTE_KIND (insn) != NOTE_INSN_CFA_RESTORE_STATE)))
index abf17f8..94cc449 100644 (file)
@@ -1,5 +1,5 @@
 /* Process source files and output type information.
 /* Process source files and output type information.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GCC.
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -1013,6 +1013,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
            break;
 
          case NOTE_INSN_VAR_LOCATION:
            break;
 
          case NOTE_INSN_VAR_LOCATION:
+         case NOTE_INSN_CALL_ARG_LOCATION:
            note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
            break;
 
            note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
            break;
 
index 83161ec..6cdbabd 100644 (file)
@@ -1,5 +1,5 @@
 /* Insn note definitions.
 /* Insn note definitions.
-   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 
 This file is part of GCC.
 
@@ -61,6 +61,9 @@ INSN_NOTE (EH_REGION_END)
 /* The location of a variable.  */
 INSN_NOTE (VAR_LOCATION)
 
 /* The location of a variable.  */
 INSN_NOTE (VAR_LOCATION)
 
+/* The values passed to callee.  */
+INSN_NOTE (CALL_ARG_LOCATION)
+
 /* Record the struct for the following basic block.  Uses
    NOTE_BASIC_BLOCK.  FIXME: Redundant with the basic block pointer
    now included in every insn.  */
 /* Record the struct for the following basic block.  Uses
    NOTE_BASIC_BLOCK.  FIXME: Redundant with the basic block pointer
    now included in every insn.  */
index 7072a75..3211fed 100644 (file)
@@ -1,6 +1,6 @@
 /* Procedure integration for GCC.
    Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* Procedure integration for GCC.
    Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -112,7 +112,8 @@ set_block_origin_self (tree stmt)
        for (local_decl = BLOCK_VARS (stmt);
             local_decl != NULL_TREE;
             local_decl = DECL_CHAIN (local_decl))
        for (local_decl = BLOCK_VARS (stmt);
             local_decl != NULL_TREE;
             local_decl = DECL_CHAIN (local_decl))
-         set_decl_origin_self (local_decl);    /* Potential recursion.  */
+         if (! DECL_EXTERNAL (local_decl))
+           set_decl_origin_self (local_decl);  /* Potential recursion.  */
       }
 
       {
       }
 
       {
@@ -173,7 +174,8 @@ set_block_abstract_flags (tree stmt, int setting)
   for (local_decl = BLOCK_VARS (stmt);
        local_decl != NULL_TREE;
        local_decl = DECL_CHAIN (local_decl))
   for (local_decl = BLOCK_VARS (stmt);
        local_decl != NULL_TREE;
        local_decl = DECL_CHAIN (local_decl))
-    set_decl_abstract_flags (local_decl, setting);
+    if (! DECL_EXTERNAL (local_decl))
+      set_decl_abstract_flags (local_decl, setting);
 
   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
     {
 
   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
     {
index 2a6a198..7748585 100644 (file)
@@ -1,6 +1,6 @@
 /* Print RTL for GCC.
    Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003,
 /* Print RTL for GCC.
    Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003,
-   2004, 2005, 2007, 2008, 2009, 2010
+   2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -302,6 +302,7 @@ print_rtx (const_rtx in_rtx)
                }
 
              case NOTE_INSN_VAR_LOCATION:
                }
 
              case NOTE_INSN_VAR_LOCATION:
+             case NOTE_INSN_CALL_ARG_LOCATION:
 #ifndef GENERATOR_FILE
                fputc (' ', outfile);
                print_rtx (NOTE_VAR_LOCATION (in_rtx));
 #ifndef GENERATOR_FILE
                fputc (' ', outfile);
                print_rtx (NOTE_VAR_LOCATION (in_rtx));
index 6e2aa8b..885cbcf 100644 (file)
@@ -2,7 +2,7 @@
    Register Transfer Expressions (rtx's) that make up the
    Register Transfer Language (rtl) used in the Back End of the GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2004,
    Register Transfer Expressions (rtx's) that make up the
    Register Transfer Language (rtl) used in the Back End of the GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2004,
-   2005, 2006, 2007, 2008, 2009, 2010
+   2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -718,6 +718,10 @@ DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA)
    addressable.  */
 DEF_RTL_EXPR(DEBUG_IMPLICIT_PTR, "debug_implicit_ptr", "t", RTX_OBJ)
 
    addressable.  */
 DEF_RTL_EXPR(DEBUG_IMPLICIT_PTR, "debug_implicit_ptr", "t", RTX_OBJ)
 
+/* Represents value that argument had on function entry.  Should
+   be only used in VAR_LOCATION location expression.  */
+DEF_RTL_EXPR(ENTRY_VALUE, "entry_value", "e", RTX_OBJ)
+
 /* All expressions from this point forward appear only in machine
    descriptions.  */
 #ifdef GENERATOR_FILE
 /* All expressions from this point forward appear only in machine
    descriptions.  */
 #ifdef GENERATOR_FILE
index a9efcb1..7141ab5 100644 (file)
 #include "tree-pretty-print.h"
 #include "pointer-set.h"
 #include "recog.h"
 #include "tree-pretty-print.h"
 #include "pointer-set.h"
 #include "recog.h"
+#include "tm_p.h"
 
 /* var-tracking.c assumes that tree code with the same value as VALUE rtx code
    has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
 
 /* var-tracking.c assumes that tree code with the same value as VALUE rtx code
    has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
@@ -408,6 +409,7 @@ static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
                                               HOST_WIDE_INT *);
 static bool vt_stack_adjustments (void);
 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
                                               HOST_WIDE_INT *);
 static bool vt_stack_adjustments (void);
+static void note_register_arguments (rtx);
 static hashval_t variable_htab_hash (const void *);
 static int variable_htab_eq (const void *, const void *);
 static void variable_htab_free (void *);
 static hashval_t variable_htab_hash (const void *);
 static int variable_htab_eq (const void *, const void *);
 static void variable_htab_free (void *);
@@ -659,11 +661,15 @@ vt_stack_adjustments (void)
            for (insn = BB_HEAD (dest);
                 insn != NEXT_INSN (BB_END (dest));
                 insn = NEXT_INSN (insn))
            for (insn = BB_HEAD (dest);
                 insn != NEXT_INSN (BB_END (dest));
                 insn = NEXT_INSN (insn))
-             if (INSN_P (insn))
-               {
-                 insn_stack_adjust_offset_pre_post (insn, &pre, &post);
-                 offset += pre + post;
-               }
+             {
+               if (INSN_P (insn))
+                 {
+                   insn_stack_adjust_offset_pre_post (insn, &pre, &post);
+                   offset += pre + post;
+                 }
+               if (CALL_P (insn))
+                 note_register_arguments (insn);
+             }
 
          VTI (dest)->out.stack_adjust = offset;
 
 
          VTI (dest)->out.stack_adjust = offset;
 
@@ -4971,6 +4977,9 @@ log_op_type (rtx x, basic_block bb, rtx insn,
 /* All preserved VALUEs.  */
 static VEC (rtx, heap) *preserved_values;
 
 /* All preserved VALUEs.  */
 static VEC (rtx, heap) *preserved_values;
 
+/* Registers used in the current function for passing parameters.  */
+static HARD_REG_SET argument_reg_set;
+
 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
 
 static void
 /* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
 
 static void
@@ -5324,10 +5333,22 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
        {
          mo.type = MO_CLOBBER;
          mo.u.loc = loc;
        {
          mo.type = MO_CLOBBER;
          mo.u.loc = loc;
+         if (GET_CODE (expr) == SET
+             && SET_DEST (expr) == loc
+             && REGNO (loc) < FIRST_PSEUDO_REGISTER
+             && TEST_HARD_REG_BIT (argument_reg_set, REGNO (loc))
+             && find_use_val (loc, mode, cui)
+             && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
+           {
+             gcc_checking_assert (type == MO_VAL_SET);
+             mo.u.loc = gen_rtx_SET (VOIDmode, loc, SET_SRC (expr));
+           }
        }
       else
        {
        }
       else
        {
-         if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
+         if (GET_CODE (expr) == SET
+             && SET_DEST (expr) == loc
+             && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
            src = var_lowpart (mode2, SET_SRC (expr));
          loc = var_lowpart (mode2, loc);
 
            src = var_lowpart (mode2, SET_SRC (expr));
          loc = var_lowpart (mode2, loc);
 
@@ -5387,7 +5408,9 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
        }
       else
        {
        }
       else
        {
-         if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
+         if (GET_CODE (expr) == SET
+             && SET_DEST (expr) == loc
+             && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
            src = var_lowpart (mode2, SET_SRC (expr));
          loc = var_lowpart (mode2, loc);
 
            src = var_lowpart (mode2, SET_SRC (expr));
          loc = var_lowpart (mode2, loc);
 
@@ -5542,6 +5565,195 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
 }
 
   VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
 }
 
+/* Arguments to the call.  */
+static rtx call_arguments;
+
+/* Compute call_arguments.  */
+
+static void
+prepare_call_arguments (basic_block bb, rtx insn)
+{
+  rtx link, x;
+  rtx prev, cur, next;
+  rtx call = PATTERN (insn);
+  tree type = NULL_TREE, t;
+  CUMULATIVE_ARGS args_so_far;
+
+  memset (&args_so_far, 0, sizeof (args_so_far));
+  if (GET_CODE (call) == PARALLEL)
+    call = XVECEXP (call, 0, 0);
+  if (GET_CODE (call) == SET)
+    call = SET_SRC (call);
+  if (GET_CODE (call) == CALL
+      && MEM_P (XEXP (call, 0))
+      && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
+    {
+      rtx symbol = XEXP (XEXP (call, 0), 0);
+      if (SYMBOL_REF_DECL (symbol)
+         && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL
+         && TYPE_ARG_TYPES (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
+       {
+         type = TREE_TYPE (SYMBOL_REF_DECL (symbol));
+         for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
+              t = TREE_CHAIN (t))
+           if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
+               && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
+             break;
+         if (t == NULL || t == void_list_node)
+           type = NULL;
+         else
+           INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX,
+                                 SYMBOL_REF_DECL (symbol),
+                                 list_length (TYPE_ARG_TYPES (type)));
+       }
+    }
+  t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
+
+  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+    if (GET_CODE (XEXP (link, 0)) == USE)
+      {
+       rtx item = NULL_RTX;
+       x = XEXP (XEXP (link, 0), 0);
+       if (REG_P (x))
+         {
+           cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
+           if (val && cselib_preserved_value_p (val))
+             item = gen_rtx_CONCAT (GET_MODE (x), x, val->val_rtx);
+           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
+             {
+               enum machine_mode mode = GET_MODE (x);
+
+               while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
+                      && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
+                 {
+                   rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
+
+                   if (reg == NULL_RTX || !REG_P (reg))
+                     continue;
+                   val = cselib_lookup (reg, mode, 0, VOIDmode);
+                   if (val && cselib_preserved_value_p (val))
+                     {
+                       item = gen_rtx_CONCAT (GET_MODE (x), x,
+                                              lowpart_subreg (GET_MODE (x),
+                                                              val->val_rtx,
+                                                              mode));
+                       break;
+                     }
+                 }
+             }
+         }
+       else if (MEM_P (x))
+         {
+           rtx mem = x;
+           cselib_val *val;
+
+           if (!frame_pointer_needed)
+             {
+               struct adjust_mem_data amd;
+               amd.mem_mode = VOIDmode;
+               amd.stack_adjust = -VTI (bb)->out.stack_adjust;
+               amd.side_effects = NULL_RTX;
+               amd.store = true;
+               mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
+                                              &amd);
+               gcc_assert (amd.side_effects == NULL_RTX);
+             }
+           val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
+           if (val && cselib_preserved_value_p (val))
+             item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x), val->val_rtx);
+         }
+       if (item)
+         call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
+       if (t && t != void_list_node)
+         {
+           enum machine_mode mode = TYPE_MODE (TREE_VALUE (t));
+           rtx reg = targetm.calls.function_arg (&args_so_far, mode,
+                                                 TREE_VALUE (t), true);
+           if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
+               && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t)))
+               && reg
+               && REG_P (reg)
+               && GET_MODE (reg) == mode
+               && GET_MODE_CLASS (mode) == MODE_INT
+               && REG_P (x)
+               && REGNO (x) == REGNO (reg)
+               && GET_MODE (x) == mode
+               && item)
+             {
+               enum machine_mode indmode
+                 = TYPE_MODE (TREE_TYPE (TREE_VALUE (t)));
+               rtx mem = gen_rtx_MEM (indmode, x);
+               cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
+               if (val && cselib_preserved_value_p (val))
+                 {
+                   item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
+                   call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
+                                                       call_arguments);
+                 }
+               else
+                 {
+                   struct elt_loc_list *l;
+                   tree initial;
+
+                   /* Try harder, when passing address of a constant
+                      pool integer it can be easily read back.  */
+                   val = CSELIB_VAL_PTR (XEXP (item, 1));
+                   for (l = val->locs; l; l = l->next)
+                     if (GET_CODE (l->loc) == SYMBOL_REF
+                         && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
+                         && SYMBOL_REF_DECL (l->loc)
+                         && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
+                       {
+                         initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
+                         if (host_integerp (initial, 0))
+                           {
+                             item = GEN_INT (tree_low_cst (initial, 0));
+                             item = gen_rtx_CONCAT (indmode, mem, item);
+                             call_arguments
+                               = gen_rtx_EXPR_LIST (VOIDmode, item,
+                                                    call_arguments);
+                           }
+                         break;
+                       }
+                 }
+             }
+           targetm.calls.function_arg_advance (&args_so_far, mode,
+                                               TREE_VALUE (t), true);
+           t = TREE_CHAIN (t);
+         }
+      }
+
+  /* Reverse call_arguments chain.  */
+  prev = NULL_RTX;
+  for (cur = call_arguments; cur; cur = next)
+    {
+      next = XEXP (cur, 1);
+      XEXP (cur, 1) = prev;
+      prev = cur;
+    }
+  call_arguments = prev;
+
+  x = PATTERN (insn);
+  if (GET_CODE (x) == PARALLEL)
+    x = XVECEXP (x, 0, 0);
+  if (GET_CODE (x) == SET)
+    x = SET_SRC (x);
+  if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
+    {
+      x = XEXP (XEXP (x, 0), 0);
+      if (GET_CODE (x) != SYMBOL_REF)
+       {
+         cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
+         if (val && cselib_preserved_value_p (val))
+           {
+             x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
+             call_arguments
+               = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
+           }
+       }
+    }
+}
+
 /* Callback for cselib_record_sets_hook, that records as micro
    operations uses and stores in an insn after cselib_record_sets has
    analyzed the sets in an insn, but before it modifies the stored
 /* Callback for cselib_record_sets_hook, that records as micro
    operations uses and stores in an insn after cselib_record_sets has
    analyzed the sets in an insn, but before it modifies the stored
@@ -5611,7 +5823,8 @@ add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
 
       mo.type = MO_CALL;
       mo.insn = insn;
 
       mo.type = MO_CALL;
       mo.insn = insn;
-      mo.u.loc = NULL_RTX;
+      mo.u.loc = call_arguments;
+      call_arguments = NULL_RTX;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
@@ -6927,6 +7140,10 @@ struct expand_loc_callback_data
      whose cur_loc has been already recomputed during current
      emit_notes_for_changes call.  */
   bool cur_loc_changed;
      whose cur_loc has been already recomputed during current
      emit_notes_for_changes call.  */
   bool cur_loc_changed;
+
+  /* True if cur_loc should be ignored and any possible location
+     returned.  */
+  bool ignore_cur_loc;
 };
 
 /* Callback for cselib_expand_value, that looks for expressions
 };
 
 /* Callback for cselib_expand_value, that looks for expressions
@@ -6940,6 +7157,7 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
     = (struct expand_loc_callback_data *) data;
   bool dummy = elcd->dummy;
   bool cur_loc_changed = elcd->cur_loc_changed;
     = (struct expand_loc_callback_data *) data;
   bool dummy = elcd->dummy;
   bool cur_loc_changed = elcd->cur_loc_changed;
+  rtx cur_loc;
   decl_or_value dv;
   variable var;
   location_chain loc;
   decl_or_value dv;
   variable var;
   location_chain loc;
@@ -7014,7 +7232,7 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
   VALUE_RECURSED_INTO (x) = true;
   result = NULL;
 
   VALUE_RECURSED_INTO (x) = true;
   result = NULL;
 
-  if (var->var_part[0].cur_loc)
+  if (var->var_part[0].cur_loc && !elcd->ignore_cur_loc)
     {
       if (dummy)
        {
     {
       if (dummy)
        {
@@ -7029,12 +7247,16 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
                                             vt_expand_loc_callback, data);
       if (result)
        set_dv_changed (dv, false);
                                             vt_expand_loc_callback, data);
       if (result)
        set_dv_changed (dv, false);
+      cur_loc = var->var_part[0].cur_loc;
     }
     }
-  if (!result && dv_changed_p (dv))
+  else
+    cur_loc = NULL_RTX;
+  if (!result && (dv_changed_p (dv) || elcd->ignore_cur_loc))
     {
     {
-      set_dv_changed (dv, false);
+      if (!elcd->ignore_cur_loc)
+       set_dv_changed (dv, false);
       for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
       for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
-       if (loc->loc == var->var_part[0].cur_loc)
+       if (loc->loc == cur_loc)
          continue;
        else if (dummy)
          {
          continue;
        else if (dummy)
          {
@@ -7056,7 +7278,8 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
          }
       if (dummy && (result || var->var_part[0].cur_loc))
        var->cur_loc_changed = true;
          }
       if (dummy && (result || var->var_part[0].cur_loc))
        var->cur_loc_changed = true;
-      var->var_part[0].cur_loc = loc ? loc->loc : NULL_RTX;
+      if (!elcd->ignore_cur_loc)
+       var->var_part[0].cur_loc = loc ? loc->loc : NULL_RTX;
     }
   if (dummy)
     {
     }
   if (dummy)
     {
@@ -7077,7 +7300,7 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
    tables.  */
 
 static rtx
    tables.  */
 
 static rtx
-vt_expand_loc (rtx loc, htab_t vars)
+vt_expand_loc (rtx loc, htab_t vars, bool ignore_cur_loc)
 {
   struct expand_loc_callback_data data;
 
 {
   struct expand_loc_callback_data data;
 
@@ -7087,6 +7310,7 @@ vt_expand_loc (rtx loc, htab_t vars)
   data.vars = vars;
   data.dummy = false;
   data.cur_loc_changed = false;
   data.vars = vars;
   data.dummy = false;
   data.cur_loc_changed = false;
+  data.ignore_cur_loc = ignore_cur_loc;
   loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 8,
                                    vt_expand_loc_callback, &data);
 
   loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 8,
                                    vt_expand_loc_callback, &data);
 
@@ -7108,6 +7332,7 @@ vt_expand_loc_dummy (rtx loc, htab_t vars, bool *pcur_loc_changed)
   data.vars = vars;
   data.dummy = true;
   data.cur_loc_changed = false;
   data.vars = vars;
   data.dummy = true;
   data.cur_loc_changed = false;
+  data.ignore_cur_loc = false;
   ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, 8,
                                          vt_expand_loc_callback, &data);
   *pcur_loc_changed = data.cur_loc_changed;
   ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, 8,
                                          vt_expand_loc_callback, &data);
   *pcur_loc_changed = data.cur_loc_changed;
@@ -7178,7 +7403,7 @@ emit_note_insn_var_location (void **varp, void *data)
          complete = false;
          continue;
        }
          complete = false;
          continue;
        }
-      loc2 = vt_expand_loc (var->var_part[i].cur_loc, vars);
+      loc2 = vt_expand_loc (var->var_part[i].cur_loc, vars, false);
       if (!loc2)
        {
          complete = false;
       if (!loc2)
        {
          complete = false;
@@ -7208,7 +7433,7 @@ emit_note_insn_var_location (void **varp, void *data)
          && mode == GET_MODE (var->var_part[j].cur_loc)
          && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
          && last_limit == var->var_part[j].offset
          && mode == GET_MODE (var->var_part[j].cur_loc)
          && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
          && last_limit == var->var_part[j].offset
-         && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
+         && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars, false))
          && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
        {
          rtx new_loc = NULL;
          && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
        {
          rtx new_loc = NULL;
@@ -7662,6 +7887,34 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
          case MO_CALL:
            dataflow_set_clear_at_call (set);
            emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
          case MO_CALL:
            dataflow_set_clear_at_call (set);
            emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
+           {
+             rtx arguments = mo->u.loc, *p = &arguments, note;
+             while (*p)
+               {
+                 XEXP (XEXP (*p, 0), 1)
+                   = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
+                                    shared_hash_htab (set->vars), true);
+                 /* If expansion is successful, keep it in the list.  */
+                 if (XEXP (XEXP (*p, 0), 1))
+                   p = &XEXP (*p, 1);
+                 /* Otherwise, if the following item is data_value for it,
+                    drop it too too.  */
+                 else if (XEXP (*p, 1)
+                          && REG_P (XEXP (XEXP (*p, 0), 0))
+                          && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
+                          && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
+                                          0))
+                          && REGNO (XEXP (XEXP (*p, 0), 0))
+                             == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
+                                                   0), 0)))
+                   *p = XEXP (XEXP (*p, 1), 1);
+                 /* Just drop this item.  */
+                 else
+                   *p = XEXP (*p, 1);
+               }
+             note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
+             NOTE_VAR_LOCATION (note) = arguments;
+           }
            break;
 
          case MO_USE:
            break;
 
          case MO_USE:
@@ -8095,8 +8348,8 @@ vt_add_function_parameter (tree parm)
       if (offset)
        return;
 
       if (offset)
        return;
 
-      val = cselib_lookup (var_lowpart (mode, incoming), mode, true,
-                          VOIDmode);
+      val = cselib_lookup_from_insn (var_lowpart (mode, incoming), mode, true,
+                                    VOIDmode, get_insns ());
 
       /* ??? Float-typed values in memory are not handled by
         cselib.  */
 
       /* ??? Float-typed values in memory are not handled by
         cselib.  */
@@ -8117,6 +8370,36 @@ vt_add_function_parameter (tree parm)
                         incoming);
       set_variable_part (out, incoming, dv, offset,
                         VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
                         incoming);
       set_variable_part (out, incoming, dv, offset,
                         VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+      if (dv_is_value_p (dv))
+       {
+         cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv));
+         struct elt_loc_list *el;
+         el = (struct elt_loc_list *)
+           ggc_alloc_cleared_atomic (sizeof (*el));
+         el->next = val->locs;
+         el->loc = gen_rtx_ENTRY_VALUE (GET_MODE (incoming), incoming);
+         el->setting_insn = get_insns ();
+         val->locs = el;
+         if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
+             && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
+           {
+             enum machine_mode indmode
+               = TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
+             rtx mem = gen_rtx_MEM (indmode, incoming);
+             val = cselib_lookup_from_insn (mem, indmode, true,
+                                            VOIDmode, get_insns ());
+             if (val)
+               {
+                 preserve_value (val);
+                 el = (struct elt_loc_list *)
+                   ggc_alloc_cleared_atomic (sizeof (*el));
+                 el->next = val->locs;
+                 el->loc = gen_rtx_ENTRY_VALUE (indmode, mem);
+                 el->setting_insn = get_insns ();
+                 val->locs = el;
+               }
+           }
+       }
     }
   else if (MEM_P (incoming))
     {
     }
   else if (MEM_P (incoming))
     {
@@ -8150,13 +8433,6 @@ vt_add_function_parameters (void)
          && DECL_NAMELESS (vexpr))
        vt_add_function_parameter (vexpr);
     }
          && DECL_NAMELESS (vexpr))
        vt_add_function_parameter (vexpr);
     }
-
-  if (MAY_HAVE_DEBUG_INSNS)
-    {
-      cselib_preserve_only_values ();
-      cselib_reset_table (cselib_get_next_uid ());
-    }
-
 }
 
 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
 }
 
 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
@@ -8184,6 +8460,23 @@ fp_setter (rtx insn)
   return false;
 }
 
   return false;
 }
 
+/* Gather all registers used for passing arguments to other functions
+   called from the current routine.  */
+
+static void
+note_register_arguments (rtx insn)
+{
+  rtx link, x;
+
+  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+    if (GET_CODE (XEXP (link, 0)) == USE)
+      {
+       x = XEXP (XEXP (link, 0), 0);
+       if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
+         SET_HARD_REG_BIT (argument_reg_set, REGNO (x));
+      }
+}
+
 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
    ensure it isn't flushed during cselib_reset_table.
    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
 /* Initialize cfa_base_rtx, create a preserved VALUE for it and
    ensure it isn't flushed during cselib_reset_table.
    Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
@@ -8286,6 +8579,8 @@ vt_initialize (void)
       valvar_pool = NULL;
     }
 
       valvar_pool = NULL;
     }
 
+  CLEAR_HARD_REG_SET (argument_reg_set);
+
   if (!frame_pointer_needed)
     {
       rtx reg, elim;
   if (!frame_pointer_needed)
     {
       rtx reg, elim;
@@ -8332,9 +8627,18 @@ vt_initialize (void)
            prologue_bb = single_succ (ENTRY_BLOCK_PTR);
        }
     }
            prologue_bb = single_succ (ENTRY_BLOCK_PTR);
        }
     }
+  if (frame_pointer_needed)
+    {
+      rtx insn;
+      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+       if (CALL_P (insn))
+         note_register_arguments (insn);
+    }
 
   hard_frame_pointer_adjustment = -1;
 
 
   hard_frame_pointer_adjustment = -1;
 
+  vt_add_function_parameters ();
+
   FOR_EACH_BB (bb)
     {
       rtx insn;
   FOR_EACH_BB (bb)
     {
       rtx insn;
@@ -8395,6 +8699,8 @@ vt_initialize (void)
                  adjust_insn (bb, insn);
                  if (MAY_HAVE_DEBUG_INSNS)
                    {
                  adjust_insn (bb, insn);
                  if (MAY_HAVE_DEBUG_INSNS)
                    {
+                     if (CALL_P (insn))
+                       prepare_call_arguments (bb, insn);
                      cselib_process_insn (insn);
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        {
                      cselib_process_insn (insn);
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        {
@@ -8445,7 +8751,6 @@ vt_initialize (void)
 
   hard_frame_pointer_adjustment = -1;
   VTI (ENTRY_BLOCK_PTR)->flooded = true;
 
   hard_frame_pointer_adjustment = -1;
   VTI (ENTRY_BLOCK_PTR)->flooded = true;
-  vt_add_function_parameters ();
   cfa_base_rtx = NULL_RTX;
   return true;
 }
   cfa_base_rtx = NULL_RTX;
   return true;
 }
index c4ec00e..2b674d7 100644 (file)
@@ -1,3 +1,12 @@
+2011-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+       * dwarf2.h (DW_TAG_GNU_call_site, DW_TAG_GNU_call_site_parameter,
+       DW_AT_GNU_call_site_value, DW_AT_GNU_call_site_data_value,
+       DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered,
+       DW_AT_GNU_tail_call, DW_AT_GNU_all_tail_call_sites,
+       DW_AT_GNU_all_call_sites,, DW_AT_GNU_all_source_call_sites,
+       DW_OP_GNU_entry_value): New.
+
 2011-02-28  Kai Tietz  <kai.tietz@onevision.com>
 
        * filenames.h (filename_ncmp): New prototype.
 2011-02-28  Kai Tietz  <kai.tietz@onevision.com>
 
        * filenames.h (filename_ncmp): New prototype.
index 7d3f5e4..46f2291 100644 (file)
@@ -1,7 +1,7 @@
 /* Declarations and definitions of codes relating to the DWARF2 and
    DWARF3 symbolic debugging information formats.
    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
 /* Declarations and definitions of codes relating to the DWARF2 and
    DWARF3 symbolic debugging information formats.
    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
    Free Software Foundation, Inc.
 
    Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
@@ -141,6 +141,12 @@ enum dwarf_tag
        are properly part of DWARF 5.  */
     DW_TAG_GNU_template_parameter_pack = 0x4107,
     DW_TAG_GNU_formal_parameter_pack = 0x4108,
        are properly part of DWARF 5.  */
     DW_TAG_GNU_template_parameter_pack = 0x4107,
     DW_TAG_GNU_formal_parameter_pack = 0x4108,
+    /* The GNU call site extension, specified at
+       http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .
+       The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
+       are properly part of DWARF 5.  */
+    DW_TAG_GNU_call_site = 0x4109,
+    DW_TAG_GNU_call_site_parameter = 0x410a,
     /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
     DW_TAG_upc_shared_type = 0x8765,
     DW_TAG_upc_strict_type = 0x8766,
     /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
     DW_TAG_upc_shared_type = 0x8765,
     DW_TAG_upc_strict_type = 0x8766,
@@ -351,6 +357,16 @@ enum dwarf_attribute
     /* Template template argument name.
        See http://gcc.gnu.org/wiki/TemplateParmsDwarf .  */
     DW_AT_GNU_template_name = 0x2110,
     /* Template template argument name.
        See http://gcc.gnu.org/wiki/TemplateParmsDwarf .  */
     DW_AT_GNU_template_name = 0x2110,
+    /* The GNU call site extension.
+       See http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open .  */
+    DW_AT_GNU_call_site_value = 0x2111,
+    DW_AT_GNU_call_site_data_value = 0x2112,
+    DW_AT_GNU_call_site_target = 0x2113,
+    DW_AT_GNU_call_site_target_clobbered = 0x2114,
+    DW_AT_GNU_tail_call = 0x2115,
+    DW_AT_GNU_all_tail_call_sites = 0x2116,
+    DW_AT_GNU_all_call_sites = 0x2117,
+    DW_AT_GNU_all_source_call_sites = 0x2118,
     /* VMS extensions.  */
     DW_AT_VMS_rtnbeg_pd_address = 0x2201,
     /* GNAT extensions.  */
     /* VMS extensions.  */
     DW_AT_VMS_rtnbeg_pd_address = 0x2201,
     /* GNAT extensions.  */
@@ -535,7 +551,12 @@ enum dwarf_location_atom
     /* The following is for marking variables that are uninitialized.  */
     DW_OP_GNU_uninit     = 0xf0,
     DW_OP_GNU_encoded_addr = 0xf1,
     /* The following is for marking variables that are uninitialized.  */
     DW_OP_GNU_uninit     = 0xf0,
     DW_OP_GNU_encoded_addr = 0xf1,
+    /* The GNU implicit pointer extension.
+       See http://www.dwarfstd.org/ShowIssue.php?issue=100831.1&type=open .  */
     DW_OP_GNU_implicit_pointer = 0xf2,
     DW_OP_GNU_implicit_pointer = 0xf2,
+    /* The GNU entry value extension.
+       See http://www.dwarfstd.org/ShowIssue.php?issue=100909.1&type=open .  */
+    DW_OP_GNU_entry_value = 0xf3,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,