0

コード内の分岐の量を減らす必要があります。median と呼ばれるベンチマークが存在し、次のようなコードがあります。

    if ( A < B )
            return A = foo[i];
        else
            return B = foo[i];

分岐を避けるために、マシン記述ファイル *.md にパターンを書きました。

    (define_insn "smin<GPR:mode>3"
      [
        (set 
          (match_operand:GPR 0 "register_operand" "=r")
            (if_then_else:GPR
          (lt:GPR 
            (match_operand:GPR 1 "register_operand" " r")
            (match_operand:GPR 2 "register_operand" " r"))
        (match_dup 1)
        (match_dup 2)))
      ]
      ""
      "min\t%0,%1,%2"
      [(set_attr "type" "move")
       (set_attr "mode" "<MODE>")]) 

単純な比較の場合に機能します。

    if ( A < B )
            return A ;
        else
            return B;

GCC エミット:

    min a0,a0,a1    # 9 smindi3 [length = 4]
    ret # 21    simple_return   [length = 4]

しかし、同じことを試しても、インデックス付き変数(配列)を使用すると、機能しません:

    if ( A < B )
            return A = foo[i];
        else
            return B = foo[i];

GCC エミット:

    blt a0,a1,.L5   # 11    *branch_orderdi [length = 4]
    sd  a1,8(a2)    # 18    *movdi_64bit/4  [length = 4]
    mv  a0,a1   # 8 *movdi_64bit/1  [length = 4]
    ret # 34    simple_return   [length = 4]
    .L5:
    sd  a0,8(a2)    # 13    *movdi_64bit/4  [length = 4]
    ret # 28    simple_return   [length = 4]

私はGCCが次のようなものを発行する必要があります:

    min a0,a0,a1    # 9 smindi3 [length = 4]
    sd  a0,8(a2)    # 18    *movdi_64bit/4  [length = 4]
    ret # 34    simple_return   [length = 4]

助けていただければ幸いです。

4

1 に答える 1