GCC Cost
Table of Contents
1. GCC Cost
https://kristerw.blogspot.com/2018/01/gcc-back-end-performance-tuning.html
https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gccint/Costs.html
gcc cost model 是指 gcc 会考虑 arch 执行不同指令的代价, 以决定是否执行某些优化
1.1. TARGET_RTX_COSTS
以 GCC Expand Mult 为例, gcc 决定 mul 是否 expand 成 shift 时, 需要通过 TARGET_RTX_COSTS 这个 来找到各个 insn 的 cost, 例如, 如果 `x*12` 的 cost 小于 `(x<<1+x)<<2` 的 cost, 则这个 expand不会进行
riscv 的 TARGET_RTX_COSTS 实现在 riscv_rtx_costs:
static bool riscv_rtx_costs( rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED, int *total, bool speed) { bool float_mode_p = FLOAT_MODE_P(mode); int cost; switch (GET_CODE(x)) { /* ... */ case ASHIFT: case ASHIFTRT: case LSHIFTRT: *total = riscv_binary_cost( x, SINGLE_SHIFT_COST, CONSTANT_P(XEXP(x, 1)) ? 4 : 9); return false; /* ... */ case MINUS: case PLUS: if (float_mode_p) /* tune_param 是根据 -mtune=xxx 参数决定的, 例如 xxx 为 * sifive-7-series */ *total = tune_param->fp_add[mode == DFmode]; else *total = riscv_binary_cost(x, 1, 4); return false; /* ... */ case MULT: if (float_mode_p) *total = tune_param->fp_mul[mode == DFmode]; else if (!TARGET_MUL) /* Estimate the cost of a library call. */ *total = COSTS_N_INSNS(speed ? 32 : 6); else if (GET_MODE_SIZE(mode) > UNITS_PER_WORD) *total = 3 * tune_param->int_mul[0] + COSTS_N_INSNS(2); else if (!speed) *total = COSTS_N_INSNS(1); else *total = tune_param->int_mul[mode == DImode]; return false; /* ... */ default: return false; } }
Backlinks
GCC Expand Mult (GCC Expand Mult > impls > set_src_cost): set_src_cost 最终会调用到 TARGET_RTX_COSTS 这个 target hook
GCC Target Hook (GCC Target Hook > cost 相关 > TARGET_RTX_COSTS): TARGET_RTX_COSTS
1.2. mtune
mtune 中定义了 branch_cost, memory_cost, fp_add/fp_mul 等 cost
1.3. llvm cost
llvm 中和 TARGET_RTX_COSTS 类似的是 TaretTransformInfo
Backlinks
GCC Target Hook (GCC Target Hook > cost 相关): cost 相关
microarchitecture (GCC Scheduler > microarchitecture): scheduler 工作时需要一个关键信息是指令的 latency, 例如 `sqrtsf2` 的 latency 在 sifive-3 是 25, 在 sifive-7 是 27, 这个值看起来和 GCC Cost 有点类似?