중간 표현
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
중간 표현은 텍스트나 바이너리 데이터 등 다양한 데이터 구조를 가지며, 프로그래밍 언어 처리 과정에서 소스 코드를 어휘 분석 및 구문 분석하여 생성된 구문 트리의 추상화 형태이다. 중간 언어는 형식 언어의 형태를 띠며, 컴파일러나 인터프리터가 소스 코드를 기계어로 변환하는 과정에서 사용된다. 1970년대부터 중간 언어에 대한 개념이 존재했으며, GNU Compiler Collection, LLVM, DirectX, OpenGL, CUDA 등 다양한 환경에서 활용되고 있다. 또한, C 언어, TypeScript, 어셈블리어 등도 중간 언어 역할을 수행하며, 정적 분석 도구에서도 사용된다.
더 읽어볼만한 페이지
- 프로그래밍 언어 분류 - 하드웨어 기술 언어
하드웨어 기술 언어(HDL)는 전자 시스템의 구조와 동작을 텍스트 기반으로 표현하는 언어로, 디지털 회로 설계의 핵심 도구로 사용되며, 시뮬레이션 및 디버깅을 통해 설계 검증을 수행한다. - 프로그래밍 언어 분류 - 고급 프로그래밍 언어
고급 프로그래밍 언어는 기계어보다 높은 수준의 추상화를 제공하며, 변수, 객체, 함수 등의 개념을 사용하여 프로그래머가 기계의 세부 사항에서 분리되어 편리하게 프로그래밍할 수 있도록 하는 언어이다. - 컴파일러 구성 - 구문 분석
구문 분석은 입력 데이터를 구조화된 형태로 변환하는 과정으로, 컴퓨터 언어에서는 소스 코드를 분석하여 추상 구문 트리를 생성하고, 자연어 처리에서는 텍스트의 문장 구조와 의미를 분석한다. - 컴파일러 구성 - 바이너리 재컴파일러
중간 표현 | |
---|---|
개요 | |
이름 | 중간 표현 |
설명 | 컴파일러 또는 가상 머신에서 소스 코드를 나타내는 데 내부적으로 사용되는 데이터 구조 또는 코드 |
목적 | |
목적 | 소스 언어와 대상 언어 간의 격차 해소 |
이점 | 최적화 및 코드 생성을 위한 공통 플랫폼 제공 |
특징 | |
특징 | 소스 언어의 모든 구문을 정확하게 표현 대상 언어의 모든 세부 사항을 포함하지 않음 비교적 추상적 기계 독립적 |
유형 | |
추상 구문 트리 (AST) | 프로그램의 구문 구조를 트리 형태로 표현 |
세 주소 코드 | 각 명령어가 최대 세 개의 피연산자를 갖는 중간 코드 형태 |
정적 단일 할당 (SSA) | 각 변수가 한 번만 할당되는 중간 코드 형태 |
Directed Acyclic Graph (DAG) | 프로그램의 계산을 그래프 형태로 표현 |
사용 | |
컴파일러 | 소스 코드를 중간 표현으로 변환 중간 표현을 최적화 중간 표현에서 대상 코드를 생성 |
가상 머신 | 중간 표현 (바이트코드)을 해석하고 실행 |
예시 | |
Java 바이트코드 | Java 가상 머신에서 실행되는 중간 표현 |
.NET 공통 중간 언어 (CIL) | .NET 런타임에서 실행되는 중간 표현 |
장점 | |
장점 | 이식성 향상 최적화 용이 다중 언어 지원 |
2. 표현 형태
중간 표현은 텍스트 또는 바이너리 데이터와 같은 다양한 데이터 구조를 가질 수 있다. Java 바이트 코드와 같은 "바이트 코드"는 필드 구분이나 구조 길이가 바이트 지향적인 중간 표현을 가리킨다. 내부적으로는 포인터를 사용하여 효율적인 표현이 가능하지만, 파일 등에 기록할 때는 영속화를 위한 방법이 필요하다. 포인터와 같이 밀결합된 표현이 아닌, 헐거운 결합된 표현을 사용하는 경우도 있다.
2. 1. 구문 트리와 중간 표현
프로그래밍 언어나 그 외의 형식 언어를 다루는 컴퓨터 프로그램에서는 소스 코드 등의 입력에 있는 문자열을 어휘 분석기(렉시컬 애널라이저)에 의한 어휘 분석을 통해 토큰(어휘)으로 분할한 후, 구문 분석기(파서)에 의한 구문 분석을 통해 토큰을 잎으로 하는 구문 트리라고 불리는 트리 구조를 구축하는 경우가 많다(구문 분석 과정에서 직접 코드를 생성하기도 한다).[1]구문 트리로 나타낼 수 있는 데이터는 추상 구문 트리의 중간 표현을 사용한다.[1] 추상 구문 트리는 구문 트리의 추상화를 목적으로 정의되며, 특정 플랫폼에 의존하는 구문 트리에서 불특정 다수의 플랫폼에 대응할 수 있는 구문 트리로 표현된다.[1] 어느 구문 트리든 동등한 정보를 유지하는 데이터를 나타낸다.[1] 명령어 집합을 갖는 데이터는 중간 표현으로 추상화한 다음, 특정 플랫폼의 명령어 집합과 중간 표현의 명령어 집합을 심볼 테이블로 연결한다.[1] 중간 표현과 심볼 테이블을 세트로 정의하고, 각 플랫폼의 명령어 집합을 중간 표현을 통해 변환한다.[1]
3. 중간 언어
'''중간 언어'''는 컴퓨터 프로그램 분석을 돕기 위해 설계된 추상 머신의 언어이다. 컴파일러에서 소스 코드를 오브젝트 파일이나 대상 머신용 기계어 코드로 변환하기 전에 코드 개선 및 변환을 위해 사용된다.
일반적으로 실제 기계어와 다음 세 가지 방식으로 구별된다.
- 각 명령어는 단 하나의 기본적인 연산을 나타낸다. (마이크로프로세서의 "시프트-더하기" 주소 지정 방식은 해당되지 않음)
- 제어 흐름 정보가 명령어 집합에 포함되지 않을 수 있다.
- 사용 가능한 프로세서 레지스터 수가 많거나 무제한일 수 있다.
3-주소 코드가 널리 쓰이는 중간 언어 형식이다.
중간 표현이 형식 언어 형태를 띨 때 "중간 언어"라고 하며, 프로그래밍 언어와 관련이 깊다.[11]
컴파일러는 소스 코드를 대상 아키텍처의 기계어로 직접 생성하지 않고 중간 표현을 거칠 수 있다.[11] 인터프리터도 소스 코드를 직접 해석하지 않고 중간 표현을 생성하여 실행할 수 있다.
C는 중간 언어로 설계되지 않았지만, 어셈블리 언어를 추상화하고 유닉스 계열 등에서 ''사실상'' 시스템 프로그래밍 언어로 널리 쓰이면서 인기 있는 중간 언어가 되었다. 에펠, 세더, 에스테렐, 리스프 방언 (러쉬, 갬빗), 스퀴크의 Smalltalk 하위 집합 Slang, 님, 사이썬, 시드7, 시스템탭, 발라, V 등이 C를 중간 언어로 쓴다. C--, C 중간 언어 등 C 변형도 C 기능을 이식 가능한 어셈블리 언어로 제공하기 위해 설계되었다.
GNU 컴파일러 모음(GCC)은 이식성과 크로스 컴파일레이션을 위해 레지스터 전송 언어(RTL), GENERIC, SSA 기반 GIMPLE 등 여러 중간 언어를 내부적으로 사용한다.
LLVM 컴파일러 프레임워크는 LLVM IR 중간 언어를 기반으로 하며, "비트코드"라고도 불리는 작고 이진 직렬화된 표현을 사용한다.[4][5]
3. 1. 역사
초기에는 단일 언어, 단일 대상 시스템이 일반적이었다. 1958년 멜빈 콘웨이가 제안한 UNCOL(UNiversal Computer Oriented Language)은 중간 언어의 초기 개념 중 하나이다.[12] 대한민국에서는 모리구치 시게카즈가 제안한 SIP(Symbolic Input Program)가 초기 전산기에서 명령어 이름의 공통화를 시도했다.[13]1980년대 GNU Compiler Collection(GCC)은 레지스터 전송 언어(RTL) 등 플랫폼 독립적인 중간 표현을 사용하여 여러 언어 및 대상 시스템을 지원했다. 2000년대 초, 대한민국에서는 COINS(COmpiler INfraStructure) 프로젝트를 통해 GPL이 아닌 컴파일러 인프라가 개발되었다.[14] LLVM은 GPL이 아닌 라이선스를 채택하고, 중간 언어를 활용하여 다양한 프로그래밍 언어 및 대상 시스템을 지원한다.[15]
3. 2. 가상 머신 및 인터프리터
일부 가상 머신과 인터프리터는 중간 언어를 직접 실행한다. 그러나 런타임 컴파일(JIT 컴파일)을 통해 중간 언어를 실행 환경에 맞는 기계어로 변환한 후 실행하는 것이 더 빠르다.[11]대표적인 예는 다음과 같다:
- 자바 바이트코드
- 마이크로소프트의 공통 중간 언어는 .NET 프레임워크용 모든 컴파일러에서 공유하도록 설계된 중간 언어로, 기계어로 정적 또는 동적 컴파일된다.
- 패럿 중간 표현은 정적으로 형식화된 언어뿐만 아니라 동적으로 형식화된 언어(초기에는 펄과 파이썬)도 지원하도록 설계되었다.
3. 3. GPU 셰이더 및 병렬 컴퓨팅
Microsoft DirectX(Direct3D)에서는 DirectX 8부터 프로그래머블 셰이더가 도입되었는데, 초기에는 어셈블리 언어를 사용하여 셰이더 프로그램을 작성했다. 이때 이미 DXBC (DirectX Bytecode)라는 GPU 벤더에 의존하지 않는 중간 표현을 채택했다. Direct3D 런타임은 먼저 셰이더 코드의 유효성 검사를 실행하여 타당성과 유효성을 사전에 평가한 다음, Direct3D 드라이버가 셰이더 코드를 해석한다.[16] 이 방식은 그래픽 드라이버 측의 부담을 줄이고 프로그램의 품질을 확보하는 데 도움이 된다. DirectX 9에서 채택된 고수준 셰이딩 언어인 HLSL의 컴파일러 "fxc.exe"는 DXBC를 출력한다. DirectX 12부터 추가된 셰이더 모델 6.0 이후에는 새로운 중간 표현 DXIL을 채용하고, LLVM/Clang 기반의 HLSL 컴파일러 "dxc.exe"를 사용한다.[17]OpenGL에서는 오랫동안 중간 표현이 표준화되지 않아, GLSL 셰이더 소스 코드 문자열을 애플리케이션에 포함시켜 드라이버에 매번 API를 통해 문자열을 전달하여 컴파일해야 했다. 그러나 OpenCL이나 Vulkan에서의 중간 표현으로서 Standard Portable Intermediate Representation|label=SPIR/SPIR-V영어가 표준화되면서, OpenGL 4.6에서도 SPIR-V 지원이 코어 기능으로 추가되었다.[18] 중간 표현 형식을 채택함으로써 셰이더 프로그램의 오프라인 컴파일이 가능해질 뿐만 아니라, 프론트 엔드의 언어 선택에 자유도를 갖게 할 수 있다는 장점도 있다. Vulkan 공식 SDK에는 SPIR-V를 출력하는 오프라인 컴파일러 "glslangValidator"가 부속되어 있으며, GLSL뿐만 아니라 HLSL도 입력을 사용할 수 있기 때문에, Vulkan에서는 셰이더 기술에 반드시 GLSL을 사용할 필요는 없고, HLSL을 사용하는 것도 가능하다.
CUDA는 NVIDIA제 GPU 전용 프로그래밍 환경이지만, GPU 아키텍처에 직접 의존하지 않는 커널 중간 표현으로 PTX를 사용할 수도 있다.
4. 기타 사례
C는 명시적으로 중간 언어로 설계되지 않았지만, 어셈블리 언어의 추상화이자 유닉스 계열 및 기타 운영 체제에서 ''사실상'' 시스템 프로그래밍 언어로 널리 사용되면서 인기 있는 중간 언어가 되었다.[7][8] 상대적으로 하위 수준에 위치한 C 언어는 다른 상위 수준 언어의 컴파일 대상으로 사용될 때 중간 언어 역할을 할 수 있다. TypeScript(TypeScript)는 JavaScript(자바스크립트) 코드를 출력하는 트랜스파일러로, 중간 언어 활용의 한 예이다.
유닉스 계열 환경에서 많은 컴파일러는 오브젝트 파일을 직접 생성하지 않고, 어셈블리어를 중간 언어로 사용하여 어셈블러가 오브젝트 파일을 생성한다. 컴파일러 드라이버에 실행 파일명을 지정하지 않으면 기본 실행 파일명이 `a.out`이 되는 관습은 과거 어셈블러의 출력 파일이었기 때문이다.
5. 정적 분석 도구와 중간 표현
정적 분석 도구는 종종 중간 표현을 사용한다. 예를 들어, Radare2는 바이너리 파일 분석 및 리버스 엔지니어링을 위한 툴박스이다. 이는 바이너리 파일을 분석하기 위해 ESIL[9] 및 REIL[10]이라는 중간 언어를 사용한다.
참조
[1]
웹사이트
CS320: Compilers: Intermediate Representation
http://www.cs.prince[...]
2016-02-12
[2]
간행물
The Challenge of Cross-language Interoperability
https://queue.acm.or[...]
2013-11-22
[3]
웹사이트
Intermediate Representations
http://cs.lmu.edu/~r[...]
2016-02-12
[4]
웹사이트
Bitcode (iOS, watchOS)
https://news.ycombin[...]
Hacker News
2015-06-10
[5]
웹사이트
LLVM Bitcode File Format
http://llvm.org/docs[...]
llvm.org
2015-06-17
[6]
웹사이트
MLIR
https://mlir.llvm.or[...]
[7]
웹사이트
An ILOC Simulator
http://www.engr.sjsu[...]
[8]
문서
CISC 471 Compiler Design
http://www.cis.udel.[...]
[9]
웹사이트
ESIL
https://radare.gitbo[...]
Radare2 Project
2015-06-17
[10]
웹사이트
The REIL language – Part I
http://blog.zynamics[...]
zynamics.com
2010-03-07
[11]
서적
bit 単語帳
共立出版
1990-08-15
[12]
웹사이트
Proposal for an UNCOL
https://dl.acm.org/c[...]
Communications of the ACM
2018-04-22
[13]
문서
日本のコンピュータパイオニア > 森口繁一
http://museum.ipsj.o[...]
[14]
웹사이트
COINSコンパイラ・インフラストラクチャ
https://coins-compil[...]
[15]
웹사이트
Modern Intermediate Representations (IR)
https://llvm.org/dev[...]
2017-06-12
[16]
문서
Shader Code Format - Windows drivers | Microsoft Learn
https://learn.micros[...]
[17]
문서
Compiling Shaders - Win32 apps | Microsoft Learn
https://learn.micros[...]
[18]
문서
クロノス・グループ、SPIR-V機能を搭載した「OpenGL® 4.6」を発表 - Press Release - Khronos Group
https://jp.khronos.o[...]
[19]
웹인용
CS320: Compilers: Intermediate Representation
http://www.cs.prince[...]
2016-02-12
[20]
저널 인용
The Challenge of Cross-language Interoperability
https://queue.acm.or[...]
2013-11-22
[21]
웹인용
Intermediate Representations
http://cs.lmu.edu/~r[...]
2016-02-12
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com