Computer Science/컴파일러개론(Compiler)

[컴개/CI] IR Translation to 3-addr Code (Statement)

gxxgsta 2023. 12. 14. 15:39
반응형
SMALL

3-주소 Translation 규칙: Statement Seq.

 

여러 문장들이 단순하게 연속해서 존재할 때, 각각에 대해 번역한 후 연결해주면 된다.

이때 위 식에서는 결과값을 t에 대입하지 않는데, statement는 결과값이 없으므로 결과값을 받을 t가 필요없다.

 

이러한 statement의 경우 단순히 연결만 하면 된다.

즉, t = [[e]]와 같이 결과값이 있는 경우를 expression, 결과값이 없고 단순히 연결하는 경우는 statement라고 한다.

 

3-주소 Translation 규칙: Assignment

 

위 경우는 단순히 expre의 결과를 할당하는 경우이다.

OP처럼 v(변수 이름)와 '='은 HIR과 LIR이 모두 사용하기 때문에 [[ ]]에서 그대로 빠져나갈 수 있다.

다만, e는 HIR 형식으로 다양한 식이 계산될 수 있으므로 [[ e ]]에 대해서만 잘 수행하여 v에 대입하면 된다.

 

 

위 경우는 array에 expr의 결과를 할당하는 경우이다.

addr v로 시작주소를 찾고, t2과 t3 과정으로 인덱스를 찾는다.

이후, t4에서 시작주소로부터 t3만큼 떨어진 위치를 통해 값을 할당할 cell의 주소를 찾고, [[e2]]를 계산하여 t5에 저장한 후 t4의 주소값에 t5를 넣어준다.

 

이때, [t4]는 t4의 주소값을 의미한다.

 

3-주소 Translation 규칙: If

if문의 경우는 structual한 표현, 즉 구조가 있는 표현이다.

 

위 예제는 if e then s의 예제로 조건부 점프인 cjump를 사용한다.

가장 먼저 [[e1]]을 계산한 값을 t1에 저장하고, t1의 값을 neg를 통해 값을 반대로 바꾸어 t2에 저장한다.

 

이후 t2가 참이면(= t1이 거짓이면) Lend로 분기한다.

t2가 거짓이면(= t1이 참이면) [[ s ]]를 실행한다.

 

 

위 예제는 if e then s1 else s2의 예제로 if e then s 예제와 굉장히 흡사하다.

이때 주의해야 할 점으로는 [[ e ]]가 참인 경우 s1을 실행한 후 s2를 실행하게 되므로 s1의 계산이 종료되면 바로 Lend로 분기할 수 있도록 jump문을 넣어줘야 한다.

 

3-주소 Translation 규칙: While

 

while문 또한 if문과 유사하다. [[e]]를 계산한 후 그 값을 반대로 뒤집어 조건분기한다.

이후 [[s]]를 실행하면 다시 조건인 [[e]]으로 향하게 되는데,

[[e]]값이 거짓이면, 즉 t2의 값이 참이면 Lend로 분기하여 while문을 탈출하게 된다.

 

즉, if문에서 'jump Lloop'가 추가되면 while문이 된다.

 

3-주소 Translation 규칙: Switch

 

switch문은 if문을 나열한 것과 비슷하다.

[[e]]를 t에 넣은 후 v1 값과 같지 않으면 다음으로 점프한다.

만약 t와 v1의 값이 같다면, [[s1]]을 수행한 후 해당 switch문을 탈출하도록 jump Lend를 넣어 주어야 한다.

 

위와 같은 방법을 사용할 수도 있지만, 컴파일러에 따라 table lookup으로 변환되는 경우가 있다.

[[e]]의 값에 따라 jump해야 하는 주소를 value로 가지는 테이블을 만들기도 한다.

if문을 통한 방식을 사용하는 경우 O(n)이라는 시간이 걸리지만, 테이블을 사용하면 O(1)의 시간이 걸린다.

 

하지만 테이블의 데이터로 주소값이 있는 경우 보안성이 낮아진다는 단점이 있다.

또, 테이블 내의 데이터로 존재하는 경우 컴파일러에서의 가시성이 떨어져 최적화에 어려움이 있다는 단점도 존재한다. 따라서 두 방법 중 더 나은 방법은 존재하지 않고, 상황에 따라 맞는 방법을 사용하면 된다.

 

3-주소 Translation 규칙: Function Call/Return

 

모든 actual 파라미터를 계산하여 t1, ..., tN에 넣은 후 함수를 call할 때 인자값으로 넣어 부른다.

리턴할 때에는 리턴되는 [[e]]를 계산하여 값을 넘겨주어야 한다.

 

이때, call과 return이라는 LIR 명령이 모두 있다는 가정 하에 위의 모양으로 변환할 수 있다.

만약 생각보다 더 low-level하여 call과 return이라는 명령어가 없다면, 변수 내에 들어있는 값을 모두 꺼내 다른 함수인 f의 시작 주소를 가져다 주고, 제어도 넘겨줘야 한다.

반응형
LIST