From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
Since VSETVL PASS in RISC-V port is using common part of 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)'
and we will also this helper function in riscv.cc for the following patches.
So extract the common part codes of 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)', the new function
of the common part is also call 'insert_insn_end_basic_block (rtx_insn *pat, basic_block bb)' but with different arguments.
And call 'insert_insn_end_basic_block (rtx_insn *pat, basic_block bb)' in 'insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)'
and VSETVL PASS in RISC-V port.
Remove redundant codes of VSETVL PASS in RISC-V port.
gcc/ChangeLog:
* config/riscv/riscv-vsetvl.cc (add_label_notes): Remove it.
(insert_insn_end_basic_block): Ditto.
(pass_vsetvl::commit_vsetvls): Adapt for new helper function.
* gcse.cc (insert_insn_end_basic_block): Export as global function.
* gcse.h (insert_insn_end_basic_block): Ditto.
---
gcc/config/riscv/riscv-vsetvl.cc | 128 +------------------------------
gcc/gcse.cc | 24 ++++--
gcc/gcse.h | 1 +
3 files changed, 23 insertions(+), 130 deletions(-)
@@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see
#include "lcm.h"
#include "predict.h"
#include "profile-count.h"
+#include "gcse.h"
#include "riscv-vsetvl.h"
using namespace rtl_ssa;
@@ -763,127 +764,6 @@ insert_vsetvl (enum emit_type emit_type, rtx_insn *rinsn,
return VSETVL_DISCARD_RESULT;
}
-/* If X contains any LABEL_REF's, add REG_LABEL_OPERAND notes for them
- to INSN. If such notes are added to an insn which references a
- CODE_LABEL, the LABEL_NUSES count is incremented. We have to add
- that note, because the following loop optimization pass requires
- them. */
-
-/* ??? If there was a jump optimization pass after gcse and before loop,
- then we would not need to do this here, because jump would add the
- necessary REG_LABEL_OPERAND and REG_LABEL_TARGET notes. */
-
-static void
-add_label_notes (rtx x, rtx_insn *rinsn)
-{
- enum rtx_code code = GET_CODE (x);
- int i, j;
- const char *fmt;
-
- if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
- {
- /* This code used to ignore labels that referred to dispatch tables to
- avoid flow generating (slightly) worse code.
-
- We no longer ignore such label references (see LABEL_REF handling in
- mark_jump_label for additional information). */
-
- /* There's no reason for current users to emit jump-insns with
- such a LABEL_REF, so we don't have to handle REG_LABEL_TARGET
- notes. */
- gcc_assert (!JUMP_P (rinsn));
- add_reg_note (rinsn, REG_LABEL_OPERAND, label_ref_label (x));
-
- if (LABEL_P (label_ref_label (x)))
- LABEL_NUSES (label_ref_label (x))++;
-
- return;
- }
-
- for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
- {
- if (fmt[i] == 'e')
- add_label_notes (XEXP (x, i), rinsn);
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- add_label_notes (XVECEXP (x, i, j), rinsn);
- }
-}
-
-/* Add EXPR to the end of basic block BB.
-
- This is used by both the PRE and code hoisting. */
-
-static void
-insert_insn_end_basic_block (rtx_insn *rinsn, basic_block cfg_bb)
-{
- rtx_insn *end_rinsn = BB_END (cfg_bb);
- rtx_insn *new_insn;
- rtx_insn *pat, *pat_end;
-
- pat = rinsn;
- gcc_assert (pat && INSN_P (pat));
-
- pat_end = pat;
- while (NEXT_INSN (pat_end) != NULL_RTX)
- pat_end = NEXT_INSN (pat_end);
-
- /* If the last end_rinsn is a jump, insert EXPR in front. Similarly we need
- to take care of trapping instructions in presence of non-call exceptions.
- */
-
- if (JUMP_P (end_rinsn)
- || (NONJUMP_INSN_P (end_rinsn)
- && (!single_succ_p (cfg_bb)
- || single_succ_edge (cfg_bb)->flags & EDGE_ABNORMAL)))
- {
- /* FIXME: What if something in jump uses value set in new end_rinsn? */
- new_insn = emit_insn_before_noloc (pat, end_rinsn, cfg_bb);
- }
-
- /* Likewise if the last end_rinsn is a call, as will happen in the presence
- of exception handling. */
- else if (CALL_P (end_rinsn)
- && (!single_succ_p (cfg_bb)
- || single_succ_edge (cfg_bb)->flags & EDGE_ABNORMAL))
- {
- /* Keeping in mind targets with small register classes and parameters
- in registers, we search backward and place the instructions before
- the first parameter is loaded. Do this for everyone for consistency
- and a presumption that we'll get better code elsewhere as well. */
-
- /* Since different machines initialize their parameter registers
- in different orders, assume nothing. Collect the set of all
- parameter registers. */
- end_rinsn = find_first_parameter_load (end_rinsn, BB_HEAD (cfg_bb));
-
- /* If we found all the parameter loads, then we want to insert
- before the first parameter load.
-
- If we did not find all the parameter loads, then we might have
- stopped on the head of the block, which could be a CODE_LABEL.
- If we inserted before the CODE_LABEL, then we would be putting
- the end_rinsn in the wrong basic block. In that case, put the
- end_rinsn after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK.
- */
- while (LABEL_P (end_rinsn) || NOTE_INSN_BASIC_BLOCK_P (end_rinsn))
- end_rinsn = NEXT_INSN (end_rinsn);
-
- new_insn = emit_insn_before_noloc (pat, end_rinsn, cfg_bb);
- }
- else
- new_insn = emit_insn_after_noloc (pat, end_rinsn, cfg_bb);
-
- while (1)
- {
- if (INSN_P (pat))
- add_label_notes (PATTERN (pat), new_insn);
- if (pat == pat_end)
- break;
- pat = NEXT_INSN (pat);
- }
-}
-
/* Get VL/VTYPE information for INSN. */
static vl_vtype_info
get_vl_vtype_info (const insn_info *insn)
@@ -4126,13 +4006,13 @@ pass_vsetvl::commit_vsetvls (void)
emit_insn (new_pat);
rtx_insn *rinsn = get_insns ();
end_sequence ();
- insert_insn_end_basic_block (rinsn, cfg_bb);
+ rtx_insn *new_insn = insert_insn_end_basic_block (rinsn, cfg_bb);
if (dump_file)
{
fprintf (dump_file,
"\nInsert vsetvl insn %d at the end of <bb %d>:\n",
- INSN_UID (rinsn), cfg_bb->index);
- print_rtl_single (dump_file, rinsn);
+ INSN_UID (new_insn), cfg_bb->index);
+ print_rtl_single (dump_file, new_insn);
}
}
@@ -2015,16 +2015,13 @@ process_insert_insn (struct gcse_expr *expr)
This is used by both the PRE and code hoisting. */
-static void
-insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)
+rtx_insn *
+insert_insn_end_basic_block (rtx_insn *pat, basic_block bb)
{
rtx_insn *insn = BB_END (bb);
rtx_insn *new_insn;
- rtx reg = expr->reaching_reg;
- int regno = REGNO (reg);
- rtx_insn *pat, *pat_end;
+ rtx_insn *pat_end;
- pat = process_insert_insn (expr);
gcc_assert (pat && INSN_P (pat));
pat_end = pat;
@@ -2084,6 +2081,21 @@ insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)
break;
pat = NEXT_INSN (pat);
}
+ return new_insn;
+}
+
+/* Add EXPR to the end of basic block BB.
+
+ This is used by both the PRE and code hoisting. */
+
+static void
+insert_insn_end_basic_block (struct gcse_expr *expr, basic_block bb)
+{
+ rtx reg = expr->reaching_reg;
+ int regno = REGNO (reg);
+
+ rtx_insn *insn = process_insert_insn (expr);
+ rtx_insn *new_insn = insert_insn_end_basic_block (insn, bb);
gcse_create_count++;
@@ -41,5 +41,6 @@ extern struct target_gcse *this_target_gcse;
void gcse_cc_finalize (void);
extern bool gcse_or_cprop_is_too_expensive (const char *);
+extern rtx_insn *insert_insn_end_basic_block (rtx_insn *, basic_block);
#endif