public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.
@ 2015-07-06 13:05 Ajit Kumar Agarwal
  2015-07-06 13:37 ` Oleg Endo
  0 siblings, 1 reply; 3+ messages in thread
From: Ajit Kumar Agarwal @ 2015-07-06 13:05 UTC (permalink / raw)
  To: GCC Patches
  Cc: Vinod Kathail, Shail Aditya Gupta, Vidhumouli Hunsigida, Nagaraju Mekala

[-- Attachment #1: Type: text/plain, Size: 7536 bytes --]

All:

The below patch optimized the usage of the reserved stack space for function arguments. The stack space is reserved if 
the function is a libcall, variable number of arguments, aggregate data types, and some parameter are reserved in registers 
and some parameters is reserved in the stack. Along with the above conditions the stack space is not reserved if no arguments 
are passed. No regressions is seen in Deja GNU tests for microblaze.

    [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.
    
    The changes are made in the patch for optimized usage of
    reserved stack space for arguments. The stack space is
    reserved if the function is a libcall, variable number of
    arguments, aggregate data types, and some parameter are
    reserved in registers and some parameters is reserved in the
    stack. Along with the above conditions the stack space is not
    reserved if no arguments are passed.
    
    ChangeLog:
    2015-07-06  Ajit Agarwal  <ajitkum@xilinx.com>
    
        * config/microblaze/microblaze.c
        (microblaze_parm_needs_stack): New.
        (microblaze_function_parms_need_stack): New.
        (microblaze_reg_parm_stack_space): New.
        * config/microblaze/microblaze.h
        (REG_PARM_STACK_SPACE): Modify the macro.
        * config/microblaze/microblaze-protos.h
        (microblaze_reg_parm_stack_space): Declare.
    
    Signed-off-by:Ajit Agarwal ajitkum@xilinx.com

---
 gcc/config/microblaze/microblaze-protos.h |    1 +
 gcc/config/microblaze/microblaze.c        |  140 +++++++++++++++++++++++++++++
 gcc/config/microblaze/microblaze.h        |    2 +-
 3 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index 57879b1..d27d3e1 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -56,6 +56,7 @@ extern bool microblaze_tls_referenced_p (rtx);
 extern int symbol_mentioned_p (rtx);
 extern int label_mentioned_p (rtx);
 extern bool microblaze_cannot_force_const_mem (machine_mode, rtx);
+extern int  microblaze_reg_parm_stack_space(tree fun);
 #endif  /* RTX_CODE */
 
 /* Declare functions in microblaze-c.c.  */
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 566b78c..0eae4cd 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -3592,7 +3592,147 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 
   return true;
 }
+/* Heuristics and criteria for having param needs stack.  */
 
+static bool
+microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree type)
+{
+  enum machine_mode mode;
+  int unsignedp;
+  rtx entry_parm;
+
+  /* Catch errors.  */
+  if (type == NULL || type == error_mark_node)
+    return true;
+
+  /* Handle types with no storage requirement.  */
+  if (TYPE_MODE (type) == VOIDmode)
+    return false;
+
+   /* Handle complex types.  */
+  if (TREE_CODE (type) == COMPLEX_TYPE)
+    return (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type))
+             || microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type)));
+
+  /* Handle transparent aggregates.  */
+  if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
+      && TYPE_TRANSPARENT_AGGR (type))
+    type = TREE_TYPE (first_field (type));
+
+  /* See if this arg was passed by invisible reference.  */
+  if (pass_by_reference (get_cumulative_args (args_so_far),
+                         TYPE_MODE (type), type, true))
+    type = build_pointer_type (type);
+
+  /* Find mode as it is passed by the ABI.  */
+  unsignedp = TYPE_UNSIGNED (type);
+  mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
+
+  /* If there is no incoming register, we need a stack.  */
+  entry_parm = microblaze_function_arg (args_so_far, mode, type, true);
+
+  if (entry_parm == NULL)
+    return true;
+
+  /* Likewise if we need to pass both in registers and on the stack.  */
+  if (GET_CODE (entry_parm) == PARALLEL
+      && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
+    return true;
+
+  /* Also true if we're partially in registers and partially not.  */
+  if (function_arg_partial_bytes (args_so_far, mode, type, true) != 0)
+    return true;
+
+  /* Update info on where next arg arrives in registers.  */
+  microblaze_function_arg_advance (args_so_far, mode, type, true);
+
+  return false;
+}
+
+/* Function need stack for param if
+   1. The function is a libcall.
+   2. Variable number of arguments.
+   3. If the param is aggregate data types.
+   4. If partially some param in registers and some in the stack.  */
+
+static bool
+microblaze_function_parms_need_stack (tree fun, bool incoming)
+{
+  tree fntype, result;
+  CUMULATIVE_ARGS args_so_far_v;
+  cumulative_args_t args_so_far;
+  int num_of_args = 0;
+
+  /* Must be a libcall, all of which only use reg parms.  */
+  if (!fun)
+    return true;
+
+  fntype = fun;
+  if (!TYPE_P (fun))
+    fntype = TREE_TYPE (fun);
+
+  /* Varargs functions need the parameter save area.  */
+  if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
+    return true;
+
+  INIT_CUMULATIVE_ARGS(args_so_far_v, fntype, NULL_RTX,0,0);
+  args_so_far = pack_cumulative_args (&args_so_far_v);
+
+  if (incoming)
+    {
+      gcc_assert (DECL_P (fun));
+      result = DECL_RESULT (fun);
+    }
+  else
+    result = TREE_TYPE (fntype);
+
+  if (result && aggregate_value_p (result, fntype))
+    {
+      if (!TYPE_P (result))
+        result = build_pointer_type (result);
+        microblaze_parm_needs_stack (args_so_far, result);
+    }
+
+  if (incoming)
+    {
+      tree parm;
+      for (parm = DECL_ARGUMENTS (fun);
+           parm && parm != void_list_node;
+           parm = TREE_CHAIN (parm))
+         if (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
+           return true;
+    }
+  else
+    {
+      function_args_iterator args_iter;
+      tree arg_type;
+
+      FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
+      {
+        num_of_args++;
+        if (microblaze_parm_needs_stack (args_so_far, arg_type))
+         return true;
+      }
+    }
+
+  if (num_of_args > 1)
+    return true;
+
+  return false;
+}
+
+/* This function defines REG_PARM_STACK_SPACE macro.If
+   the Param needs stack returns the number of words to
+   be reserved. Otherwise return 0.  */
+
+int
+microblaze_reg_parm_stack_space(tree fun)
+{
+  if (microblaze_function_parms_need_stack (fun, false))
+    return MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD;
+  else
+    return 0;
+}
 

 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO      microblaze_encode_section_info
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index faeb780..69fbd89 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -451,7 +451,7 @@ extern struct microblaze_frame_info current_frame_info;
 
 #define ARG_POINTER_CFA_OFFSET(FNDECL)		0
 
-#define REG_PARM_STACK_SPACE(FNDECL)  		(MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
+#define REG_PARM_STACK_SPACE(FNDECL)  		microblaze_reg_parm_stack_space (FNDECL)
 
 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE)	1
 
-- 
1.7.1

[-- Attachment #2: 0001-Patch-microblaze-Optimized-usage-of-reserved-stack-s.patch --]
[-- Type: application/octet-stream, Size: 6932 bytes --]

From 3e42116eb2941e0db2964edb77f51d762f1573de Mon Sep 17 00:00:00 2001
From: Ajit Kumar Agarwal <ajitkum@xhdspdgnu.(none)>
Date: Mon, 6 Jul 2015 18:15:02 +0530
Subject: [PATCH] [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.

The changes are made in the patch for optimized usage of
reserved stack space for arguments. The stack space is
reserved if the function is a libcall, variable number of
arguments, aggregate data types, and some parameter are
reserved in registers and some parameters is reserved in the
stack. Along with the above conditions the stack space is not
reserved if no arguments are passed.

ChangeLog:
2015-07-06  Ajit Agarwal  <ajitkum@xilinx.com>

	* config/microblaze/microblaze.c
	(microblaze_parm_needs_stack): New.
	(microblaze_function_parms_need_stack): New.
	(microblaze_reg_parm_stack_space): New.
	* config/microblaze/microblaze.h
	(REG_PARM_STACK_SPACE): Modify the macro.
	* config/microblaze/microblaze-protos.h
	(microblaze_reg_parm_stack_space): Declare.

Signed-off-by:Ajit Agarwal ajitkum@xilinx.com
---
 gcc/config/microblaze/microblaze-protos.h |    1 +
 gcc/config/microblaze/microblaze.c        |  140 +++++++++++++++++++++++++++++
 gcc/config/microblaze/microblaze.h        |    2 +-
 3 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
index 57879b1..d27d3e1 100644
--- a/gcc/config/microblaze/microblaze-protos.h
+++ b/gcc/config/microblaze/microblaze-protos.h
@@ -56,6 +56,7 @@ extern bool microblaze_tls_referenced_p (rtx);
 extern int symbol_mentioned_p (rtx);
 extern int label_mentioned_p (rtx);
 extern bool microblaze_cannot_force_const_mem (machine_mode, rtx);
+extern int  microblaze_reg_parm_stack_space(tree fun);
 #endif  /* RTX_CODE */
 
 /* Declare functions in microblaze-c.c.  */
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 566b78c..0eae4cd 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -3592,7 +3592,147 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 
   return true;
 }
+/* Heuristics and criteria for having param needs stack.  */
 
+static bool
+microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree type)
+{
+  enum machine_mode mode;
+  int unsignedp;
+  rtx entry_parm;
+
+  /* Catch errors.  */
+  if (type == NULL || type == error_mark_node)
+    return true;
+
+  /* Handle types with no storage requirement.  */
+  if (TYPE_MODE (type) == VOIDmode)
+    return false;
+
+   /* Handle complex types.  */
+  if (TREE_CODE (type) == COMPLEX_TYPE)
+    return (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type))
+             || microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type)));
+
+  /* Handle transparent aggregates.  */
+  if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
+      && TYPE_TRANSPARENT_AGGR (type))
+    type = TREE_TYPE (first_field (type));
+
+  /* See if this arg was passed by invisible reference.  */
+  if (pass_by_reference (get_cumulative_args (args_so_far),
+                         TYPE_MODE (type), type, true))
+    type = build_pointer_type (type);
+
+  /* Find mode as it is passed by the ABI.  */
+  unsignedp = TYPE_UNSIGNED (type);
+  mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
+
+  /* If there is no incoming register, we need a stack.  */
+  entry_parm = microblaze_function_arg (args_so_far, mode, type, true);
+
+  if (entry_parm == NULL)
+    return true;
+
+  /* Likewise if we need to pass both in registers and on the stack.  */
+  if (GET_CODE (entry_parm) == PARALLEL
+      && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
+    return true;
+
+  /* Also true if we're partially in registers and partially not.  */
+  if (function_arg_partial_bytes (args_so_far, mode, type, true) != 0)
+    return true;
+
+  /* Update info on where next arg arrives in registers.  */
+  microblaze_function_arg_advance (args_so_far, mode, type, true);
+
+  return false;
+}
+
+/* Function need stack for param if
+   1. The function is a libcall.
+   2. Variable number of arguments.
+   3. If the param is aggregate data types.
+   4. If partially some param in registers and some in the stack.  */
+
+static bool
+microblaze_function_parms_need_stack (tree fun, bool incoming)
+{
+  tree fntype, result;
+  CUMULATIVE_ARGS args_so_far_v;
+  cumulative_args_t args_so_far;
+  int num_of_args = 0;
+
+  /* Must be a libcall, all of which only use reg parms.  */
+  if (!fun)
+    return true;
+
+  fntype = fun;
+  if (!TYPE_P (fun))
+    fntype = TREE_TYPE (fun);
+
+  /* Varargs functions need the parameter save area.  */
+  if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
+    return true;
+
+  INIT_CUMULATIVE_ARGS(args_so_far_v, fntype, NULL_RTX,0,0);
+  args_so_far = pack_cumulative_args (&args_so_far_v);
+
+  if (incoming)
+    {
+      gcc_assert (DECL_P (fun));
+      result = DECL_RESULT (fun);
+    }
+  else
+    result = TREE_TYPE (fntype);
+
+  if (result && aggregate_value_p (result, fntype))
+    {
+      if (!TYPE_P (result))
+        result = build_pointer_type (result);
+        microblaze_parm_needs_stack (args_so_far, result);
+    }
+
+  if (incoming)
+    {
+      tree parm;
+      for (parm = DECL_ARGUMENTS (fun);
+           parm && parm != void_list_node;
+           parm = TREE_CHAIN (parm))
+         if (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
+           return true;
+    }
+  else
+    {
+      function_args_iterator args_iter;
+      tree arg_type;
+
+      FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
+      {
+        num_of_args++;
+        if (microblaze_parm_needs_stack (args_so_far, arg_type))
+         return true;
+      }
+    }
+
+  if (num_of_args > 1)
+    return true;
+
+  return false;
+}
+
+/* This function defines REG_PARM_STACK_SPACE macro.If
+   the Param needs stack returns the number of words to
+   be reserved. Otherwise return 0.  */
+
+int
+microblaze_reg_parm_stack_space(tree fun)
+{
+  if (microblaze_function_parms_need_stack (fun, false))
+    return MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD;
+  else
+    return 0;
+}
 \f
 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO      microblaze_encode_section_info
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index faeb780..69fbd89 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -451,7 +451,7 @@ extern struct microblaze_frame_info current_frame_info;
 
 #define ARG_POINTER_CFA_OFFSET(FNDECL)		0
 
-#define REG_PARM_STACK_SPACE(FNDECL)  		(MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
+#define REG_PARM_STACK_SPACE(FNDECL)  		microblaze_reg_parm_stack_space (FNDECL)
 
 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE)	1
 
-- 
1.7.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.
  2015-07-06 13:05 [Patch,microblaze]: Optimized usage of reserved stack space for function arguments Ajit Kumar Agarwal
@ 2015-07-06 13:37 ` Oleg Endo
  2015-07-07  3:12   ` Ajit Kumar Agarwal
  0 siblings, 1 reply; 3+ messages in thread
From: Oleg Endo @ 2015-07-06 13:37 UTC (permalink / raw)
  To: Ajit Kumar Agarwal
  Cc: GCC Patches, Vinod Kathail, Shail Aditya Gupta,
	Vidhumouli Hunsigida, Nagaraju Mekala

Hi,

Just some general comments...

On 06 Jul 2015, at 22:05, Ajit Kumar Agarwal <ajit.kumar.agarwal@xilinx.com> wrote:

> +static bool
> +microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree type)
> +{
> +  enum machine_mode mode;
     ^^^^
     'enum' is not required in C++, please omit it.
     We've been trying to remove unnecessary 'struct' and 'enum' after the
     switch to C++.  Although there are still some of them around, please
     don't add new ones.

> +  int unsignedp;
> +  rtx entry_parm;
     ^^^^
     Please declare variables at their first use.
     (there are other such cases in your patch)

Cheers,
Oleg

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.
  2015-07-06 13:37 ` Oleg Endo
@ 2015-07-07  3:12   ` Ajit Kumar Agarwal
  0 siblings, 0 replies; 3+ messages in thread
From: Ajit Kumar Agarwal @ 2015-07-07  3:12 UTC (permalink / raw)
  To: Oleg Endo
  Cc: GCC Patches, Vinod Kathail, Shail Aditya Gupta,
	Vidhumouli Hunsigida, Nagaraju Mekala



-----Original Message-----
From: Oleg Endo [mailto:oleg.endo@t-online.de] 
Sent: Monday, July 06, 2015 7:07 PM
To: Ajit Kumar Agarwal
Cc: GCC Patches; Vinod Kathail; Shail Aditya Gupta; Vidhumouli Hunsigida; Nagaraju Mekala
Subject: Re: [Patch,microblaze]: Optimized usage of reserved stack space for function arguments.

>>Hi,

>>Just some general comments...

Thanks.

On 06 Jul 2015, at 22:05, Ajit Kumar Agarwal <ajit.kumar.agarwal@xilinx.com> wrote:

> +static bool
> +microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree 
> +type) {
> +  enum machine_mode mode;
     ^^^^
  >>   'enum' is not required in C++, please omit it.
    >> We've been trying to remove unnecessary 'struct' and 'enum' after the
     >>switch to C++.  Although there are still some of them around, please
     >>don't add new ones.
     Sure.

> +  int unsignedp;
> +  rtx entry_parm;
     ^^^^
     >>Please declare variables at their first use.
     >>(there are other such cases in your patch)

    I have declared  the above variables  in the first scope of their first use. Sorry, it's not clear to me.
    You meant to say to declare in the following way.

   int unsignedp = TYPE_UNSIGNED (type);
   rtx entry_parm = microblaze_function_arg (args_so_far, mode, type, true);
   
Thanks & Regards
Ajit

Cheers,
Oleg

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-07-07  3:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-06 13:05 [Patch,microblaze]: Optimized usage of reserved stack space for function arguments Ajit Kumar Agarwal
2015-07-06 13:37 ` Oleg Endo
2015-07-07  3:12   ` Ajit Kumar Agarwal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).