2017-05-11 15 views
1

점프없이 코드를 직렬로 생성해야한다는 것을 GCC 컴파일러에 알리는 방법.GCC 컴파일러에서 점프없이 코드를 직렬로 생성해야하는 방법

저는 C 소스 코드 (또는 LLVM IR)에 인라인 어셈블리를 포함시키는 프로젝트 작업을하고 있습니다.

내 구현은 실행 파일에 그대로 쓰여지는 인라인 어셈블리 사이의 코드에 달려 있습니다.

공식적으로

더, 나는 soure 코드 (C 또는 LLVM IR)가 있다고 가정 : 이제

.label_start: (inserted as inline assembly) 
inline_assembly0 
source_code0 
source_code1 
inline_assembly1 
... 
.label_end: (inserted as inline assembly) 
... 

을,이 컴파일하지 말아야 등 :

.jmp_target: 
source_code1 
inline_assembly1 
... 
.label_end: (inserted as inline assembly) 
... 

.label_start: (inserted as inline assembly) 
inline_assembly0 
source_code0 
jmp jmp_target 

즉, 코드는 .label_start.label_end 순서로 점프하지 않고 레이블 사이에 있어야합니다.

두 개의 인라인 어셈블리 레이블 사이의 모든 것이 재정렬되지 않고 "손상되지 않은"상태를 유지해야한다고 GCC에 알리는 방법이 있습니까? 내 구현은 이것에 달려있다.

+0

이 코드 세그먼트가 루프 내부에 있습니까? –

+0

왜 이것을 필요로합니까? 어쨌든 비 순차적 실행을 저해하지 않는 CPU를 갖추고 있습니까? –

+0

일반적으로 코드는 루프 @BenVoigt 내부에있을 수 있습니다. – Shuzheng

답변

4

질문을 이해하는 경우 GCC manual에 이에 대한 몇 가지 단어가 있습니다 (강조 표시됨).

컴파일러는 점프 명령어를 비롯하여 휘발성 asm 명령어를 다른 코드와 비교하여 이동할 수 있습니다. 예를 들어, 많은 타겟에는 부동 소수점 연산의 반올림 모드를 제어하는 ​​시스템 레지스터가 있습니다. 휘발성이있는 asm으로 설정하면 다음 PowerPC 예제와 같이 안정적으로 작동하지 않습니다.

asm volatile("mtfsf 255, %0" : : "f" (fpenv)); 
sum = x + y; 

컴파일러는 휘발성이있는 asm보다 먼저 추가를 이동할 수 있습니다. 는 예상대로 작동 예를 들어, 다음 코드에서 변수를 참조하여 asm에 인공 종속성을 추가하기 :

asm volatile("mtfsf 255,%1" : "=X" (sum) : "f" (fpenv)); 
sum = x + y; 

는 기본적으로, 당신이 재 배열을 방지하기 위해 "더미 사용"을해야합니다.

우리는 또한 GC는 루틴 인터럽트 경우는 조기에 해제되지 않습니다 보장, 낮은 수준의 GC 코드의 참조의 생동감을 확장하는 모노에서 이런 종류의 물건을 사용

static inline void dummy_use (void *v) 
    __asm__ volatile ("" : "=r"(v) : "r"(v)); 
} 
+1

이것은 실행 순서를 다루지 만, 질문은 메모리 레이아웃을 논의합니다. –

+0

감사합니다. 이것은 매우 유익했습니다! 하지만 메모리 레이아웃을 보장합니까? – Shuzheng

+2

@Shuzheng : Ben Voigt가 말했듯이, 코드가 특정 순서로 실행되도록 보장하는 것은 아닙니다. 예를 들어, 콜드 브랜치가 여전히 라인 밖으로 이동할 수 있습니다. 일반적으로 모든 최적화를 로컬에서 비활성화하려면'#pragma GCC push_options', #pragma GCC optimize ("O0")', ...,'#pragma GCC pop_options' 등의 작업을 수행해야합니다. ('-fno-reorder-blocks'만으로도 충분할 수 있습니다.) 가능하다면이 블록의 모든 것을 인라인 어셈블리로 사용할 수도 있습니다. –

1

시도 최적화를 비활성화하려면 gcc -O0 source.c