aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2006-11-20 12:40:57 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2006-11-20 12:40:57 +0000
commitbcbb974df49f31123d9283eac9d80561258a0ef7 (patch)
treebaa194c46049520fe8a1193c7e40dedc138f13de /gcc
parent93147119042e5056f979d58573470a9cff2710b0 (diff)
downloadgcc-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/ChangeLog3
-rw-r--r--gcc/config/bfin/bfin.c23
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