답변:
C / C ++ 파일이 있습니다 foo.c
.
> clang -S -emit-llvm foo.c
생산 foo.ll
LLVM IR 파일이다.
이 -emit-llvm
옵션은 다음과 같은 방법으로 드라이버가 아닌 컴파일러 프런트 엔드로 직접 전달 될 수도 있습니다 -cc1
.
> clang -cc1 foo.c -emit-llvm
foo.ll
IR로 제작 합니다. -cc1
과 같은 멋진 옵션을 추가합니다 -ast-print
. -cc1 --help
자세한 내용을 확인 하십시오.
LLVM IR을 어셈블리로 추가 컴파일하려면 다음 llc
도구를 사용하십시오 .
> llc foo.ll
foo.s
어셈블리로 생산합니다 (기본값은 기계 아키텍처를 실행 함). llc
LLVM 도구 중 하나입니다 . 여기에 해당 문서가 있습니다.
사용하다
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
.o
는 이진 객체 파일, .s
어셈블리 파일 및 .ll
LLVM IR 파일에 대한 다른 규칙을 참조해야합니다. 그렇지 않으면 혼동되기 쉽습니다. Clang / LLVM에는 이제 바이너리 객체에 대한 자체 링커가 없습니다 (하나는 작품에 있습니다). LLVM 링커 llvm-ld
는 여러 IR 파일을 하나로 결합합니다
.bc
사용 되면 올바른 일을합니다 . 또한 llvm-ld
시스템 툴체인의 프론트 엔드 역할 을 할 수 있음을 명심 하십시오. 예를 들어, 이전의 답변 llvm-ld -native
은 예상대로 작동해야합니다 ....
foo.bc
LLVM 비트 코드 파일입니다
clang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode
.
소스 파일이 여러 개인 경우 실제로 링크 시간 최적화를 사용하여 전체 프로그램에 대해 하나의 비트 코드 파일을 출력하려고합니다. 주어진 다른 답변은 모든 소스 파일에 대한 비트 코드 파일로 끝납니다.
대신 링크 시간 최적화를 사용하여 컴파일하려고합니다.
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
최종 연결 단계에서 -Wl, -plugin-opt = also-emit-llvm 인수를 추가하십시오.
clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
이것은 당신에게주는 모두 컴파일 된 프로그램과 (program.bc)에 해당하는 비트 코드를. 그런 다음 원하는 방식으로 program.bc를 수정하고 언제든지 수정 된 프로그램을 다시 컴파일 할 수 있습니다.
clang program.bc -o program
이 단계에서 필요한 링커 플래그 (외부 라이브러리 등)를 다시 포함해야합니다.
이 작업을하려면 골드 링커를 사용해야합니다. clang이 특정 링커를 사용하도록하려면 컴퓨터의 "fakebin"이라는 특수 디렉토리에 "ld"라는 링커에 대한 심볼릭 링크를 작성하고 옵션을 추가하십시오.
-B/home/jeremy/fakebin
위의 모든 연결 단계
여러 파일이 있고 각 파일을 입력하지 않으려면 다음과 같은 간단한 단계를 따르는 것이 좋습니다 (사용 clang-3.8
중이지만 다른 버전을 사용할 수 있음).
모든 .ll
파일을 생성
clang-3.8 -S -emit-llvm *.c
그것들을 하나의 것으로 연결
llvm-link-3.8 -S -v -o single.ll *.ll
(선택 사항) 코드 최적화 (일부 별칭 분석 일 수 있음)
opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
어셈블리 생성 ( optimised.s
파일 생성 )
llc-3.8 optimised.ll
실행 파일 만들기 ( a.out
)
clang-3.8 optimised.s
-S
옵션 (2 단계)을 사용하고 LLVM IR에서 출력을 생성하도록 지정합니다. 기본적으로 모든 * .ll 파일을 단일 파일에 넣습니다. 최적화가 실제로 코드를 변경하는지 확인하기 위해이 작업을 수행합니다. 즉 single.ll
, optimised.ll
코드가 다르게 보일 수 있으며 보고서에 차이가 있는지 확인할 수도 있습니다.
-basicaaa
잘못된 플래그이므로 -basicaa
대신 사용해야합니다.