blob: 1f8decc77a3802fb50ac2d90a772a716eb3e2a9e [file] [log] [blame]
Andrew Geisslera9ff2b32020-10-16 10:11:54 -05001From 59273a71f1f180456d87eb4a1a5f95fcc6d17003 Mon Sep 17 00:00:00 2001
Brad Bishop286d45c2018-10-02 15:21:57 -04002From: Mahesh Bodapati <mbodapat@xilinx.com>
Brad Bishop26bdd442019-08-16 17:08:17 -04003Date: Tue, 17 Jan 2017 16:42:44 +0530
Andrew Geisslera9ff2b32020-10-16 10:11:54 -05004Subject: [PATCH 18/58] [Patch, microblaze]: Reducing Stack space for arguments
5
6Currently in Microblaze target stack space for arguments in register is being
7allocated even if there are no arguments in the function.
8This patch will optimize the extra 24 bytes that are being allocated.
Brad Bishop286d45c2018-10-02 15:21:57 -04009
Brad Bishop26bdd442019-08-16 17:08:17 -040010Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
11 :Ajit Agarwal <ajitkum@xilinx.com>
Brad Bishop286d45c2018-10-02 15:21:57 -040012
13ChangeLog:
Brad Bishop26bdd442019-08-16 17:08:17 -0400142015-04-17 Nagaraju Mekala <nmekala@xilix.com>
15 Ajit Agarwal <ajitkum@xilinx.com>
Brad Bishop286d45c2018-10-02 15:21:57 -040016
Brad Bishop26bdd442019-08-16 17:08:17 -040017 *microblaze.c (microblaze_parm_needs_stack, microblaze_function_parms_need_stack): New
18 *microblaze.c (REG_PARM_STACK_SPACE): Modify
Brad Bishop286d45c2018-10-02 15:21:57 -040019---
20 gcc/config/microblaze/microblaze-protos.h | 1 +
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050021 gcc/config/microblaze/microblaze.c | 132 +++++++++++++++++++++-
Brad Bishop286d45c2018-10-02 15:21:57 -040022 gcc/config/microblaze/microblaze.h | 4 +-
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050023 3 files changed, 134 insertions(+), 3 deletions(-)
Brad Bishop286d45c2018-10-02 15:21:57 -040024
25diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050026index 982b2abd2d4..96f7bb67f6c 100644
Brad Bishop286d45c2018-10-02 15:21:57 -040027--- a/gcc/config/microblaze/microblaze-protos.h
28+++ b/gcc/config/microblaze/microblaze-protos.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -050029@@ -59,6 +59,7 @@ extern int symbol_mentioned_p (rtx);
Brad Bishop286d45c2018-10-02 15:21:57 -040030 extern int label_mentioned_p (rtx);
31 extern bool microblaze_cannot_force_const_mem (machine_mode, rtx);
32 extern void microblaze_eh_return (rtx op0);
33+int microblaze_reg_parm_stack_space(tree fun);
34 #endif /* RTX_CODE */
35
36 /* Declare functions in microblaze-c.c. */
37diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050038index 9eae5515c60..a4bdf66f045 100644
Brad Bishop286d45c2018-10-02 15:21:57 -040039--- a/gcc/config/microblaze/microblaze.c
40+++ b/gcc/config/microblaze/microblaze.c
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050041@@ -2057,6 +2057,136 @@ microblaze_must_save_register (int regno)
Brad Bishop286d45c2018-10-02 15:21:57 -040042 return 0;
43 }
44
45+static bool
46+microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree type)
47+{
Brad Bishop286d45c2018-10-02 15:21:57 -040048+ int unsignedp;
49+ rtx entry_parm;
50+
51+ /* Catch errors. */
52+ if (type == NULL || type == error_mark_node)
53+ return true;
54+
55+ if (TREE_CODE (type) == POINTER_TYPE)
56+ return true;
57+
58+ /* Handle types with no storage requirement. */
59+ if (TYPE_MODE (type) == VOIDmode)
60+ return false;
61+
62+ /* Handle complex types. */
63+ if (TREE_CODE (type) == COMPLEX_TYPE)
64+ return (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type))
65+ || microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type)));
66+
67+ /* Handle transparent aggregates. */
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050068+ if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
Brad Bishop286d45c2018-10-02 15:21:57 -040069+ && TYPE_TRANSPARENT_AGGR (type))
70+ type = TREE_TYPE (first_field (type));
71+
72+ /* See if this arg was passed by invisible reference. */
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050073+ function_arg_info arg (type, /*named=*/true);
74+ apply_pass_by_reference_rules (get_cumulative_args (args_so_far), arg);
Brad Bishop286d45c2018-10-02 15:21:57 -040075+
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050076+ /* Find mode as it is passed by the ABI. */
77+ unsignedp = TYPE_UNSIGNED (type);
78+ arg.mode = promote_mode (arg.type, arg.mode, &unsignedp);
Brad Bishop286d45c2018-10-02 15:21:57 -040079+
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050080+ /* If there is no incoming register, we need a stack. */
81+ entry_parm = microblaze_function_arg (args_so_far, arg);
82+ if (entry_parm == NULL)
Brad Bishop286d45c2018-10-02 15:21:57 -040083+ return true;
84+
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050085+ /* Likewise if we need to pass both in registers and on the stack. */
86+ if (GET_CODE (entry_parm) == PARALLEL
Brad Bishop286d45c2018-10-02 15:21:57 -040087+ && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
88+ return true;
89+
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050090+ /* Also true if we're partially in registers and partially not. */
91+ if (function_arg_partial_bytes (args_so_far, arg) != 0)
Brad Bishop286d45c2018-10-02 15:21:57 -040092+ return true;
93+
Andrew Geisslera9ff2b32020-10-16 10:11:54 -050094+ /* Update info on where next arg arrives in registers. */
95+ microblaze_function_arg_advance (args_so_far, arg);
96+ return false;
97+}
Brad Bishop286d45c2018-10-02 15:21:57 -040098+
99+static bool
100+microblaze_function_parms_need_stack (tree fun, bool incoming)
101+{
102+ tree fntype, result;
103+ CUMULATIVE_ARGS args_so_far_v;
104+ cumulative_args_t args_so_far;
105+ int num_of_args = 0;
106+
107+ /* Must be a libcall, all of which only use reg parms. */
108+ if (!fun)
109+ return true;
110+
111+ fntype = fun;
112+ if (!TYPE_P (fun))
113+ fntype = TREE_TYPE (fun);
114+
115+ /* Varargs functions need the parameter save area. */
116+ if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
117+ return true;
118+
119+ INIT_CUMULATIVE_ARGS(args_so_far_v, fntype, NULL_RTX,0,0);
120+ args_so_far = pack_cumulative_args (&args_so_far_v);
121+
122+ /* When incoming, we will have been passed the function decl.
123+ * It is necessary to use the decl to handle K&R style functions,
124+ * where TYPE_ARG_TYPES may not be available. */
125+ if (incoming)
126+ {
127+ gcc_assert (DECL_P (fun));
128+ result = DECL_RESULT (fun);
129+ }
130+ else
131+ result = TREE_TYPE (fntype);
132+
133+ if (result && aggregate_value_p (result, fntype))
134+ {
135+ if (!TYPE_P (result))
136+ result = build_pointer_type (result);
137+ microblaze_parm_needs_stack (args_so_far, result);
138+ }
139+
140+ if (incoming)
141+ {
142+ tree parm;
143+ for (parm = DECL_ARGUMENTS (fun);
144+ parm && parm != void_list_node;
145+ parm = TREE_CHAIN (parm))
146+ if (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
147+ return true;
148+ }
149+ else
150+ {
151+ function_args_iterator args_iter;
152+ tree arg_type;
153+
154+ FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
155+ {
156+ num_of_args++;
157+ if (microblaze_parm_needs_stack (args_so_far, arg_type))
158+ return true;
159+ }
160+ }
161+
162+ if (num_of_args > 3) return true;
163+
164+ return false;
165+}
166+
167+int microblaze_reg_parm_stack_space(tree fun)
168+{
169+ if (microblaze_function_parms_need_stack (fun,false))
170+ return MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD;
171+ else
172+ return 0;
173+}
174+
175 /* Return the bytes needed to compute the frame pointer from the current
176 stack pointer.
177
Andrew Geisslera9ff2b32020-10-16 10:11:54 -0500178@@ -3403,7 +3533,7 @@ microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
Brad Bishop286d45c2018-10-02 15:21:57 -0400179 emit_insn (gen_indirect_jump (temp2));
180
181 /* Run just enough of rest_of_compilation. This sequence was
182- "borrowed" from rs6000.c. */
183+ "borrowed" from microblaze.c. */
184 insn = get_insns ();
185 shorten_branches (insn);
Andrew Geisslera9ff2b32020-10-16 10:11:54 -0500186 assemble_start_function (thunk_fndecl, fnname);
Brad Bishop286d45c2018-10-02 15:21:57 -0400187diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
Andrew Geisslera9ff2b32020-10-16 10:11:54 -0500188index 8aa3f155790..1e155e4041c 100644
Brad Bishop286d45c2018-10-02 15:21:57 -0400189--- a/gcc/config/microblaze/microblaze.h
190+++ b/gcc/config/microblaze/microblaze.h
Brad Bishop26bdd442019-08-16 17:08:17 -0400191@@ -434,9 +434,9 @@ extern struct microblaze_frame_info current_frame_info;
Brad Bishop286d45c2018-10-02 15:21:57 -0400192
193 #define ARG_POINTER_CFA_OFFSET(FNDECL) 0
194
195-#define REG_PARM_STACK_SPACE(FNDECL) (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
196+#define REG_PARM_STACK_SPACE(FNDECL) microblaze_reg_parm_stack_space(FNDECL)
197
198-#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
199+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
200
201 #define STACK_BOUNDARY 32
202
203--
Andrew Geisslera9ff2b32020-10-16 10:11:54 -05002042.17.1
Brad Bishop286d45c2018-10-02 15:21:57 -0400205