diff options
Diffstat (limited to 'gcc-4.8.1/gcc/lra-coalesce.c')
-rw-r--r-- | gcc-4.8.1/gcc/lra-coalesce.c | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/gcc-4.8.1/gcc/lra-coalesce.c b/gcc-4.8.1/gcc/lra-coalesce.c deleted file mode 100644 index 859e02f0d..000000000 --- a/gcc-4.8.1/gcc/lra-coalesce.c +++ /dev/null @@ -1,331 +0,0 @@ -/* Coalesce spilled pseudos. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - Contributed by Vladimir Makarov <vmakarov@redhat.com>. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - - -/* This file contains a pass making some simple RTL code - transformations by coalescing pseudos to remove some move insns. - - Spilling pseudos in LRA can create memory-memory moves. We should - remove potential memory-memory moves before the next constraint - pass because the constraint pass will generate additional insns for - such moves and all these insns will be hard to remove afterwards. - - Here we coalesce only spilled pseudos. Coalescing non-spilled - pseudos (with different hard regs) might result in spilling - additional pseudos because of possible conflicts with other - non-spilled pseudos and, as a consequence, in more constraint - passes and even LRA infinite cycling. Trivial the same hard - register moves will be removed by subsequent compiler passes. - - We don't coalesce special reload pseudos. It complicates LRA code - a lot without visible generated code improvement. - - The pseudo live-ranges are used to find conflicting pseudos during - coalescing. - - Most frequently executed moves is tried to be coalesced first. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "tm_p.h" -#include "insn-config.h" -#include "recog.h" -#include "output.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "flags.h" -#include "function.h" -#include "expr.h" -#include "basic-block.h" -#include "except.h" -#include "timevar.h" -#include "ira.h" -#include "lra-int.h" -#include "df.h" - -/* Arrays whose elements represent the first and the next pseudo - (regno) in the coalesced pseudos group to which given pseudo (its - regno is the index) belongs. The next of the last pseudo in the - group refers to the first pseudo in the group, in other words the - group is represented by a cyclic list. */ -static int *first_coalesced_pseudo, *next_coalesced_pseudo; - -/* The function is used to sort moves according to their execution - frequencies. */ -static int -move_freq_compare_func (const void *v1p, const void *v2p) -{ - rtx mv1 = *(const rtx *) v1p; - rtx mv2 = *(const rtx *) v2p; - int pri1, pri2; - - pri1 = BLOCK_FOR_INSN (mv1)->frequency; - pri2 = BLOCK_FOR_INSN (mv2)->frequency; - if (pri2 - pri1) - return pri2 - pri1; - - /* If frequencies are equal, sort by moves, so that the results of - qsort leave nothing to chance. */ - return (int) INSN_UID (mv1) - (int) INSN_UID (mv2); -} - -/* Pseudos which go away after coalescing. */ -static bitmap_head coalesced_pseudos_bitmap; - -/* Merge two sets of coalesced pseudos given correspondingly by - pseudos REGNO1 and REGNO2 (more accurately merging REGNO2 group - into REGNO1 group). Set up COALESCED_PSEUDOS_BITMAP. */ -static void -merge_pseudos (int regno1, int regno2) -{ - int regno, first, first2, last, next; - - first = first_coalesced_pseudo[regno1]; - if ((first2 = first_coalesced_pseudo[regno2]) == first) - return; - for (last = regno2, regno = next_coalesced_pseudo[regno2];; - regno = next_coalesced_pseudo[regno]) - { - first_coalesced_pseudo[regno] = first; - bitmap_set_bit (&coalesced_pseudos_bitmap, regno); - if (regno == regno2) - break; - last = regno; - } - next = next_coalesced_pseudo[first]; - next_coalesced_pseudo[first] = regno2; - next_coalesced_pseudo[last] = next; - lra_reg_info[first].live_ranges - = (lra_merge_live_ranges - (lra_reg_info[first].live_ranges, - lra_copy_live_range_list (lra_reg_info[first2].live_ranges))); - if (GET_MODE_SIZE (lra_reg_info[first].biggest_mode) - < GET_MODE_SIZE (lra_reg_info[first2].biggest_mode)) - lra_reg_info[first].biggest_mode = lra_reg_info[first2].biggest_mode; -} - -/* Change pseudos in *LOC on their coalescing group - representatives. */ -static bool -substitute (rtx *loc) -{ - int i, regno; - const char *fmt; - enum rtx_code code; - bool res; - - if (*loc == NULL_RTX) - return false; - code = GET_CODE (*loc); - if (code == REG) - { - regno = REGNO (*loc); - if (regno < FIRST_PSEUDO_REGISTER - || first_coalesced_pseudo[regno] == regno) - return false; - *loc = regno_reg_rtx[first_coalesced_pseudo[regno]]; - return true; - } - - res = false; - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - { - if (substitute (&XEXP (*loc, i))) - res = true; - } - else if (fmt[i] == 'E') - { - int j; - - for (j = XVECLEN (*loc, i) - 1; j >= 0; j--) - if (substitute (&XVECEXP (*loc, i, j))) - res = true; - } - } - return res; -} - -/* The current iteration (1, 2, ...) of the coalescing pass. */ -int lra_coalesce_iter; - -/* Return true if the move involving REGNO1 and REGNO2 is a potential - memory-memory move. */ -static bool -mem_move_p (int regno1, int regno2) -{ - return reg_renumber[regno1] < 0 && reg_renumber[regno2] < 0; -} - -/* Pseudos used instead of the coalesced pseudos. */ -static bitmap_head used_pseudos_bitmap; - -/* Set up USED_PSEUDOS_BITMAP, and update LR_BITMAP (a BB live info - bitmap). */ -static void -update_live_info (bitmap lr_bitmap) -{ - unsigned int j; - bitmap_iterator bi; - - bitmap_clear (&used_pseudos_bitmap); - EXECUTE_IF_AND_IN_BITMAP (&coalesced_pseudos_bitmap, lr_bitmap, - FIRST_PSEUDO_REGISTER, j, bi) - bitmap_set_bit (&used_pseudos_bitmap, first_coalesced_pseudo[j]); - if (! bitmap_empty_p (&used_pseudos_bitmap)) - { - bitmap_and_compl_into (lr_bitmap, &coalesced_pseudos_bitmap); - bitmap_ior_into (lr_bitmap, &used_pseudos_bitmap); - } -} - -/* Return true if pseudo REGNO can be potentially coalesced. */ -static bool -coalescable_pseudo_p (int regno) -{ - lra_assert (regno >= FIRST_PSEUDO_REGISTER); - return (/* We don't want to coalesce regnos with equivalences, at - least without updating this info. */ - ira_reg_equiv[regno].constant == NULL_RTX - && ira_reg_equiv[regno].memory == NULL_RTX - && ira_reg_equiv[regno].invariant == NULL_RTX); -} - -/* The major function for aggressive pseudo coalescing of moves only - if the both pseudos were spilled and not special reload pseudos. */ -bool -lra_coalesce (void) -{ - basic_block bb; - rtx mv, set, insn, next, *sorted_moves; - int i, mv_num, sregno, dregno; - int coalesced_moves; - int max_regno = max_reg_num (); - bitmap_head involved_insns_bitmap; - - timevar_push (TV_LRA_COALESCE); - - if (lra_dump_file != NULL) - fprintf (lra_dump_file, - "\n********** Pseudos coalescing #%d: **********\n\n", - ++lra_coalesce_iter); - first_coalesced_pseudo = XNEWVEC (int, max_regno); - next_coalesced_pseudo = XNEWVEC (int, max_regno); - for (i = 0; i < max_regno; i++) - first_coalesced_pseudo[i] = next_coalesced_pseudo[i] = i; - sorted_moves = XNEWVEC (rtx, get_max_uid ()); - mv_num = 0; - /* Collect moves. */ - coalesced_moves = 0; - FOR_EACH_BB (bb) - { - FOR_BB_INSNS_SAFE (bb, insn, next) - if (INSN_P (insn) - && (set = single_set (insn)) != NULL_RTX - && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)) - && (sregno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER - && (dregno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER - && mem_move_p (sregno, dregno) - && coalescable_pseudo_p (sregno) && coalescable_pseudo_p (dregno) - && ! side_effects_p (set) - && !(lra_intersected_live_ranges_p - (lra_reg_info[sregno].live_ranges, - lra_reg_info[dregno].live_ranges))) - sorted_moves[mv_num++] = insn; - } - qsort (sorted_moves, mv_num, sizeof (rtx), move_freq_compare_func); - /* Coalesced copies, most frequently executed first. */ - bitmap_initialize (&coalesced_pseudos_bitmap, ®_obstack); - bitmap_initialize (&involved_insns_bitmap, ®_obstack); - for (i = 0; i < mv_num; i++) - { - mv = sorted_moves[i]; - set = single_set (mv); - lra_assert (set != NULL && REG_P (SET_SRC (set)) - && REG_P (SET_DEST (set))); - sregno = REGNO (SET_SRC (set)); - dregno = REGNO (SET_DEST (set)); - if (first_coalesced_pseudo[sregno] == first_coalesced_pseudo[dregno]) - { - coalesced_moves++; - if (lra_dump_file != NULL) - fprintf - (lra_dump_file, " Coalescing move %i:r%d-r%d (freq=%d)\n", - INSN_UID (mv), sregno, dregno, - BLOCK_FOR_INSN (mv)->frequency); - /* We updated involved_insns_bitmap when doing the merge. */ - } - else if (!(lra_intersected_live_ranges_p - (lra_reg_info[first_coalesced_pseudo[sregno]].live_ranges, - lra_reg_info[first_coalesced_pseudo[dregno]].live_ranges))) - { - coalesced_moves++; - if (lra_dump_file != NULL) - fprintf - (lra_dump_file, - " Coalescing move %i:r%d(%d)-r%d(%d) (freq=%d)\n", - INSN_UID (mv), sregno, ORIGINAL_REGNO (SET_SRC (set)), - dregno, ORIGINAL_REGNO (SET_DEST (set)), - BLOCK_FOR_INSN (mv)->frequency); - bitmap_ior_into (&involved_insns_bitmap, - &lra_reg_info[sregno].insn_bitmap); - bitmap_ior_into (&involved_insns_bitmap, - &lra_reg_info[dregno].insn_bitmap); - merge_pseudos (sregno, dregno); - } - } - bitmap_initialize (&used_pseudos_bitmap, ®_obstack); - FOR_EACH_BB (bb) - { - update_live_info (df_get_live_in (bb)); - update_live_info (df_get_live_out (bb)); - FOR_BB_INSNS_SAFE (bb, insn, next) - if (INSN_P (insn) - && bitmap_bit_p (&involved_insns_bitmap, INSN_UID (insn))) - { - if (! substitute (&insn)) - continue; - lra_update_insn_regno_info (insn); - if ((set = single_set (insn)) != NULL_RTX && set_noop_p (set)) - { - /* Coalesced move. */ - if (lra_dump_file != NULL) - fprintf (lra_dump_file, " Removing move %i (freq=%d)\n", - INSN_UID (insn), BLOCK_FOR_INSN (insn)->frequency); - lra_set_insn_deleted (insn); - } - } - } - bitmap_clear (&used_pseudos_bitmap); - bitmap_clear (&involved_insns_bitmap); - bitmap_clear (&coalesced_pseudos_bitmap); - if (lra_dump_file != NULL && coalesced_moves != 0) - fprintf (lra_dump_file, "Coalesced Moves = %d\n", coalesced_moves); - free (sorted_moves); - free (next_coalesced_pseudo); - free (first_coalesced_pseudo); - timevar_pop (TV_LRA_COALESCE); - return coalesced_moves != 0; -} |