summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch')
-rw-r--r--meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch198
1 files changed, 198 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch b/meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch
new file mode 100644
index 00000000..73b170c1
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/gcc/gcc-12/0051-Patch-microblaze-Reducing-Stack-space-for-arguments.patch
@@ -0,0 +1,198 @@
1From f52258e89f2ea416f418b6c55fef15552a081e18 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 24 Nov 2020 12:26:32 +0530
4Subject: [PATCH 51/53] [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.
9
10Signed-off-by :Nagaraju Mekala <nmekala@xilix.com>
11 :Ajit Agarwal <ajitkum@xilinx.com>
12---
13 gcc/config/microblaze/microblaze-protos.h | 1 +
14 gcc/config/microblaze/microblaze.c | 132 +++++++++++++++++++++-
15 gcc/config/microblaze/microblaze.h | 4 +-
16 3 files changed, 134 insertions(+), 3 deletions(-)
17
18diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
19index 302f6bbda2e..87a7093e369 100644
20--- a/gcc/config/microblaze/microblaze-protos.h
21+++ b/gcc/config/microblaze/microblaze-protos.h
22@@ -60,6 +60,7 @@ extern int symbol_mentioned_p (rtx);
23 extern int label_mentioned_p (rtx);
24 extern bool microblaze_cannot_force_const_mem (machine_mode, rtx);
25 extern void microblaze_eh_return (rtx op0);
26+int microblaze_reg_parm_stack_space(tree fun);
27 #endif /* RTX_CODE */
28
29 /* Declare functions in microblaze-c.c. */
30diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
31index 5afac2ba8d1..6914eb8380c 100644
32--- a/gcc/config/microblaze/microblaze.c
33+++ b/gcc/config/microblaze/microblaze.c
34@@ -2080,6 +2080,136 @@ microblaze_must_save_register (int regno)
35 return 0;
36 }
37
38+static bool
39+microblaze_parm_needs_stack (cumulative_args_t args_so_far, tree type)
40+{
41+ int unsignedp;
42+ rtx entry_parm;
43+
44+ /* Catch errors. */
45+ if (type == NULL || type == error_mark_node)
46+ return true;
47+
48+ if (TREE_CODE (type) == POINTER_TYPE)
49+ return true;
50+
51+ /* Handle types with no storage requirement. */
52+ if (TYPE_MODE (type) == VOIDmode)
53+ return false;
54+
55+ /* Handle complex types. */
56+ if (TREE_CODE (type) == COMPLEX_TYPE)
57+ return (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type))
58+ || microblaze_parm_needs_stack (args_so_far, TREE_TYPE (type)));
59+
60+ /* Handle transparent aggregates. */
61+ if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
62+ && TYPE_TRANSPARENT_AGGR (type))
63+ type = TREE_TYPE (first_field (type));
64+
65+ /* See if this arg was passed by invisible reference. */
66+ function_arg_info arg (type, /*named=*/true);
67+ apply_pass_by_reference_rules (get_cumulative_args (args_so_far), arg);
68+
69+ /* Find mode as it is passed by the ABI. */
70+ unsignedp = TYPE_UNSIGNED (type);
71+ arg.mode = promote_mode (arg.type, arg.mode, &unsignedp);
72+
73+ /* If there is no incoming register, we need a stack. */
74+ entry_parm = microblaze_function_arg (args_so_far, arg);
75+ if (entry_parm == NULL)
76+ return true;
77+
78+ /* Likewise if we need to pass both in registers and on the stack. */
79+ if (GET_CODE (entry_parm) == PARALLEL
80+ && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
81+ return true;
82+
83+ /* Also true if we're partially in registers and partially not. */
84+ if (function_arg_partial_bytes (args_so_far, arg) != 0)
85+ return true;
86+
87+ /* Update info on where next arg arrives in registers. */
88+ microblaze_function_arg_advance (args_so_far, arg);
89+ return false;
90+}
91+
92+static bool
93+microblaze_function_parms_need_stack (tree fun, bool incoming)
94+{
95+ tree fntype, result;
96+ CUMULATIVE_ARGS args_so_far_v;
97+ cumulative_args_t args_so_far;
98+ int num_of_args = 0;
99+
100+ /* Must be a libcall, all of which only use reg parms. */
101+ if (!fun)
102+ return true;
103+
104+ fntype = fun;
105+ if (!TYPE_P (fun))
106+ fntype = TREE_TYPE (fun);
107+
108+ /* Varargs functions need the parameter save area. */
109+ if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
110+ return true;
111+
112+ INIT_CUMULATIVE_ARGS(args_so_far_v, fntype, NULL_RTX,0,0);
113+ args_so_far = pack_cumulative_args (&args_so_far_v);
114+
115+ /* When incoming, we will have been passed the function decl.
116+ * * It is necessary to use the decl to handle K&R style functions,
117+ * * where TYPE_ARG_TYPES may not be available. */
118+ if (incoming)
119+ {
120+ gcc_assert (DECL_P (fun));
121+ result = DECL_RESULT (fun);
122+ }
123+ else
124+ result = TREE_TYPE (fntype);
125+
126+ if (result && aggregate_value_p (result, fntype))
127+ {
128+ if (!TYPE_P (result))
129+ result = build_pointer_type (result);
130+ microblaze_parm_needs_stack (args_so_far, result);
131+ }
132+
133+ if (incoming)
134+ {
135+ tree parm;
136+ for (parm = DECL_ARGUMENTS (fun);
137+ parm && parm != void_list_node;
138+ parm = TREE_CHAIN (parm))
139+ if (microblaze_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
140+ return true;
141+ }
142+ else
143+ {
144+ function_args_iterator args_iter;
145+ tree arg_type;
146+
147+ FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
148+ {
149+ num_of_args;
150+ if (microblaze_parm_needs_stack (args_so_far, arg_type))
151+ return true;
152+ }
153+ }
154+
155+ if (num_of_args > 3) return true;
156+
157+ return false;
158+}
159+
160+int microblaze_reg_parm_stack_space(tree fun)
161+{
162+ if (microblaze_function_parms_need_stack (fun,false))
163+ return MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD;
164+ else
165+ return 0;
166+}
167+
168 /* Return the bytes needed to compute the frame pointer from the current
169 stack pointer.
170
171@@ -3470,7 +3600,7 @@ microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
172 emit_insn (gen_indirect_jump (temp2));
173
174 /* Run just enough of rest_of_compilation. This sequence was
175- "borrowed" from rs6000.c. */
176+ "borrowed" from microblaze.c */
177 insn = get_insns ();
178 shorten_branches (insn);
179 assemble_start_function (thunk_fndecl, fnname);
180diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
181index 2581d52d17a..9c48978d2ca 100644
182--- a/gcc/config/microblaze/microblaze.h
183+++ b/gcc/config/microblaze/microblaze.h
184@@ -447,9 +447,9 @@ extern struct microblaze_frame_info current_frame_info;
185 #define ARG_POINTER_CFA_OFFSET(FNDECL) 0
186 #define DWARF_CIE_DATA_ALIGNMENT -1
187
188-#define REG_PARM_STACK_SPACE(FNDECL) (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
189+#define REG_PARM_STACK_SPACE(FNDECL) microblaze_reg_parm_stack_space(FNDECL)
190
191-#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
192+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
193
194 #define STACK_BOUNDARY (TARGET_MB_64 ? 64 : 32)
195
196--
1972.17.1
198