diff options
author | Bernd Schmidt <bernd.schmidt@analog.com> | 2006-11-20 12:40:57 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@gcc.gnu.org> | 2006-11-20 12:40:57 +0000 |
commit | bcbb974df49f31123d9283eac9d80561258a0ef7 (patch) | |
tree | baa194c46049520fe8a1193c7e40dedc138f13de /gcc | |
parent | 93147119042e5056f979d58573470a9cff2710b0 (diff) | |
download | gcc-bcbb974df49f31123d9283eac9d80561258a0ef7.zip gcc-bcbb974df49f31123d9283eac9d80561258a0ef7.tar.gz gcc-bcbb974df49f31123d9283eac9d80561258a0ef7.tar.bz2 |
bfin.c (bfin_function_ok_for_sibcall): Handle some edge cases with local functions and TARGET_ID_SHARED_LIBRARY.
* config/bfin/bfin.c (bfin_function_ok_for_sibcall): Handle some
edge cases with local functions and TARGET_ID_SHARED_LIBRARY.
From-SVN: r119013
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/config/bfin/bfin.c | 23 |
2 files changed, 25 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e182213..0dc55b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -25,6 +25,9 @@ (TARGET_SWITCHES): Add -mleaf-id-shared-library and -msep-data. * doc/invoke.texi (Blackfin Options): Document new switches. + * config/bfin/bfin.c (bfin_function_ok_for_sibcall): Handle some + edge cases with local functions and TARGET_ID_SHARED_LIBRARY. + 2006-11-19 Andrew Pinski <pinskia@gmail.com> PR rtl-opt/29879 diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 6238690..b71b123 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -1596,7 +1596,28 @@ bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_UNUSED) { e_funkind fkind = funkind (TREE_TYPE (current_function_decl)); - return fkind == SUBROUTINE; + if (fkind != SUBROUTINE) + return false; + if (!TARGET_ID_SHARED_LIBRARY || TARGET_SEP_DATA) + return true; + + /* When compiling for ID shared libraries, can't sibcall a local function + from a non-local function, because the local function thinks it does + not need to reload P5 in the prologue, but the sibcall wil pop P5 in the + sibcall epilogue, and we end up with the wrong value in P5. */ + + if (!flag_unit_at_a_time || decl == NULL) + /* Not enough information. */ + return false; + + { + struct cgraph_local_info *this_func, *called_func; + rtx addr, insn; + + this_func = cgraph_local_info (current_function_decl); + called_func = cgraph_local_info (decl); + return !called_func->local || this_func->local; + } } /* Emit RTL insns to initialize the variable parts of a trampoline at |