RISC-V: Fix bugs of supporting AVL=REG (single-real-def) in VSETVL PASS
gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (same_bb_and_before_p): Remove it. (real_insn_and_same_bb_p): New function. (same_bb_and_after_or_equal_p): Remove it. (before_p): New function. (reg_killed_by_bb_p): Ditto. (has_vsetvl_killed_avl_p): Ditto. (get_vl): Move location so that we can call it. (anticipatable_occurrence_p): Fix issue of AVL=REG support. (available_occurrence_p): Ditto. (dominate_probability_p): Remove it. (can_backward_propagate_p): Remove it. (get_all_nonphi_defs): New function. (get_all_predecessors): Ditto. (any_insn_in_bb_p): Ditto. (insert_vsetvl): Adjust AVL REG. (source_equal_p): New function. (extract_single_source): Ditto. (avl_info::single_source_equal_p): Ditto. (avl_info::operator==): Adjust for AVL=REG. (vl_vtype_info::same_avl_p): Ditto. (vector_insn_info::set_demand_info): Remove it. (vector_insn_info::compatible_p): Adjust for AVL=REG. (vector_insn_info::compatible_avl_p): New function. (vector_insn_info::merge): Adjust AVL=REG. (vector_insn_info::dump): Ditto. (pass_vsetvl::merge_successors): Remove it. (enum fusion_type): New enum. (pass_vsetvl::get_backward_fusion_type): New function. (pass_vsetvl::backward_demand_fusion): Adjust for AVL=REG. (pass_vsetvl::forward_demand_fusion): Ditto. (pass_vsetvl::demand_fusion): Ditto. (pass_vsetvl::prune_expressions): Ditto. (pass_vsetvl::compute_local_properties): Ditto. (pass_vsetvl::cleanup_vsetvls): Ditto. (pass_vsetvl::commit_vsetvls): Ditto. (pass_vsetvl::init): Ditto. * config/riscv/riscv-vsetvl.h (enum fusion_type): New enum. (enum merge_type): New enum.
This commit is contained in:
parent
acc10c7931
commit
4f673c5ee2
2 changed files with 717 additions and 293 deletions
File diff suppressed because it is too large
Load diff
|
@ -52,6 +52,19 @@ enum demand_type
|
|||
NUM_DEMAND
|
||||
};
|
||||
|
||||
enum fusion_type
|
||||
{
|
||||
INVALID_FUSION,
|
||||
VALID_AVL_FUSION,
|
||||
KILLED_AVL_FUSION
|
||||
};
|
||||
|
||||
enum merge_type
|
||||
{
|
||||
LOCAL_MERGE,
|
||||
GLOBAL_MERGE
|
||||
};
|
||||
|
||||
/* AVL info for RVV instruction. Most RVV instructions have AVL operand in
|
||||
implicit dependency. The AVL comparison between 2 RVV instructions is
|
||||
very important since it affects our decision whether we should insert
|
||||
|
@ -129,6 +142,7 @@ public:
|
|||
avl_info (rtx, rtl_ssa::set_info *);
|
||||
rtx get_value () const { return m_value; }
|
||||
rtl_ssa::set_info *get_source () const { return m_source; }
|
||||
bool single_source_equal_p (const avl_info &) const;
|
||||
avl_info &operator= (const avl_info &);
|
||||
bool operator== (const avl_info &) const;
|
||||
bool operator!= (const avl_info &) const;
|
||||
|
@ -174,6 +188,7 @@ public:
|
|||
|
||||
rtx get_avl () const { return m_avl.get_value (); }
|
||||
const avl_info &get_avl_info () const { return m_avl; }
|
||||
rtl_ssa::set_info *get_avl_source () const { return m_avl.get_source (); }
|
||||
void set_avl_info (const avl_info &avl) { m_avl = avl; }
|
||||
uint8_t get_sew () const { return m_sew; }
|
||||
riscv_vector::vlmul_type get_vlmul () const { return m_vlmul; }
|
||||
|
@ -199,7 +214,25 @@ private:
|
|||
/* The block is polluted as containing VSETVL instruction during dem
|
||||
backward propagation to gain better LCM optimization even though
|
||||
such VSETVL instruction is not really emit yet during this time. */
|
||||
DIRTY
|
||||
DIRTY,
|
||||
/* The block is polluted with killed AVL.
|
||||
We will backward propagate such case:
|
||||
bb 0: def a5, 55 (empty).
|
||||
...
|
||||
bb 1: vsetvli zero, a5.
|
||||
...
|
||||
bb 2: empty.
|
||||
...
|
||||
bb 3: def a3, 55 (empty).
|
||||
...
|
||||
bb 4: vsetvli zero, a3.
|
||||
|
||||
To elide vsetvli in bb 4, we need to backward pollute bb 3 and bb 2
|
||||
as DIRTY block as long as there is a block def AVL which has the same
|
||||
source with AVL in bb 4. Such polluted block, we call it as
|
||||
DIRTY_WITH_KILLED_AVL
|
||||
*/
|
||||
DIRTY_WITH_KILLED_AVL
|
||||
};
|
||||
|
||||
enum state_type m_state;
|
||||
|
@ -247,10 +280,19 @@ public:
|
|||
bool valid_p () const { return m_state == VALID; }
|
||||
bool unknown_p () const { return m_state == UNKNOWN; }
|
||||
bool empty_p () const { return m_state == EMPTY; }
|
||||
bool dirty_p () const { return m_state == DIRTY; }
|
||||
bool dirty_p () const
|
||||
{
|
||||
return m_state == DIRTY || m_state == DIRTY_WITH_KILLED_AVL;
|
||||
}
|
||||
bool dirty_with_killed_avl_p () const
|
||||
{
|
||||
return m_state == DIRTY_WITH_KILLED_AVL;
|
||||
}
|
||||
bool real_dirty_p () const { return m_state == DIRTY; }
|
||||
bool valid_or_dirty_p () const
|
||||
{
|
||||
return m_state == VALID || m_state == DIRTY;
|
||||
return m_state == VALID || m_state == DIRTY
|
||||
|| m_state == DIRTY_WITH_KILLED_AVL;
|
||||
}
|
||||
|
||||
static vector_insn_info get_unknown ()
|
||||
|
@ -263,9 +305,22 @@ public:
|
|||
void set_valid () { m_state = VALID; }
|
||||
void set_unknown () { m_state = UNKNOWN; }
|
||||
void set_empty () { m_state = EMPTY; }
|
||||
void set_dirty () { m_state = DIRTY; }
|
||||
void set_dirty (enum fusion_type type)
|
||||
{
|
||||
gcc_assert (type == VALID_AVL_FUSION || type == KILLED_AVL_FUSION);
|
||||
if (type == VALID_AVL_FUSION)
|
||||
m_state = DIRTY;
|
||||
else
|
||||
m_state = DIRTY_WITH_KILLED_AVL;
|
||||
}
|
||||
void set_dirty (bool dirty_with_killed_avl_p)
|
||||
{
|
||||
if (dirty_with_killed_avl_p)
|
||||
m_state = DIRTY_WITH_KILLED_AVL;
|
||||
else
|
||||
m_state = DIRTY;
|
||||
}
|
||||
void set_insn (rtl_ssa::insn_info *insn) { m_insn = insn; }
|
||||
void set_demand_info (const vector_insn_info &);
|
||||
|
||||
bool demand_p (enum demand_type type) const { return m_demands[type]; }
|
||||
void demand (enum demand_type type) { m_demands[type] = true; }
|
||||
|
@ -274,9 +329,10 @@ public:
|
|||
|
||||
bool compatible_p (const vector_insn_info &) const;
|
||||
bool compatible_avl_p (const vl_vtype_info &) const;
|
||||
bool compatible_avl_p (const avl_info &) const;
|
||||
bool compatible_vtype_p (const vl_vtype_info &) const;
|
||||
bool compatible_p (const vl_vtype_info &) const;
|
||||
vector_insn_info merge (const vector_insn_info &, bool) const;
|
||||
vector_insn_info merge (const vector_insn_info &, enum merge_type) const;
|
||||
|
||||
rtl_ssa::insn_info *get_insn () const { return m_insn; }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue