Next: , Previous: Jump Patterns, Up: Machine Desc


16.13 定义循环指令模式

一些机器具有特定的跳转指令,可以使循环更为有效。 常见的例子为68000的‘dbra’指令,其执行一个寄存器的递减, 并且如果结果大于0,则进行一个分支。其它机器,特别是数字信号处理器(DSP), 具有特定的块重复指令,以提供低成本的循环支持。 例如TI TMS320C3x/C4x DSP具有一个块重复指令, 其加载特定的寄存器来标记一个循环的顶部和底部,并计算循环迭代的次数。 这就避免了对‘dbra’这样的指令的取指和执行的需要, 并避免了和跳转相关的流水线阻塞。

GCC具有三个特定的命名指令模式,来支持低开销循环。 它们为‘decrement_and_branch_until_zero’, ‘doloop_begin’和‘doloop_end’。 第一个指令模式‘decrement_and_branch_until_zero’,在RTL生成过程中没有被产生, 但可以在指令合并阶段被产生。这需要循环优化器的帮助, 使用在strength reduction过程中所搜集的信息,来将一个循环转换为向下计数到0。 一些target还要求循环优化器增加一个REG_NONNEG注解,来指示迭代计数总是为正的。 这在target执行一个有符号循环终止测试的时候被需要。例如, 68000为它的dbra指令使用了下面类似的指令模式:

     (define_insn "decrement_and_branch_until_zero"
       [(set (pc)
             (if_then_else
               (ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
                            (const_int -1))
                   (const_int 0))
               (label_ref (match_operand 1 "" ""))
               (pc)))
        (set (match_dup 0)
             (plus:SI (match_dup 0)
                      (const_int -1)))]
       "find_reg_note (insn, REG_NONNEG, 0)"
       "...")

注意,由于该insn为jump insn并且具有一个输出,所以其必须处理自己的重载, 因此要使用`m' constraint。还要注意,由于该insn是在指令组合过程中, 通过将两个连序insn组合成一个隐式并行的insn而生成的,所以迭代计数器需要。 注意下面类似的指令模式将不会被编译器匹配。

     (define_insn "decrement_and_branch_until_zero"
       [(set (pc)
             (if_then_else
               (ge (match_operand:SI 0 "general_operand" "+d*am")
                   (const_int 1))
               (label_ref (match_operand 1 "" ""))
               (pc)))
        (set (match_dup 0)
             (plus:SI (match_dup 0)
                      (const_int -1)))]
       "find_reg_note (insn, REG_NONNEG, 0)"
       "...")

另外两个特定的循环指令模式‘doloop_begin’和‘doloop_end’, 由循环优化器为一些具有有限循环迭代, 使用强度消减所搜集的信息的良好行为的循环所生成的。

doloop_end’指令模式描述了实际的循环指令(或者隐式的循环操作), ‘doloop_begin’指令模式为一个可选的配套指令模式, 可以用于一些低开销循环指令的初始化需要。

注意有些机器需要在循环顶部生成实际的循环指令(例如TMS320C3x/C4x DSP)。 在循环顶部生成真正的RTL循环指令,会对流分析造成问题。所以,替换的, 一个假‘doloop’ insn在循环的结尾处被生成。 机器相关的reorg过程会检查该‘doloop’ insn的存在, 然后向后搜寻插入了真正循环insn(假设在循环中没有会造成问题的指令)的循环顶部。 任何额外的标号都可以在该点被生成。另外, 如果所需要的特定迭代技术器寄存器没有被分配, 则该机器相关的reorg过程能够生成一个传统的比较跳转指令对。

指令模式‘decrement_and_branch_until_zero’和‘doloop_end’的本质区别为, 循环优化器会为后者分配一个额外的伪寄存器作为迭代计数器。 该伪寄存器不能用在循环中(即,通用的规约变量不能由此生成),但是, 许多情况下循环规约变量可能变成冗余的并且被后续的过程移除掉。