diff options
Diffstat (limited to 'meta-xilinx/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-8/0020-Patch-microblaze-Reducing-Stack-space-for-arguments.patch')
-rw-r--r-- | meta-xilinx/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-8/0020-Patch-microblaze-Reducing-Stack-space-for-arguments.patch | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-8/0020-Patch-microblaze-Reducing-Stack-space-for-arguments.patch b/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-8/0020-Patch-microblaze-Reducing-Stack-space-for-arguments.patch new file mode 100644 index 0000000000..6e07ac4fcc --- /dev/null +++ b/meta-xilinx/meta-xilinx-bsp/recipes-microblaze/gcc/gcc-8/0020-Patch-microblaze-Reducing-Stack-space-for-arguments.patch @@ -0,0 +1,206 @@ +From 0cc6aabbd3f7b331c3995f11efec545499297358 Mon Sep 17 00:00:00 2001 +From: Mahesh Bodapati <mbodapat@xilinx.com> +Date: Tue, 17 Jan 2017 16:42:44 +0530 +Subject: [PATCH 20/54] [Patch, microblaze]: Reducing Stack space for arguments + Currently in Microblaze target stack space for arguments in register is being + allocated even if there are no arguments in the function. This patch will + optimize the extra 24 bytes that are being allocated. + +Signed-off-by :Nagaraju Mekala <nmekala@xilix.com> + :Ajit Agarwal <ajitkum@xilinx.com> + +ChangeLog: +2015-04-17 Nagaraju Mekala <nmekala@xilix.com> + Ajit Agarwal <ajitkum@xilinx.com> + + *microblaze.c (microblaze_parm_needs_stack, microblaze_function_parms_need_stack): New + *microblaze.c (REG_PARM_STACK_SPACE): Modify +--- + gcc/config/microblaze/microblaze-protos.h | 1 + + gcc/config/microblaze/microblaze.c | 134 +++++++++++++++++++++++++++++- + gcc/config/microblaze/microblaze.h | 4 +- + 3 files changed, 136 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h +index 4cbba0c..f8a56f7 100644 +--- a/gcc/config/microblaze/microblaze-protos.h ++++ b/gcc/config/microblaze/microblaze-protos.h +@@ -58,6 +58,7 @@ extern int symbol_mentioned_p (rtx); + extern int label_mentioned_p (rtx); + extern bool microblaze_cannot_force_const_mem (machine_mode, rtx); + extern void microblaze_eh_return (rtx op0); ++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 53b44df..0dec362 100644 +--- a/gcc/config/microblaze/microblaze.c ++++ b/gcc/config/microblaze/microblaze.c +@@ -1989,6 +1989,138 @@ microblaze_must_save_register (int regno) + return 0; + } + ++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; ++ ++ if (TREE_CODE (type) == POINTER_TYPE) ++ 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; ++ } ++ ++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); ++ ++ /* When incoming, we will have been passed the function decl. ++ * It is necessary to use the decl to handle K&R style functions, ++ * where TYPE_ARG_TYPES may not be available. */ ++ 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 > 3) return true; ++ ++ return false; ++} ++ ++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; ++} ++ + /* Return the bytes needed to compute the frame pointer from the current + stack pointer. + +@@ -3298,7 +3430,7 @@ microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, + emit_insn (gen_indirect_jump (temp2)); + + /* Run just enough of rest_of_compilation. This sequence was +- "borrowed" from rs6000.c. */ ++ "borrowed" from microblaze.c. */ + insn = get_insns (); + shorten_branches (insn); + final_start_function (insn, file, 1); +diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h +index 88e0351..9f74ec8 100644 +--- a/gcc/config/microblaze/microblaze.h ++++ b/gcc/config/microblaze/microblaze.h +@@ -434,9 +434,9 @@ 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 ++#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 + + #define STACK_BOUNDARY 32 + +-- +2.7.4 + |