[PATCH][02/10] -fuse-caller-save - Add new reg-note REG_CALL_DECL

2013-03-30 Thread Tom de Vries
Vladimir,

This patch addes the REG_CALL_DECL reg-note.  Using the reg-note we are able to
easily link call_insns to their corresponding declaration, even after the calls
may have been split into an insn (set register to function address) and a
call_insn (call register), which can happen for f.i. sh, and mips
with -mabi-calls.

Thanks,
  -Tom

2013-03-30  Radovan Obradovic  
Tom de Vries  

* reg-notes.def (REG_NOTE (CALL_DECL)): New reg-note REG_CALL_DECL.
* calls.c (expand_call, emit_library_call_value_1): Add REG_CALL_DECL
reg-note.
* combine.c (distribute_notes): Handle REG_CALL_DECL reg-note.
* emit-rtl.c (try_split): Same.
diff --git a/gcc/calls.c b/gcc/calls.c
index cdab8e0..39571da 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3158,6 +3158,19 @@ expand_call (tree exp, rtx target, int ignore)
 		   next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
 		   flags, args_so_far);
 
+  if (flag_use_caller_save)
+	{
+	  rtx last, datum = NULL_RTX;
+	  if (fndecl != NULL_TREE)
+	{
+	  datum = XEXP (DECL_RTL (fndecl), 0);
+	  gcc_assert (datum != NULL_RTX
+			  && GET_CODE (datum) == SYMBOL_REF);
+	}
+	  last = last_call_insn ();
+	  add_reg_note (last, REG_CALL_DECL, datum);
+	}
+
   /* If the call setup or the call itself overlaps with anything
 	 of the argument setup we probably clobbered our call address.
 	 In that case we can't do sibcalls.  */
@@ -4185,6 +4198,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
 	   valreg,
 	   old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
 
+  if (flag_use_caller_save)
+{
+  rtx last, datum = orgfun;
+  gcc_assert (GET_CODE (datum) == SYMBOL_REF);
+  last = last_call_insn ();
+  add_reg_note (last, REG_CALL_DECL, datum);
+}
+
   /* Right-shift returned value if necessary.  */
   if (!pcc_struct_value
   && TYPE_MODE (tfom) != BLKmode
diff --git a/gcc/combine.c b/gcc/combine.c
index acb4cb4..191eb71 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13187,6 +13187,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
 	case REG_NORETURN:
 	case REG_SETJMP:
 	case REG_TM:
+	case REG_CALL_DECL:
 	  /* These notes must remain with the call.  It should not be
 	 possible for both I2 and I3 to be a call.  */
 	  if (CALL_P (i3))
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index e412bef..e4843fe 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3473,6 +3473,7 @@ try_split (rtx pat, rtx trial, int last)
   int probability;
   rtx insn_last, insn;
   int njumps = 0;
+  rtx call_insn = NULL_RTX;
 
   /* We're not good at redistributing frame information.  */
   if (RTX_FRAME_RELATED_P (trial))
@@ -3545,6 +3546,9 @@ try_split (rtx pat, rtx trial, int last)
 	  {
 	rtx next, *p;
 
+	gcc_assert (call_insn == NULL_RTX);
+	call_insn = insn;
+
 	/* Add the old CALL_INSN_FUNCTION_USAGE to whatever the
 	   target may have explicitly specified.  */
 	p = &CALL_INSN_FUNCTION_USAGE (insn);
@@ -3616,6 +3620,11 @@ try_split (rtx pat, rtx trial, int last)
 	  fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));
 	  break;
 
+	case REG_CALL_DECL:
+	  gcc_assert (call_insn != NULL_RTX);
+	  add_reg_note (call_insn, REG_NOTE_KIND (note), XEXP (note, 0));
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index db61c09..f0b6dad 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -216,3 +216,8 @@ REG_NOTE (ARGS_SIZE)
that the return value of a call can be used to reinitialize a
pseudo reg.  */
 REG_NOTE (RETURNED)
+
+/* Used to mark a call with the function decl called by the call.
+   The decl might not be available in the call due to splitting of the call
+   insn.  This note is a SYMBOL_REF.  */
+REG_NOTE (CALL_DECL)


[PATCH][02/10] -fuse-caller-save - Add new reg-note REG_CALL_DECL

2013-03-29 Thread Tom de Vries
Vladimir,



This patch addes the REG_CALL_DECL reg-note.  Using the reg-note we are able to

easily link call_insns to their corresponding declaration, even after the calls

may have been split into an insn (set register to function address) and a

call_insn (call register), which can happen for f.i. sh, and mips

with -mabi-calls.



Thanks,

  -Tom



2013-03-29  Radovan Obradovic  

Tom de Vries  



* reg-notes.def (REG_NOTE (CALL_DECL)): New reg-note REG_CALL_DECL.

* calls.c (expand_call, emit_library_call_value_1): Add REG_CALL_DECL

reg-note.

* combine.c (distribute_notes): Handle REG_CALL_DECL reg-note.

* emit-rtl.c (try_split): Same.
diff --git a/gcc/calls.c b/gcc/calls.c

index cdab8e0..39571da 100644

--- a/gcc/calls.c

+++ b/gcc/calls.c

@@ -3158,6 +3158,19 @@ expand_call (tree exp, rtx target, int ignore)

 		   next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,

 		   flags, args_so_far);

 

+  if (flag_use_caller_save)

+	{

+	  rtx last, datum = NULL_RTX;

+	  if (fndecl != NULL_TREE)

+	{

+	  datum = XEXP (DECL_RTL (fndecl), 0);

+	  gcc_assert (datum != NULL_RTX

+			  && GET_CODE (datum) == SYMBOL_REF);

+	}

+	  last = last_call_insn ();

+	  add_reg_note (last, REG_CALL_DECL, datum);

+	}

+

   /* If the call setup or the call itself overlaps with anything

 	 of the argument setup we probably clobbered our call address.

 	 In that case we can't do sibcalls.  */

@@ -4185,6 +4198,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,

 	   valreg,

 	   old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);

 

+  if (flag_use_caller_save)

+{

+  rtx last, datum = orgfun;

+  gcc_assert (GET_CODE (datum) == SYMBOL_REF);

+  last = last_call_insn ();

+  add_reg_note (last, REG_CALL_DECL, datum);

+}

+

   /* Right-shift returned value if necessary.  */

   if (!pcc_struct_value

   && TYPE_MODE (tfom) != BLKmode

diff --git a/gcc/combine.c b/gcc/combine.c

index acb4cb4..191eb71 100644

--- a/gcc/combine.c

+++ b/gcc/combine.c

@@ -13187,6 +13187,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,

 	case REG_NORETURN:

 	case REG_SETJMP:

 	case REG_TM:

+	case REG_CALL_DECL:

 	  /* These notes must remain with the call.  It should not be

 	 possible for both I2 and I3 to be a call.  */

 	  if (CALL_P (i3))

diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c

index e412bef..e4843fe 100644

--- a/gcc/emit-rtl.c

+++ b/gcc/emit-rtl.c

@@ -3473,6 +3473,7 @@ try_split (rtx pat, rtx trial, int last)

   int probability;

   rtx insn_last, insn;

   int njumps = 0;

+  rtx call_insn = NULL_RTX;

 

   /* We're not good at redistributing frame information.  */

   if (RTX_FRAME_RELATED_P (trial))

@@ -3545,6 +3546,9 @@ try_split (rtx pat, rtx trial, int last)

 	  {

 	rtx next, *p;

 

+	gcc_assert (call_insn == NULL_RTX);

+	call_insn = insn;

+

 	/* Add the old CALL_INSN_FUNCTION_USAGE to whatever the

 	   target may have explicitly specified.  */

 	p = &CALL_INSN_FUNCTION_USAGE (insn);

@@ -3616,6 +3620,11 @@ try_split (rtx pat, rtx trial, int last)

 	  fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));

 	  break;

 

+	case REG_CALL_DECL:

+	  gcc_assert (call_insn != NULL_RTX);

+	  add_reg_note (call_insn, REG_NOTE_KIND (note), XEXP (note, 0));

+	  break;

+

 	default:

 	  break;

 	}

diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def

index db61c09..f0b6dad 100644

--- a/gcc/reg-notes.def

+++ b/gcc/reg-notes.def

@@ -216,3 +216,8 @@ REG_NOTE (ARGS_SIZE)

that the return value of a call can be used to reinitialize a

pseudo reg.  */

 REG_NOTE (RETURNED)

+

+/* Used to mark a call with the function decl called by the call.

+   The decl might not be available in the call due to splitting of the call

+   insn.  This note is a SYMBOL_REF.  */

+REG_NOTE (CALL_DECL)