MIR을 코드 생성 IR로 로워링하기
이제 수집기로부터 생성할 심볼 목록을 얻었으므로, 일종의 코드 생성 IR을 생성해야 합니다. 이 장에서는 rustc가 보통 사용하는 LLVM IR을 가정합니다. 실제 단형화(monomorphization)는 번역을 진행하는 도중에 그때그때 수행됩니다.
백엔드는 rustc_codegen_ssa::base::codegen_crate에 의해 시작된다는 점을 떠올려 보십시오. 결국 이는 rustc_codegen_ssa::mir::codegen_mir에 도달하며, 이 함수가 MIR에서 LLVM IR로의 로워링을 수행합니다.
코드는 특정 MIR 기본 요소를 처리하는 모듈들로 나뉘어 있습니다:
rustc_codegen_ssa::mir::block은 블록과 그 종결자(terminator)의 번역을 담당합니다. 이 모듈이 하는 일 중 가장 복잡하면서도 가장 흥미로운 것은 필요한 언와인딩 처리 IR을 포함하여 함수 호출에 대한 코드를 생성하는 것입니다.rustc_codegen_ssa::mir::statement는 MIR 문장을 번역합니다.rustc_codegen_ssa::mir::operand는 MIR 피연산자를 번역합니다.rustc_codegen_ssa::mir::place는 MIR 플레이스(place) 참조를 번역합니다.rustc_codegen_ssa::mir::rvalue는 MIR r-값을 번역합니다.
함수가 번역되기 전에, 더 단순하고 효율적인 LLVM IR을 생성하는 데 도움이 되도록 여러 가지 단순하고 기초적인 분석 패스가 실행됩니다. 이러한 분석 패스의 예로는 어떤 변수가 SSA와 유사한지 파악하는 것이 있으며, 이를 통해 해당 변수들에 대해서는 LLVM의 mem2reg에 의존하지 않고 직접 SSA로 번역할 수 있습니다. 이 분석은 rustc_codegen_ssa::mir::analyze에서 찾을 수 있습니다.
일반적으로 하나의 MIR 기본 블록은 하나의 LLVM 기본 블록에 대응하며, 예외는 매우 적습니다: 인트린직(intrinsic)이나 함수 호출, 그리고 assert처럼 덜 기본적인 MIR 문장은 여러 개의 기본 블록을 만들어 낼 수 있습니다. 이는 코드 생성 중 이식 불가능한 LLVM 전용 부분으로 넘어가기 위한 완벽한 도입부입니다. 인트린직 생성은 중간에 관여하는 추상화 계층이 매우 적어 이해하기가 꽤 쉬우며, rustc_codegen_llvm::intrinsic에서 찾을 수 있습니다.
그 밖의 모든 것은 빌더 인터페이스를 사용합니다. 이것이 앞서 설명한 rustc_codegen_ssa::mir::* 모듈에서 호출되는 코드입니다.
TODO: 상수가 어떻게 생성되는지 설명하기