Next: , Previous: Condition Code, Up: Target Macros


17.17 描述操作的相对代价

这些宏让你描述target机器上各种操作的相对速度。

— Macro: REGISTER_MOVE_COST (mode, from, to)

一个C表达式, 为从寄存器类别from到类别to移动模式为mode的数据的代价。 类别使用枚举值表示,例如GENERAL_REGS。缺省值为2;其它值相对于它来解析。

fromto相同时,并不要求代价总是为2;在一些机器上, 如果不是通用寄存器,则寄存器之间的移动代价是昂贵的。

如果重载遇到一个insn,由两个硬件寄存器之间的单个set组成, 并且如果REGISTER_MOVE_COST应用到它们的类别上返回2, 则重载不检查insn的约束是否满足。将代价设为2以外的值将允许重载验证约束是否满足。 如果‘movm’模式的约束不允许这样的复制,则你应该这样做。

These macros are obsolete, new ports should use the target hook TARGET_REGISTER_MOVE_COST instead.

— Target Hook: int TARGET_REGISTER_MOVE_COST (enum machine_mode mode, reg_class_t from, reg_class_t to)

This target hook should return the cost of moving data of mode mode from a register in class from to one in class to. The classes are expressed using the enumeration values such as GENERAL_REGS. A value of 2 is the default; other values are interpreted relative to that.

It is not required that the cost always equal 2 when from is the same as to; on some machines it is expensive to move between registers if they are not general registers.

If reload sees an insn consisting of a single set between two hard registers, and if TARGET_REGISTER_MOVE_COST applied to their classes returns a value of 2, reload does not check to ensure that the constraints of the insn are met. Setting a cost of other than 2 will allow reload to verify that the constraints are met. You should do this if the ‘movm’ pattern's constraints do not allow such copying.

The default version of this function returns 2.

— Macro: MEMORY_MOVE_COST (mode, class, in)

一个C表达式, 为在寄存器类别class和内存之间移动模式为mode的数据的代价; in为0,如果值要被写到内存中,非0,如果要从内存中读进。 该代价为REGISTER_MOVE_COST的相对值。 如果在寄存器和内存间移动比两个寄存器之间更昂贵,则应该定义该宏来表示相对代价。

如果你没有定义该宏,如果需要的话, 则GCC使用缺省值4加上通过第二个重载寄存器复制的代价。 如果你的机器需要第二个重载寄存器在内存和寄存器类别class直接复制, 但是重载机制比通过中间物质复制更复杂,则定义该宏来反映move的实际代价。

GCC定义函数memory_move_secondary_cost,如果需要第二次重载。 其根据通过第二个寄存器复制来计算代价。 如果你的机器使用第二个寄存器按照约定的方式从内存中复制, 但是缺省值4对你的机器不正确,则定义该宏来增加某个其它值作为那个函数的结果。 函数的参数与该宏相同。

These macros are obsolete, new ports should use the target hook TARGET_MEMORY_MOVE_COST instead.

— Target Hook: int TARGET_MEMORY_MOVE_COST (enum machine_mode mode, reg_class_t rclass, bool in)

This target hook should return the cost of moving data of mode mode between a register of class rclass and memory; in is false if the value is to be written to memory, true if it is to be read in. This cost is relative to those in TARGET_REGISTER_MOVE_COST. If moving between registers and memory is more expensive than between two registers, you should add this target hook to express the relative cost.

If you do not add this target hook, GCC uses a default cost of 4 plus the cost of copying via a secondary reload register, if one is needed. If your machine requires a secondary reload register to copy between memory and a register of rclass but the reload mechanism is more complex than copying via an intermediate, use this target hook to reflect the actual cost of the move.

GCC defines the function memory_move_secondary_cost if secondary reloads are needed. It computes the costs due to copying via a secondary register. If your machine copies from memory using a secondary register in the conventional way but the default base value of 4 is not correct for your machine, use this target hook to add some other value to the result of that function. The arguments to that function are the same as to this target hook.

— Macro: BRANCH_COST (speed_p, predictable_p)

A C expression for the cost of a branch instruction. A value of 1 is the default; other values are interpreted relative to that. Parameter speed_p is true when the branch in question should be optimized for speed. When it is false, BRANCH_COST should be returning value optimal for code size rather then performance considerations. predictable_p is true for well predictable branches. On many architectures the BRANCH_COST can be reduced then. 一个C表达式,为分支指令的代价。缺省值为1;其它值相对于它来解析。

这些是额外的宏,其不指定确切的相对代价,而只是指定特定的动作比GCC通常期望的要昂贵。

— Macro: SLOW_BYTE_ACCESS

定义该宏为一个C表达式,如果访问小于一个字的内存 (即char或者short)不如访问一个字的内存快,即, 如果这样的访问需要多于一条的指令,并且如果字节和(对齐的)字加载的代价没有区别, 则值为非零。

当该宏没有被定义,则编译器将通过找到最小的包含对象来访问一个域;当其被定义, 如果允许对齐,则会使用全字的加载。除非字节访问比字访问快,则使用字访问比较好, 因为其可以消除后续的内存访问,如果后续的访问发生在结构体的相同字的其它域。

— Macro: SLOW_UNALIGNED_ACCESS (mode, alignment)

定义该宏的值为1, 如果由modealignment参数描述的内存访问比对齐的访问具有多倍的代价, 例如如果它们在陷阱处理中被模拟。

当该宏为非0时,编译器在为块移动生成代码时, 将按照STRICT_ALIGNMENT为非0的方式执行。这可以引起相当多的指令被产生。 因此如果非对齐访问只是增加一个周期或者两个,则不要设置该宏为非零。

如果该宏的值总是0,则不需要被定义。如果该宏被定义,其应该产生一个非0值, 当STRICT_ALIGNMENT非0时。

— Macro: MOVE_RATIO

标量的内存到内存的move insn的临界数,低于其值的时候, 应该生成一个insn序列,而不是字符串move insn或者库调用。 增加值将总是使得代码更快,但是会最终由于代码大小的增加而产生高的代价。

注意在一些机器上,对应的move insn为一个define_expand, 其产生一个insn序列,则该宏为该序列的个数。

The parameter speed is true if the code is currently being optimized for speed rather than size.

如果没有定义,则会使用一个合理的缺省值。

— Macro: MOVE_BY_PIECES_P (size, alignment)

一个C表达式,用于确定是否使用move_by_pieces来复制一块内存, 或者使用其它某种块移动机制。缺省为1, 如果move_by_pieces_ninsns返回值小于MOVE_RATIO

— Macro: MOVE_MAX_PIECES

一个C表达式, 由move_by_pieces使用用于确定load或者store用于复制内存的最大单元。 缺省为MOVE_MAX

— Macro: CLEAR_RATIO

标量move insn的临界数,低于其值时,应该生成一个insn序列来清除内存, 而不是字符串clear insn或者库调用。增加值将总是使得代码更快, 但是会最终由于代码大小的增加而产生高的代价。

The parameter speed is true if the code is currently being optimized for speed rather than size.

如果没有定义,则会使用一个合理的缺省值。

— Macro: CLEAR_BY_PIECES_P (size, alignment)

一个C表达式,用于确定是否使用clear_by_pieces来清除一块内存, 或者使用其它块清楚机制。缺省为1, 如果move_by_pieces_ninsns返回值小于CLEAR_RATIO

— Macro: SET_RATIO

标量move insn的临界数,低于其值时, 应该生成一个insn序列来将内存设为一个常量值,而不是一个块设置insn或者库调用。 增加值将总是使得代码更快,但是会最终由于代码大小的增加而产生高的代价。

The parameter speed is true if the code is currently being optimized for speed rather than size.

如果没有定义,缺省值为MOVE_RATIO

— Macro: SET_BY_PIECES_P (size, alignment)

一个C表达式用来确定是否使用store_by_pieces来设置内存块为常量值, 或者使用其它机制。当存储非常数0的值时,由__builtin_memset使用。 缺省为1,如果move_by_pieces_ninsns返回值小于SET_RATIO

— Macro: STORE_BY_PIECES_P (size, alignment)

一个C表达式用来确定是否使用store_by_pieces来设置内存块为常量字符串, 或者使用其它的机制。当使用常量源字符串调用时,被__builtin_strcpy使用。 缺省为1,如果move_by_pieces_ninsns返回值小于MOVE_RATIO

— Macro: USE_LOAD_POST_INCREMENT (mode)

一个C表达式用于确定对于给定的mode,后增加载是否好。 缺省值为HAVE_POST_INCREMENT

— Macro: USE_LOAD_POST_DECREMENT (mode)

一个C表达式用于确定对于给定的mode,后减加载是否好。 缺省值为HAVE_POST_DECREMENT

— Macro: USE_LOAD_PRE_INCREMENT (mode)

一个C表达式用于确定对于给定的mode,前增加载是否好。 缺省值为HAVE_PRE_INCREMENT

— Macro: USE_LOAD_PRE_DECREMENT (mode)

一个C表达式用于确定对于给定的mode,前减加载是否好。 缺省值为HAVE_PRE_DECREMENT

— Macro: USE_STORE_POST_INCREMENT (mode)

一个C表达式用于确定对于给定的mode,后增存储是否好。 缺省值为HAVE_POST_INCREMENT

— Macro: USE_STORE_POST_DECREMENT (mode)

一个C表达式用于确定对于给定的mode,后减存储是否好。 缺省值为HAVE_POST_DECREMENT

— Macro: USE_STORE_PRE_INCREMENT (mode)

一个C表达式用于确定对于给定的mode,前增存储是否好。 缺省值为HAVE_PRE_INCREMENT

— Macro: USE_STORE_PRE_DECREMENT (mode)

一个C表达式用于确定对于给定的mode,前减存储是否好。 缺省值为HAVE_PRE_DECREMENT

— Macro: NO_FUNCTION_CSE

定义该宏,如果调用常量函数地址要比调用保存在寄存器中的地址好些。

— Macro: RANGE_TEST_NON_SHORT_CIRCUIT

定义该宏,如果由‘fold_range_test ()’产生的non-short-circuit操作为可选的。 该宏缺省为真,如果BRANCH_COST大于或等于2。

— Target Hook: bool TARGET_RTX_COSTS (rtx x, int code, int outer_code, int *total)

该target钩子描述了RTL表达式的相对代价。

代价可以依赖于表达式的确切形式,可以通过检查x来获得表达式的形式, 表达式包含的rtx的代码为outer_codecode为表达式代码,冗余的, 因为其可以使用GET_CODE (x)获得。

实现该钩子时, 你可以使用结构COSTS_N_INSNS (n)来指定代价等价于n个指令。

在钩子的入口处,*total包含了缺省的表达式代价的估值。需要的话, 钩子应该修改该值。传统的,缺省代价对于乘法为COSTS_N_INSNS (5), 对于除法和求模为COSTS_N_INSNS (7), 对于其它操作为COSTS_N_INSNS (1)

当优化代码大小时,即,当optimize_size非0时, 该target钩子应该用于估计一个表达式的相对大小代价, 同样也是相对于COSTS_N_INSNS

钩子返回真,当所有x的子表达式都被处理,当rtx_cost应该递归时返回假。

— Target Hook: int TARGET_ADDRESS_COST (rtx address)

该钩子计算包含address的寻址模式的代价。如果没有定义, 代价通过address表达式和TARGET_RTX_COST钩子来计算。

对于大多数CISC机器,缺省代价为寻址模式的真实代价的合理近似值。 然而,在RISC机器上,所有指令通常具有相同的长度和执行时间。 因此所有寻址将具有相等的代价。

对于多于一个的形式的寻址,将会使用最低代价的形式。 如果多个形式具有相同的,最低的代价,则使用最复杂的。

例如,假设地址等于寄存器和常量的和,并在同一基本块中使用两次。 当该宏没有被定义,地址将在寄存器中计算,并且内存引用将通过寄存器间接实现。 在一些机器上,包含该和的寻址模式的代价不比简单的间接引用高, 这样则会产生一条额外的指令,并且可能需要一个额外的寄存器。 对该宏进行合适的指定,会消除这样的情况。

该钩子从不会被无效地址调用。

在一些机器上,地址包括多于一个寄存器的代价, 跟只包含一个寄存器的地址计算代价一样低, 则定义TARGET_ADDRESS_COST来反映这种情况, 可以使得两个寄存器在代码域中为活跃的,如果没有定义则可能只有一个为活跃的。 这种效果在定义该宏时应该被考虑。 可能只有对于有大量寄存器的机器才可能会有相等的代价。