Next: , Previous: Constant Attributes, Up: Insn Attributes


16.19.7 延迟槽调度

如果在一个目标机上存在延迟槽的话,insn属性机制可以用于指定对延迟槽的需求。 一条指令被称为需要延迟槽, 如果在物理上位于该指令之后的一些指令将被按照它们仿佛是位于之前的情况被执行。 典型的例子是分支和调用指令,其通常在执行分支或调用之前先执行后面的指令。

在一些机器上,条件分支指令可以选择性的废除(annul)延迟槽中的指令。 这意味着该指令对于特定的分支结果将不被执行。 对于分支为真时废除指令和分支为假时废除指令,这两种方式都被支持。

延迟槽调度与指令调度的不同之处在于, 判定一条指令是否需要延迟槽只依赖于正被生成的指令的类型,而不是指令间的数据流。 关于数据相关的指令调度的讨论,参见下一个章节。

一个insn对一个或多个延迟槽的需求是通过define_delay表达式来表示的。 其具有下列形式:

     (define_delay test
                   [delay-1 annul-true-1 annul-false-1
                    delay-2 annul-true-2 annul-false-2
                    ...])

test是一个属性测试,用来表示该define_delay是否应用到特定的insn。 如果是,则所需延迟槽的数目通过作为第二个参数的向量的长度来确定。 放在延迟槽n中的insn必须满足属性测试delay-nannul-true-n是一个属性测试,用来指定当分支为真时哪些insn可以被废除。 如果该延迟槽不支持废除,则应该使用(nil)

例如,通常情况下分支和调用insns都需要一个单个的延迟槽, 其可以包含任何不是分支或调用的其它insn,则下面的可以放入md文件中:

     (define_delay (eq_attr "type" "branch,call")
                   [(eq_attr "type" "!branch,call") (nil) (nil)])

可以指定多个define_delay表达式。在这种情况下, 每个这样的表达式都指定了不同的延迟槽需求, 并且在两个define_delay表达式中的test必须不能都为真。

例如,如果我们有一个机器,其对分支需要一个延迟槽,但对调用需要两个, 延迟槽不能包含分支或调用insn,并且当分支为真时, 任何在分支延迟槽中的有效insn可以被废除,则我们可以使用下列方式来表示:

     (define_delay (eq_attr "type" "branch")
        [(eq_attr "type" "!branch,call")
         (eq_attr "type" "!branch,call")
         (nil)])
     
     (define_delay (eq_attr "type" "call")
                   [(eq_attr "type" "!branch,call") (nil) (nil)
                    (eq_attr "type" "!branch,call") (nil) (nil)])