This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][4.5] Fix PR47278


This fixes PR47278 by backporting some of the cgraph changes from trunk.
In particular this replaces DECL_REPLACEABLE_P with a stripped down
(non-LTO aware) version of the trunk replacement.

Bootstrap and regtest running on x86_64-unknown-linux-gnu (a 4.3 version
bootstrapped and tested ok).

Looks ok?

Thanks,
Richard.

2011-03-02  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/47278
	* tree.h (DECL_REPLACEABLE_P): Remove.
	(decl_replaceable_p): Declare.
	(decl_binds_to_current_def_p): Likewise.
	* varasm.c (decl_replaceable_p): New function.
	(decl_binds_to_current_def_p): Likewise.
	* cgraph.c (cgraph_function_body_availability): Use decl_replaceable_p.
	* tree-inline.c (inlinable_function_p): Likewise.

	cp/
	* decl.c (finish_function): Use decl_replaceable_p.

	testsuite/
	* gcc.dg/torture/pr47278-1.c: New testcase.
	* gcc.dg/torture/pr47278-2.c: Likewise.

Index: gcc/testsuite/gcc.dg/torture/pr47278-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr47278-1.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr47278-1.c	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ /* { dg-do run } */
+ /* { dg-additional-sources "pr47278-2.c" } */
+ 
+ int foo (void) { return 1; }
Index: gcc/testsuite/gcc.dg/torture/pr47278-2.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr47278-2.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr47278-2.c	(revision 0)
***************
*** 0 ****
--- 1,13 ----
+ extern void abort (void);
+ 
+ int __attribute__((weak,visibility("hidden"))) foo (void)
+ {
+   return 0;
+ }
+ 
+ int main()
+ {
+   if (foo() != 1)
+     abort ();
+   return 0;
+ }
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c	(revision 170616)
--- gcc/cgraph.c	(working copy)
*************** cgraph_function_body_availability (struc
*** 2093,2099 ****
       AVAIL_AVAILABLE here?  That would be good reason to preserve this
       bit.  */
  
!   else if (DECL_REPLACEABLE_P (node->decl) && !DECL_EXTERNAL (node->decl))
      avail = AVAIL_OVERWRITABLE;
    else avail = AVAIL_AVAILABLE;
  
--- 2093,2099 ----
       AVAIL_AVAILABLE here?  That would be good reason to preserve this
       bit.  */
  
!   else if (decl_replaceable_p (node->decl) && !DECL_EXTERNAL (node->decl))
      avail = AVAIL_OVERWRITABLE;
    else avail = AVAIL_AVAILABLE;
  
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 170616)
--- gcc/tree.h	(working copy)
*************** struct GTY(()) tree_parm_decl {
*** 2913,2938 ****
  
  #define DECL_COMDAT_GROUP(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group)
  
- /* A replaceable function is one which may be replaced at link-time
-    with an entirely different definition, provided that the
-    replacement has the same type.  For example, functions declared
-    with __attribute__((weak)) on most systems are replaceable.
- 
-    COMDAT functions are not replaceable, since all definitions of the
-    function must be equivalent.  It is important that COMDAT functions
-    not be treated as replaceable so that use of C++ template
-    instantiations is not penalized.
- 
-    For example, DECL_REPLACEABLE is used to determine whether or not a
-    function (including a template instantiation) which is not
-    explicitly declared "inline" can be inlined.  If the function is
-    DECL_REPLACEABLE then it is not safe to do the inlining, since the
-    implementation chosen at link-time may be different.  However, a
-    function that is not DECL_REPLACEABLE can be inlined, since all
-    versions of the function will be functionally identical.  */
- #define DECL_REPLACEABLE_P(NODE) \
-   (!DECL_COMDAT (NODE) && !targetm.binds_local_p (NODE))
- 
  /* The name of the object as the assembler will see it (but before any
     translations made by ASM_OUTPUT_LABELREF).  Often this is the same
     as DECL_NAME.  It is an IDENTIFIER_NODE.  */
--- 2913,2918 ----
*************** extern void finish_aliases_1 (void);
*** 5145,5150 ****
--- 5125,5132 ----
  extern void finish_aliases_2 (void);
  extern tree emutls_decl (tree);
  extern void remove_unreachable_alias_pairs (void);
+ extern bool decl_replaceable_p (tree);
+ extern bool decl_binds_to_current_def_p (tree);
  
  /* In stmt.c */
  extern void expand_computed_goto (tree);
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c	(revision 170616)
--- gcc/cp/decl.c	(working copy)
*************** finish_function (int flags)
*** 12502,12508 ****
    if (!processing_template_decl
        && !cp_function_chain->can_throw
        && !flag_non_call_exceptions
!       && !DECL_REPLACEABLE_P (fndecl))
      TREE_NOTHROW (fndecl) = 1;
  
    /* This must come after expand_function_end because cleanups might
--- 12502,12508 ----
    if (!processing_template_decl
        && !cp_function_chain->can_throw
        && !flag_non_call_exceptions
!       && !decl_replaceable_p (fndecl))
      TREE_NOTHROW (fndecl) = 1;
  
    /* This must come after expand_function_end because cleanups might
Index: gcc/varasm.c
===================================================================
*** gcc/varasm.c	(revision 170616)
--- gcc/varasm.c	(working copy)
*************** default_binds_local_p_1 (const_tree exp,
*** 6691,6696 ****
--- 6691,6741 ----
    return local_p;
  }
  
+ /* Return true when references to DECL must bind to current definition in
+    final executable.
+ 
+    The condition is usually equivalent to whether the function binds to the
+    current module (shared library or executable), that is to binds_local_p.
+    We use this fact to avoid need for another target hook and implement
+    the logic using binds_local_p and just special cases where
+    decl_binds_to_current_def_p is stronger than binds local_p.  In particular
+    the weak definitions (that can be overwritten at linktime by other
+    definition from different object file) and when resolution info is available
+    we simply use the knowledge passed to us by linker plugin.  */
+ bool
+ decl_binds_to_current_def_p (tree decl)
+ {
+   gcc_assert (DECL_P (decl));
+   if (!TREE_PUBLIC (decl))
+     return true;
+   if (!targetm.binds_local_p (decl))
+     return false;
+   /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks
+      binds localy but still can be overwritten).
+      This rely on fact that binds_local_p behave as decl_replaceable_p
+      for all other declaration types.  */
+   return !DECL_WEAK (decl);
+ }
+ 
+ /* A replaceable function or variable is one which may be replaced
+    at link-time with an entirely different definition, provided that the
+    replacement has the same type.  For example, functions declared
+    with __attribute__((weak)) on most systems are replaceable.
+ 
+    COMDAT functions are not replaceable, since all definitions of the
+    function must be equivalent.  It is important that COMDAT functions
+    not be treated as replaceable so that use of C++ template
+    instantiations is not penalized.  */
+ 
+ bool
+ decl_replaceable_p (tree decl)
+ {
+   gcc_assert (DECL_P (decl));
+   if (!TREE_PUBLIC (decl) || DECL_COMDAT (decl))
+     return false;
+   return !decl_binds_to_current_def_p (decl);
+ }
+ 
  /* Default function to output code that will globalize a label.  A
     target must define GLOBAL_ASM_OP or provide its own function to
     globalize a label.  */
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 170616)
--- gcc/tree-inline.c	(working copy)
*************** tree_inlinable_function_p (tree fn)
*** 3067,3073 ****
    /* Don't auto-inline anything that might not be bound within
       this unit of translation.  */
    else if (!DECL_DECLARED_INLINE_P (fn)
! 	   && DECL_REPLACEABLE_P (fn))
      inlinable = false;
  
    else if (!function_attribute_inlinable_p (fn))
--- 3067,3073 ----
    /* Don't auto-inline anything that might not be bound within
       this unit of translation.  */
    else if (!DECL_DECLARED_INLINE_P (fn)
! 	   && decl_replaceable_p (fn))
      inlinable = false;
  
    else if (!function_attribute_inlinable_p (fn))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]