https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.html
Sample
def fib(x)
if x < 3 then
1
else
fib(x-1)+fib(x-2);
fib(10)
DWARF : Debugging With Attributed Record Formats
컴파일된 바이너리 안에 소스코드와 대응되는 정보를 저장
ex)
int a = 3 + 4;
int b = a * 2;
-> int b = (3 + 4) * 2;
원래 두 줄이었던 코드가 최적화로 줄어듦
디버거는 명령어가 몇 번째 줄에서 왔는지 결정할 수 없음
int x = 10;
int y = x + 5;
-> int y = 15;
최적화로 인해 변수가 상수로 대체됨. 디버거 입장에선 x가 어디 있는지 알 수 없음
그래서 디버그 정보를 제대로 다루기 위해 최적화를 꺼놓고 수행
AOT(Ahedad-of-Time) : 사전 컴파일 모드
.ll파일로 저장하고, clang으로 실행파일을 만드는 방식을 사용
먼저 최상위 명령문을 포함하는 익명 함수를 "main"으로 만든다. -> 디버깅 도구에서 진입점을 찾기 쉽게 하기 위해
REPL : 인터프리터처럼 한 줄씩 입력받아 실행

위와 같이 while을 통해 하나씩 입력받아 실행하는 로직을 제거

모든 최적화 패스와 JIT을 비활성화하여 코드 구문 분석 및 생성이 완료된 후 LLVM IR이 표준 오류로 전송되는 것만 발생하도록 함.
DWARF에서 코드 섹션의 최상위 컨테이너는 컴파일 단위이다. 여기에는 개별 번역 단위(소스 코드 파일 하나)의 형식 및 함수 데이터가 포함.
따라서 가장 먼저 해야할 일은 fib.ks 파일에 대한 컴파일 단위를 생성하는 것.
LLVM IR에 DWARF 디버깅 정보를 붙이기 위해 DIBuilder와 DebugInfo구조를 설정하는 과정


"double"이란 이름, 64바이트 크기, 실수 타입을 의미하는 DW_ATE_float을 넣어서 DWARF 타입 정보를 만듦


디버깅 정보 생성이 끝났다는 신호를 주는 함수
LLVM IR에 함수 정의의 메타데이터를 붙여서 디버깅 시 함수 이름, 정의 위치, 시작 줄, 파라미터 정보 등을 디버거에서 볼 수 있도록 설정
파일에 정의된 함수에 대한 디버그 정보(DWARF의 DISubprogram 메타데이터)를 생성

KSDbgInfo.TheCU는 아가 만든 컴파일 단위. 이를 바탕으로 디버그 정보용 파일 객체(DIFile)를 생성

이 함수는 DISubprogram이라는 함수 전체 정보를 담는 노드를 만들어 줌. 디버깅 시 함수 이름, 정의 위치, 인자 등을 이 정보로 확인
마지막에 생성한 디버깅 정보를 LLVM 함수에 붙인다. LLVM 함수 TheFunction은 SP라는 디버깅 정보를 갖게 된다. 디버거는 이 정보를 통해 이 IR 함수가 "fib.ks"의 몇 번째 줄에 있는 함수인지 알 수 있음.
LLVM IR 디버깅 정보 중에서 소스 코드 위치 추적을 구현한 부분

줄과 열을 추적하기 위한 구조체, 모든 AST 노드에서 이 정보를 갖고 있게 됨

getchar()를 통해 문자열을 읽어와 Line, Col을 계산

AST 객체 생성시 현재 소스 위치를 받아서 저장

BinLoc에는 해당 연산자의 소스 코드 위치가 들어감
모든 AST 객체에서 코드의 위치를 알 수 있음

IRBuilder가 명령어를 생성할 때, 소스코드 몇 번째 줄에서 나왔는지 알려주는 역할
DILocation은 명령어의 열과 줄의 정보

현재 어떤 블록 안에 있는지 관리하는 스택

함수에 대해 코드 생성 시작시 스택의 맨 위로 푸시

함수에 대한 코드 생성이 끝날 때 스택에서 팝
이를 통해 IRBuilder가 현재 어떤 범위 안에 있는지 추적이 가능
함수에 대한 정보를 생성, 범위 내에 있는 변수들을 출력할 수 있어햐 한다.
디버깅 정보를 통해 변수의 이름과 타입, 위치 정보를 생성

CreateEntryBlockAlloca : 함수의 entry block에 스택 변수 생성createParameterVariable : 디버깅 정보용 인자 변수(DILocalVariable) 생성insertDeclare : alloca와 변수 정보를 연결CreateStore : 함수 인자의 실제 값을 alloca에 저장NameValues : AST codegen에서 이 변수 이름으로 접근 가능하게 등록CreateParamterVariable

함수 프롤로그는 디버거가 스킵하도록 명시

본문 진입 전 줄 번호 정보 재지정



clang으로 컴파일 하는데 리턴타입이 int인 main을 찾는데 IR에는 리턴 타입이 double인 main이 존재
wrapper를 만들어 해결
#include <stdio.h>
extern double kaleidoscope_main();
int main(int argc, char** argv) {
double result = kaleidoscope_main();
printf("Fibonacci result: %f\n", result);
return 0;
}


