코드 생성 (컴파일러)

컴퓨팅에서 코드 생성(code generation)은 컴파일러의 처리 과정 중 일부로, 소스 코드의 중간 표현을 대상 시스템이 즉시 실행할 수 있는 형태(예: 기계어)로 변환하는 단계를 말한다.

정교한 컴파일러는 일반적으로 다양한 중간 형태에 대해 여러 번의 패스를 수행한다. 이러한 다단계 프로세스가 사용되는 이유는 분산 계산 알고리즘을 포함한 많은 코드 최적화 알고리즘을 한 번에 하나씩 적용하기가 더 쉽거나, 한 최적화의 입력이 다른 최적화에 의해 수행된 완료된 처리에 의존하기 때문이다. 또한 이러한 구성은 여러 아키텍처를 대상으로 할 수 있는 단일 컴파일러의 제작을 용이하게 하는데, 코드 생성 단계의 마지막 부분(백엔드)만 타겟마다 변경하면 되기 때문이다. (컴파일러 설계에 대한 자세한 내용은 컴파일러를 참조하라.)

코드 생성기의 입력은 일반적으로 파스 트리 또는 추상 구문 트리로 구성된다. 이 트리는 보통 3-어드레스 코드와 같은 중간 언어의 선형 명령어 시퀀스로 변환된다. 컴파일의 후속 단계는 프로그램 표현의 상당한 변화를 수반하는지 여부에 따라 "코드 생성"이라고 불릴 수도 있고 그렇지 않을 수도 있다. (예를 들어, 핍홀 최적화 패스는 코드 생성기에 포함될 수는 있지만, 그 자체를 "코드 생성"이라고 부르지는 않는다.)

 주요 작업 
중간 표현을 기계 명령어의 선형 시퀀스로 변환하는 것 외에도, 전형적인 코드 생성기는 생성된 코드를 최적화하려고 시도한다.

정교한 컴파일러의 "코드 생성" 단계에 일반적으로 포함되는 작업은 다음과 같다:
 명령어 선택: 어떤 명령어를 사용할 것인지 결정.
 명령어 스케줄링: 해당 명령어들을 어떤 순서로 배치할 것인지 결정. 스케줄링은 파이프라인 기계에 결정적인 영향을 미칠 수 있는 속도 최적화 기법이다.
 레지스터 할당: 변수를 프로세서 레지스터에 할당.
 필요한 경우 코드의 디버그를 위해 디버그 데이터 생성.

명령어 선택은 일반적으로 추상 구문 트리에서 재귀적인 후위 순회(postorder traversal)를 수행하여 특정 트리 구성과 템플릿을 대조함으로써 수행된다. 예를 들어, W := ADD(X,MUL(Y,Z))라는 트리는 t1 := X 및 t2 := MUL(Y,Z)에 대한 시퀀스를 재귀적으로 생성한 다음 ADD W, t1, t2 명령어를 내보냄으로써 선형 명령어 시퀀스로 변환될 수 있다.

중간 언어를 사용하는 컴파일러에는 두 개의 명령어 선택 단계가 있을 수 있다. 하나는 파스 트리를 중간 코드로 변환하는 단계이고, 훨씬 나중에 중간 코드를 대상 머신의 명령어 집합으로 변환하는 두 번째 단계이다. 이 두 번째 단계는 트리 순회가 필요하지 않으며, 선형적으로 수행될 수 있고 일반적으로 중간 언어 연산을 그에 대응하는 명령 코드로 단순 교체하는 과정을 포함한다. 그러나 컴파일러가 언어 번역기(예: 자바를 C++로 변환하는 번역기)인 경우, 두 번째 코드 생성 단계에는 선형 중간 코드로부터 트리를 구축하는 과정이 포함될 수 있다.

 런타임 코드 생성 
JIT 컴파일(JIT)과 같이 런타임에 코드 생성이 발생하는 경우, 전체 프로세스는 공간과 시간 측면에서 알고리즘 효율성이 높아야 한다. 예를 들어, 정규 표현식을 해석하여 런타임에 코드를 생성할 때, 결정적 유한 상태 기계 대신 비결정적 유한 상태 기계가 생성되는 경우가 많은데, 이는 후자가 일반적으로 더 빠르게 생성될 수 있고 메모리 공간을 덜 차지하기 때문이다. 일반적으로 덜 효율적인 코드를 생성함에도 불구하고, JIT 코드 생성은 런타임에만 제공되는 프로파일링 정보를 활용할 수 있다는 장점이 있다.

 관련 개념 
한 언어의 입력을 받아 상당히 다른 언어의 출력을 생성하는 기본 작업은 형식 언어 이론의 핵심 변형 작업의 관점에서 이해될 수 있다. 결과적으로, 컴파일러에서 사용하기 위해 처음 개발된 일부 기술들은 다른 방식으로도 고용되었다. 예를 들어, YACC(Yet Another 컴파일러 컴파일러)는 배커스-나우르 표기법의 입력을 받아 C 언어의 파서로 변환한다. 비록 처음에는 컴파일러용 파서의 자동 생성을 위해 만들어졌지만, yacc은 사양이 바뀔 때마다 수정이 필요한 코드를 자동으로 작성하는 데에도 자주 사용된다.Code Generation: The Real Lesson of Rails. Artima.com (2006-03-16). Retrieved on 2013-08-10.

많은 통합 개발 환경(IDE)은 자동화된 소스 코드 생성의 일부 형태를 지원하며, 이는 흔히 컴파일러 코드 생성기와 공통된 알고리즘을 사용하지만 대개 그보다는 덜 복잡하다. (프로그램 변환 및 데이터 변환 참조.)

 리플렉션 
일반적으로 구문 및 의미 분석기는 소스 코드로부터 프로그램의 구조를 추출하려고 시도하는 반면, 코드 생성기는 이 구조적 정보(예: 자료형)를 사용하여 코드를 생성한다. 즉, 전자는 정보를 추가하는 반면 후자는 정보를 일부 잃게 된다. 이러한 정보 손실의 한 가지 결과는 리플렉션이 어려워지거나 심지어 불가능해질 수 있다는 것이다. 이 문제를 해결하기 위해 코드 생성기는 종종 구문 및 의미 정보와 실행에 필요한 코드를 함께 포함시킨다.

 같이 보기 
 자동 프로그래밍
 코드 생성 도구 비교
 소스 대 소스 컴파일러: 한 프로그래밍 언어로 된 컴퓨터 프로그램을 다른 프로그래밍 언어로 자동 번역

 각주 

분류:기계어
분류:컴파일러 구성