2016-10-18 11 views
14

属性System.Runtime.CompilerServices.MethodImplAttributeを使用すると、装飾されたメソッドの処理方法に関するヒントをJITコンパイラに与えることができます。特に、オプションMethodImplOptions.AggressiveInliningは、可能であれば、影響を受けるメソッドをインライン化するようにコンパイラに指示します。残念ながら、F#コンパイラは、ILを生成するときにこの属性を単に無視するようです。MethodImplOptions.AggressiveInliningをF#関数に適用する

例:次のC#コード

[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static int Inc(int x) => x + 1; 

.method public hidebysig static int32 Inc(int32 x) cil managed aggressiveinlining 
{  
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.1 
    IL_0002: add 
    IL_0003: ret 
} 

注 "aggressiveinlining" フラグに変換されます。

このF#コードは、しかし

[<MethodImpl(MethodImplOptions.AggressiveInlining)>] 
let inc x = x + 1 

.method public static int32 inc(int32 x) cil managed 
{ 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ldc.i4.1 
    IL_0003: add 
    IL_0004: ret 
} 

いいえ "aggressiveinlining" になります。私はまた、適切なクラスの静的メソッドと非静的メソッドに属性を適用しようとしましたが(type ...)、結果は同じです。

私は」と同等であるかどうかはわからないけれどもそう

type Dummy = 
    member self.Item 
     with [<MethodImpl(MethodImplOptions.AggressiveInlining)>] get x = x + 1 

結果ILは...

.method public hidebysig specialname instance int32 get_Item(int32 x) cil managed 
{ 
    .custom instance void [mscorlib]System.Runtime.CompilerServices.MethodImplAttribute::.ctor(valuetype [mscorlib]System.Runtime.CompilerServices.MethodImplOptions) = (01 00 00 01 00 00 00 00) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldarg.1 
    IL_0002: ldc.i4.1 
    IL_0003: add 
    IL_0004: ret 
} 

あるようにしかし、私は、カスタムインデクサにそれを適用した場合C#コンパイラによって生成された "aggressiveinling"フラグを返します。

この動作は望ましく、予想されますか? F#コンパイラのバグですか?

(注:私はF#のinlineキーワードを認識してんだけど、それが唯一の私のライブラリではなく、C#の消費者のF#のクライアントのために動作します。)

+0

AFAIKこの属性は、JITによって使用されます。このメソッドは、インライン化する必要があることを示します。それが正しい場合は、マシンコードを生成する必要があります。注意; JITを実行しているデバッガと同じように、.NETで逆アセンブリを表示するのと同じくらい簡単ではありません。erはあまり攻撃的ではありません。 – FuleSnabel

+0

ああ、私はあなたが意味するものを参照してください。 ILメタデータには欠けているようです。後でこれをチェックさせてください。 – FuleSnabel

+3

'PreserveSig'、' Synchronized'、 'NoInlining'だけが尊重されているようです - [IlxGen.fs]の' ComputeMethodImplAttribs'(https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp)を参照してください。 /IlxGen.fs) – kvb

答えて

6

@kvbが正しいそれはF#コンパイラはストリップように見える思われることMethodImplを送信してください。

ComputeMethodImplAttribsIlxGen.fsと呼び、メソッド属性を計算します。 4990::

and ComputeMethodImplAttribs cenv (_v:Val) attrs = 
    let implflags = 
     match TryFindFSharpAttribute cenv.g cenv.g.attrib_MethodImplAttribute attrs with 
     | Some (Attrib(_,_,[ AttribInt32Arg flags ],_,_,_,_)) -> flags 
     | _ -> 0x0 

    let hasPreserveSigAttr = 
     match TryFindFSharpAttributeOpt cenv.g cenv.g.attrib_PreserveSigAttribute attrs with 
     | Some _ -> true 
     | _ -> false 

    // strip the MethodImpl pseudo-custom attribute  
    // The following method implementation flags are used here 
    // 0x80 - hasPreserveSigImplFlag 
    // 0x20 - synchronize 
    // (See ECMA 335, Partition II, section 23.1.11 - Flags for methods [MethodImplAttributes]) 
    let attrs = attrs 
        |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_MethodImplAttribute >> not) 
         |> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_PreserveSigAttribute >> not) 
    let hasPreserveSigImplFlag = ((implflags &&& 0x80) <> 0x0) || hasPreserveSigAttr 
    let hasSynchronizedImplFlag = (implflags &&& 0x20) <> 0x0 
    let hasNoInliningImplFlag = (implflags &&& 0x08) <> 0x0 
    hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningImplFlag, attrs 

行を中心に、より密接に探し

let attrs = attrs 
        |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_MethodImplAttribute >> not) 
         |> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_PreserveSigAttribute >> not) 

最初filterフィルター離れMethodImplAttribute

ここでは、根拠を見つけようとしていますが、このコードはlatkin初期コミットに戻っています。私はそれがおそらくAggressiveInliningのためにMethodImplを取り除くことはおそらく間違っていると思うが、私はJITに影響を与えると考えている:したがって、それはアセンブリにする必要があります。

issueの登録をお勧めします。おそらく、少なくともあなたは説明を得ることができます。

+3

属性をフィルタリングすることは、実際には擬似カスタム属性でありメタデータに実際のカスタム属性として存在してはならないため意味があります(例:http://weblog.ikvm.net/2008/を参照)。 11/25/PseudoCustomAttributes.aspx)。 – kvb

+0

私はGitHubリポジトリに問題をオープンします。 – Frank

+2

c.f. https://github.com/Microsoft/visualfsharp/issues/1637 – Frank

関連する問題