Mercurial > hg > CbC > CbC_gcc
diff gcc/early-remat.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/early-remat.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/early-remat.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Early (pre-RA) rematerialization - Copyright (C) 2017 Free Software Foundation, Inc. + Copyright (C) 2017-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -36,6 +36,8 @@ #include "rtlhash.h" #include "print-rtl.h" #include "rtl-iter.h" +#include "regs.h" +#include "function-abi.h" /* This pass runs before register allocation and implements an aggressive form of rematerialization. It looks for pseudo registers R of mode M @@ -435,6 +437,8 @@ void compute_clobbers (unsigned int); void assign_value_number (unsigned int); void decide_candidate_validity (void); + void restrict_remat_for_unavail_regs (bitmap, const_bitmap); + void restrict_remat_for_call (bitmap, rtx_insn *); bool stable_use_p (unsigned int); void emit_copy_before (unsigned int, rtx, rtx); void stabilize_pattern (unsigned int); @@ -889,8 +893,8 @@ else { /* The instruction can set additional registers, provided that - they're call-clobbered hard registers. This is useful for - instructions that alter the condition codes. */ + they're hard registers. This is useful for instructions + that alter the condition codes. */ if (!HARD_REGISTER_NUM_P (def_regno)) { if (dump_file) @@ -898,20 +902,6 @@ " pseudo reg %d\n", FAILURE_ARGS, def_regno); return false; } - if (global_regs[def_regno]) - { - if (dump_file) - fprintf (dump_file, FAILURE_FORMAT "insn also sets" - " global reg %d\n", FAILURE_ARGS, def_regno); - return false; - } - if (!TEST_HARD_REG_BIT (regs_invalidated_by_call, def_regno)) - { - if (dump_file) - fprintf (dump_file, FAILURE_FORMAT "insn also sets" - " call-preserved reg %d\n", FAILURE_ARGS, def_regno); - return false; - } } } @@ -1123,7 +1113,6 @@ ec->representative = cand1_index; cand1->equiv_class = ec; } - cand1 = &m_candidates[ec->representative]; cand2->equiv_class = ec; bitmap_set_bit (ec->members, cand2_index); if (cand2_index > ec->representative) @@ -1533,6 +1522,39 @@ } } +/* Remove any candidates in CANDIDATES that would clobber a register in + UNAVAIL_REGS. */ + +void +early_remat::restrict_remat_for_unavail_regs (bitmap candidates, + const_bitmap unavail_regs) +{ + bitmap_clear (&m_tmp_bitmap); + unsigned int cand_index; + bitmap_iterator bi; + EXECUTE_IF_SET_IN_BITMAP (candidates, 0, cand_index, bi) + { + remat_candidate *cand = &m_candidates[cand_index]; + if (cand->clobbers + && bitmap_intersect_p (cand->clobbers, unavail_regs)) + bitmap_set_bit (&m_tmp_bitmap, cand_index); + } + bitmap_and_compl_into (candidates, &m_tmp_bitmap); +} + +/* Remove any candidates in CANDIDATES that would clobber a register + that is potentially live across CALL. */ + +void +early_remat::restrict_remat_for_call (bitmap candidates, rtx_insn *call) +{ + /* We don't know whether partially-clobbered registers are live + across the call or not, so assume that they are. */ + bitmap_view<HARD_REG_SET> call_preserved_regs + (~insn_callee_abi (call).full_reg_clobbers ()); + restrict_remat_for_unavail_regs (candidates, call_preserved_regs); +} + /* Assuming that every path reaching a point P contains a copy of a use U of REGNO, return true if another copy of U at P would have access to the same value of REGNO. */ @@ -1985,10 +2007,13 @@ init_temp_bitmap (&m_required); } else - /* The fully-local case: candidates that need to be - rematerialized after a previous call in the block. */ - emit_remat_insns (m_required, NULL, info->rd_after_call, - last_call); + { + /* The fully-local case: candidates that need to be + rematerialized after a previous call in the block. */ + restrict_remat_for_call (m_required, last_call); + emit_remat_insns (m_required, NULL, info->rd_after_call, + last_call); + } last_call = insn; bitmap_clear (m_available); gcc_checking_assert (empty_p (m_required)); @@ -2481,8 +2506,11 @@ remat_block_info *info = &m_block_info[bb->index]; if (info->last_call && !empty_p (info->required_after_call)) - emit_remat_insns (info->required_after_call, NULL, - info->rd_after_call, info->last_call); + { + restrict_remat_for_call (info->required_after_call, info->last_call); + emit_remat_insns (info->required_after_call, NULL, + info->rd_after_call, info->last_call); + } if (!empty_p (info->required_in)) { @@ -2490,6 +2518,7 @@ while (insn != BB_END (bb) && !INSN_P (NEXT_INSN (insn))) insn = NEXT_INSN (insn); + restrict_remat_for_unavail_regs (info->required_in, DF_LR_IN (bb)); emit_remat_insns (info->required_in, info->available_in, info->rd_in, insn); }