컴파일러
[컴파일러/LLVM] 2. Module, Function, Basic Block 순회하며 Instruction 출력하기
용성군
2021. 8. 1. 10:24
728x90
반응형
이번 글에서는 LLVM의 기본적인 Module 구조를 보고, IR파일 내의 명령어들을 출력해보도록 하겠다.
Module은 하나의 IR 파일이라고 생각하면 편하다. 그리고 LLVM IR에서는 llvm::Module -> llvm::Function -> llvm::BasicBlock -> llvm::Instruction의 계층구조로 IR 프로그램을 관리한다.
Module은 여러 개의 Function으로 구성되어 있고, Function은 다시 여러 개의 Basic Block 으로 구성되어 있으며, Basic Block은 Instruction로 구성되어 있다.
- Module = 모듈, 일반적으로 하나의 소스 파일
- Function = 함수
- Basic Block = Branch나 Return같은 제어 명령어로 끝남(다른 위치로 이동하지 않고 순서대로 실행되는 코드의 Block들을 의미)
- Instruction = 명령어
다음 그림은 빨간색은 Module, 진한 파란색은 Function, 초록색은 Basic Block, 하늘색은 Instruction을 의미한다.
전역 변수를 나타내는 llvm::GlobalVariable와 Metadata 등은 llvm::Module 내에서 따로 관리된다.
명령어 출력
IR파일은 계층구조로 되어있기 때문에 3중 for문을 이용해서 명령어에 접근한다. 첫번째는 Module, 두번째 Function을 iterator로 접근한다.
llvm::raw_os_ostream raw_cout( std::cout );
// Module::iterator --> Function
for( llvm::Module::iterator ModIter = TheModule->begin(); ModIter != TheModule->end(); ++ModIter )
{
llvm::Function* Func = llvm::cast<llvm::Function>(ModIter);
// Print Function Name
raw_cout << Func->getName() << '\n';
// Function::iterator --> BasicBlock
for( llvm::Function::iterator FuncIter = Func->begin(); FuncIter != Func->end(); ++FuncIter )
{
llvm::BasicBlock* BB = llvm::cast<llvm::BasicBlock>(FuncIter);
// BasicBlock::iterator --> Instruction
for( llvm::BasicBlock::iterator BBIter = BB->begin(); BBIter != BB->end(); ++BBIter )
{
llvm::Instruction* Inst = llvm::cast<llvm::Instruction>(BBIter);
// Print Instruction
raw_cout << '\t';
Inst->print(raw_cout);
raw_cout << '\n';
}
}
}
728x90
반응형