2016-10-18 4 views
14

System.Runtime.CompilerServices.MethodImplAttribute 속성은 데코 레이팅 된 메서드를 처리하는 방법에 대한 힌트를 JIT 컴파일러에 제공하는 데 사용할 수 있습니다. 특히 옵션 MethodImplOptions.AggressiveInlining은 가능한 경우 영향을받는 메소드를 인라인하도록 컴파일러에 지시합니다. 불행하게도 F # 컴파일러는 일리노이 생성시이 속성을 무시하는 것처럼 보입니다.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 
} 

경우 aggressiveinling "플래그를 생성합니다.

동작이 바람직합니까? F # 컴파일러의 버그입니까?

(참고 : 나는 F 번호 inline 키워드 알고 있어요,하지만 그건 단지 내 도서관,하지 C#을 소비자의 F 번호 클라이언트에 적용됩니다.)

+0

AFAIK이 속성은 JIT에서 사용합니다. 즉, 메서드가 인라인되어야 함을 나타냅니다. 따라서 올바른 경우 기계 코드 생성을 확인해야합니다.노트; JIT를 실행하는 디버거 에서처럼 .NET에서 디스 어셈블리를 보는 것만 큼 간단하지 않습니다. 어 : 공격적이지 않습니다. – FuleSnabel

+0

Awww, 무슨 뜻인지 알 겠어. 일리노이 메타 데이터가 누락 된 것 같습니다. 나중에 이것을 확인하겠습니다. – 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

관련 문제