다음 명령열이 아직 필요로 하는 레지스터만 저장한다.
명령열의 need와 modify 집합을 사용하면 합성 코드가 이전 값을 save/restore로 보호해야 하는 시점을 판단할 수 있습니다.
두 명령열 사이에서 컴파일러는 언제 레지스터를 보존해야 할까요?
- Read register needs and modifications as sequence contracts
- Detect a value needed after an earlier sequence overwrites it
- Insert save and restore only around that conflict
- Update the composed sequence contract after preservation
A conflict exists when the second sequence needs the incoming value of a register and the first sequence modifies that register. Preserving wraps the first statements with save and restore so the second sequence sees the original value.
The wrapped first sequence now needs the register in order to save it and no longer exposes that register as modified after restore. If either side of the conflict is absent, composition emits no stack instructions.
(begin
(define (contains? item items)
(cond ((null? items) #f)
((eq? item (car items)) #t)
(else (contains? item (cdr items)))))
(define (adjoin item items)
(if (contains? item items) items (append items (list item))))
(define (union left right)
(if (null? right) left
(union (adjoin (car right) left) (cdr right))))
(define (difference left right)
(cond ((null? left) '())
((contains? (car left) right)
(difference (cdr left) right))
(else
(cons (car left) (difference (cdr left) right)))))
(define (make-sequence needs modifies statements)
(list needs modifies statements))
(define (needs sequence) (car sequence))
(define (modifies sequence) (cadr sequence))
(define (statements sequence) (caddr sequence))
(define (append-sequences first second)
(make-sequence
(union (needs first)
(difference (needs second) (modifies first)))
(union (modifies first) (modifies second))
(append (statements first) (statements second))))
(define (preserving register first second)
(if (and (contains? register (needs second))
(contains? register (modifies first)))
(append-sequences
(make-sequence
(adjoin register (needs first))
(difference (modifies first) (list register))
(append (list (list 'save register))
(append (statements first)
(list (list 'restore register)))))
second)
(append-sequences first second)))
(preserving
'env
(make-sequence '(env) '(env val)
'((assign env extended) (assign val operand)))
(make-sequence '(env val) '(val)
'((perform apply)))))- 출력
- —
- 값
- —
- 진단
- —
The first program returns a sequence that needs (env), modifies (val), and surrounds the first statements with (save env) and (restore env). The second returns (#t #f).
Follow both membership checks before the sequence is wrapped. Then inspect how difference removes env from the exposed modification set while the emitted statement list gains save and restore.
힌트를 보기 전에 프로그램을 바꿔 보세요.
Change the second sequence so it needs only val. Predict the composed need and modification sets and whether any save or restore remains.
힌트 하나 보기
Without env in the second need set, preserving takes the ordinary append-sequences branch.