From 659e47fb241303d55e264111360d41aa132947e1 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Mon, 18 Sep 2000 19:27:37 +0000 Subject: [PATCH] toplev.c (rest_of_compilation): Call purge_hard_subreg_sets to remove all SETs of SUBREGs of hard registers. 2000-09-15 Andrew Haley * toplev.c (rest_of_compilation): Call purge_hard_subreg_sets to remove all SETs of SUBREGs of hard registers. * function.c (purge_hard_subreg_sets): New function. (purge_single_hard_subreg_set): New function. * rtl.h: (purge_hard_subreg_sets): New function. From-SVN: r36511 --- gcc/ChangeLog | 8 ++++++ gcc/function.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/rtl.h | 1 + gcc/toplev.c | 11 ++++++--- 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c0edc7a9ec..4e99ee99762 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2000-09-15 Andrew Haley + + * toplev.c (rest_of_compilation): Call purge_hard_subreg_sets to + remove all SETs of SUBREGs of hard registers. + * function.c (purge_hard_subreg_sets): New function. + (purge_single_hard_subreg_set): New function. + * rtl.h: (purge_hard_subreg_sets): New function. + 2000-09-18 Richard Henderson * config/ia64/ia64-protos.h: Update. diff --git a/gcc/function.c b/gcc/function.c index 6a9bdc922f7..969887fe94f 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -294,6 +294,7 @@ static void emit_return_into_block PARAMS ((basic_block, rtx)); static void put_addressof_into_stack PARAMS ((rtx, struct hash_table *)); static boolean purge_addressof_1 PARAMS ((rtx *, rtx, int, int, struct hash_table *)); +static void purge_single_hard_subreg_set PARAMS ((rtx)); #ifdef HAVE_epilogue static void keep_stack_depressed PARAMS ((rtx)); #endif @@ -3393,6 +3394,71 @@ purge_addressof (insns) unshare_all_rtl_again (get_insns ()); } +/* Convert a SET of a hard subreg to a set of the appropriet hard + register. A subroutine of purge_hard_subreg_sets. */ + +static void +purge_single_hard_subreg_set (pattern) + rtx pattern; +{ + rtx reg = SET_DEST (pattern); + enum machine_mode mode = GET_MODE (SET_DEST (pattern)); + int word = 0; + + while (GET_CODE (reg) == SUBREG) + { + word += SUBREG_WORD (reg); + reg = SUBREG_REG (reg); + } + + if (REGNO (reg) < FIRST_PSEUDO_REGISTER) + { + reg = gen_rtx_REG (mode, REGNO (reg) + word); + SET_DEST (pattern) = reg; + } +} + +/* Eliminate all occurrences of SETs of hard subregs from INSNS. The + only such SETs that we expect to see are those left in because + integrate can't handle sets of parts of a return value register. + + We don't use alter_subreg because we only want to eliminate subregs + of hard registers. */ + +void +purge_hard_subreg_sets (insn) + rtx insn; +{ + for (; insn; insn = NEXT_INSN (insn)) + { + if (INSN_P (insn)) + { + rtx pattern = PATTERN (insn); + switch (GET_CODE (pattern)) + { + case SET: + if (GET_CODE (SET_DEST (pattern)) == SUBREG) + purge_single_hard_subreg_set (pattern); + break; + case PARALLEL: + { + int j; + for (j = XVECLEN (pattern, 0) - 1; j >= 0; j--) + { + rtx inner_pattern = XVECEXP (pattern, 0, j); + if (GET_CODE (inner_pattern) == SET + && GET_CODE (SET_DEST (inner_pattern)) == SUBREG) + purge_single_hard_subreg_set (inner_pattern); + } + } + break; + default: + break; + } + } + } +} + /* Pass through the INSNS of function FNDECL and convert virtual register references to hard register references. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index a866595d23c..190e9717c37 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1776,6 +1776,7 @@ extern void preserve_rtl_expr_result PARAMS ((rtx)); extern void mark_temp_addr_taken PARAMS ((rtx)); extern void update_temp_slot_address PARAMS ((rtx, rtx)); extern void purge_addressof PARAMS ((rtx)); +extern void purge_hard_subreg_sets PARAMS ((rtx)); /* In reload.c */ extern int operands_match_p PARAMS ((rtx, rtx)); diff --git a/gcc/toplev.c b/gcc/toplev.c index 333cde6a00e..74e0e3ebcae 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2829,11 +2829,14 @@ rest_of_compilation (decl) if (! DECL_DEFER_OUTPUT (decl)) TREE_ASM_WRITTEN (decl) = 1; - /* Now that integrate will no longer see our rtl, we need not distinguish - between the return value of this function and the return value of called - functions. */ + /* Now that integrate will no longer see our rtl, we need not + distinguish between the return value of this function and the + return value of called functions. Also, we can remove all SETs + of subregs of hard registers; they are only here because of + integrate.*/ rtx_equal_function_value_matters = 0; - + purge_hard_subreg_sets (get_insns ()); + /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) goto exit_rest_of_compilation; -- 2.30.2