From patchwork Fri Mar 3 04:53:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Michael Collison X-Patchwork-Id: 65953 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BB51A383EC4B for ; Fri, 3 Mar 2023 04:53:46 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x829.google.com (mail-qt1-x829.google.com [IPv6:2607:f8b0:4864:20::829]) by sourceware.org (Postfix) with ESMTPS id A095038515FD for ; Fri, 3 Mar 2023 04:53:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A095038515FD Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rivosinc.com Received: by mail-qt1-x829.google.com with SMTP id c18so1736824qte.5 for ; Thu, 02 Mar 2023 20:53:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=i6SnaafxPCkWdg7nZywvKlXaEBftLbKirFYFeulg/7Q=; b=cOBXMidLtuyDEGjGFELHcccr2zs4uC1JwjC652Xv6C9G0A3YM/64tuxu0LM118LYE/ pOY4TiLZffRgSeJN66rF3XoAKY1Qzrljws8cCxH8zvdhiDEgQcdf7e0DdzHP2wKBL0dP Q1yAeHg3kvWfTfFWXUX3bXlutZ11Yx/RnEyxKQSctILdh/omZpvtFOOCJspidHHa8YDf +gSFi3PG6b0n9nocrWCHC7PYhvy1sgR8/srMJzQbIcjvLtV8L9MOHAJQq0Bz4PenL1K6 aF4jNZIyZcUfJzRDPlaz5Cc51ycWJFy45zKacFaioeTSdkYoWIjGPEUM08IzGVuTd5VX 9CKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=i6SnaafxPCkWdg7nZywvKlXaEBftLbKirFYFeulg/7Q=; b=YPOb7mDtxLXcYAzVi3RiGxWHWC4uIo1e7YhZblTcwQom5+06BSB6KCtxv8touGkBYv suffxTHD1WGRVUM/EF+rBy5/zTiY+byztKUSTiuLRRquHIy02Ggzg3p6fSYJcWbioL1n yb4nH+N6WcpcSaFHp1oXABudJC/4YoqJjxQrsdtu/jwYT94OEvMEkcXL+XtlI9EYdN8D 4LvuuG4YlAHIcxGay19DaXT1UIl78tAu1WxX0yxI2746m80MlAnvkT0KP35YRX13pxlG XHNGH4Lc7FIPFwrg65jCQw11MCvs+em7krABUgji+R7Pr6ueraRLz+mSueQpQPSq1sbS Hbmg== X-Gm-Message-State: AO0yUKV+ISng5BR05ARUCZnpHvc7zYHv+Aeg2JRLEzUthOCY4mB1gTpY aDFGHPsxLwQqwzarKUSfgixjjmk42ZEE3DCC X-Google-Smtp-Source: AK7set9JgBFXQExPLJ2QM3Fyve4FOyLML8mkGQkzaCuFK+KrK/OMH6V/Eyp7HecXWpLmgtS9s3TxrQ== X-Received: by 2002:ac8:7d42:0:b0:3bf:d688:2a77 with SMTP id h2-20020ac87d42000000b003bfd6882a77mr821493qtb.64.1677819205701; Thu, 02 Mar 2023 20:53:25 -0800 (PST) Received: from [192.168.86.117] ([136.57.172.92]) by smtp.gmail.com with ESMTPSA id l5-20020ac87245000000b003b9a426d626sm1071865qtp.22.2023.03.02.20.53.25 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 02 Mar 2023 20:53:25 -0800 (PST) Message-ID: Date: Thu, 2 Mar 2023 23:53:25 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.7.1 From: Michael Collison Subject: [PATCH 05/07] RISC-V: Add auto-vectorization support To: gcc-patches Content-Language: en-US X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch adds support for registering target hooks for basic autovectorization support as well as basic tuning information for the vector extension. gcc/ChangeLog:     * config/riscv/riscv-cores.def (RISCV_TUNE):     Add VECTOR_TUNE_INFO parameter and     * common/config/riscv/riscv-common.cc (RISCV_TUNE):     Add VECTOR_TUNE_INFO parameter.     * config/riscv/riscv.cc (riscv_vector_tune_param):     New struct for vector tuning information.     (riscv_tune_info): add vector_tune_param.     (vector_tune_param): New static variable.     (riscv_vectorization_factor): New variable.     (generic_rvv_insn_scale_table): New struct.     (generic_rvv_stmt_scale_table): New struct.     (generic_rvv_insn_cost_table): New vector insn cost table.     (generic_rvv_stmt_cost_table): New vector statement cost table.     (generic_rvv_tune_info): New rvv tuning table.     (RISCV_TUNE): Add VECTOR_TUNE_INFO parameter.     (riscv_rtx_costs): Return vector estimate if vector mode.     (riscv_option_override): Set vector_tune_param.     (riscv_option_override): Set riscv_vectorization_factor.     (riscv_estimated_poly_value): Implement     TARGET_ESTIMATED_POLY_VALUE.     (riscv_preferred_simd_mode): Implement     TARGET_VECTORIZE_PREFERRED_SIMD_MODE.     (riscv_autovectorize_vector_modes): Implement     TARGET_AUTOVECTORIZE_VECTOR_MODES.     (riscv_get_mask_mode): Implement TARGET_VECTORIZE_GET_MASK_MODE.     (riscv_empty_mask_is_expensive): Implement     TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE.     (riscv_builtin_vectorization_cost): Implement     TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST.     (riscv_vectorize_create_costs): Implement     TARGET_VECTORIZE_CREATE_COSTS.     (TARGET_ESTIMATED_POLY_VALUE): Register target macro.     (TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST): Ditto.     (TARGET_VECTORIZE_PREFERRED_SIMD_MODE): Ditto.     (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES): Ditto.     (TARGET_VECTORIZE_GET_MASK_MODE): Ditto.     (TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE): Ditto.     (TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK): Ditto.     (TARGET_VECTORIZE_CREATE_COSTS): Ditto ---  gcc/common/config/riscv/riscv-common.cc |   2 +-  gcc/config/riscv/riscv-cores.def        |  14 +-  gcc/config/riscv/riscv.cc               | 321 +++++++++++++++++++++++-  3 files changed, 325 insertions(+), 12 deletions(-)  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *); @@ -403,8 +469,8 @@ static const unsigned gpr_save_reg_order[] = {  /* A table describing all the processors GCC knows about.  */  static const struct riscv_tune_info riscv_tune_info_table[] = { -#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO)    \ -  { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO}, +#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO, VECTOR_TUNE_INFO)    \ +  { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO, &VECTOR_TUNE_INFO},  #include "riscv-cores.def"  }; @@ -2237,8 +2303,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN       Cost Model need to be well analyzed and supported in the future. */    if (riscv_v_ext_vector_mode_p (mode))      { -      *total = COSTS_N_INSNS (1); -      return true; +      return vector_tune_param->rvv_insn_costs_table->get_cost (x, mode, total, speed);      }    bool float_mode_p = FLOAT_MODE_P (mode); @@ -6079,6 +6144,7 @@ riscv_option_override (void)                 RISCV_TUNE_STRING_DEFAULT));    riscv_microarchitecture = cpu->microarchitecture;    tune_param = optimize_size ? &optimize_size_tune_info : cpu->tune_param; +  vector_tune_param = cpu->vector_tune_param;    /* Use -mtune's setting for slow_unaligned_access, even when optimizing       for size.  For architectures that trap and emulate unaligned accesses, @@ -6198,6 +6264,10 @@ riscv_option_override (void)    /* Convert -march to a chunks count.  */    riscv_vector_chunks = riscv_convert_vector_bits (); + +  if (TARGET_VECTOR) +    riscv_vectorization_factor = riscv_vector_lmul; +  }  /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */ @@ -6892,6 +6962,218 @@ riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,    return RISCV_DWARF_VLENB;  } +/* Implement TARGET_ESTIMATED_POLY_VALUE. +   Look into the tuning structure for an estimate. +   KIND specifies the type of requested estimate: min, max or likely. +   For cores with a known RVV width all three estimates are the same. +   For generic RVV tuning we want to distinguish the maximum estimate from +   the minimum and likely ones. +   The likely estimate is the same as the minimum in that case to give a +   conservative behavior of auto-vectorizing with RVV when it is a win +   even for 128-bit RVV. +   When RVV width information is available VAL.coeffs[1] is multiplied by +   the number of VQ chunks over the initial Advanced SIMD 128 bits.  */ + +static HOST_WIDE_INT +riscv_estimated_poly_value (poly_int64 val, +                            poly_value_estimate_kind kind = POLY_VALUE_LIKELY) +{ +  unsigned int width_source = +      BITS_PER_RISCV_VECTOR.is_constant () +          ? (unsigned int)BITS_PER_RISCV_VECTOR.to_constant () +          : (unsigned int)RVV_SCALABLE; + +  /* If there is no core-specific information then the minimum and likely +     values are based on 128-bit vectors and the maximum is based on +     the architectural maximum of 2048 bits.  */ +  if (width_source == RVV_SCALABLE) +    switch (kind) +      { +      case POLY_VALUE_MIN: +      case POLY_VALUE_LIKELY: +        return val.coeffs[0]; + +      case POLY_VALUE_MAX: +        return val.coeffs[0] + val.coeffs[1] * 15; +      } + +  /* Allow BITS_PER_RISCV_VECTOR to be a bitmask of different VL, treating the +     lowest as likely.  This could be made more general if future -mtune +     options need it to be.  */ +  if (kind == POLY_VALUE_MAX) +    width_source = 1 << floor_log2 (width_source); +  else +    width_source = least_bit_hwi (width_source); + +  /* If the core provides width information, use that.  */ +  HOST_WIDE_INT over_128 = width_source - 128; +  return val.coeffs[0] + val.coeffs[1] * over_128 / 128; +} + +/* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE.  */ + +static machine_mode +riscv_preferred_simd_mode (scalar_mode mode) +{ +  machine_mode vmode = +    riscv_vector::riscv_vector_preferred_simd_mode (mode, riscv_vectorization_factor); +  if (VECTOR_MODE_P (vmode)) +    return vmode; + +  return word_mode; +} + +/* Implement TARGET_AUTOVECTORIZE_VECTOR_MODES for RVV.  */ +static unsigned int +riscv_autovectorize_vector_modes (vector_modes *modes, bool) +{ +  if (!TARGET_VECTOR) +    return 0; + +  if (riscv_vectorization_factor == RVV_LMUL1) +    { +      modes->safe_push (VNx16QImode); +      modes->safe_push (VNx8QImode); +      modes->safe_push (VNx4QImode); +      modes->safe_push (VNx2QImode); +    } +  else if (riscv_vectorization_factor == RVV_LMUL2) +    { +      modes->safe_push (VNx32QImode); +      modes->safe_push (VNx16QImode); +      modes->safe_push (VNx8QImode); +      modes->safe_push (VNx4QImode); +    } +  else if (riscv_vectorization_factor == RVV_LMUL4) +    { +      modes->safe_push (VNx64QImode); +      modes->safe_push (VNx32QImode); +      modes->safe_push (VNx16QImode); +      modes->safe_push (VNx8QImode); +    } +  else +    { +      modes->safe_push (VNx64QImode); +      modes->safe_push (VNx32QImode); +      modes->safe_push (VNx16QImode); +    } + +  return 0; +} + +/* Implement TARGET_VECTORIZE_GET_MASK_MODE.  */ + +static opt_machine_mode +riscv_get_mask_mode (machine_mode mode) +{ +  machine_mode mask_mode = VOIDmode; +  if (TARGET_VECTOR && +      riscv_vector::riscv_vector_get_mask_mode (mode).exists (&mask_mode)) +    return mask_mode; + +  return default_get_mask_mode (mode); +} + +/* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE.  Assume for now that +   it isn't worth branching around empty masked ops (including masked +   stores).  */ + +static bool +riscv_empty_mask_is_expensive (unsigned) +{ +  return false; +} + +/* Implement targetm.vectorize.builtin_vectorization_cost.  */ +int +riscv_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, +                                  tree vectype, int misalign ATTRIBUTE_UNUSED) +{ +  unsigned elements; +  bool fp = false; +  rtx x = NULL_RTX; +  machine_mode mode = VOIDmode; + +  if (vectype != NULL) +    { +      fp = FLOAT_TYPE_P (vectype); +      mode = TYPE_MODE (vectype); +    } + +  switch (type_of_cost) +    { +    case scalar_stmt: +      return fp ? vector_tune_param->rvv_stmt_costs_table->scalar_fp->cost ( +                      x, mode) +                : vector_tune_param->rvv_stmt_costs_table->scalar_int->cost ( +                      x, mode); + +    case scalar_load: +      return vector_tune_param->rvv_stmt_costs_table->scalar_load->cost (x, + mode); + +    case scalar_store: +      return vector_tune_param->rvv_stmt_costs_table->scalar_store->cost (x, + mode); + +    case vector_stmt: +      return fp ? vector_tune_param->rvv_stmt_costs_table->vec_fp->cost (x, + mode) +                : vector_tune_param->rvv_stmt_costs_table->vec_int->cost (x, + mode); + +    case vector_load: +      return vector_tune_param->rvv_stmt_costs_table->vec_align_load->cost ( +          x, mode); + +    case vector_store: +      return vector_tune_param->rvv_stmt_costs_table->vec_store->cost (x, mode); + +    case vec_to_scalar: +      return vector_tune_param->rvv_stmt_costs_table->vec_to_scalar->cost ( +          x, mode); + +    case scalar_to_vec: +      return vector_tune_param->rvv_stmt_costs_table->scalar_to_vec->cost ( +          x, mode); + +    case unaligned_load: +    case vector_gather_load: +      return vector_tune_param->rvv_stmt_costs_table->vec_unalign_load->cost ( +          x, mode); + +    case unaligned_store: +    case vector_scatter_store: +      return vector_tune_param->rvv_stmt_costs_table->vec_unalign_store->cost ( +          x, mode); + +    case cond_branch_taken: +      return vector_tune_param->rvv_stmt_costs_table->cond_taken_branch->cost ( +          x, mode); + +    case cond_branch_not_taken: +      return vector_tune_param->rvv_stmt_costs_table->cond_not_taken_branch +          ->cost (x, mode); + +    case vec_perm: +      return vector_tune_param->rvv_stmt_costs_table->vec_permute->cost (x, + mode); + +    case vec_promote_demote: +      return fp ? vector_tune_param->rvv_stmt_costs_table->vec_fp->cost (x, + mode) +                : vector_tune_param->rvv_stmt_costs_table->vec_int->cost (x, + mode); + +    case vec_construct: +      elements = estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)); +      return elements / 2 + 1; + +    default: +      gcc_unreachable (); +    } +} +  /* Return true if a shift-amount matches the trailing cleared bits on     a bitmask.  */ @@ -6901,6 +7183,13 @@ riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)    return shamt == ctz_hwi (mask);  } +/* Implement TARGET_VECTORIZE_CREATE_COSTS.  */ +vector_costs * +riscv_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar) +{ +  return new riscv_vector_costs (vinfo, costing_for_scalar); +} +  /* Initialize the GCC target structure.  */  #undef TARGET_ASM_ALIGNED_HI_OP  #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -7143,6 +7432,30 @@ riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)  #undef TARGET_VERIFY_TYPE_CONTEXT  #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context +#undef TARGET_ESTIMATED_POLY_VALUE +#define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value + +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST +#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST riscv_builtin_vectorization_cost + +#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE +#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode + +#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES +#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES riscv_autovectorize_vector_modes + +#undef TARGET_VECTORIZE_GET_MASK_MODE +#define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode + +#undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE +#define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive + +#undef TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK +#define TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK riscv_loop_len_override_mask + +#undef TARGET_VECTORIZE_CREATE_COSTS +#define TARGET_VECTORIZE_CREATE_COSTS riscv_vectorize_create_costs +  #undef TARGET_VECTOR_ALIGNMENT  #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index ebc1ed7d7e4..6b8d92af986 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -246,7 +246,7 @@ static const riscv_cpu_info riscv_cpu_tables[] =  static const char *riscv_tunes[] =  { -#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \ +#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO, VECTOR_TUNE_INFO)    \      TUNE_NAME,  #include "../../../config/riscv/riscv-cores.def"      NULL diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index 2a834cae21d..4feb0366222 100644 --- a/gcc/config/riscv/riscv-cores.def +++ b/gcc/config/riscv/riscv-cores.def @@ -30,15 +30,15 @@     identifier, reference to riscv.cc.  */  #ifndef RISCV_TUNE -#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) +#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO, VECTOR_TUNE_INFO)  #endif -RISCV_TUNE("rocket", generic, rocket_tune_info) -RISCV_TUNE("sifive-3-series", generic, rocket_tune_info) -RISCV_TUNE("sifive-5-series", generic, rocket_tune_info) -RISCV_TUNE("sifive-7-series", sifive_7, sifive_7_tune_info) -RISCV_TUNE("thead-c906", generic, thead_c906_tune_info) -RISCV_TUNE("size", generic, optimize_size_tune_info) +RISCV_TUNE("rocket", generic, rocket_tune_info, generic_rvv_tune_info) +RISCV_TUNE("sifive-3-series", generic, rocket_tune_info, generic_rvv_tune_info) +RISCV_TUNE("sifive-5-series", generic, rocket_tune_info, generic_rvv_tune_info) +RISCV_TUNE("sifive-7-series", sifive_7, sifive_7_tune_info, generic_rvv_tune_info) +RISCV_TUNE("thead-c906", generic, thead_c906_tune_info, generic_rvv_tune_info) +RISCV_TUNE("size", generic, optimize_size_tune_info, generic_rvv_tune_info)  #undef RISCV_TUNE diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index f11b7949a49..16b38ba4d76 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -60,6 +60,16 @@ along with GCC; see the file COPYING3.  If not see  #include "opts.h"  #include "tm-constrs.h"  #include "rtl-iter.h" +#include "gimple.h" +#include "cfghooks.h" +#include "cfgloop.h" +#include "cfgrtl.h" +#include "sel-sched.h" +#include "fold-const.h" +#include "gimple-iterator.h" +#include "gimple-expr.h" +#include "tree-vectorizer.h" +#include "riscv-vector-cost.h"  /* This file should be included last.  */  #include "target-def.h" @@ -238,6 +248,12 @@ struct riscv_tune_param    bool slow_unaligned_access;  }; +/* Cost for vector insn classes.  */ +struct riscv_vector_tune_param { +    const vector_insn_cost_table* rvv_insn_costs_table; +    const vector_stmt_cost_table* rvv_stmt_costs_table; +}; +  /* Information about one micro-arch we know about.  */  struct riscv_tune_info {    /* This micro-arch canonical name.  */ @@ -248,6 +264,9 @@ struct riscv_tune_info {    /* Tuning parameters for this micro-arch.  */    const struct riscv_tune_param *tune_param; + +  /* Tuning vector parameters for this micro-arch.  */ +  const struct riscv_vector_tune_param *vector_tune_param;  };  /* Global variables for machine-dependent things.  */ @@ -266,6 +285,9 @@ static int epilogue_cfa_sp_offset;  /* Which tuning parameters to use.  */  static const struct riscv_tune_param *tune_param; +/* Which vector tuning parameters to use.  */ +static const struct riscv_vector_tune_param *vector_tune_param; +  /* Which automaton to use for tuning.  */  enum riscv_microarchitecture_type riscv_microarchitecture; @@ -275,6 +297,9 @@ poly_uint16 riscv_vector_chunks;  /* The number of bytes in a vector chunk.  */  unsigned riscv_bytes_per_vector_chunk; +/* Prefer vf for auto-vectorizer.  */ +unsigned riscv_vectorization_factor; +  /* Index R is the smallest register class that contains register R.  */  const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {    GR_REGS,    GR_REGS,    GR_REGS,    GR_REGS, @@ -367,6 +392,47 @@ static const struct riscv_tune_param optimize_size_tune_info = {    false,                    /* slow_unaligned_access */  }; +static const vector_insn_scale_table generic_rvv_insn_scale_table = { +    4, /*load*/ +    1, /*store*/ +    1, /*alu*/ +    1, /*mult*/ +    1, /*movi*/ +    1, /*dup*/ +    1, /*extract*/ +    1, /*if_then_else*/ +}; + +static const vector_stmt_scale_table generic_rvv_stmt_scale_table = { +    1, /* scalar_int_stmt_cost  */ +    1, /* scalar_fp_stmt_cost  */ +    1, /* scalar_load_cost  */ +    1, /* scalar_store_cost  */ +    1, /* vec_int_stmt_cost  */ +    1, /* vec_fp_stmt_cost  */ +    1, /* vec_permute_cost  */ +    1, /* vec_to_scalar_cost  */ +    1, /* scalar_to_vec_cost  */ +    1, /* vec_align_load_cost  */ +    1, /* vec_unalign_load_cost  */ +    1, /* vec_unalign_store_cost  */ +    1, /* vec_store_cost  */ +    1, /* cond_taken_branch_cost  */ +    1 /* cond_not_taken_branch_cost  */ +}; + +static const vector_insn_cost_table* generic_rvv_insn_cost_table = +            new vector_insn_cost_table(&generic_rvv_insn_scale_table); + +static const vector_stmt_cost_table* generic_rvv_stmt_cost_table = +            new vector_stmt_cost_table(&generic_rvv_stmt_scale_table); + +/* Costs to use when optimizing for riscv vector.  */ +static const struct riscv_vector_tune_param generic_rvv_tune_info = { +  generic_rvv_insn_cost_table, +  generic_rvv_stmt_cost_table +}; +  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);