TECH 으로 돌아가기
TECH HACKER NEWS 어제 6분 읽기 31 READS

Julia 컴파일러의 심장 수술 — 중간 표현을 하나로 합치는 UnifiedIR

Julia 컴파일러의 심장 수술 — 중간 표현을 하나로 합치는 UnifiedIR

과학 계산과 머신러닝 분야에서 사랑받는 언어 Julia의 공식 저장소에 'UnifiedIR'라는 이름의 굵직한 PR이 올라왔어요. 이름 그대로 컴파일러 내부의 중간 표현(IR)을 하나로 통일하는 작업인데요. 사용자 눈에 보이는 새 문법이나 기능은 아니지만, 언어의 심장부인 컴파일러 파이프라인을 뜯어고치는 일이라 Julia의 앞날에 꽤 큰 의미가 있는 변화예요.

IR이 뭐냐면요

IR(Intermediate Representation, 중간 표현)은 소스코드와 기계어 사이의 중간 형태예요. 번역에 비유하면 이해가 쉬운데요. 한국어를 스와힐리어로 바로 번역하는 전문가는 드물지만, 한국어에서 영어로, 영어에서 스와힐리어로 옮기는 번역가는 구하기 쉽잖아요. 컴파일러도 마찬가지로 사람이 읽는 코드를 곧장 기계어로 바꾸는 대신, 분석과 최적화에 유리한 중간 형태로 먼저 바꿔놓고 작업해요. 죽은 코드 제거나 함수 인라이닝 같은 최적화가 전부 이 IR 위에서 일어나거든요. IR을 어떻게 설계하느냐가 컴파일러의 성능과 유지보수성을 좌우한다고 해도 과언이 아니에요.

Julia 컴파일러에는 IR이 여러 벌 있었어요

Julia의 컴파일 과정은 대략 이렇게 흘러가요. 소스코드를 파싱하고, lowering이라는 단계를 거쳐 CodeInfo라는 표현으로 만들고, 그 위에서 Julia의 자랑인 타입 추론을 돌려요. 그다음 본격적인 최적화를 위해 IRCode라는 또 다른 표현으로 변환하는데, 이건 SSA 형식이라고 해서 각 변수에 값을 딱 한 번만 할당해 데이터 흐름을 추적하기 쉽게 만든 형태예요. 최적화가 끝나면 결과를 다시 넘겨서 LLVM을 통해 기계어를 만들고요. 문제는 이 CodeInfo와 IRCode라는 두 표현이 오랫동안 공존해 왔다는 거예요. 같은 코드를 담는 자료구조가 두 벌이니 둘 사이를 오가는 변환 비용이 계속 발생하고, 컴파일러 기능 하나를 고칠 때마다 양쪽을 다 신경 써야 했고, 컴파일러에 기여하려는 사람에게도 진입 장벽이 됐죠. 이번 UnifiedIR 작업은 이 이중 구조를 정리해서, 파이프라인이 하나의 표현을 중심으로 흐르게 만들려는 거예요.

이게 왜 중요하냐면요

Julia 커뮤니티의 오랜 숙제가 바로 컴파일 지연이에요. 'time to first plot'이라는 별명이 있을 정도로, 처음 함수를 실행할 때 컴파일 때문에 기다리는 시간이 Julia의 대표적인 약점으로 꼽혀왔거든요. 최근 버전들에서 네이티브 코드 캐싱 등으로 많이 좋아졌지만, 컴파일러 내부 구조가 깔끔해지면 이런 개선 작업 자체가 쉬워져요. IR이 하나로 정리되면 변환 오버헤드가 줄어드는 것은 물론이고, 컴파일 결과의 캐싱이나 정적 컴파일 같은 미래 기능을 얹을 토대도 단단해지고요. 업계 전체를 봐도 비슷한 흐름이 있어요. Rust는 MIR라는 중간 표현을 도입하면서 borrow checker 개선과 최적화의 길을 열었고, LLVM 진영은 MLIR로 여러 수준의 표현을 통합하는 프레임워크를 만들었죠. 언어의 장기적인 발전 속도는 결국 컴파일러 내부 구조가 얼마나 잘 정리되어 있느냐에 달려 있다는 걸 보여주는 사례들이에요.

한국 개발자에게 주는 시사점

Julia를 실무에 쓰는 분이라면 당장 뭔가 바뀌는 건 아니지만, 앞으로 나올 버전들에서 컴파일 지연 개선과 도구 생태계 발전의 기반이 되는 작업이라 지켜볼 가치가 있어요. Julia를 안 쓰는 분에게도 이 PR은 좋은 공부 소재예요. 실제 프로덕션 언어의 컴파일러가 어떤 단계로 구성되는지, SSA 같은 개념이 왜 필요한지를 살아있는 코드로 볼 수 있는 기회거든요. 컴파일러라고 하면 교과서 속 이야기 같지만, 요즘은 트랜스파일러, 린터, 코드 생성 도구처럼 IR 개념이 쓰이는 실무 영역이 정말 많아서 한 번 익혀두면 여기저기서 도움이 돼요.

정리하며

겉으로 드러나는 기능은 없지만, 언어의 미래 속도를 결정하는 기초 공사라는 점에서 의미가 큰 변화예요. 여러분은 사용하는 언어의 컴파일러나 런타임 내부를 들여다본 적 있나요? '이 언어의 내부 구조 덕분에, 혹은 때문에 이런 특성이 생겼구나' 하고 느낀 경험이 있다면 나눠주세요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/JuliaLang/julia/pull/62334
SHARE
처리 중...