Today Mini Learned :

기록하는 습관 들이기

ACTIVITY/모각코 (2020 여름)

[모각코] 5회차 결과 (200729)

얌챠 2020. 7. 29. 17:59
  • llvm pass 알아보기 ✔
  • llvm pass로 hello world 출력

  llvm pass는 컴파일러에서 수행하는 변환과 최적화를 해 주며, 컴파일러 코드의 구조화 기법이라고 한다. 컴파일러의 부분들을 구현해 놓은 것 같다. 패스들은 패스라는 클래스를 재정의해서 기능을 구현할 수 있다고 하고, 패스의 작동 방식에 따라서 다양한 클래스들에서 상속이 가능한 듯 하다. 또한 패스에 제약 조건을 두고 효율적으로 패스를 실행하게 설정이 가능하다고 한다.

(참고 : https://llvm.org/docs/WritingAnLLVMPass.html#introduction-what-is-a-pass)

(4.0.0 버전 문서 : https://releases.llvm.org/4.0.0/docs/WritingAnLLVMPass.html)

 

  간단한 출력을 해 볼 것이다. 역시 위의 링크에서 "Quick Start — Writing hello world" 부분을 참고했다.

Hello pass를 만들어 볼 것인데, 이는 그냥 수정 이런건 없고 프로그램이 컴파일될때 외부 function이 아닌 것들의 이름을 출력해주는 패스이다.

우선, 예전에 llvm을 설치했던 파일에서 lib/Transforms/Hello를 찾아 보았다.

해당 폴더에는 이렇게 파일들이 있었다. 이 파일들이 이 예시로 만든 결과물이라고 볼 수 있을 것 같다.

 

 

이게 패스를 만드는 방법 같아서 "Yampass"라는 이름으로 이름만 다르게 새로 만들어서 해 보았다.

1. lib/Transform/YampassCMakeLists.txt를 만들고 다음과 같이 붙여넣는다.

add_llvm_loadable_module( LLVMHello
  Hello.cpp

  PLUGIN_TOOL
  opt
  )

 

2. lib/Transform에 있는 CMakeLists.txt의 맨 아랫줄에 다음과 같이 붙여넣는다.

add_subdirectory(Yampass)

Yampass라는 서브디렉토리를 추가해 주었다.

 

3. 다시 lib/Transform/Yampass로 돌아와서 Yampass.cpp파일을 생성하고 다음과 같이 작성한다.

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
//패스를 작성하고 있으니까 Pass헤드와, 사용하는 기능에 따른 헤드들을 include 해 준다.

using namespace llvm;
//또한 이 include된 파일이 llvm 네임스페이스 안에 존재하므로 이렇게 이 네임스페이스를 사용한다고 추가해 준다.

namespace {
struct Yampass : public FunctionPass {
  static char ID;
  Yampass() : FunctionPass(ID) {} //Yampass를 FunctionPass의 subclass로 선언해 주고,

  bool runOnFunction(Function &F) override {
    errs() << "Yampass: ";
    errs().write_escaped(F.getName()) << '\n';
    return false;
  } //FunctionPass안의 runOnFunction메소드를 선언한다. 이 메소드를 통해 각각의 function들의 이름을 출력한다.
};
}

char Yampass::ID = 0;
//패스 아이디를 설정해주는데 llvm에서는 패스들을 구분할 때 아이디의 주소를 이용하기 때문에 값 설정 자체는 중요하지 않다고 한다.
static RegisterPass<Yampass> X("yampass", "hello yampass",
                             false /* Only looks at CFG */,
                             false /* Analysis Pass */);
                             //yampass라는 커맨드라인 값을 주었고, hello yampass라는 이름을 주었다.
                             //마지막 두 값은, 각각 패스가 CFG를 수정하지 않고 지나가는지 여부와 패스가 analysis 패스인지 여부라고 한다. 

 

만드는건 다 했고 이제 실행만 남은 것 같다! 실행도 이어서 할 것이다.