QBE - 컴파일러 백엔드: 버전 1.3
(c9x.me)- 성능 최적화가 크게 추가되어 QBE 1.3은 vanilla coremark에서 상용 컴파일러 성능의 63% 이상을 기록하고, Hare 테스트 스위트에서는 qbe-1.2 대비 33% 개선됨
- QBE 1.3은 1.0 이후 가장 큰 릴리스로, 약 7k 줄 추가와 1.5k 줄 삭제가 포함됨
- 새 최적화에는 GVN/GCM, 루프 최적화, if 제거, CFG 단순화 등이 포함됐지만, 검증된 일부 패스만 유지됨
- 인라이닝은 QBE의 함수 단위 스트리밍 컴파일 모델과 맞지 않는 문제가 있어 이번 최적화 세트에서 제외됨
ee_isdigit를 인라인하고crcu8를 더 단순한 분기 없는 구현으로 바꾼 coremark 변형에서는 QBE가 목표였던gcc -O2대비 70% 성능에 도달함- 새 OCaml 도구
mgen이 lispy IL 패턴을 C 매칭 코드로 컴파일해, 기존 수작업 명령 선택 로직을 대체하거나 단순화할 수 있게 됨 mgen은 특수 주석 블록의 IL 패턴을 찾아 바로 아래에 C 코드를 삽입하며, 현재 사용 예는isel.c에 있음- 명령 DAG 매칭은 Ken Thompson의 Plan9 C 컴파일러 방식과 유사한 번호 매기기 접근을 따르며,
runmatch()가 해석하는 단순 바이트코드 매처도 생성됨 - Windows ABI 지원이 추가되어
-t amd64_win을 넘기면 Windows 대상 컴파일이 가능해짐 - QBE가 생성하는 어셈블리는 여전히 AT&T 문법이며, mingw 어셈블러로 컴파일하는 방식이 적합하다고 안내됨
- 위치 독립 코드 지원이 개선되어 대부분의 대상에서 공유 객체와 더 원활히 링크하고 공유 객체를 생성할 수 있게 됨
- 새
extern동적 상수 플래그(DYNCONST)로 IL 수준에서 동적 라이브러리 변수 같은 전역 심볼의 간접 접근을 표현할 수 있음
댓글과 토론
Lobste.rs 의견들
-
오래 진행 중인 취미 프로젝트로 TRIPOS/Amiga Exec 스타일의 작은 OS를 만들고 있음
메모리 보호가 없고, 평면 메모리 맵이며, 메시지 전달도 포인터를 넘기는 수준임
이런 시스템을 자체 호스팅하려면 PIE/PIC를 만들 수 있는 작은 컴파일러가 훨씬 편함. Amiga 스타일 라이브러리는 당연히 PIC여야 하고, 실행 파일을 공유 메모리 맵 어딘가에 올릴 때 로드 시점 패치를 많이 하지 않아도 되는 점도 좋음
GCC와 Clang은 가능하지만 너무 거대함. 마지막으로 확인했을 때 TCC는 PIC를 못 했고, QBE를 더 살펴봐야겠음- 내 C 컴파일러는 PIC를 만들 수 있으니 관심 있을지도 모름: https://codeberg.org/lsof/antcc/
자기 홍보처럼 들리지 않았으면 함. 작은 컴파일러 분야를 정말 좋아하고, 테스트도 더 많이 필요함 - 나도 평면 메모리 맵, 전부 PIE, 시스템 호출이 함수 호출인 OS인 Ashet OS를 만들고 있음
이미 꽤 진척됐고, 여러 플랫폼을 지원함
곧 자체 호스팅까지 가기는 어려울 듯함. Thumb-2 코드 생성이 필요하고, 이를 돌릴 방법이 사실상 직접 컴파일러를 쓰는 것뿐이기 때문임. 커널 코드를 제외하고 사용 가능한 RAM이 8MB뿐이라는 제약이 있음
ELF 파일을 변환해 만드는 자체 실행 파일 형식.ashex를 사용함. 이 과정에서 사실상 절대 점프 하나인 특수 섹션을 소비하고, 앱 로더가 이를 실제 시스템 호출 주소로 다시 씀
평면 메모리 시스템의 어려움은 공유 객체를 깔끔하게 지원하는 데 있음. 서로 다른 애플리케이션 사이에서 코드를 공유하려면 모든 동적 심볼 접근이 레지스터에 저장된 변수를 통해 이뤄지도록 컴파일러 지원이 필요함
- 내 C 컴파일러는 PIC를 만들 수 있으니 관심 있을지도 모름: https://codeberg.org/lsof/antcc/
-
새
extern키워드가 생겨서 정말 반가움
릴리스 노트에는 없지만 이것이thread와도 함께 동작해서 initial-exec TLS를 가능하게 함. 다른 공유 라이브러리에 정의된 스레드 로컬 전역 변수에 접근할 때 필요하며, FreeBSD의ctype.h에 필요함
extern은 macOS나 Haiku 같은 플랫폼에서 공유 라이브러리의 일반 전역 변수, 예를 들어stderr에 접근할 때도 필요함. 이제 QBE 기반 컴파일러가 훨씬 더 많은 운영체제와 사용 사례를 지원할 수 있게 됨
Roland의 성능 개선도 매우 고마움. 정말 훌륭한 작업을 했음 -
이걸 제대로 읽은 게 맞다면 정식 Windows 지원이 들어간 건가?
QBE의 역사적이면서도 현재까지 큰 제약 중 하나가 이 부분 아니었나? 정말 보기 좋음 -
이 프로젝트의 목표가 Cranelift와 겹치나? 언제 QBE를 쓰는지 잘 감이 안 옴
- QBE는 컴파일러 백엔드계의 “OpenBSD”에 가까움. 단순성과 미니멀리즘이 철학이고, 공식 설명에 따르면 “산업용 최적화 컴파일러 성능의 70%를 코드 10%로 제공”하는 것이 목표임
경쟁 대상은 실제로 Cranelift와 LLVM임
아쉽게도 과거에는 주로 취미 언어나 컴파일러 구현에서 쓰였음. 예를 들어 새 C 계열 언어처럼 보였던 myrddin은 이제 죽은 듯하고, cproc는 아직 살아 있는 취미용 C 컴파일러 구현임
그래도 Hare가 QBE를 채택한 뒤로는 기대가 생겼음. 질문에 대한 답은 여기 있음: https://harelang.org/documentation/faq.html#why-qbe-instead-of-llvm - Cranelift뿐 아니라 LLVM과도 목표가 겹친다고 봄
자세히 잘 아는 건 아니지만 비교 자료는 많이 있음. 아는 범위에서는 QBE가 다른 두 가지보다 훨씬 단순한 백엔드를 지향함
- QBE는 컴파일러 백엔드계의 “OpenBSD”에 가까움. 단순성과 미니멀리즘이 철학이고, 공식 설명에 따르면 “산업용 최적화 컴파일러 성능의 70%를 코드 10%로 제공”하는 것이 목표임
-
명령어 선택 매처를 생성하는 데 작은 DSL을 쓰는 방식이 정말 멋짐