2011-08-22 5 views
7

(LLVM-IR의) 수신자에게 전달하는 방법에 대한 조언이 필요합니다.LLVM의 인수 전달

처음에 모듈의 다른 함수가 호출 된 F 함수가 있다고 가정합니다. F에서 직접 호출자에게 전달 된 인수에 액세스 (읽기)해야합니다.

지금은 구조체 내부의 호출자에있는 모든 인수를 상자에 넣고 F으로 구조체에 대한 포인터 i8*을 전달하고 어떤 호출자에게 F이 호출되는지 알려줍니다. F은 거대한 스위치를 가지며 적절한 언 박싱 코드로 분기합니다. 모듈의 함수가 다른 서명 (인수/반환 값 개수 및 유형이 다르거 나 호출 규칙이 다를지라도)이 있기 때문에이 작업을 수행해야합니다. 그러나 성능 및 코드 크기 관점에서 볼 때 차선책입니다. 스택에 구조체를 할당하고, 내부에 인수를 복사하고, 추가 포인터를 F에 전달한 다음 언 박싱을 수행해야합니다.

이 할 수있는 더 나은 방법, 함수의 직접 실행 호출자의 스택 프레임에서 액세스 할 수있는 방법이 있다면 내가 (함수가 호출 된 발신자 식별자, 덕분에 아는) 궁금하거나 , 일반적으로 직접 호출 자에 정의 된 임의의 값. 어떤 제안?

참고 : 내가하고있는 작업의 요점은이 모든 작업을 수행하는 기능 F입니다. 분할/인라인/전문/템플릿 F은 (는) 옵션이 아닙니다. 명확하게


, 우리가 FuncAFuncB에는 다음과 같은 기능이 있다고 가정

Type1 FuncA(Type2 ArgA1) { 
    F(); 
    // ... 
} 

Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) { 
    F(); 
    // ... 
} 

(노트! 무슨 일이 다음은 의사 C 코드, 항상 우리가 LLVM-IR에 대해 얘기 기억이다)

void F() { 
    switch (caller) { 
    case FuncA: 
     // do something with ArgA1 
     break; 
    case FuncB: 
     // do something with ArgB1, ArgB2, ArgB3 
     break; 
    } 
} 

내가 첫 번째 부분에서 설명한 바와 같이, 지금 내 01,232 : 내가 필요한 것은 다음을 수행 할 수있는 기능 F위한 효율적인 방법입니다

struct Args_FuncA { Type2 ArgA1 }; 
struct Args_FuncB { Type4 ArgB1, Type5 ArgB2, Type6 ArgB3 }; 

void F(int callerID, void *args) { 
    switch (callerID) { 
    case ID_FuncA: 
     Args_FuncA *ArgsFuncA = (Args_FuncA*)args; 
     Type2 ArgA1 = ArgsFuncA->ArgA1; 
     // do something with ArgA1 
     break; 
    case ID_FuncB: 
     Args_FuncB *ArgsFuncB = (Args_FuncB*)args; 
     Type4 ArgB1 = ArgsFuncB->ArgB1; 
     Type5 ArgB2 = ArgsFuncB->ArgB2; 
     Type6 ArgB3 = ArgsFuncB->ArgB3; 
     // do something with ArgB1, ArgB2, ArgB3 
     break; 
    } 
} 

을 두 기능이 될 :은 다음과 같습니다 당신이 바로 그것을

Type1 FuncA(Type2 ArgA1) { 
    Args_FuncA args = { ArgA1 }; 
    F(ID_FuncA, (void*)&args); 
    // ... 
} 

Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) { 
    Args_FuncB args = { ArgB1, ArgB2, ArgB3 }; 
    F(ID_FuncB, (void*)&args); 
    // ... 
} 

답변

1

을했습니다 IMHO. Machinecode 어셈블리에는 솔루션이 있지만 "고수준"이므로 LLVM 어셈블리에는 솔루션이 없을 수도 있습니다. 일부 기능의 시작 부분에 함수를 실행하려는 경우 당신이 Valgrind

와 (GDB 같은)

  • 디버거 소스
  • 바이너리 계측 확인에 대한 생각이 나는 직접하지 압니다 대답,하지만 어떤면에서 도움이되기를 바랍니다.).

+1

dtrace는 CAFxX가 설명한 것과 매우 동일합니다. – osgx

1

이것이 도움이되는지는 확실치 않지만 비슷한 문제가 있으며 LLVM의 tbaa 분석의 한계를 극복하기 위해 llvm 벡터를 사용하여 중간 값을 저장합니다. LLVM 최적화 패스는 나중에 스칼라 레지스터에 벡터로드/저장을 최적화 할 수있었습니다.

내가 상기 한 몇 가지주의 사항이있었습니다. 이 경로를 탐색하면 몇 가지 코드를 파헤 칠 수 있습니다.