From: Bernd Schmidt Date: Tue, 6 Oct 1998 20:38:40 +0000 (-0600) Subject: loop.c (count_one_set): New static function, broken out of count_loop_regs_set X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a4c3ddd83ae219749907c77f23787ffe085ed8c4;p=gcc.git loop.c (count_one_set): New static function, broken out of count_loop_regs_set * loop.c (count_one_set): New static function, broken out of count_loop_regs_set (count_loop_regs_set): Call it. * global.c (mark_reg_store): Handle clobbers here by not calling set_preference. (mark_reg_clobber): Just call mark_reg_store after ensuring SETTER is in fact a clobber. * integrate.c (process_reg_param): New function, broken out of expand_inline_function. (expand_inline_function): Call it. From-SVN: r22875 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bdb86557458..85d9497c7df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -23,6 +23,18 @@ Tue Oct 6 17:00:42 1998 J"orn Rennecke Tue Oct 6 01:36:00 1998 Bernd Schmidt + * loop.c (count_one_set): New static function, broken out of + count_loop_regs_set + (count_loop_regs_set): Call it. + * global.c (mark_reg_store): Handle clobbers here by not calling + set_preference. + (mark_reg_clobber): Just call mark_reg_store after ensuring SETTER + is in fact a clobber. + * integrate.c (process_reg_param): New function, broken out of + expand_inline_function. + (expand_inline_function): Call it. + + * i386.md (addsidi3_1): Delete unused variable temp. (addsidi3_2): Likewise. (clstrstrsi): Delete unused variable addr1. diff --git a/gcc/global.c b/gcc/global.c index 04a836c0003..0bacc238172 100644 --- a/gcc/global.c +++ b/gcc/global.c @@ -1323,16 +1323,13 @@ record_conflicts (allocno_vec, len) if so, we do nothing. SETTER is 0 if this register was modified by an auto-increment (i.e., - a REG_INC note was found for it). - - CLOBBERs are processed here by calling mark_reg_clobber. */ + a REG_INC note was found for it). */ static void -mark_reg_store (orig_reg, setter) - rtx orig_reg, setter; +mark_reg_store (reg, setter) + rtx reg, setter; { register int regno; - register rtx reg = orig_reg; /* WORD is which word of a multi-register group is being stored. For the case where the store is actually into a SUBREG of REG. @@ -1349,16 +1346,9 @@ mark_reg_store (orig_reg, setter) if (GET_CODE (reg) != REG) return; - if (setter && GET_CODE (setter) == CLOBBER) - { - /* A clobber of a register should be processed here too. */ - mark_reg_clobber (orig_reg, setter); - return; - } - regs_set[n_regs_set++] = reg; - if (setter) + if (setter && GET_CODE (setter) != CLOBBER) set_preference (reg, SET_SRC (setter)); regno = REGNO (reg); @@ -1396,55 +1386,8 @@ static void mark_reg_clobber (reg, setter) rtx reg, setter; { - register int regno; - - /* WORD is which word of a multi-register group is being stored. - For the case where the store is actually into a SUBREG of REG. - Except we don't use it; I believe the entire REG needs to be - made live. */ - int word = 0; - - if (GET_CODE (setter) != CLOBBER) - return; - - if (GET_CODE (reg) == SUBREG) - { - word = SUBREG_WORD (reg); - reg = SUBREG_REG (reg); - } - - if (GET_CODE (reg) != REG) - return; - - regs_set[n_regs_set++] = reg; - - regno = REGNO (reg); - - /* Either this is one of the max_allocno pseudo regs not allocated, - or it is or has a hardware reg. First handle the pseudo-regs. */ - if (regno >= FIRST_PSEUDO_REGISTER) - { - if (reg_allocno[regno] >= 0) - { - SET_ALLOCNO_LIVE (reg_allocno[regno]); - record_one_conflict (regno); - } - } - - if (reg_renumber[regno] >= 0) - regno = reg_renumber[regno] /* + word */; - - /* Handle hardware regs (and pseudos allocated to hard regs). */ - if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno]) - { - register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg)); - while (regno < last) - { - record_one_conflict (regno); - SET_HARD_REG_BIT (hard_regs_live, regno); - regno++; - } - } + if (GET_CODE (setter) == CLOBBER) + mark_reg_store (reg, setter); } /* Record that REG has conflicts with all the regs currently live. diff --git a/gcc/integrate.c b/gcc/integrate.c index db82e322b06..76ccf5f59b5 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -59,25 +59,31 @@ extern struct obstack *function_maybepermanent_obstack; : (8 * (8 + list_length (DECL_ARGUMENTS (DECL))))) #endif -static rtx initialize_for_inline PROTO((tree, int, int, int, int)); -static void finish_inline PROTO((tree, rtx)); -static void adjust_copied_decl_tree PROTO((tree)); -static tree copy_decl_list PROTO((tree)); -static tree copy_decl_tree PROTO((tree)); -static void copy_decl_rtls PROTO((tree)); -static void save_constants PROTO((rtx *)); -static void note_modified_parmregs PROTO((rtx, rtx)); -static rtx copy_for_inline PROTO((rtx)); -static void integrate_parm_decls PROTO((tree, struct inline_remap *, rtvec)); -static void integrate_decl_tree PROTO((tree, int, struct inline_remap *)); +static rtx initialize_for_inline PROTO((tree, int, int, int, int)); +static void finish_inline PROTO((tree, rtx)); +static void adjust_copied_decl_tree PROTO((tree)); +static tree copy_decl_list PROTO((tree)); +static tree copy_decl_tree PROTO((tree)); +static void copy_decl_rtls PROTO((tree)); +static void save_constants PROTO((rtx *)); +static void note_modified_parmregs PROTO((rtx, rtx)); +static rtx copy_for_inline PROTO((rtx)); +static void integrate_parm_decls PROTO((tree, struct inline_remap *, + rtvec)); +static void integrate_decl_tree PROTO((tree, int, + struct inline_remap *)); static void save_constants_in_decl_trees PROTO ((tree)); -static void subst_constants PROTO((rtx *, rtx, struct inline_remap *)); -static void restore_constants PROTO((rtx *)); -static void set_block_origin_self PROTO((tree)); -static void set_decl_origin_self PROTO((tree)); -static void set_block_abstract_flags PROTO((tree, int)); +static void subst_constants PROTO((rtx *, rtx, + struct inline_remap *)); +static void restore_constants PROTO((rtx *)); +static void set_block_origin_self PROTO((tree)); +static void set_decl_origin_self PROTO((tree)); +static void set_block_abstract_flags PROTO((tree, int)); +static void process_reg_param PROTO((struct inline_remap *, rtx, + rtx)); -void set_decl_abstract_flags PROTO((tree, int)); + +void set_decl_abstract_flags PROTO((tree, int)); static tree copy_and_set_decl_abstract_origin PROTO((tree)); /* Returns the Ith entry in the label_map contained in MAP. If the @@ -1300,6 +1306,38 @@ int global_const_equiv_map_size; && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER \ && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER) +/* Called to set up a mapping for the case where a parameter is in a + register. If it is read-only and our argument is a constant, set up the + constant equivalence. + + If LOC is REG_USERVAR_P, the usual case, COPY must also have that flag set + if it is a register. + + Also, don't allow hard registers here; they might not be valid when + substituted into insns. */ +static void +process_reg_param (map, loc, copy) + struct inline_remap *map; + rtx loc, copy; +{ + if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG) + || (GET_CODE (copy) == REG && REG_USERVAR_P (loc) + && ! REG_USERVAR_P (copy)) + || (GET_CODE (copy) == REG + && REGNO (copy) < FIRST_PSEUDO_REGISTER)) + { + rtx temp = copy_to_mode_reg (GET_MODE (loc), copy); + REG_USERVAR_P (temp) = REG_USERVAR_P (loc); + if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy)) + && REGNO (temp) < map->const_equiv_map_size) + { + map->const_equiv_map[REGNO (temp)] = copy; + map->const_age_map[REGNO (temp)] = CONST_AGE_PARM; + } + copy = temp; + } + map->reg_map[REGNO (loc)] = copy; +} /* Integrate the procedure defined by FNDECL. Note that this function may wind up calling itself. Since the static variables are not reentrant, we do not assign them until after the possibility @@ -1610,87 +1648,16 @@ expand_inline_function (fndecl, parms, target, ignore, type, ; } else if (GET_CODE (loc) == REG) - { - /* This is the good case where the parameter is in a register. - If it is read-only and our argument is a constant, set up the - constant equivalence. - - If LOC is REG_USERVAR_P, the usual case, COPY must also have - that flag set if it is a register. - - Also, don't allow hard registers here; they might not be valid - when substituted into insns. */ - - if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG) - || (GET_CODE (copy) == REG && REG_USERVAR_P (loc) - && ! REG_USERVAR_P (copy)) - || (GET_CODE (copy) == REG - && REGNO (copy) < FIRST_PSEUDO_REGISTER)) - { - temp = copy_to_mode_reg (GET_MODE (loc), copy); - REG_USERVAR_P (temp) = REG_USERVAR_P (loc); - if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy)) - && REGNO (temp) < map->const_equiv_map_size) - { - map->const_equiv_map[REGNO (temp)] = copy; - map->const_age_map[REGNO (temp)] = CONST_AGE_PARM; - } - copy = temp; - } - map->reg_map[REGNO (loc)] = copy; - } + process_reg_param (map, loc, copy); else if (GET_CODE (loc) == CONCAT) { - /* This is the good case where the parameter is in a - pair of separate pseudos. - If it is read-only and our argument is a constant, set up the - constant equivalence. - - If LOC is REG_USERVAR_P, the usual case, COPY must also have - that flag set if it is a register. - - Also, don't allow hard registers here; they might not be valid - when substituted into insns. */ rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc); rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc); rtx copyreal = gen_realpart (GET_MODE (locreal), copy); rtx copyimag = gen_imagpart (GET_MODE (locimag), copy); - if ((GET_CODE (copyreal) != REG && GET_CODE (copyreal) != SUBREG) - || (GET_CODE (copyreal) == REG && REG_USERVAR_P (locreal) - && ! REG_USERVAR_P (copyreal)) - || (GET_CODE (copyreal) == REG - && REGNO (copyreal) < FIRST_PSEUDO_REGISTER)) - { - temp = copy_to_mode_reg (GET_MODE (locreal), copyreal); - REG_USERVAR_P (temp) = REG_USERVAR_P (locreal); - if ((CONSTANT_P (copyreal) || FIXED_BASE_PLUS_P (copyreal)) - && REGNO (temp) < map->const_equiv_map_size) - { - map->const_equiv_map[REGNO (temp)] = copyreal; - map->const_age_map[REGNO (temp)] = CONST_AGE_PARM; - } - copyreal = temp; - } - map->reg_map[REGNO (locreal)] = copyreal; - - if ((GET_CODE (copyimag) != REG && GET_CODE (copyimag) != SUBREG) - || (GET_CODE (copyimag) == REG && REG_USERVAR_P (locimag) - && ! REG_USERVAR_P (copyimag)) - || (GET_CODE (copyimag) == REG - && REGNO (copyimag) < FIRST_PSEUDO_REGISTER)) - { - temp = copy_to_mode_reg (GET_MODE (locimag), copyimag); - REG_USERVAR_P (temp) = REG_USERVAR_P (locimag); - if ((CONSTANT_P (copyimag) || FIXED_BASE_PLUS_P (copyimag)) - && REGNO (temp) < map->const_equiv_map_size) - { - map->const_equiv_map[REGNO (temp)] = copyimag; - map->const_age_map[REGNO (temp)] = CONST_AGE_PARM; - } - copyimag = temp; - } - map->reg_map[REGNO (locimag)] = copyimag; + process_reg_param (map, locreal, copyreal); + process_reg_param (map, locimag, copyimag); } else abort (); diff --git a/gcc/loop.c b/gcc/loop.c index 24f1b6d7479..f9a7d2e0a47 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -3313,6 +3313,51 @@ find_single_use_in_loop (insn, x, usage) } } +/* Count and record any set in X which is contained in INSN. Update + MAY_NOT_MOVE and LAST_SET for any register set in X. */ + +static void +count_one_set (insn, x, may_not_move, last_set) + rtx insn, x; + varray_type may_not_move; + rtx *last_set; +{ + if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG) + /* Don't move a reg that has an explicit clobber. + It's not worth the pain to try to do it correctly. */ + VARRAY_CHAR (may_not_move, REGNO (XEXP (x, 0))) = 1; + + if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER) + { + rtx dest = SET_DEST (x); + while (GET_CODE (dest) == SUBREG + || GET_CODE (dest) == ZERO_EXTRACT + || GET_CODE (dest) == SIGN_EXTRACT + || GET_CODE (dest) == STRICT_LOW_PART) + dest = XEXP (dest, 0); + if (GET_CODE (dest) == REG) + { + register int regno = REGNO (dest); + /* If this is the first setting of this reg + in current basic block, and it was set before, + it must be set in two basic blocks, so it cannot + be moved out of the loop. */ + if (VARRAY_INT (n_times_set, regno) > 0 + && last_set[regno] == 0) + VARRAY_CHAR (may_not_move, regno) = 1; + /* If this is not first setting in current basic block, + see if reg was used in between previous one and this. + If so, neither one can be moved. */ + if (last_set[regno] != 0 + && reg_used_between_p (dest, last_set[regno], insn)) + VARRAY_CHAR (may_not_move, regno) = 1; + if (VARRAY_INT (n_times_set, regno) < 127) + ++VARRAY_INT (n_times_set, regno); + last_set[regno] = insn; + } + } +} + /* Increment N_TIMES_SET at the index of each register that is modified by an insn between FROM and TO. If the value of an element of N_TIMES_SET becomes 127 or more, @@ -3359,76 +3404,15 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs) find_single_use_in_loop (insn, REG_NOTES (insn), single_usage); } - if (GET_CODE (PATTERN (insn)) == CLOBBER - && GET_CODE (XEXP (PATTERN (insn), 0)) == REG) - /* Don't move a reg that has an explicit clobber. - We might do so sometimes, but it's not worth the pain. */ - VARRAY_CHAR (may_not_move, REGNO (XEXP (PATTERN (insn), 0))) = 1; - if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == CLOBBER) - { - dest = SET_DEST (PATTERN (insn)); - while (GET_CODE (dest) == SUBREG - || GET_CODE (dest) == ZERO_EXTRACT - || GET_CODE (dest) == SIGN_EXTRACT - || GET_CODE (dest) == STRICT_LOW_PART) - dest = XEXP (dest, 0); - if (GET_CODE (dest) == REG) - { - register int regno = REGNO (dest); - /* If this is the first setting of this reg - in current basic block, and it was set before, - it must be set in two basic blocks, so it cannot - be moved out of the loop. */ - if (VARRAY_INT (n_times_set, regno) > 0 - && last_set[regno] == 0) - VARRAY_CHAR (may_not_move, regno) = 1; - /* If this is not first setting in current basic block, - see if reg was used in between previous one and this. - If so, neither one can be moved. */ - if (last_set[regno] != 0 - && reg_used_between_p (dest, last_set[regno], insn)) - VARRAY_CHAR (may_not_move, regno) = 1; - if (VARRAY_INT (n_times_set, regno) < 127) - ++VARRAY_INT (n_times_set, regno); - last_set[regno] = insn; - } - } + count_one_set (insn, PATTERN (insn), may_not_move, last_set); else if (GET_CODE (PATTERN (insn)) == PARALLEL) { register int i; for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) - { - register rtx x = XVECEXP (PATTERN (insn), 0, i); - if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG) - /* Don't move a reg that has an explicit clobber. - It's not worth the pain to try to do it correctly. */ - VARRAY_CHAR (may_not_move, REGNO (XEXP (x, 0))) = 1; - - if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER) - { - dest = SET_DEST (x); - while (GET_CODE (dest) == SUBREG - || GET_CODE (dest) == ZERO_EXTRACT - || GET_CODE (dest) == SIGN_EXTRACT - || GET_CODE (dest) == STRICT_LOW_PART) - dest = XEXP (dest, 0); - if (GET_CODE (dest) == REG) - { - register int regno = REGNO (dest); - if (VARRAY_INT (n_times_set, regno) > 0 - && last_set[regno] == 0) - VARRAY_CHAR (may_not_move, regno) = 1; - if (last_set[regno] != 0 - && reg_used_between_p (dest, last_set[regno], insn)) - VARRAY_CHAR (may_not_move, regno) = 1; - if (VARRAY_INT (n_times_set, regno) < 127) - ++VARRAY_INT (n_times_set, regno); - last_set[regno] = insn; - } - } - } + count_one_set (insn, XVECEXP (PATTERN (insn), 0, i), + may_not_move, last_set); } }