Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:ARM
libgcj43
pr47278.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr47278.diff of Package libgcj43
2011-01-13 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. * except.c (set_nothrow_function_flags): Likewise. * tree-inline.c (inlinable_function_p): Likewise. cp/ * decl.c (finish_function): Likewise. Index: gcc/tree.h =================================================================== *** gcc/tree.h (revision 168743) --- gcc/tree.h (working copy) *************** extern void decl_restrict_base_insert (t *** 3023,3048 **** something which is DECL_COMDAT. */ #define DECL_COMDAT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag) - /* 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. */ --- 3023,3028 ---- *************** extern void process_pending_assemble_ext *** 5067,5072 **** --- 5047,5054 ---- extern void finish_aliases_1 (void); extern void finish_aliases_2 (void); extern tree emutls_decl (tree); + 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/varasm.c =================================================================== *** gcc/varasm.c (revision 168743) --- gcc/varasm.c (working copy) *************** default_valid_pointer_mode (enum machine *** 6257,6262 **** --- 6257,6307 ---- return (mode == ptr_mode || mode == Pmode); } + /* 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/cgraph.c =================================================================== *** gcc/cgraph.c (revision 168743) --- gcc/cgraph.c (working copy) *************** cgraph_function_body_availability (struc *** 1007,1021 **** ??? Does the C++ one definition rule allow us to always return AVAIL_AVAILABLE here? That would be good reason to preserve this ! hook Similarly deal with extern inline functions - this is again ! necessary to get C++ shared functions having keyed templates ! right and in the C extension documentation we probably should ! document the requirement of both versions of function (extern ! inline and offline) having same side effect characteristics as ! good optimization is what this optimization is about. */ ! else if (!(*targetm.binds_local_p) (node->decl) ! && !DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl)) avail = AVAIL_OVERWRITABLE; else avail = AVAIL_AVAILABLE; --- 1007,1015 ---- ??? Does the C++ one definition rule allow us to always return 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/except.c =================================================================== *** gcc/except.c (revision 168743) --- gcc/except.c (working copy) *************** set_nothrow_function_flags (void) *** 2807,2813 **** /* If we don't know that this implementation of the function will actually be used, then we must not set TREE_NOTHROW, since callers must not assume that this function does not throw. */ ! if (DECL_REPLACEABLE_P (current_function_decl)) return 0; TREE_NOTHROW (current_function_decl) = 1; --- 2807,2813 ---- /* If we don't know that this implementation of the function will actually be used, then we must not set TREE_NOTHROW, since callers must not assume that this function does not throw. */ ! if (decl_replaceable_p (current_function_decl)) return 0; TREE_NOTHROW (current_function_decl) = 1; Index: gcc/tree-inline.c =================================================================== *** gcc/tree-inline.c (revision 168743) --- gcc/tree-inline.c (working copy) *************** inlinable_function_p (tree fn) *** 2103,2109 **** /* 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)) --- 2103,2109 ---- /* 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: gcc/cp/decl.c =================================================================== *** gcc/cp/decl.c (revision 168743) --- gcc/cp/decl.c (working copy) *************** finish_function (int flags) *** 11885,11891 **** 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 --- 11885,11891 ---- 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/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; + }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor