From: Soumya AR <soum...@nvidia.com> This patch adds functionality to dump AArch64 CPU tuning parameters to a JSON file. The new '-fdump-tuning-model=' flag allows users to export the current tuning model configuration to a JSON file.
This patch was bootstrapped and regtested on aarch64-linux-gnu, no regression. Signed-off-by: Soumya AR <soum...@nvidia.com> gcc/ChangeLog: * config.gcc: Add aarch64-json-tunings-printer.o. * config/aarch64/aarch64.cc (aarch64_override_options_internal): Invoke aarch64_print_tune_params if -fdump-tuning-model= is specified. * config/aarch64/aarch64.opt: New option. * config/aarch64/t-aarch64 (aarch64-json-tunings-printer.o): New define. * config/aarch64/aarch64-json-tunings-printer.cc: New file. * config/aarch64/aarch64-json-tunings-printer.h: New file. --- gcc/config.gcc | 2 +- .../aarch64/aarch64-json-tunings-printer.cc | 517 ++++++++++++++++++ .../aarch64/aarch64-json-tunings-printer.h | 28 + gcc/config/aarch64/aarch64.cc | 4 + gcc/config/aarch64/aarch64.opt | 4 + gcc/config/aarch64/t-aarch64 | 9 + 6 files changed, 563 insertions(+), 1 deletion(-) create mode 100644 gcc/config/aarch64/aarch64-json-tunings-printer.cc create mode 100644 gcc/config/aarch64/aarch64-json-tunings-printer.h diff --git a/gcc/config.gcc b/gcc/config.gcc index a518e976b82..4d23b578457 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -350,7 +350,7 @@ aarch64*-*-*) c_target_objs="aarch64-c.o" cxx_target_objs="aarch64-c.o" d_target_objs="aarch64-d.o" - extra_objs="aarch64-builtins.o aarch-common.o aarch64-sve-builtins.o aarch64-sve-builtins-shapes.o aarch64-sve-builtins-base.o aarch64-sve-builtins-sve2.o aarch64-sve-builtins-sme.o cortex-a57-fma-steering.o aarch64-speculation.o aarch-bti-insert.o aarch64-cc-fusion.o aarch64-early-ra.o aarch64-ldp-fusion.o" + extra_objs="aarch64-builtins.o aarch-common.o aarch64-sve-builtins.o aarch64-sve-builtins-shapes.o aarch64-sve-builtins-base.o aarch64-sve-builtins-sve2.o aarch64-sve-builtins-sme.o cortex-a57-fma-steering.o aarch64-speculation.o aarch-bti-insert.o aarch64-cc-fusion.o aarch64-early-ra.o aarch64-ldp-fusion.o aarch64-json-tunings-printer.o" target_gtfiles="\$(srcdir)/config/aarch64/aarch64-protos.h \$(srcdir)/config/aarch64/aarch64-builtins.h \$(srcdir)/config/aarch64/aarch64-builtins.cc \$(srcdir)/config/aarch64/aarch64-sve-builtins.h \$(srcdir)/config/aarch64/aarch64-sve-builtins.cc" target_has_targetm_common=yes ;; diff --git a/gcc/config/aarch64/aarch64-json-tunings-printer.cc b/gcc/config/aarch64/aarch64-json-tunings-printer.cc new file mode 100644 index 00000000000..6c440838390 --- /dev/null +++ b/gcc/config/aarch64/aarch64-json-tunings-printer.cc @@ -0,0 +1,517 @@ +/* Routines to print the AArch64 tuning parameters to a JSON file. + Copyright The GNU Toolchain Authors. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "pretty-print.h" +#include "tm.h" +#include "diagnostic-core.h" +#include "aarch64-json-tunings-printer.h" +#include "aarch64-protos.h" +#include "config/arm/aarch-common-protos.h" +#include "json.h" + +static std::unique_ptr<json::object> +serialize_alu_cost_table (const struct alu_cost_table &alu) +{ + auto alu_obj = std::make_unique<json::object> (); + + alu_obj->set_integer ("arith", alu.arith); + alu_obj->set_integer ("logical", alu.logical); + alu_obj->set_integer ("shift", alu.shift); + alu_obj->set_integer ("shift_reg", alu.shift_reg); + alu_obj->set_integer ("arith_shift", alu.arith_shift); + alu_obj->set_integer ("arith_shift_reg", alu.arith_shift_reg); + alu_obj->set_integer ("log_shift", alu.log_shift); + alu_obj->set_integer ("log_shift_reg", alu.log_shift_reg); + alu_obj->set_integer ("extend", alu.extend); + alu_obj->set_integer ("extend_arith", alu.extend_arith); + alu_obj->set_integer ("bfi", alu.bfi); + alu_obj->set_integer ("bfx", alu.bfx); + alu_obj->set_integer ("clz", alu.clz); + alu_obj->set_integer ("rev", alu.rev); + alu_obj->set_integer ("non_exec", alu.non_exec); + alu_obj->set_bool ("non_exec_costs_exec", alu.non_exec_costs_exec); + + return alu_obj; +} + +static std::unique_ptr<json::array> +serialize_mult_cost_table (const struct mult_cost_table *mult) +{ + auto mult_arr = std::make_unique<json::array> (); + + for (int i = 0; i < 2; ++i) + { + auto mult_obj = std::make_unique<json::object> (); + + mult_obj->set_integer ("simple", mult[i].simple); + mult_obj->set_integer ("flag_setting", mult[i].flag_setting); + mult_obj->set_integer ("extend", mult[i].extend); + mult_obj->set_integer ("add", mult[i].add); + mult_obj->set_integer ("extend_add", mult[i].extend_add); + mult_obj->set_integer ("idiv", mult[i].idiv); + + mult_arr->append (std::move (mult_obj)); + } + + return mult_arr; +} + +static std::unique_ptr<json::object> +serialize_mem_cost_table (const struct mem_cost_table &mem) +{ + auto mem_obj = std::make_unique<json::object> (); + + mem_obj->set_integer ("load", mem.load); + mem_obj->set_integer ("load_sign_extend", mem.load_sign_extend); + mem_obj->set_integer ("ldrd", mem.ldrd); + mem_obj->set_integer ("ldm_1st", mem.ldm_1st); + mem_obj->set_integer ("ldm_regs_per_insn_1st", mem.ldm_regs_per_insn_1st); + mem_obj->set_integer ("ldm_regs_per_insn_subsequent", + mem.ldm_regs_per_insn_subsequent); + mem_obj->set_integer ("loadf", mem.loadf); + mem_obj->set_integer ("loadd", mem.loadd); + mem_obj->set_integer ("load_unaligned", mem.load_unaligned); + mem_obj->set_integer ("store", mem.store); + mem_obj->set_integer ("strd", mem.strd); + mem_obj->set_integer ("stm_1st", mem.stm_1st); + mem_obj->set_integer ("stm_regs_per_insn_1st", mem.stm_regs_per_insn_1st); + mem_obj->set_integer ("stm_regs_per_insn_subsequent", + mem.stm_regs_per_insn_subsequent); + mem_obj->set_integer ("storef", mem.storef); + mem_obj->set_integer ("stored", mem.stored); + mem_obj->set_integer ("store_unaligned", mem.store_unaligned); + mem_obj->set_integer ("loadv", mem.loadv); + mem_obj->set_integer ("storev", mem.storev); + + return mem_obj; +} + +static std::unique_ptr<json::array> +serialize_fp_cost_table (const struct fp_cost_table *fp) +{ + auto fp_arr = std::make_unique<json::array> (); + + for (int i = 0; i < 2; ++i) + { + auto fp_obj = std::make_unique<json::object> (); + + fp_obj->set_integer ("div", fp[i].div); + fp_obj->set_integer ("mult", fp[i].mult); + fp_obj->set_integer ("mult_addsub", fp[i].mult_addsub); + fp_obj->set_integer ("fma", fp[i].fma); + fp_obj->set_integer ("addsub", fp[i].addsub); + fp_obj->set_integer ("fpconst", fp[i].fpconst); + fp_obj->set_integer ("neg", fp[i].neg); + fp_obj->set_integer ("compare", fp[i].compare); + fp_obj->set_integer ("widen", fp[i].widen); + fp_obj->set_integer ("narrow", fp[i].narrow); + fp_obj->set_integer ("toint", fp[i].toint); + fp_obj->set_integer ("fromint", fp[i].fromint); + fp_obj->set_integer ("roundint", fp[i].roundint); + + fp_arr->append (std::move (fp_obj)); + } + + return fp_arr; +} + +static std::unique_ptr<json::object> +serialize_vector_cost_table (const struct vector_cost_table &vect) +{ + auto vec_costs_obj = std::make_unique<json::object> (); + + vec_costs_obj->set_integer ("alu", vect.alu); + vec_costs_obj->set_integer ("mult", vect.mult); + vec_costs_obj->set_integer ("movi", vect.movi); + vec_costs_obj->set_integer ("dup", vect.dup); + vec_costs_obj->set_integer ("extract", vect.extract); + + return vec_costs_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_cost_table (const struct cpu_cost_table &insn_extra_cost) +{ + auto insn_extra_cost_obj = std::make_unique<json::object> (); + + insn_extra_cost_obj->set ("alu", + serialize_alu_cost_table (insn_extra_cost.alu)); + insn_extra_cost_obj->set ("mult", + serialize_mult_cost_table (insn_extra_cost.mult)); + insn_extra_cost_obj->set ("ldst", + serialize_mem_cost_table (insn_extra_cost.ldst)); + insn_extra_cost_obj->set ("fp", serialize_fp_cost_table (insn_extra_cost.fp)); + insn_extra_cost_obj->set ("vect", + serialize_vector_cost_table (insn_extra_cost.vect)); + + return insn_extra_cost_obj; +} + +static std::unique_ptr<json::object> +serialize_addr_scale_costs_objr_mode_cost ( + const scale_addr_mode_cost &addr_scale_costs) +{ + auto addr_scale_costs_objr_obj = std::make_unique<json::object> (); + + addr_scale_costs_objr_obj->set_integer ("hi", addr_scale_costs.hi); + addr_scale_costs_objr_obj->set_integer ("si", addr_scale_costs.si); + addr_scale_costs_objr_obj->set_integer ("di", addr_scale_costs.di); + addr_scale_costs_objr_obj->set_integer ("ti", addr_scale_costs.ti); + return addr_scale_costs_objr_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_addrcost_table (const cpu_addrcost_table &addr_cost) +{ + auto addr_cost_obj = std::make_unique<json::object> (); + + addr_cost_obj->set ("addr_scale_costs", + serialize_addr_scale_costs_objr_mode_cost ( + addr_cost.addr_scale_costs)); + addr_cost_obj->set_integer ("pre_modify", addr_cost.pre_modify); + addr_cost_obj->set_integer ("post_modify", addr_cost.post_modify); + addr_cost_obj->set_integer ("post_modify_ld3_st3", + addr_cost.post_modify_ld3_st3); + addr_cost_obj->set_integer ("post_modify_ld4_st4", + addr_cost.post_modify_ld4_st4); + addr_cost_obj->set_integer ("register_offset", addr_cost.register_offset); + addr_cost_obj->set_integer ("register_sextend", addr_cost.register_sextend); + addr_cost_obj->set_integer ("register_zextend", addr_cost.register_zextend); + addr_cost_obj->set_integer ("imm_offset", addr_cost.imm_offset); + return addr_cost_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_regmove_cost (const cpu_regmove_cost ®move_cost) +{ + auto regmove_cost_obj = std::make_unique<json::object> (); + + regmove_cost_obj->set_integer ("GP2GP", regmove_cost.GP2GP); + regmove_cost_obj->set_integer ("GP2FP", regmove_cost.GP2FP); + regmove_cost_obj->set_integer ("FP2GP", regmove_cost.FP2GP); + regmove_cost_obj->set_integer ("FP2FP", regmove_cost.FP2FP); + return regmove_cost_obj; +} + +static std::unique_ptr<json::object> +serialize_advsimd_vec_cost (const advsimd_vec_cost &advsimd) +{ + auto advsimd_obj = std::make_unique<json::object> (); + + advsimd_obj->set_integer ("int_stmt_cost", advsimd.int_stmt_cost); + advsimd_obj->set_integer ("fp_stmt_cost", advsimd.fp_stmt_cost); + advsimd_obj->set_integer ("ld2_st2_permute_cost", + advsimd.ld2_st2_permute_cost); + advsimd_obj->set_integer ("ld3_st3_permute_cost", + advsimd.ld3_st3_permute_cost); + advsimd_obj->set_integer ("ld4_st4_permute_cost", + advsimd.ld4_st4_permute_cost); + advsimd_obj->set_integer ("permute_cost", advsimd.permute_cost); + advsimd_obj->set_integer ("reduc_i8_cost", advsimd.reduc_i8_cost); + advsimd_obj->set_integer ("reduc_i16_cost", advsimd.reduc_i16_cost); + advsimd_obj->set_integer ("reduc_i32_cost", advsimd.reduc_i32_cost); + advsimd_obj->set_integer ("reduc_i64_cost", advsimd.reduc_i64_cost); + advsimd_obj->set_integer ("reduc_f16_cost", advsimd.reduc_f16_cost); + advsimd_obj->set_integer ("reduc_f32_cost", advsimd.reduc_f32_cost); + advsimd_obj->set_integer ("reduc_f64_cost", advsimd.reduc_f64_cost); + advsimd_obj->set_integer ("store_elt_extra_cost", + advsimd.store_elt_extra_cost); + advsimd_obj->set_integer ("vec_to_scalar_cost", advsimd.vec_to_scalar_cost); + advsimd_obj->set_integer ("scalar_to_vec_cost", advsimd.scalar_to_vec_cost); + advsimd_obj->set_integer ("align_load_cost", advsimd.align_load_cost); + advsimd_obj->set_integer ("unalign_load_cost", advsimd.unalign_load_cost); + advsimd_obj->set_integer ("unalign_store_cost", advsimd.unalign_store_cost); + advsimd_obj->set_integer ("store_cost", advsimd.store_cost); + + return advsimd_obj; +} +static std::unique_ptr<json::object> +serialize_sve_vec_cost (const sve_vec_cost &sve) +{ + auto sve_obj = std::make_unique<json::object> (); + + sve_obj->set_integer ("clast_cost", sve.clast_cost); + sve_obj->set_integer ("fadda_f16_cost", sve.fadda_f16_cost); + sve_obj->set_integer ("fadda_f32_cost", sve.fadda_f32_cost); + sve_obj->set_integer ("fadda_f64_cost", sve.fadda_f64_cost); + sve_obj->set_integer ("gather_load_x32_cost", sve.gather_load_x32_cost); + sve_obj->set_integer ("gather_load_x64_cost", sve.gather_load_x64_cost); + sve_obj->set_integer ("gather_load_x32_init_cost", + sve.gather_load_x32_init_cost); + sve_obj->set_integer ("gather_load_x64_init_cost", + sve.gather_load_x64_init_cost); + sve_obj->set_integer ("scatter_store_elt_cost", sve.scatter_store_elt_cost); + + return sve_obj; +} + +static std::unique_ptr<json::object> +serialize_aarch64_base_vec_issue_info (const aarch64_base_vec_issue_info &base) +{ + auto base_obj = std::make_unique<json::object> (); + + base_obj->set_integer ("loads_stores_per_cycle", base.loads_stores_per_cycle); + base_obj->set_integer ("stores_per_cycle", base.stores_per_cycle); + base_obj->set_integer ("general_ops_per_cycle", base.general_ops_per_cycle); + base_obj->set_integer ("fp_simd_load_general_ops", + base.fp_simd_load_general_ops); + base_obj->set_integer ("fp_simd_store_general_ops", + base.fp_simd_store_general_ops); + + return base_obj; +} + +static std::unique_ptr<json::object> +serialize_aarch64_simd_vec_issue_info (const aarch64_simd_vec_issue_info &simd) +{ + std::unique_ptr<json::object> simd_obj + = serialize_aarch64_base_vec_issue_info (simd); + + simd_obj->set_integer ("ld2_st2_general_ops", simd.ld2_st2_general_ops); + simd_obj->set_integer ("ld3_st3_general_ops", simd.ld3_st3_general_ops); + simd_obj->set_integer ("ld4_st4_general_ops", simd.ld4_st4_general_ops); + + return simd_obj; +} + +static std::unique_ptr<json::object> +serialize_aarch64_sve_vec_issue_info (const aarch64_sve_vec_issue_info &sve) +{ + std::unique_ptr<json::object> sve_obj + = serialize_aarch64_simd_vec_issue_info (sve); + + sve_obj->set_integer ("pred_ops_per_cycle", sve.pred_ops_per_cycle); + sve_obj->set_integer ("while_pred_ops", sve.while_pred_ops); + sve_obj->set_integer ("int_cmp_pred_ops", sve.int_cmp_pred_ops); + sve_obj->set_integer ("fp_cmp_pred_ops", sve.fp_cmp_pred_ops); + sve_obj->set_integer ("gather_scatter_pair_general_ops", + sve.gather_scatter_pair_general_ops); + sve_obj->set_integer ("gather_scatter_pair_pred_ops", + sve.gather_scatter_pair_pred_ops); + + return sve_obj; +} + +static std::unique_ptr<json::object> +serialize_aarch64_vec_issue_info (const aarch64_vec_issue_info &issue_info) +{ + auto issue_obj = std::make_unique<json::object> (); + + if (issue_info.scalar) + issue_obj->set ("scalar", + serialize_aarch64_base_vec_issue_info (*issue_info.scalar)); + if (issue_info.advsimd) + issue_obj->set ("advsimd", serialize_aarch64_simd_vec_issue_info ( + *issue_info.advsimd)); + if (issue_info.sve) + issue_obj->set ("sve", + serialize_aarch64_sve_vec_issue_info (*issue_info.sve)); + + return issue_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_vector_cost (const cpu_vector_cost &vec_costs) +{ + auto vec_costs_obj = std::make_unique<json::object> (); + + vec_costs_obj->set_integer ("scalar_int_stmt_cost", + vec_costs.scalar_int_stmt_cost); + vec_costs_obj->set_integer ("scalar_fp_stmt_cost", + vec_costs.scalar_fp_stmt_cost); + vec_costs_obj->set_integer ("scalar_load_cost", vec_costs.scalar_load_cost); + vec_costs_obj->set_integer ("scalar_store_cost", vec_costs.scalar_store_cost); + vec_costs_obj->set_integer ("cond_taken_branch_cost", + vec_costs.cond_taken_branch_cost); + vec_costs_obj->set_integer ("cond_not_taken_branch_cost", + vec_costs.cond_not_taken_branch_cost); + if (vec_costs.advsimd) + vec_costs_obj->set ("advsimd", + serialize_advsimd_vec_cost (*vec_costs.advsimd)); + if (vec_costs.sve) + vec_costs_obj->set ("sve", serialize_sve_vec_cost (*vec_costs.sve)); + if (vec_costs.issue_info) + vec_costs_obj->set ("issue_info", serialize_aarch64_vec_issue_info ( + *vec_costs.issue_info)); + + return vec_costs_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_branch_cost (const cpu_branch_cost &branch_costs) +{ + auto branch_costs_obj = std::make_unique<json::object> (); + branch_costs_obj->set_integer ("predictable", branch_costs.predictable); + branch_costs_obj->set_integer ("unpredictable", branch_costs.unpredictable); + return branch_costs_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_approx_modes (const cpu_approx_modes &approx_modes) +{ + auto approx_modes_obj = std::make_unique<json::object> (); + approx_modes_obj->set_integer ("division", approx_modes.division); + approx_modes_obj->set_integer ("sqrt", approx_modes.sqrt); + approx_modes_obj->set_integer ("recip_sqrt", approx_modes.recip_sqrt); + return approx_modes_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_memmov_cost (const cpu_memmov_cost &memmov_cost) +{ + auto memmov_cost_obj = std::make_unique<json::object> (); + memmov_cost_obj->set_integer ("load_int", memmov_cost.load_int); + memmov_cost_obj->set_integer ("store_int", memmov_cost.store_int); + memmov_cost_obj->set_integer ("load_fp", memmov_cost.load_fp); + memmov_cost_obj->set_integer ("store_fp", memmov_cost.store_fp); + memmov_cost_obj->set_integer ("load_pred", memmov_cost.load_pred); + memmov_cost_obj->set_integer ("store_pred", memmov_cost.store_pred); + + return memmov_cost_obj; +} + +static std::unique_ptr<json::object> +serialize_cpu_prefetch_tune (const cpu_prefetch_tune &prefetch) +{ + auto prefetch_obj = std::make_unique<json::object> (); + prefetch_obj->set_integer ("num_slots", prefetch.num_slots); + prefetch_obj->set_integer ("l1_cache_size", prefetch.l1_cache_size); + prefetch_obj->set_integer ("l1_cache_line_size", prefetch.l1_cache_line_size); + prefetch_obj->set_integer ("l2_cache_size", prefetch.l2_cache_size); + prefetch_obj->set_bool ("prefetch_dynamic_strides", + prefetch.prefetch_dynamic_strides); + prefetch_obj->set_integer ("minimum_stride", prefetch.minimum_stride); + prefetch_obj->set_integer ("default_opt_level", prefetch.default_opt_level); + + return prefetch_obj; +} + +static const char * +serialize_autoprefetcher_model ( + const enum tune_params::aarch64_autoprefetch_model model) +{ + switch (model) + { + case tune_params::AUTOPREFETCHER_OFF: + return "AUTOPREFETCHER_OFF"; + case tune_params::AUTOPREFETCHER_WEAK: + return "AUTOPREFETCHER_WEAK"; + case tune_params::AUTOPREFETCHER_STRONG: + return "AUTOPREFETCHER_STRONG"; + } + return "AUTOPREFETCHER_OFF"; +} + +static const char * +serialize_ldp_stp_policy (const enum aarch64_ldp_stp_policy policy) +{ + switch (policy) + { + case AARCH64_LDP_STP_POLICY_DEFAULT: + return "AARCH64_LDP_STP_POLICY_DEFAULT"; + case AARCH64_LDP_STP_POLICY_ALIGNED: + return "AARCH64_LDP_STP_POLICY_ALIGNED"; + case AARCH64_LDP_STP_POLICY_ALWAYS: + return "AARCH64_LDP_STP_POLICY_ALWAYS"; + case AARCH64_LDP_STP_POLICY_NEVER: + return "AARCH64_LDP_STP_POLICY_NEVER"; + } + return "AARCH64_LDP_STP_POLICY_DEFAULT"; +} + +static std::unique_ptr<json::object> +serialize_tune_params (const tune_params ¶ms) +{ + auto params_obj = std::make_unique<json::object> (); + if (params.insn_extra_cost) + params_obj->set ("insn_extra_cost", + serialize_cpu_cost_table (*params.insn_extra_cost)); + if (params.addr_cost) + params_obj->set ("addr_cost", + serialize_cpu_addrcost_table (*params.addr_cost)); + if (params.regmove_cost) + params_obj->set ("regmove_cost", + serialize_cpu_regmove_cost (*params.regmove_cost)); + if (params.vec_costs) + params_obj->set ("vec_costs", + serialize_cpu_vector_cost (*params.vec_costs)); + if (params.branch_costs) + params_obj->set ("branch_costs", + serialize_cpu_branch_cost (*params.branch_costs)); + if (params.approx_modes) + params_obj->set ("approx_modes", + serialize_cpu_approx_modes (*params.approx_modes)); + params_obj->set_integer ("sve_width", params.sve_width); + + params_obj->set ("memmov_cost", + serialize_cpu_memmov_cost (params.memmov_cost)); + + params_obj->set_integer ("issue_rate", params.issue_rate); + params_obj->set_integer ("fusible_ops", params.fusible_ops); + params_obj->set_string ("function_align", params.function_align); + params_obj->set_string ("jump_align", params.jump_align); + params_obj->set_string ("loop_align", params.loop_align); + params_obj->set_integer ("int_reassoc_width", params.int_reassoc_width); + params_obj->set_integer ("fp_reassoc_width", params.fp_reassoc_width); + params_obj->set_integer ("fma_reassoc_width", params.fma_reassoc_width); + params_obj->set_integer ("vec_reassoc_width", params.vec_reassoc_width); + params_obj->set_integer ("min_div_recip_mul_sf", params.min_div_recip_mul_sf); + params_obj->set_integer ("min_div_recip_mul_df", params.min_div_recip_mul_df); + params_obj->set_integer ("max_case_values", params.max_case_values); + params_obj->set_string ("autoprefetcher_model", + serialize_autoprefetcher_model ( + params.autoprefetcher_model)); + + params_obj->set_integer ("extra_tuning_flags", params.extra_tuning_flags); + if (params.prefetch) + params_obj->set ("prefetch", + serialize_cpu_prefetch_tune (*params.prefetch)); + + params_obj->set_string ("ldp_policy_model", + serialize_ldp_stp_policy (params.ldp_policy_model)); + params_obj->set_string ("stp_policy_model", + serialize_ldp_stp_policy (params.stp_policy_model)); + + return params_obj; +} + +void +aarch64_print_tune_params (const tune_params ¶ms, const char *filename) +{ + auto aarch64_tune_params_json = std::make_unique<json::object> (); + aarch64_tune_params_json->set ("tune_params", serialize_tune_params (params)); + + pretty_printer pp; + aarch64_tune_params_json->print (&pp, true); + + FILE *outputFile = fopen (filename, "w"); + if (!outputFile) + { + error ("Error opening file %s", filename); + return; + } + + fprintf (outputFile, "%s", pp_formatted_text (&pp)); + fclose (outputFile); + return; +} \ No newline at end of file diff --git a/gcc/config/aarch64/aarch64-json-tunings-printer.h b/gcc/config/aarch64/aarch64-json-tunings-printer.h new file mode 100644 index 00000000000..d5cc1229c82 --- /dev/null +++ b/gcc/config/aarch64/aarch64-json-tunings-printer.h @@ -0,0 +1,28 @@ +/* Routine to print the AArch64 tuning parameters to a JSON file. + Copyright The GNU Toolchain Authors. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef AARCH64_JSON_TUNINGS_PRINTER_H +#define AARCH64_JSON_TUNINGS_PRINTER_H + +#include "aarch64-protos.h" + +void +aarch64_print_tune_params (const tune_params ¶ms, const char *filename); + +#endif \ No newline at end of file diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index f9d56eea7ee..2bbed9d2e54 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -97,6 +97,7 @@ #include "ipa-prop.h" #include "ipa-fnsummary.h" #include "hash-map.h" +#include "aarch64-json-tunings-printer.h" /* This file should be included last. */ #include "target-def.h" @@ -18592,6 +18593,9 @@ aarch64_override_options_internal (struct gcc_options *opts) if (opts->x_aarch64_stp_policy_param) aarch64_tune_params.stp_policy_model = opts->x_aarch64_stp_policy_param; + if (opts->x_fdump_tuning_model) + aarch64_print_tune_params (aarch64_tune_params, opts->x_fdump_tuning_model); + /* This target defaults to strict volatile bitfields. */ if (opts->x_flag_strict_volatile_bitfields < 0 && abi_version_at_least (2)) opts->x_flag_strict_volatile_bitfields = 1; diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index f32d56d4ffa..4c8ea2eb323 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -188,6 +188,10 @@ mabi= Target RejectNegative Joined Enum(aarch64_abi) Var(aarch64_abi) Init(AARCH64_ABI_DEFAULT) Generate code that conforms to the specified ABI. +fdump-tuning-model= +Target RejectNegative Negative(fdump-tuning-model=) ToLower Joined Var(fdump_tuning_model) +Dump current tuning model to a JSON file. + moverride= Target RejectNegative ToLower Joined Var(aarch64_override_tune_string) Save -moverride=<string> Power users only! Override CPU optimization parameters. diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64 index 5aa77809948..c5002eab595 100644 --- a/gcc/config/aarch64/t-aarch64 +++ b/gcc/config/aarch64/t-aarch64 @@ -197,6 +197,15 @@ aarch64-ldp-fusion.o: $(srcdir)/config/aarch64/aarch64-ldp-fusion.cc \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/aarch64/aarch64-ldp-fusion.cc +aarch64-json-tunings-printer.o: $(srcdir)/config/aarch64/aarch64-json-tunings-printer.cc \ + $(CONFIG_H) $(SYSTEM_H) $(CORETYPES_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \ + $(PRETTY_PRINT_H) json.h \ + $(srcdir)/config/aarch64/aarch64-json-tunings-printer.h \ + $(srcdir)/config/aarch64/aarch64-protos.h \ + $(srcdir)/config/arm/aarch-common-protos.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/aarch64/aarch64-json-tunings-printer.cc + comma=, MULTILIB_OPTIONS = $(subst $(comma),/, $(patsubst %, mabi=%, $(subst $(comma),$(comma)mabi=,$(TM_MULTILIB_CONFIG)))) MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG)) -- 2.44.0