Home | History | Annotate | Line # | Download | only in riscv
      1 /* Cost model declaration of RISC-V 'V' Extension for GNU compiler.
      2    Copyright (C) 2023-2024 Free Software Foundation, Inc.
      3    Contributed by Juzhe Zhong (juzhe.zhong (at) rivai.ai), RiVAI Technologies Ltd.
      4 
      5    This file is part of GCC.
      6 
      7    GCC is free software; you can redistribute it and/or modify it
      8    under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GCC is distributed in the hope that it will be useful, but
     13    WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15    General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GCC; see the file COPYING3.  If not see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 #ifndef GCC_RISCV_VECTOR_COST_H
     22 #define GCC_RISCV_VECTOR_COST_H
     23 
     24 namespace riscv_vector {
     25 
     26 struct stmt_point
     27 {
     28   /* Program point.  */
     29   unsigned int point;
     30   gimple *stmt;
     31   stmt_vec_info stmt_info;
     32 };
     33 
     34 enum cost_type_enum
     35 {
     36   SCALAR_COST,
     37   VLA_VECTOR_COST,
     38   VLS_VECTOR_COST
     39 };
     40 
     41 /* Pair typedef used by live range: <start, end>.  */
     42 typedef std::pair<unsigned int, unsigned int> pair;
     43 
     44 /* rvv-specific vector costs.  */
     45 class costs : public vector_costs
     46 {
     47   using vector_costs::vector_costs;
     48 
     49 public:
     50   costs (vec_info *, bool);
     51 
     52   bool better_main_loop_than_p (const vector_costs *other) const override;
     53 
     54 private:
     55   unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
     56 			      stmt_vec_info stmt_info, slp_tree node,
     57 			      tree vectype, int misalign,
     58 			      vect_cost_model_location where) override;
     59   void finish_cost (const vector_costs *) override;
     60 
     61   /* True if we have performed one-time initialization based on the
     62      vec_info.  */
     63   bool m_analyzed_vinfo = false;
     64 
     65   /* - If M_COST_TYPE = SCALAR_COST then we're costing the original scalar code.
     66      - If M_COST_TYPE = VLA_VECTOR_COST is nonzero then we're costing VLA
     67        partial vectorization codes.
     68      - If M_COST_TYPE = VLS_VECTOR_COST is nonzero then we're costing VLS
     69        minimum length vector codes.  */
     70   enum cost_type_enum m_cost_type;
     71 
     72   /* On some CPUs, VLA and VLS provide the same theoretical vector
     73      throughput, such as 4x128 VLS vs. 2x256 VLA.  In those
     74      situations, we try to predict whether an VLS implementation
     75      of the loop could be completely unrolled and become straight-line code.
     76      If so, it is generally better to use the VLS version rather
     77      than length-agnostic VLA, since the VLA loop would execute an unknown
     78      number of times and so could not be completely unrolled in the same way.
     79 
     80      If we're applying this heuristic, M_UNROLLED_VLS_NITERS is the
     81      number of VLS loop iterations that would be unrolled and
     82      M_UNROLLED_VLS_STMTS estimates the total number of statements
     83      in the unrolled loop.  Both values are zero if we're not applying
     84      the heuristic.  */
     85   unsigned HOST_WIDE_INT m_unrolled_vls_niters = 0;
     86   unsigned HOST_WIDE_INT m_unrolled_vls_stmts = 0;
     87 
     88   tree cst0 = build_int_cst (integer_type_node, 0);
     89 
     90   /* Store the memory references already processed.  */
     91   typedef pair_hash <tree_operand_hash, tree_operand_hash> tree_pair_hash;
     92   hash_set <tree_pair_hash> memrefs;
     93 
     94   void analyze_loop_vinfo (loop_vec_info);
     95   void record_potential_vls_unrolling (loop_vec_info);
     96   bool prefer_unrolled_loop () const;
     97 
     98   /* Analyze the vectorized program statements and compute the maximum live
     99      V_REGS live at some program point if we enable dynamic LMUL cost model.
    100 
    101      It's true when LMUL of loop vectorization factor > 1 and has unexpected
    102      V_REGS spills according to the analysis.  */
    103   bool m_has_unexpected_spills_p = false;
    104   void record_potential_unexpected_spills (loop_vec_info);
    105 
    106   void adjust_vect_cost_per_loop (loop_vec_info);
    107   unsigned adjust_stmt_cost (enum vect_cost_for_stmt kind,
    108 			     loop_vec_info,
    109 			     stmt_vec_info stmt_info, slp_tree,
    110 			     tree vectype, int stmt_cost);
    111 };
    112 
    113 } // namespace riscv_vector
    114 
    115 #endif // GCC_RISCV_VECTOR_COST_H
    116