KR950006607B1 - 다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스 - Google Patents

다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스 Download PDF

Info

Publication number
KR950006607B1
KR950006607B1 KR1019920702690A KR920702690A KR950006607B1 KR 950006607 B1 KR950006607 B1 KR 950006607B1 KR 1019920702690 A KR1019920702690 A KR 1019920702690A KR 920702690 A KR920702690 A KR 920702690A KR 950006607 B1 KR950006607 B1 KR 950006607B1
Authority
KR
South Korea
Prior art keywords
tuple
gem
type
locator
node
Prior art date
Application number
KR1019920702690A
Other languages
English (en)
Inventor
로버트 네일 쥬니어 페이만
데이비드 스콧트 블리크스테인
스티븐 오. 호브스
캐롤라인 스위니 데이비드슨
리차드 배리 그로브
데니스 죠셉 머피
Original Assignee
디지탈 이큅먼트 코오포레이숀
로날드 이. 마이릭
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by 디지탈 이큅먼트 코오포레이숀, 로날드 이. 마이릭 filed Critical 디지탈 이큅먼트 코오포레이숀
Application granted granted Critical
Publication of KR950006607B1 publication Critical patent/KR950006607B1/ko

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/436Semantic checking
    • G06F8/437Type checking
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/447Target code generation

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computational Linguistics (AREA)
  • Devices For Executing Special Programs (AREA)
  • Stored Programmes (AREA)
  • Debugging And Monitoring (AREA)
  • Measuring Magnetic Variables (AREA)

Abstract

내용 없음.

Description

[발명의 명칭]
다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스
[도면의 간단한 설명]
본 발명의 특징으로 생각되는 신규의 구성은 부속 청구범위에 기재된다. 그러나 발명 그자체 뿐만 아니라 그것의 다른 특징 및 장점은 첨부 도면을 참조로 한 다음의 특정 실시예에 대한 상세한 설명에 의해 가장 잘 이해될 수 있을 것이다.
제1도는 본 발명의 구성을 사용한 컴파일러의 개략도이다.
제2도는 본 발명의 다양한 특성을 갖는 방법이 실행될 수 있는 호스트 컴퓨터의 블록도이다.
제3도는 제1도의 컴파일러에 의해 번역될 코드를 소스 코드 형태, 중간 언어 형태, 트리 형태(tree form) 및 어셈블리 언어 형태로 나타낸 도면이다.
제4도는 제1도의 컴파일러에 사용된 튜브의 데이타 구조를 나타낸 도면이다.
제5도는 제1도의 셀의 동작을 나타낸 논리 순서도이다.
제6도는 정수를 포함하는 코드 리시트의 예를 나타낸 도면이다.
제7도는 본 발명의 한 특징에 따른 타입 정의를 예시하기 위한 데이타 필드 및 관계(포인터)를 나타낸 도면이다.
[발명의 상세한 설명]
[발명의 배경]
본 발명은 디지탈 컴퓨터 프로그램용 컴파일러에 관한 것으로서, 구체적으로는 다수의 상이한 타겟 머신(target machine)용 코드를 발생하기 위하여 다수의 상이한 컴퓨터 언어로써 사용되기에 적합한 컴파일러 프레임워크(framework)에 관한 것이다.
컴파일러는 보통 특정 오퍼레이팅 시스템을 갖는 특정 타겟 머시의 실행을 위해 특정 소스 언어를 목적코드로 변환하도록 구성된다. 예를들어, 포트란 컴파일러(Fortran Compiler)는 VMS 오퍼레이팅 시스템을 사용하는 VAX아키텍쳐 또는 MS/DOS를 실행하는 80386컴퓨터용 C컴파일러를 갖는 컴퓨터용 코드를 발생시키는데 이용될 수 있다. 이러한 언어 및 타겟 특정 컴파일러의 중간부는 통상의 구조 및 기능을 상당량 공유하지만, 새로운 컴파일러의 구성은 기존의 컴파일러의 구성 부품의 일부를 사용하고 다른 부품을 변경함으로써 얻어질 수 있다. 그럼에도 불구하고, 소스 언어와 타겟 머신의 각 조합을 위해 새로운 컴파일러를 구성하는 것이 실용화 되어 왔고, 또 새로운 고성능 컴퓨터 아키텍쳐가 고안될 경우 공통으로 사용된 소스 언어 각각에 대하여 컴파일러는 재기입하는 작업이 주 작업이 되어왔다.
컴퓨터를 이용한 소프트웨어 엔지니어링(CASE)분야는 컴파일러 기술에 크게 좌우된다. CASE도구 및 프로그래밍 환경은 코어 컴파일러(core compiler)상에 구성된다. 아울러, 컴퓨터 하드웨어의 성능 명세서는 보통 컴파일러 기술과 종합적으로 관련된다. 프로세서의 속도는 통상 고급 언어 밴치마크(benchmark)로 측정되므로, 컴파일러의 최적화는 새로운 컴퓨터 장비의 가격 및 성능에 영향을 줄 수 있다.
각종 다른 고급 언어용 컴파일러 및 다른 타겟 컴퓨터 아키텍쳐의 구성을 용이하게 하기 위해서는, 컴퓨터 프레임 워크의 핵심 부품의 공통을 높이는 것이 바람직하다. 컴파일러의 전단은 소스 코드 모듈을 직접 액세스하므로 언어 특정성이 필요하며, 파스칼(Pascal)을 해석하도록 구성된 컴파일러 전단은 C를 해석하는데에는 이용되지 않을 것이다.
이와 마찬가지로, 컴파일러 후단의 코드 발생기는 타겟 컴퓨터 아키텍쳐의 명령 세트를 사용하여야 하므로 머신 특정성을 갖는다. 따라서, 보다 일반적으로 되기 쉬운 컴파일러의 중간부 구성요소가 된다. 컴파일러의 전단은 보통 소스 코드를 중간 언어로 번역하는 기능을 하므로, 원래 고급 소스 언어로 쓰여졌던 프로그램은 컴파일러의 내부 동작을 위해 보다 기초적인 언어로 나타나게 된다. 그 전단부는 보통 심볼 테이블(symbol table)과 함께 소위 그래프의 형태로 중간 언어로 프로그램 또는 루틴을 표시한다. 이들 두가지 데이타 구조, 중간 언어 그래프 및 심볼 테이블은 컴파일러에 의해 내부적으로 사용되는 프로그램의 표시이다. 따라서, 중간 언어를 만들고 범용 또는 일반 문자의 심볼 테이블을 구성함으로써 전단 다음의 구성요소들은 보다 일반적인 것이 될 수 있다.
컴파일러 전단이 중간 언어 그래프 및 심볼 테이블을 발생한 후, 보통 여러가지 최적화 기술이 실시된다. 타겟 머신의 실행 속도를 최적화 하기 위해 순서 그래프가 재배열 즉 프로그램이 다시 쓰여진다. 어떤 최적화는 타겟 특정성을 갖지만 대부분은 일반성을 갖는다. 통상 사용되는 최적화는 코드 모션(code motion), 스트랭스 저감(stength reduction) 등이다. 다음 컴파일러의 내부 조직은 메모리 및 레지스터 할당이다. 이 시점까지, 데이타 참조(data reference)는 어디에 기억되는가에 관계없이 변수 또는 정수로 명명되지만, 이제 데이타 참조는 특정 레지스터 및 메모리 변위 장소(어드레스를 아직 메모리 하지 않음)와 같은 보다 구체적인 위치에 할당된다. 이 시점에서, 더욱 최적화가 가능해지고 레지스터내의 데이타를 유지하도록 레지스터 할당의 형태로 메모리 참조가 최소화되므로, 프로그램이 레지스터 사용을 최적화하도록 다시 재배열 될 수 있다. 레지스터 할당은 또한 타겟 머신과 어느 정도 관계를 갖기 때문에 컴파일러의 일반적 성질을 타겟 CPU의 레지스터 세트에 대한 번호, 크기 및 특수 지정을 특정하는 것을 수용하여야만 한다. 레지스터 및 메모리 할당에 이어서 컴파일러는 목적 코드 이미지를 생성하는 코드 발생 단계를 실시하는데 이것은 물론 타겟 머신 언어 또는 명령 세트 즉 머신 특정성을 갖는다.
그다음, 목적 코드 이미지는 모두 머신 특정성을 갖는 다양한 런 타임 모듈(run-time module)을 추가하여 실행가능한 패키지를 생성하도록 링크된다.
전형적인 컴파일러 구성에서는, 중간 언어 그래프의 구조, 최적화, 레지스터 및 메모리 할당 단계가 보다 일반화되기 쉽다는 것을 알 수 있다. 그러나, 오늘날 가장 흔히 사용되는 고급 언어의 실질적인 차이 및 타겟 머신 아케텍쳐의 차이로 인해, 일반적인 컴파일러 코어의 구성을 장려하는데에 장애 요인이 되고 있다.
[발명의 개요]
본 발명의 한 실시예에 의하면, 일반적 "셀"(shell) 또는 제어 및 시퀸싱 메카니즘 및 일반적 후단(물론 코드 발생기는 타겟 특정성을 갖는다)을 사용하는 컴파일러 프레임 워크가 제공된다. 그 일반적 후단은 최적화, 레지스터와 메모리 할당 및 코드 발생 기능을 제공한다. 그 셀은 각종 호스트 컴퓨터에 대하여 실행될 수 있고, 후단의 코드 발생 기능은 다수의 컴퓨터 아케텍쳐를 위해 타겟으로 할 수 있다. 전단은 코볼(Cobol) 포트란(Fortran), 파스칼(Pascal), C, C++, Ada 등과 같은 각각의 다른 소스 언어에 대하여 설계된다.
그 전단은 소스 코드 모듈을 주사 및 분석하여 그로부터 코드로 표현된 프로그램의 중간 언어 표시를 발생한다. 이 중간 언어는 통상의 방식으로 소스코드 언어를 나타내도록 구성되므로, 전단과 후단 사이의 인터페이스는 표준 형식으로 이루어지고 각각의 언어 특정성을 갖는 전달을 위해 다시 쓰여질 필요가 없다.
전단에 의해 발생된 중간 언어 표시는 튜플(tuple)을 기본 단위로 사용하고 있는데, 각 튜플은 로드(load), 스토어(store), 애드(add), 라벨(label), 브렌치(branch) 등과 같은 수행될 단일 동작을 나타낸다. 데이타 구조는 각 튜플에 대한 전단에 의해 꾸며지고 각종 필요 정보에 대한 필드를 갖는다. 전단은 주문된 튜플 시리즈와 함게 통상의 실용화된 방식과 같이 변수, 루틴, 라벨등의 모든 참조에 대한 심볼 테이블을 발생한다. 그 튜플은 블록이 루틴 또는 라벨로 시작하여 브랜치로 끝나는 경우 예컨대 블록의 시작과 종료 사이에 입구와 출구가 허용되지 않는 경우 블록들내에 주문된 순서로 존재한다. 각 블록은 또한 데이타 구조 또는 노드이며 그것의 석세서(successor)프리디세서(predecessor)에 대한 포인터를 포함한다(이들은 심볼 테이블내의 심볼들에 속한다). 상호 연결된 블록들은 소위 중간 언어 그래프가 불리우는 플로우 그래프를 구성하는데 그 플로우 그래프는 최적화, 레지스터 및 메모리 할당등을 행하도록 후단에 의해 사용된 프로그램의 표시이다.
본 발명의 특징중 하나는 전단과 후단 사이의 인터페이스의 효과 및 종속성을 타나내기 위한 메카니즘에 있어, 튜플은 메모리에 쓰여지는 경우 효과를 가지며 어떤 다른 노드에 쓰여질 수 있는 위치로부터 읽혀지는 경우 종속성을 갖는다. 다양한 고급 언어는 동작을 표현하는 다른 방법을 가지며, 동일 시퀸스는 어떤 언어에서는 결과 또는 종속성을 허용할 수 있는 반면 다른 언어에서는 허용할 수 없다. 따라서, 소스 언어와 독립적인 메카니즘이 프로그램 실행 효과를 기입하기 위해 제공된다. 이 메카니즘은 컴파일러 전단으로 하여금 컴파일러 후단내의 다중 언어 옵티마이저(multi-language optimizer)에 대한 상세한 언어 특정성 정보를 발생케 하는 수단을 제공한다.
이 케카니즘은 공통 부표현 인식 및 코드 모션을 포함하여 적법하고 유효한 최적화를 결점하도록 전연 옵티마이저(global optimizer)에 의해 사용된다.
튜플들의 중간 언어 및 구조는 정보는 포함하므로 후단(옵티마이저들)은 전단의 질문을 요구할 수 있고(중간 언어 그래프로부터 정보를 얻음), 그것으로부터 후단은 한 튜플에 대한 타겟 머신을 위해 생성된 코드의 선행은 다른 튜플에 대한 코드에 의해 계산된 값에 영향을 줄 것이다. 후단과 전단 사이의 인터페이스는 이러한 점에서 언어 독립성을 갖는다. 후단은 어떤 언어가 번역되고 있는지 알 필요가 없다. 상이한 후단(및 셀)이 각 소스 언어에 대하여 쓰여질 필요가 없지만 그 대신 최적화 컴파일러가 단지 각각의 다른 언어에 대한 전단을 설계함으로써 각 소스 언어에 대하여 제작될 수 있는 잇점을 갖는다.
본 발명의 한 실시예의 다른 특징은 유도 변수를 분석하기 위한 방법을 컴파일러의 최적화 부에 사용한다는 점이다. 변수는 그것의 루우프(loop)를 통해 매 타임마다 한번 증분 및 감분되는 경우 유도 변수라 일컬어지며 루우프를 통해 각 타임마다 최대로 한번 실행된다. 이 최적화는 유도 변수를 찾는 것외에 유도변수의 선형 함수로서 계산될 수 있는 표현인 유도성 표현을 찾는다. 이 최적화의 목적은 일반적으로 승산을 가산을 바꾸는 것인데 그것은 대부분의 아키텍쳐에 있어서 저렴하고 실행 속도가 신속하기 때문에 스트랭스 저감으로 알려져 있다. 유도 변수의 검출은 잠재적 유도 변수 "세트"(sets)의 사용을 필요로 하며, 각 루우프에 대하여 이것을 동적으로 행하는 것은 고가이고 복잡한 동작이므로, 여기서의 개선점은 IDEF 세트를 구성하는데 사용된 측면 효과를 세트를 사용하는데 있다.
본 발명의 한 실시예의 다른 특징은 최적화부의 하나로서 포함된 "폴딩정수"(folding constants)(K 폴딩 또는 KFOLD 루틴으로 일컬어짐)에 대한 메카니즘이다. 이 메카니즘은 표현이 정수로 감소되어 런 타임시 많은 시간이 소요되는 계산이 아니라 번역 시간에서 계산될 수 있는 폴딩을 발생하기 위한 것이다. 중요한 특징은 KFOLD가 사용자에 의해 코드화되거나 계산되기 보다는 컴파일러 프레임 워크에 의해 구성된다. KFOLD 구성자는 다른 언어 특정성 전단처럼 전단으로서 기능을 하지만 소스 코드 입력이 필요없으며, 그대신 입력이 중간 언어로 되고 단지 모든 연산자 및 모든 데이타 형태의 리스트로 구성된다. 훨씬 더 많은 완전한 KFOLD 패키지가 훨씬 저 가격으로 발생될 수 있다.
본 발명의 한 실시예의 다른 특징은 TD 모듈이라 불리는 타입 정의 메카니즘이다. 이 모듈은 링커(linker) 또는 디버거(debugger)에 의해 사용될 수 있도록 목적 모듈에서 종합될 프로그램 "타입 정보"를 구성함에 있어 전단에 의해 사용된 메카니즘과 후단의 컴파일러를 제공한다. "타입 정보"의 발생은 심볼 테이블의 발생과 관련하여 생기며 전단으로 하여금 프로그램 타입 정보의 요약 표시를 후단에 특정할 수 있도록 한다. TD 모듈은 전단으로 하여금 기본 타입과 요약 타입을 기재할 수 있게 하는 서비스 루틴을 제공한다.
아울러, 한 실시예의 특징은 멀티패스(multipass)방식으로 코드 템플리트(templates)를 사용하여 코드발생을 행하는 방법이다. 코드 템플리트의 선택 및 적용은 번역 과정시 4개의 차등 시간에서 발생한다. 즉, (1) 패턴 선택 즉 PATSELECT단계는 가장 좋은 코드 템플리트를 선택하도록 CONTEXT패스에서 패턴 정합을 행한다 ; (2) CONTEXT 패스의 TANSSIGN 및 TNLIFE 작업은 표현에 대한 평가 순서를 분석하고 코드 템플리트에 비로컬한(nonlocal)수명을 갖는 일시적 명칭(TN)을 할당하도록 선택된 템플리트의 콘텍스트 액션(context action)을 사용한다 ; (3) TNBIND 패스는 코드 템플리트에 로컬한(local)수명을 갖는 TN을 할당하도록 선택된 템플리트의 바인딩 액션(binding action)을 사용한다 ; (4) 최종적으로, CODE 패스는 목적 코드의 발생을 안내하도록 선택된 템플리트의 코드 발생 액션을 사용한다.
[특정 실시예에 대한 상세한 설명]
제1도는 참조하면, 본 발명의 한 실시예에 따른 컴파일러 프레임워크(10)는 휴대 가능하고 목표 재설정 가능한 컴파일러의 생성을 위한 언어 독립성을 갖는 프레임워크이다. 컴파일러 프레임워크(10)는 셀(1)이라 불리우는 휴대 가능한 오퍼레이팅 시스템 인터페이스와 목표 재설정 가능한 옵티마이저 및 코드, 발생기(12)(후단)로 구성된다. 셀(11)은 호스트 컴퓨터를 실행하는 VAX/VMS, Unix 등과 같은 수종의 오퍼레이팅 시스템 어느것과도 기능을 행하기에 적합하다는 점에서 휴대 가능하다. 그 셀은 제2도에 도시한 바와같이 전형적으로 시스템 버스(16)에 의해 주 메모리(15)에 결합됨과 동시에I/O 제어기(18)에 의해 디스크 기억장치(17)에 결합되는 CPU(14)를 포함하는 호스트 계산 시스템을 실행하는 이 호스트 오퍼레이팅 시스템(13)에 의해 동작한다.
셀(11) 및 컴파일러(12)는 특정 소스 언어에 대한 휴대 가능하고 목표 재설정 가능한 컴파일러를 생성한도록 전단(20)과 결합될 수 있다. 따라서, 본 발명의 프레임워크(10)를 기본으로 사용하는 컴파일러는 세개의 기본 요소, 즉 특정 호스트 오퍼레이팅 시스템(14)를 위해 설계되었던 셀(11)-이것은 컴파일러의 호스트 환경을 결정한다-, 특정 소스 언어(예, C, C++, 파스칼, Ada, 코볼등)를 위한 전단(20)-이것은 컴파일러의 소스 언어를 결정한다- 그리고 특정 타켓 머신을 위한 후단(12)(즉 VAX, RISC 등과 같은 특정 아키텍쳐)-이것은 컴파일러의 타켓 머신을 결정한다-로 구성된다.
셀(11), 전단(20) 및 후단(12) 사이의 인터페이스가 고정되기 때문에, 본 발명에 따라 제작된 컴파일러의 개별 부품들은 자유롭게 교체될 수 있다. 즉, 전단(20)은 다수의 호환성을 갖는 전단, 예컨대 포트란을 위한것, 코볼을 위한것, 파스칼을 위한것, C를 위한 것등으로 구성된다. 이와 마찬가지로, VAX컴퓨터상의 VMS하에서 동작하도록 설계된 셀(11)은 RISC워크스테이션상의 Unix 오퍼레이팅 시스템하에서 동작하는 셀(11)로 교체될 수 있는 반면 전단(20)과 후단(12)은 동일하게 유지될 수 있다.
셀(11)은 호스트 오퍼레이팅 시스템(13)과 컴파일러의 나머지 사이에 고정된 인터페이스를 제공한다. 첫째, 셀(11)은 오퍼레이팅 시스템(13)의 기본 구성에 휴대가능한 인터페이스를 제공한다. 예를들어, 전단(20)은 파일 시스템의 세부, 호스트 오퍼레이팅 시스템(13)에 의한 명령 파싱(command parsing) 또는 힙(heap) 저장 할당에 대해 알 필요가 없는데, 그 이유는 모든 이들 서비스가 셀루틴을 통해 액세스되고 그 셀이 사용중인 오퍼레이팅 시스템(13)에 대하여 설계되기 때문이다. 둘째, 셀(11)은 명령 라인 파싱, 인클루드 파일처리(Include-file prooessing) 및 전단 파일 발생과 같은 어떤 공통의 컴파일러 구성요소의 단일 구성을 제공함으로써 노력의 중복을 없애준다. 셋째, 이들 공통의 구성요소를 사용하는 것은 프레임 워크(10)를 사용하여 생성된 컴파일러들간에 일치성을 보장해준다. 즉, 프레임워크(10)를 사용하여 생성된 모든 컴파일러는 동일한 포맷으로 파일 리스트를 작성하고 명령 라인 한정사(command line qualifier)를 동일하게 처리하여 유사한 모습의 에러 메세지를 발송한다. 넷째, 셀(11)에 공통 셀 유틸리티를 갖는 것은 컴파일러의 내부적 통합을 개선시켜 주는데 그 이유는 전단(20) 및 후단(12)이 동일한 기능의 셀을 사용하기 때문이다. 예를들어, 셀 로케이터(shell locator)패키지의 사용은 소스 파일 위치가 소스 리스팅, 전단 발생 진단, 목적 리스팅 및 디버거 정보에서 일관성있게 불리울 수 있음을 의미한다.
전단(20)은 번역중이 소스 언어를 이해하는 프레임 워크(10)에 의해 생성된 컴파일러의 유일한 구성요소이다. 이 소스 언어는 컴파일러의 입력을 정의하는 소스 코드 파일 또는 파일들(모듈 또는 모듈들)(21)의 텍스트를 발생하는데 사용되는 것이다. 전단(20)은 다수의 기능을 수행한다. 첫째, 그것은 소스 파일(21)로 부터 명령 라인 정보 및 텍스트 라인을 얻도록 셀(11)을 호출한다.
둘째, 전단(20)은 리스팅 파일을 제어하고 진단 메세지를 기입하여 가능한한 특정 언어에 대한 다른 파일을 작성하도록 셀(11)을 호출한다. 셋째, 전단(20)은 전단(20)과 후단(12)사이의 인터페이스(22)에 대해 사용된 언어 독립성을 갖는 내부적 표시로 파일(21)내의 소스 텍스트를 변환시키기 위해 어휘, 구문 및 어의 분석을 행한다. 넷째, 전단(20)은 내부적 표시의 정보로부터 타겟 시스템 목적 코드(23)를 발생하도록 후단(12)를 호출한다. 다섯째, 전단(20)은 후단 처리시 언어 특정성을 갖는 정보를 얻기 위해 후단(12)이 호출 통로(24)를 통해 호출하도록 루틴을 제공한다. 제1도의 컴파일러 프레임워크에는 실행 가능한 이미지를 형성하여 타겟 머신(25)을 동작시키도록 목적 코드모듈 또는 이미지(23)를 연결하는 링커가 포함되지 않는다.
컴파일러의 후단(12)으로 하여금 코드를 생성케 하는 타겟 머신(25)은 어떤 특정 아키덱쳐의 컴퓨터이다. 즉, 그것은 어떤 특정 번호 및 데이타 폭을 갖는 레지스터 세트를 구비하고, 그 로직은 특정 명령 세트를 실행하며, 특정 어드레싱 모드가 이용될 수 있다. 그 예로는 (1) VAX 아키텍쳐, (2) MIPS, Inc. 사로부터 입수 가능한 32비트 RISC칩(부품번호 R2000 또는 R3000)을 기본 구성으로 하고 Lane 씨에 의해 "MIPS R2000 RISC Architecture", Printice-Hall, 1987에 기고된 바와 같은 아키텍쳐를 갖는 RISC타입, 및 (3) 1990. 6.29자로 출원된 계류중인 미국 특허원 제547,589호에 기재된 바와 같은 64비트 레지스터를 갖는 개량된 RISC 아키텍쳐를 들 수 있다. 마찬가지로 각종 다른 아키텍쳐도 가능하다.
일반적으로, 전단(20)은 그것이 소스 코드(15)로부터 인터페이스(22)의 내부적 표시로 변환중일때 목적 코드(23)를 실행하는 타겟 머신(25)의 아케텍쳐를 고려할 필요가 없는데 그 이유는 그 내부적 표시가 타겟 머신(25)의 아키텍쳐와 무관하기 때문이다. 그러나, 전단(20)의 어떤 특징은 타겟 시스템으로 설계될 필요가 있다. 예컨대, 할당 및 정렬과 같은 데이타 표시의 양태는 타겟 머신(25) 아키텍쳐를 더 잘 부합되도록 주문 설계될 수 있고 루틴 호출 인자 메카니즘은 타겟 시스템 호출 표준 방식에 좌우될 수 있다. 그리고 런 타임 라이브러리 인터페이스는 아마도 각 타겟 시스템마다 다르게 될 것이다.
후단(12)은 전단(20)에 의해 구성된 내부적 표시(22)를 타겟 시스템 목적 코드(23)로 번역하는 기능을 한다. 후단(12)은 최적화(26), 코드 발생(27), 기억 및 레지스터 할당(28) 및 목적 파일 방출(29)의 기본 기능을 수행한다. 최적화 기능은 내부적 표시에 있을때의 코드에 대하여 수행된다. 후단(12)은 또한 심볼 테이블(30) 및 중간 언어 데이타 구조를 생성하도록 전단(20)에 의해 호출되는 유틸리티 루틴을 포함한다.
사용자(즉, 컴퓨터 시스템이 오퍼레이팅 시스템(13)를 실행중인 경우 제2도의 컴퓨터 시스템의 사용자)가 제1도의 컴파일러를 불러낼때, 셀(11)은 제어 신호를 수신한다. 셀(11)은 전단(20)을 호출하여 소스 파일(15)로부터 입력 스트림(input stream)을 목적 파일(23)로 번역한다. 전단(20)은 후단(12)를 호출하여 목적 파일(23)내의 각 개별 루틴용 코드를 하거나, 혹은 전체 모듈용 코드를 한번에 발생할 후단 구동기를 호출할 수도 있다.
전단(20)은 소스 코드(21)를 분석하여 소스 코드로 표현된 프로그램의 중간 언어 버전을 발생한다. 중간 언어의 기본 구조는 튜플이다. 튜플은 소스언어로 한 동작을 수행하는 표현이다. 예컨데, 제3도를 참조하면, 소스 언어로 나타낸 바와 같은 표현식
I=J+1
은 중간 언어로 표시하기 위한 4개의 튜플로 분할되는데, 이것은 $1, $2, $3, $4의 번호가 매겨진다. 이와 같이 코드를 IL로 표현하는 방법은 아이템(31)로 표시된 페치(fatch)인 제1튜플 $1을 포함하는데 그 페치의 목적은 심볼 J이다. 다음 튜플은 역시 심볼"1"을 참조하는 아이템(32)의 리터럴(literal)이다. 그다음 튜플은 튜플 $1 및 s2의 결과를 참조하는 아이템(33)의 애드(Add)이다. 마지막 튜플은 튜플 $3의 결과를 참조하여 심볼 테이블에 심볼 I의 결과를 두는 아이템(34)의 스토어(store)이다. 그 표현은 또한 제3도에 도시한 바와 같은 논리 트리로서 표현될 수 있으며, 여기서 튜플은 동일 참조 번호로 식별된다. 이 소스 코드의 동일 라인은 레지스터 파일내의 REG4와 같은 어떤 레지스터를 사용하여 세개의 명령 LOAD, ADD정수 및 STORE 처럼 제3도에 도시된 일반적인 형태로 RISC 타입 타겟 머신용 어셈블리로서 표현될 수 있다.
혹은, CISC 머신의 경우 방출된 코드가 단지 도면에 도시한 바와 같은 단일 명령 ADD#1, J.I일 수도 있다.
이어서 튜플은 컴퓨터 프로그램의 기본 표현이 되며, 본 발명에 사용된 형태에서는 적어도 (1) 연산자 및 타입 필드(36), 예컨대 페치, 스토어, 애드 등, (2) 소스 모듈(21)내에서 튜플에 해당하는 소스가 위치하는 장소를 정의하기 위한 로케이터(locator)(37), (3) 제3도에서의 I 및 #1과 튜플 $1 및 $2에 대한 포인터와 같은 다른 튜플, 리터럴 노드 또는 심볼 노드에 대한 피연산자 포인터(operand pointer)(38)를 포함하는 제4도에 표시된 요소들을 내장하는 데이타 구조(35)이다. 튜플은 또한 예컨대 라벨, 조건부 브랜치, 인수(호출용) 또는 SymRef (심볼 테이블내의 심볼)을 포함할 수도 있는 속성 필드(39)를 갖는다. 그 튜플은 이 튜플의 순서를 블록으로 나타낸 번호 필드(40)를 갖는다.
전단(20)은 소스 코드를 분석하여 튜플을 식별한 다음 코드의 기본 블록을 식별한다. 코드 블록은 최초 및 최종 튜플 사이에 입구 또는 출구를 갖는 않는 일련의 튜플로서 정의된다. 통상적으로, 블록은 라벨 또는 루틴 입구에서 시작하여 다른 라벨의 브랜치에서 끝난다. 전단(20)의 작업은 소스 코드(21)를 분석하여 튜플 및 블록을 식별하는 일인데 그것은 물론 전단이 언어 특정상을 갖게 하는 것을 필요로 한다. 따라서, 그 튜플은 이 튜플이 블록의 시작인지 블록의 끝인지의 여부를 알려주는 필드(41)를 포함한다.
이하 상세히 논의된 바와 같이, 본 발명의 한 특징은 결과(effect)를 표시하는 방법이다. 튜플은 기억 장소(심볼로서 IL 레벨로 표시됨)에 기억 또는 기입하는 경우 결과를 갖거나 혹은 다른 튜플이 기억 장소에 기입되느냐의 여부에 관계된다. 따라서, 제3도의 실시예에서는, 튜플 $4가 결과(I에 기억)를 가지며 튜플 $1은 종속성(J의 내용)을 갖는다. 따라서, 제4도에 표시된 튜플 데이타 구조는 이 튜플의 결과 및 종속성을 기억하도록 필드(42,43)를 갖는다.
제1도의 컴파일러의 한번의 실행은 제5도의 순서도에 예시한 바와 같이 셀(11)에 의해 구동된다. 제5도에서 부호(45)로 표시한 것처럼, 셀(11)은 제1도의 컴파일러가 오퍼레이팅 시스템(13)을 통해 사용자에의해 호출될때 제어명령을 수신한다. 명령 라인내의 사용자는 동작되어질 모듈(21)의 "플러스리스트"(plus-list) 또는 리스트를 특정한다. 다음 단계는 부호(46)으로 표시된 전단에 대한 어떤 필요한 초기화를 행하는 전단 루틴 GEM $ XXD_INIT의 셀(11)에 의해 호출되는 것이다. 이 전단 루틴 GEM $ SS_INIT는 부록에 기재된다.
다음, 셀(11)은 전역 명령 한정사(global command qualifiers)를 분석하여 부호(47)로 표시한 바와 같이 전단 루틴 GEM $ XX_PROCESS_GLOBALS를 호출한다.
이어서, 컴파일러를 호출하도록 오퍼레이팅 시스템(13)레벨에서 사용된 명령 라인의 각 "플러스 리스트"(콤마-분리형 엔티티(comma-separated entity)에 대하여, 셀은 일련의 액션을 실행하며, 이것은 플러스 리스트를 검사하도록 판별지점(48)을 사용하는 루우프에 의해 실현된다. 플러스 리스트에 남겨진 항목이 있는 한, 부호(49-52)로 나타낸 액션이 실행된다. 이 액션들은 명령 라인에서 특정된 소스 파일(21)을 액세스 하여 그들을 위한 입력 스트림을 생성하는 것(부호 (49)로 나타냄)과, 이어서 로컬 한정사(local qualifier) (그 플러스 리스트에 특정)을 분석하여 그들에 대한 전단 결정 처리를 행하도록 GEM $ XX PROCESS_LOCALS를 호출한 다음 한정사에 의해 특정된 출력 파일을 여는 것(부호(50)으로 나타냄)을 포함한다. 그 루우프내의 액션은 입력 스트림을 번역하도록 전단 루틴 GEM $ XX_COMPILE을 호출하는 것(부호(51)로 나타냄)과, 이어서 출력 파일을 닫는 것(부호 (52)로 나타냄)을 포함한다. 루우프가 실현되지 않아 모든 플러스 리스트 항목이 처리되었음을 나타낼 경우, 다음 단계는 전단 클린업(front-end clean up)을 행하도록 전단 루틴 GEM $ XX_FINI를 호출하는 것(부호 (53)으로 표시)이다. 이어서, 실행이 종료되고 제어 명령을 호출기(invoker)로 복귀시킨다(부호 (54)로 표시).
셀(11)은 단일 입력 스트림을 번역하도록 GEM $ XX_COMPILE을 호출한다. 입력 스트림은 컴파일러 명령 라인내의 단일 "플러스 리스트"에서 특정된 소스 파일 또는 모듈(21) 뿐만 아니라 어떤 내장 파일 또는 라이브러리 텍스트(library text)의 연결(concatenation)을 나타낸다. 기정(default : 기정)에 의해, 입력 스트림의 번역시 컴파일러가 전단(20)으로 하여금 다수의 목적 파일(23)을 특정하도록 하지만, 단일 입력 스트림을 번역하는 것은 단일 목적 파일(23)을 생성한다.
GEM $ XX_COMPILE을 호출하기 전에, 셀(11)은 입력 스트림을 생성하여 로컬 한정사를 분석하고, 출력 파일을 연다. GEM $ XX_COMPILE을 호출한 후, 셀(11)은 모든 입력 및 출력 파일을 닫는다.
전단(20) (GEM $ XX_COMPILE 및 그것으로부터 호출되는 전단 루틴)은 입력스트림으로부터 소스 레코드(21)를 읽어내서 인터페이스(22)의 중간 표시(중간 언어 그래프의 튜플, 블록 등 및 심볼 테이블을 포함)로 변환하고 후단(12)을 호출하여 그 중간 표시를 목적 파일(23)내의 목적 코드로 변환한다.
목적 파일(23)은 다수의 목적 모듈을 포함할 수도 있다. 파스칼은 전체 입력 스트림용의 단일 목적 모듈(MODULE 또는 PROGRAM)를 생성한다. 포트란(한 실시예에서)은 입력 스트림내의 각 END문용이 별도의 목적 모듈을 생성한다. BLISS는 각 MODULE용의 목적 모듈을 생성한다.
목적 파일(23)을 생성하기 위해, 전단(20)은 입력 스트림 또는 그것의 어떤 시퀸스(소스 모듈(21)이라고 도할 수 있음)를 인터페이스(22)에 대한 내부적 표시로 변환하는데, 그 내부적 표시는 모듈에 대한 심볼 테이블(30) 및 각 루틴에 대한 중간 언어 그래프(55)로 구성된다. 이어서 전단(20)은 후단 루틴을 다시 호출하여 목적 모듈(23)을 초기화하고, 기억 할당(28)을 통해 심볼 테이블(30)내의 심볼에 대한 기억부를 할당하고, 그 기억부를 초기화 하고, 에미터(29)를 통해 루틴용 코드를 발생하고, 목적 모듈(23)은 완성한다.
컴파일러는 패키지의 집합으로 구성되는데, 각 패키지는 번역 과정의 어떤 단계되는 루틴 또는 데이타 구조의 집합을 정의한다. 각 패키지는 일반적으로 패키지 기능의 약어인 2문자 코드로 식별되다. 패키지에 대한 인터페이스는 명세 파일에 의해 정의된다. 패키지가 ZZ로 명명되면, 그것의 명세 파일은 GEM$ Z.SDL이 될 것이다.
패키지 명세 파일에서 선언된 어떤 심볼은 그 패키지로부터 방출되는 것으로 일컬어진다. 일반적으로, 패키지 ZZ로부터 방출된 심볼은 GEM $ ZZ_로서 시작되는 명칭을 가진다. 전역 및 방출 명칭에 대한 특정 표제 규약은 테이블 1에 기재되어 있다.
셀(11)은 통상의 컴파일러 동작을 보조하는 루틴의 집합이다. 셀의 구성 요소는 상호 연관 관계를 가지므로, 어떤 셀 구성 요소를 사용하는 프로그램은 전체 셀을 얻는다. 그러나, 프로그램이 후단(12)을 사용치 않고 셀(11)을 사용하는 것도 가능하다. 이것은 생산-한정 특성(producton-quality features)(입자 파일 연결 및 포함, 명령 라인 분석, 진단 파일 발생, 양호한 리스팅 파일 등)을 갖는 소규모 유틸리티 프로그램을 작성하는 편리한 방법이다. 셀(11)은 실제로 사용하는 어떤 프로그램의 "주 프로그램"이며, 응용 프로그램의 주요부는 후술될 규약을 사용하여 셀(11)로부터 호출되어야 한다. BLISS 프로그램으로부터 셀 패키지 ZZ를 사용하기 위해서는, 사용자가 LIBRARY'GEM$ZZ'를 행한다. 다른 언어로부터 셀을 사용하기 위해서는, 사용자가 먼저 셀 명세 파일을 구현 언어(implementation lauguage)로 변환하여야 한다.
셀 패키지는 다음의 구문으로 요약된다. 즉, 그들은 부록내의 명세 파일(GEM $ ZZ.SDL 파일)에서 제공된다. 대부분의 셀 루틴 인수(예, 정수, 문자 열 등)는 테이블2에 기재된 카테고리중 하나에 속한다.
셀(11)에서 전단(20)에 대한 인터페이스는 어떤 필요한 조건을 갖는다. 셀(11)은 제1도의 컴파일러가 호출될때 제어 명령을 수신하기 때문에, 전단(2)은 입력 지점을 선언하여 셀(11)이 그것을 호출하여 셀(11)로 전단 특정 정보를 통과시키도록 전역 변수를 선언하여야 한다. 전단(20)은 한 실시예에서 테이블 3에 기재된 전역 루틴을 제공한다. 이 루틴을 파라미터를 갖지 않고 또 결과없이 복귀한다.
가상 메모리 패키지(GEM $ VM) : 가상 메모리 패키지는 가상 메모리를 할당하기 위한 표준 인터페이스를 제공한다. 그것은 VMS LIB $ VN의 존 메모리 개념을 지원하며, 사실상 VMS하에서 GEM$VM은 LIB $ VM 위의 거의 투명성의 층(transparent layer)이다. 그러나, GEM $ vm 인터페이스는 호스트 컴퓨터상에서 변화되지 않은채 지원되도록 보장 받는다.
로케이터 패키지(GEM $ LO) : 로케이터 소스 텍스트(21)의 범위(파일, 라인 및 열 번호의 시작 및 끝)를 기재한다. 렉스트 입력 패키지는 그것이 읽어낸 소스 라인을 위해 로케이터를 복귀시킨다. 로케이터는 또한 메세지 및 디버거 테이블 발생을 용이하게 하도록 심볼 테이블(30)중간 언어 노드(43)에서 사용되고 또 리스팅 파일내의 어디에서 리스팅 패키지가 액션을 수행하는가를 특정하기 위해 사용된다. 로케이터를 긴 워드로소 표시된다. 로케이터 패키지는 로케이터 데이타 베이스를 유지하고, 로케이터를 생성 및 인터럽트시키는 루틴을 제공한다. 사용자 생성 로케이터를 위한 설비가 존재하는데, 그것은 전단으로 하여금 비표준 소스로부터 들어오는 프로그램 요소(예컨데, BLISS 매크로 또는 Ada 일반 개시)를 기재하도록 독자적인 로케이터를 생성하도록 한다.
텍스트 입력 패키지(GEM $ TI) : 텍스트 입력 패키지는 연결 소스 파일(21), 내장 소스파일(21), 기정 및 관련 파일 명세를 지원하는 반면, 배후의 오퍼레이팅 시스템(13)의 I/O 아키텍쳐로부터 전단(20)을 격리시킨다. 소스파일(21)의 텍스트는 한번에 한라인씩 판독된다. 텍스트 입력 패키지 GEM $ $ TI는 그것이 읽어내는 각 소스 라인을 기재하여 로케이터를 생성하도록 로케이터 패키지 GEM $ LO와 협동한다.
텍스트 출력 패키지(GEM $ TX) : 텍스트 출력 패키지는 일정한 수의 출력 파일(44)로의 출력을 동시에 지원하다. 텍스트 입력 패키지 처럼, 그것은 오퍼페이팅 시스템(13)으로부터 그것의 호출자를 격리시킨다. 이 패키지는 참조 또는 디스크립터(descriptor)에 의해 통과된 문자열을 기입할 것이다.
이 패키지는 자동 라인 랩핑(wrapping) 및 인덴테이션(Indentation : 들여쓰기), 페이지 랩핑, 사용자 제공 페이지의 시작(user-provided start-of-page)루틴으로의 역호출을 제공한다.
리스팅 패키지(GEM $ LS) : 리스팅 패키지는 소스 파일(21)의 사본을 포함하는 표준 포맷 리스팅 파일(텍스트 입력 패키지 GEM $ TI에 의해 읽혀짐)을 로케이터로써 특정된 위치에 전단(11)에 의해 제공된 주석(annotation)과 함께 기입할 것이다. 리스팅 파일은 GEM $ TX 출력 파일(44)로서 생성되며, 전단(20)은 GEM $ TX 출력 루틴을 사용하여 직접 그것에 기입할 수도 있다.
[내부적 표시]
모듈(21)의 내부적 표시는 소스 모듈(21)내의 각 루틴에 대하여 모듈용 심볼 테이블(30) 및 간결한 중간 언어 그래프(55) 또는 CILG를 포함한다. 이들은 모두 노드로 구성된 포인터 연결형 데이타 구조이다.
제1도의 프레임 워크의 노드들을 정의하겠다. 전단(20)과 후단(12) 사이의 인터페이스에 사용된 모든 데이타 구조(및 후단(12)에 의해 전용으로 사용되는 대부분의 데이타 구조)는 노드들이다. 여기서 사용된 노드란 용어는 일반적으로 GEM $ GET와 함께 힙(heap)으로부터 할당된 기억장치의 자체 식별용 블록이다. 모든 노드들은 필드 GEM $ NOD KIND 및 GEM $ NOD SUBKIND를 갖는 집합형 GEM $ VM_NODE를 가진다. 카인드(kind)는 노드의 일반적 종류를 식별하는 열거형 GEM $ NODE_KINDS로부터의 값이다. 서브 카인드(Subkind)는 카인드에 의해 일반적 유형의 노드들중에서 특정 카인드의 노드를 식별하는 열거형 GEM $ NODE_SUBKIND로부터의 값이다. 어떤 특정 노드는 또한 그것의 카인드 필드에 의해 결정된 집합 형을 갖는다. 예를들어, 카인드가 GEM $ NODE_K_SYMBOL이라면, 노드는 GEM $ SYNBOL_NODE를 갖는다. 노드들과 관련된 타입은 상술한 명칭 규약을 위반하지 않는다. 인터페이스 노드 타입 및 그 관련 열거형 정수는 테이블 4에 기재된다.
제1도의 컴파일러 프레임 워크는 간단한 트리 구조의 실볼 테이블(30)을 지원하여, 여기서 심볼 노드들은 트리에서 배열된 블록 노드들의 체인에 함께 링크된다. 컴파일러에 의해 사용된 모든 심볼 정도는 이 심볼 테이블(30)에 포함되어야 한다. 또한 번역된 프로그램 리터럴 값을 표시하는 리터럴 노드, 변수가 할당되어질 기억 영역(PSECT 및 스택 프레임)을 나타내는 프레임 노드, 루틴 입력 지점의 파라미터 리스트내의 요소를 나타내는 파라미터 노드가 존재한다. 심볼 테이블 구조 및 심볼 테이블 노드의 내용은 이하에서 설명될 것이다.
중간 언어는 소스 코드(21)의 모든 내부적 표시를 위해 사용되는 언어이다. 전단(20)은 간결한 중간 언어 그래프(55) 또는 CILG로서 번역된 루틴의 코드를 기재한다. 이것은 단지 제4도의 CIL 튜플 노드(35) (또한 튜플 노드 또는 튜플로서 일컬어짐)의 연결 리스트인바 그 리스트는 각각 어떤 동작을 나타내며 그것의 피연산자를 표시하는 튜플 노드에 대한 포인터(38)를 갖는다. 튜플노드는 심볼 테이블 노드에 대한 포인터(38)를 포함할 수도 있다. 중간 언어는 이하에서 보다 상세히 설명된다.
전단(20)은 한번에 한 노드씩 모듈(21)의 내부적 표시(22)를 생성하여 노드들은 심볼 테이블 및 IL데이타 구조(55)에 연결한다. 테이블 5의 루틴 및 매크로(부록에)기재됨)는 내부적 표시(22)의 데이타 구조를 생성 및 조정한다.
후단(22)은 전단(20)이 어떻게 블록명 및 심볼명을 표시하는지에 대한 가정을 하지 않는다. 그대신, 전단(20)은 후단(12)이 이들의 명칭을 얻는데 사용할 수 있도록 표준 역할 인터페이스를 제공하는 것이 필요하다.
모든 심볼 노드는 플래그 GEM $ SYM_HAS_NAME을 가지며 모든 블록 노드는 플래그 GEM $ BLKHAS_NAME을 갖는다. 전단(20)이 심볼 또는 블록 노드를 초기화 할때, 전단(20)은 명칭 문자열이 이용 가능한지의 여부를 나타내도록 명칭 플래그를 세트하여야 한다(전역 및 외부 심볼, 톱레벨 모듈과 같은 어떤 심볼 및 블록은 명칭을 가져야 한다).
ST패키지에는 전역 변수 GEM $ ST_G_GET_NAME가 존재한다. 후단을 호출하기 전에, 전단은 이 변수를 테이블 5에 기재된 설명에 부합되는 역호출 로우틴의 어드레스에 세트하여야 한다.
GEM $ CO_COMPILE_MODULE 인터페이스를 사용하여 소스 모듈을 번역하기 위해서, 전단(즉 루틴 GEM $ XX_COMPILE)은 다음에서 설명된 각 동작을 행한다.
1. 내부적 표시 생성
전단(20)의 제1작업은 소스 모듈의 내부적 표시(22)를 생성하는 것이다. 먼저, 샘볼 테이블(30) 및 관련 가상 메모리 존을 초기 설정하도록 GEM $ ST_INIT를 호출하여야 한다. 이어서 GEM $ T1 패키지를 사용하여 입력 스트림으로부터 소스 모듈(21)을 읽어내고 ; 소스 모듈(21)의 어휘, 구문 및 어의 분석을 행하고 ; 부록에 기재된 GEM $ ST 및 GEM $ IL 루틴을 사용하여 상술한 모듈에 대한 심볼 테이블(30) 및 중간 언어 그래프(55)를 발생한다.
아울러, 모듈의 소스 리스트는 GEM $ LS 셀 패키지에 대한 호출로써 주석이 붙여질 수도 있고, 모듈내에서의 에러는 GEM $ MS 패키지에 대한 호출로써 보고될 수도 있다.
소스 모듈(21)이 코드 발생을 막기에 충분한 심각한 에러를 포함한다면, 전단(20)은 이제 GEM $ LS WRITE_SOURCE를 호출하여 내부적 표시(22)를 위해 할당된 모든 스페이스를 배포하도록 리스팅 파일 및 GEM $ ST_FINI를 작성하여야 한다. 그렇지 않다면 전단(2)은 다음의 단계로 진행해야 한다.
2. 역할 루틴의 특정
후단(12)을 호출하여 모듈(21)을 번역하기 전에, 전단(21)은 후단(12)에 의해 호출될 루틴의 어드레스와 함께 다음의 전역 변수를 초기 설정하여야 한다.
(1) GEM $ ST_G_GET_NAME은 상술한 바와 같이 심볼 테이블(30)내의 심볼 및 블록 노드의 명칭을 생성하게될 루틴의 어드레스로 초기 설정하여야 한다.
(2) GEM $ SE_G 전역 변수는 상술한 바와 같이 소스 언어로 정의된 부작용 분석을 행할 루틴의 어드레스로 초기 설정되어야 한다. 컴파일러는 전단(20)의 초기 개발시에 사용하기 적합한 부작용 루틴의 소정의 집합을 제공하는데 그것은 GEM $ SE_DEFAULT_INPLEMENTATION을 호출함으로써 선택될 수 있다.
(3) GEM $ ER_G_REPORT_ROUINTE은 상술한 바와 같이 후단 검출 에러를 보고하기 위한 전단의 루틴의 어드레스를 포함한다.
3. 번역의 수행
내부적 표시가 완성될때, 전단(20)은 GEM $ SO_COMPILE_MODULE (이하에서 설명)을 호출하여 그것을 타겟 머신 목적 표시(23)로 변환시킨다. 이어서 전단은 GEM $ LS_WRITE_SOURCE를 호출하여 리스팅 파일에 입력 스트림을 리스트한다. 또한 GEM $ LM_LIST_MACHINE_CODE를 호출하여 번역 모듈(23)의 어셈블리 코드 리스팅을 생성한다.
정상적으로 GEM $ LS_WRITE_SOURCE는 GEM $ CO_COMPLIE_MODULE 후에 호출되어야 하므로 소스 리팅(21)은 후단 처리시 발생된 어떤 에러 메세지로써 주석이 붙여질 수 있다. 그러나, 전단(20)은 먼저 GEM $ LS_WRITE_SOURCE가 호출되게할 디버깅 스위치를 제공하는 것이 좋은 아이디어이다. 이것은 버그(bug)가 후단 처리시 컴파일러로 하여금 동작 중지시키더라도 소스 리스팅을 얻을 수 있게 한다.
4. 클린 업(Clean Up)
번역이 완료될대, 전단(20)은 GEM $ CO_COMPLETE_MODULE을 호출하여 후단 처리 동안 사용된 스페이스를 해제하여야 하고 이어서 GEM $ ST_FINI를 호출하여 내부적 표시를 위해 사용된 스페이스를 해제하여야 한다.
후단(12)은 초기 설정되지 않은 변수, 도달될 수 없는 코드 또는 정적 기억장치 초기화의 충돌과 같은 사용자에게 보고되어야 하는 소스 프로그램(21)의 조건을 표시하게 되는 번역시 조건을 검출할 수 있다. 그러나, 특정 전단(20)은 이들 조건중 어떤 것이 보고될 것인지의 여부, 또는 반송된 정확한 메세지를 주문하는 것이 필요할 수도 있다.
이를 위해, 후단(20)은 그것이 어드레스가 전역 변수로 된 루틴 GEM34_G_REPORT_ROUTINE을 후술될 인수 리스트와 함께 검출하는 모든 비정상 조건을 보고한다. 이 루틴은 실제로 에러 메세지를 발송하는 역할을 한다.
GEM $ ER_REPORT_ROUTINE이라 명명된 부록에 기재된 기정 에러 보고용 루틴이 존재하는데 그것의 어드레스는 전단이 거기에 독자저긴 보고 루틴의 어드레스를 저장하지 않는한 GEM $ ER_G_REPORT ROUTINE으로 될 것이다. 이 기정 루틴 다음의 세가지 사용 상태를 갖는다.
(1) 기정 루틴은 올바른 메세지를 제공하므로, 전단 개발기(front end developer)는 그들이 독자적인 루틴을 주문할 필요가 없는 한 그것을 제공하지 않아도 된다.
(2) 전단 개발기가 보고 루틴을 기입하는 것을 선택할때, 그것은 기정 루틴을 하나의 모델로서 사용한다.
(3) 전단의 루틴은 어떤 에러 자체를 처리(또는 무시)하고 또 기정 루틴은 모든 루틴과 함께 호출하는 필터로써 기입될 수 있다. 결과를 표시하기 위한 인터레이스 공통 부표현(CSE), 불변표현, 코드 액션을 위한 기회를 검출하는데 있어 필수적인 단계처럼, 후단(12)내의 옵티마이저(26)는 두개의 표현 듀플의 동일값을 계산하도록 보장 받을 시기를 결정할 수 있어야 한다. 기본적 기준은 다음과 같은 경우 표현 B가 동일 값을 표현 A로서 계산한다는 것이다.
1. A와 B가 동일 값을 갖는 리터럴에 대한 리터럴 참조, 동일 CSE에 대한 CSE참조, 또는 동일 심볼에 대한 심볼 참조인 경우 ; 혹은
2. a. A가 루틴의 시작으로부터 B로의 모든 제어흐름 경로상에서 평가되는 경우와,
b. A와 B가 동일 연산자 및 데이타 타입을 갖는 경우와,
c. B의 피연산자가 동일 값을 A의 대응 피연산자(명백히 순환적 정의)로서 계산하는 경우와.
d. A의 평가부터 B의 평가까지 어떤 경로상에서 발생하는 어떠한 튜플도 B에 의해 계산된 값에 영향 주지 않는 경우.
제1도의 옵티마이저(26)는 기준 1,2a, 2b 및 2c를 자체로서 유효화시킬 수 있어야 하지만, 기준 2d는 번역중인 언어 즉 소스 모듈(21)의 언어의 어의에 관계된다. 그러나, 후단내의 컴파일러(2)는 언어 독립성을 가져야 하기 때문에, 필요한 정보를 제공하도록 전단(20)에 일반적 인터페이스가 제공된다. 한 튜플의 실행이 다른 튜플에 의해 계산된 값에 영향을 줄 수 있는 시기는 언제인가? 인터페이스(22)는 옵티마이저(26)로 하여금 이러한 질문을 할 수 있도록 하여야 하며, 컴파일러 전단(20)으로 하여금 그것에 답할 수 있도록 하여야 한다.
이 인터페이스(22) 배후의 모델은 어떤 튜플이 결과를 가지고 다른 튜플은 종속성을 갖도록 하는 것이다. 튜플이 하나이상의 기억 장소의 내용을 변경시키는 경우 튜플은 결과를 갖는다. 튜플에 의해 계산된 값이 기억장소의 내용에 관계되는 경우 튜플은 기억장소에 대한 종속성을 갖는다. 따라서, 한 튜플의 실행은 다른 튜플이 관계되는 기억 장소를 수정하는 결과를 갖는 경우 다른 튜플에 의해 계산된 값에 영향을 줄 수 있다.
어드레스 연산 및 간접 어드레싱의 결과가 주어지면, 일반적으로 튜플에 의해 액세스된 특정 기억 장소를 결정하는 것이 불가능하다.
실제의 인터페이스(22)는 옵티마이저(26)에 두가지 메카니즘을 제공한다. 이들은 직선 종속성 인터페이스 및 결과 분류 인터페이스이다.
직선 종속성 인터페이스에서는, 종속성을 직선 코드로 판별하기 위해 옵티마이저(26)가 전단(20)으로 하여금(1) 결과 스택상에 튜플들을 밀어 넣고 다시 그것을 꺼내도록 요구하고, 또 (2) 그것의 실행으로 특정튜플에 의해 계산된 갓이 영향받을 수 있는 결과 스택상의 최상위 튜플을 찾아내도록 요구한 것이다.
직선 메카니즘은 옵티마이저(26)가 흐름 경로의 임의의 세트를 통한 프로그램의 흐름에 의해 어떠한 결과가 발생할 것인지 계사할 필요가 있을때에는 적합하지 않다. 이러한 상황에서는, 전단(2)이 각각 기억장소의 어떤 (아마도 비결정의)세트를 표시하는 특정 수(초기에 128)의 결과 분류를 정의할 수 있게 된다. 결과 분류의 한 세트는 하나의 비트 백터로 표시된다.
예를들어, 결과 분류는 특정 변수로 명명된 기억장소, 수순 호출에 의해 수정될 수 있는 모든 메모리 기억 장소 세트, 또는 간접 참조(포인터 참조)에 의해 액세스될 수 있는 기억 장소 세트를 표시할 수도 있다.
결과 분류 인터페이스 경우는, 옵티마이저가 전단으로 하여금 (1) 특정 류플에 의해 변경될 수 있는 기억 장소들을 포함하는 결과 분류 세트를 계산하고, (2) 특정 튜플이 관계될 수도 있는 기억 장소를 포함하는 결과 분류 세트를 계산하도록 요구할 것이다.
이 결과 분류 인터페이스를 사용하여 옵티마이저는 각 기본 블록에 대하여 그 기본 블록내의 어떤 튜플에 의해 수정될 수 있는 기억 장소를 포함하는 결과 분류 세트를 표시하는 비트 백터(LDEF세트라 일컬어짐)을 계산할 수 있다.
옵티마이저는 또한 전단으로 하여금 (3) 특정 변수 심볼과 관련된 기억 장소를 포함할 수도 있는 결과 분류 세트를 계산하도록 요구한다.
이 정보는 분할 부호(split candidate)의 수명을 계산하도록 분할 수명 최적화 단계(추후 설명)에 의해 사용된다.
옵티마이저(26)는 이들 인터페이스를 다음과 같이 사용한다. 이들 인터페이스가 설치되는 이유는 후단(12)내의 옵티마이저(12)로 하여금 "A의 평가부터 B의 평가까지 어떤 경로상에 발생하는 튜플이 B에의 계산된 값에 영향을 줄 수 없는 시기"를 판별할 수 있도록 하는 것이라는 사실을 상기하기 바란다. 만일 A와 B가 동일 기본 블록내에 발생한다면, 이것은 바로 "A와 B사이의 튜플리 B에 의해 계산된 값을 변화시킬 수 없음"을 의미한다. 이것은 직선 종속성 인터페이스를 사용하여 쉽게 결정될 수 있다.
만일 A를 포함하는 기본 블록이 B를 포함하는 기본 블록을 좌우한다면(즉 루틴 이력 노드로부터 B를 포함하는 기본 블록까지의 모든 흐름 경로가 A를 포함하는 기본 블록을 통과한다면), 옵티마이저는 기본 블록 X1,X2…Xn의 시리즈를 찾아내는데 여기서 X1은 A를 포함하는 기본 블록이고, Xn은 B를 포함하는 기본 블록이며, 각 X1는 바로 X(i+1)를 좌우한다. 여기서 그 테스트는 두 개의 파트를 갖는다.
1. A와 기본 블록 X1의 끝 사이, 기본 블록 Xn의 시작과 B사이, 혹은 B에 의헤 계산된 값을 변경시킬 수 있는 기본 블록 X2, X3, …X(n-1)의 어느 것에도 튜플이 존재하지 않아야 한다. 이것은 직선 종속성 인터페이스를 사용하여 쉽게 판별될 수 있다.
2. B에 의해 계산된 값을 변경시킬 수 있는 튜플을 포함하는 기본 블록 Xi 및 X(i+1)의 둘 사이에 흐름 경로가 존재하지 않아야 한다. 옵티마이저는 이것을 Xi에서 X(i+1)까지의 어떤 흐름 경로상에서 발생하는 모든 기본 블록의 LDEF 세트의 집합을 계산하고, B가 종속될 수도 있는 기억 장소를 포함하는 결과 분류 세트와 이 세트와의 교집합(intersection)을 계산한 다음, 이 교집합이 비어 있는지의 여부를 테스트하는 것에 의해 결과 분류 메카니즘으로써 테스트한다.
이하 인터페이스의 구조에 관해 설명한다. 인터페이스 루틴은 후단(12)에 의해 호출된다. 전단(20)은 그것이 후단(12)을 호출하기 전에 이용될 수 있는 인터페이스를 실현할 수 있어야 한다. 인터페이스 루틴은 인터페이스 루틴 입력 지점의 어드레스를 표준 전역 변수로 둠으로써 이것을 행한다. 이어서 옵티마이저(26)는 이 루틴중 하나를 호출할때 적절한 전역 변수로부터 루틴 어드레스를 적재할 수 있다. 인터페이스 루틴은 형식 GEM_SE_XXX의 명칭으로 추후 기재된다. 전단은 GEM_SE_XXX라는 명칭의 전역 변수로된 각 대응 실현 루틴의 입력 어드레스를 저장하여야 한다.
결과 및 종속성을 갖는 튜플들은 이 인터페이스에 중요한 것이다. 소수의 IL 튜플만이 결과 및 종속성을 갖는다(개략적으로, 스토어를 행하는 튜플들은 결과를 가지고, 패치를 행하는 튜플들은 종속성을 가지며 루틴 호출을 행하는 튜플들은 양자를 가질 수 있다).
구체적으로, 각 튜플은 다음의 카테고리중 하나에 속한다.
1.. 튜플이 어떤 결과를 갖지 않고 또한 어떤 결과에 대한 종속성도 갖지 않는다(예 : ADD). 이 분류에 속하는 튜플들은 결과 스택상에 넣어지지 않으며, 그러한 튜플들은 결고 GEM_SE_EFFECTS로 통가되지도 않는다.
2. 튜플이 결과를 가질 수도 있지만 종속성을 갖지 않는다(예 : STORE).
3. 튜플이 종속성을 가질 수도 있지만 어떠한 결과도 생기지 않는다(예 : FETCH).
4. 튜플이 결과(외부 효과 : out-effect) 및 별도 세트의 종속성(내부 효과 : in-effects) 양자를 가질수도 있다(예 : 수순 호출).
5. 튜플이 결과 및 종속성 양자를 가질 수도 있다. 그것이 생성하는 결과와 동일하다(예 : PREINCR).
DEFINES 튜플이라 불리는 특정 튜플은 전단으로 하여금 어떤 튜플과 관련되지 않은 결과를 특정하도록 하기 위하여 제공된다. DEFINES 튜플의 한가지 기능한 사용은 최적화가 허용되지 않은 장벽으로 작용하는 BLISS CODE COMMENT 특징을 실현케 하는 것이다. CODE COMMENT의 변환은 모든 결과를 갖는 DEFINES 튜플로 되므로 모든 튜플을 뮤효화시킨다.
인수 통과용 튜플(예컨데 ARGVAL 및 ARGADR)은 결과 및 종속성을 갖는다. 그러나, 이것은 .X+.Y의 이전에 계산된 값을 무효화 시키는데 그 이유는 F가 호출될때까지 결과가 실제로 발생하지 않기 때문이다.
튜플을 나타내는 제4도의 데이터 구조는 전단(20) 및 후단(12)양자에 의해 엑세스되며, 이 구조의 어떤 필드들은 단지 전단 혹은 단지 후단 액세스로 제한된다. 결과 또는 종속성을 가질 수 있는 모든 튜플(35)은 전형적으로 GEM_TPL_XXX_EFFECTS 또는 GEM_TPL_XXX_DEPENDENCIES라 명명된 하나이상의 장 워드 필드(42) 또는 (43)을 포함할 것이다. 특정 튜플에 사용된 필드 명칭은「중간 언어」라 섹션에 기재된다. 후단내의 코드는 이 필드들을 결코 검사 또는 수정하지 않을 것이다. 그들은 전단에 의해 사용하도록 보존된다. 그들은 인터페이스 루틴의 코드화를 간소화하는데 사용될 수 있는 정보를 기록하기에 편리한 장소가 된다. 심볼 테이블(30)의 각 심볼 노드에는 GEM_SYM_EFFECTS라 명명된 유사한 장워드 필드가 있는데, 그것 역시 전단(20)에 의해 사용되도록 보존된다.
직선 종속성 인터페이스에 있어서, 이하 루틴을 설명한다. 전단은 다음의 루틴을 실현한다.
GEM_SE-PUSH_EFFECT CEIL_TUPLE iN GEM_TUPLE_NODE)
어드레스가 EIL_TUPLE 파라미터인 EIL 튜플을 결과 스택상에 넣어라.
GEM_SE_PUSH_EFFECT(EIL_TUPLE : GEM_TUPLE_NODE에서)-유효 스택으로부터의 최상부 EIL 튜플을 팝(POP)한다. 이것은 어드레스가 EIL_TUPLE 파라미터내에 있는 튜플이 되도록 보장된다. 물론 이것은 파라미터가 용장성임을 의미한다. 그러나, 이것은 유효 스택에 대한 단일 스택 실시를 사용하지 않는 전단에 대한 POP 절차의 코팅을 단순화한다(이하의 실시예 설명 참조)
GEM_PUPLE_NODE=
GEM_SE_FIND_EFFECT(
EIL_TUPLE : GEM_TUPLE_NODE에서,
MIN_EXPR_COUNT : 값)
GEM_TPL_EXTR_COUNT 필드가 MIN_EXPR_COUNT(하기 참조) 보다 더 크고 그 실행이 EIL TUPLE에 의해 산출된 결과를 변경시키지 않는 가장 최근에 푸쉬된 튜플을 복귀시킨다. 파라미터에 의해 지정된 동일한 튜플을 또한 복귀시킬 수 있다.
GEM_PUPLE_NODE=
GEM_SE_FIND_EFFECT(
VAR_SYM : GEM_SYMBOL_NODE에서,
MIN_EXPR_CONT : 값)
GEM,_TPL_EXTR-COUNT 필드가 MIN_EXPR_COUNT(하기 참조) 보다 더크고 그 실행이 가변성 VVAR_SYM의 값을 수정할 수 있는 가장 최근에 푸쉬된 튜플을 복귀시킨다. 스택상의 튜플이 EIL TUPLE에 영향을 주지 않으면 널(null : 제로)을 복귀시킨다. 또한, 파라미터에서 지정된 동일한 튜플을 복귀시킬 수도 있다. 또한 파라미터에서 지정된 동일한 튜플을 복귀시킬 수도 있다. GEM_SE_PUSH EFFECT 및 GEM_SE_POP_EFFECT는 유효를 갖는 튜프과 함께 호출된다. GEM_SE_FIND_EFFECT는 종속성을 가질 수 있는 튜플과 함께 호출된다.
여기에는 실시의 순서가 있다. 각 EIL 튜플은 GEM_TPL_EXPR_COUNT라 하는 필드를 갖는다. 이 필드는 기본 블록이 도미네이터 트리 깊이-제1프리오더(tree depth-first preorder)에 유도되는 EILG의 행보의 튜플 인덱스를 포함한다. 후단(12)이 튜플 A로써 GEM_SE_PUSH_EFFECT를 호출하면, 그기로 중간에서 튜플 A로써 GEM_SE_PUP_EFFECT를 호출함이 없어 튜플 B로써 GEM_SE_PUSH_EFFECT 또는 GEM_SE_FIND_EFFECT를 연속적으로 호출하면 튜플 A가 동일한 기본 블록에서 튜플 B를 앞서거나 튜플 A를 포함하는 기본 블록이 튜플 B를 포함하는 기본 블록을 적절히 지배하는 것을 보장한다. 그러므로 유효 스택상의 튜플의 EXPR COUNT 값은 스택 깊이의 증가에 따라 감소한다(즉, 보다 최근에 푸쉬된 튜플들은 보다 덜 최근에 푸쉬된 튜플들보다 더 높은 EXPR_COUNT를 갖는다), 이것은 FIND EFFECT 루틴이 EXPR_COUNT가 MIN_EXPR_COUNT인자(argument) 보다 더적거나 동일한 튜플 T와 만나자마다 유효 스택의 조사를 짧게 단축할 수 있다는 것을 의미한다. 이것은 T보다 더 깊게 스택된 모든 튜플들이 MIN_EXPR_COUNT 보다 더 적은 EXPR_COUNT들을 갖도록 보장되기 때문이다.
유효 스택을 실시하는데 사용되는 메카니즘은 하나의 튜플의 실행이 다른 튜플에 의해 계산되는 값에 영향을 줄 가능성이 있을때를 결정하는데 사용되는 규칙처럼 전단(20)까지이다. 순수한 스택 실시는 유효가 없을 가능성이 있다 할지라도 확실히 가능하다. 보다 복잡한 실시가 해쉬 테이블(hash table) 부근에서 이룩될 수 있으며, 따라서 복수의 작은 스택들(각각이 단지 하나 또는 수개의 변수와 관련될 수 있음)을 하나의 큰 스택 대신에 사용할 수 있다.
이제 유효 클래스 인터페이스에 대하여 설명한다. 유효 세트가 한 세트의 유효 클래스를 나타내는 비트백터이고 유효 클래스가 어떤 임의의 메모리 위치세트를 나타냄을 상기한다. 일반적으로 유효 클래스는 이하의 것중 하나를 나타낸다.
1. 단일명의 변수, 유효한 최적화를 위하여, 루틴에서 빈번하게 사용되는 각각의 단순한(즉, 분산된) 로컬 변수는 그것에 부여된 유효 클래스를 가져야 한다.
2. 어떤 공통 특성을 갖는 한 세트의 명명된 변수값 ; 예컨데, FORTRAN에서 특수명의 공통 블록내의 모든 변수.
3. 구동 시간까지 결정되지 않고 어떤 공통의 특성을 갖는 한 세트의 메모리 위치 ; 예컨데 이 루틴의 외측에서 볼 수 있는 모든 메모리 위치(따라서 이것을 루틴 호출에 의해 수정됨) ; 또는 파스칼에서 새로운 호출로 동적 할당되고 특수한 형태를 갖는 모든 메모리 위치.
문자 GEM_SE_K_MAX_EFFECTS는 GEM_SE 패키지에 의해 엑스포트(export) 된다.
이것은 전단(20)을 규정할 수 있는 별개의 유효 클래스의 최대수이다. 이것은 초기 실시에서 128일 수 있다. GEM_SE_EFFECTS_SET형은 GEM_SE 패키지에 의해 엑스포트 된다. 이것은 BITVECTOR[GEM SE_K_MAX_EFFECTS]까지 연장하는 대량이다. 따라서, 선언(declaration) X : GEM_SE_EFFECTS SET가 주어지면, 이하의 구성은 매우 자연스럽다(여기에서 0≤N≤GEM_SE_K_MAX_EFFECTS-1) :
X(N)=참(true) : 유효 클래스 N을 세트X에 부가.
X(N)=거짓(false) : 세트 X로부터 유효 클래스 N을 제거
X(N)이면…: 유효 클래스 N이 세트 X 내에 있으면…
이제 유효 클래스 인터페이스에 대한 인터페이스 루틴을 설명한다. 전단(20)은 하기 루틴의 실시를 제공하여야 한다.
GEM_SE_EFFECTS(
EIL_TUPLE : GEM_TUPLE_NODE 내,
EFFECTS_BV : GEM_SE_EFFECTS_SET 외)
튜플 EIL_TUPLE 및 EFFECTS_BV의 유효의 결합은 EFFECTS_BV로 기록된다.
EGM_SE_DEPENDENCIES(
EIL_TUPLE : GEM_TUPLE_NODE 내,
EFFECTS_BC : GEM_SE_EFFECTS_SET 외)
EIL_TUPLE이 EFFECTS_BV에 의존하는 유효 클래스의 세트를 기록한다.
GEM_SE_VARIABLE_DEPENDENCIES(
SAMBOL : GEM_SYMBOL_NODE 내,
EFFECTS_BV : GEM_SE_EFFECTS_SET 외)
변수 SYMBOL과 관련된 메모리를 포함한 유효 클래스의 세트를 EFFECTS_BV에 기록한다.
GEM_SE_EFFECTS는 유효를 가질 수 있는 튜플과 함께만 호출된다. GEM_SE_DEPENDENCIES는 종속성을 가질 수 있는 튜플과 함께만 호출된다.
컴파일러는 상기 언급한 인터페이스 루틴에 대한 실시를 제공할 수 있지만, 이 루틴들은 생산 컴파일러에서 사용하고자 하는 것은 아니다. 이들은 뮤효하고, 하나의 튜플이 다른 것을 무효화하는 동안 그 규칙들은 어떤 특수 언어의 의미론(Semantics)과 정확히 일치하지 않는다. 그러나 이들은 전단(20)의 다른 성분들이 실시될 때 유용한 기정 최적화(default optimization)가 발생되게 한다.
각 심볼 노드의 EFFECTS 필드는 32와 GEM_SE_K_MAX_EFFECTS 사이에서 유효 클래스 번호로서 처리된다. 인출 또는 기억 튜플의 어드레스 표현이 베이스 심볼을 가질 때 그 심볼의 EFFECTS 필드가 체크된다. 이것이 만일 제로이면 이것은 32와 GEM_SE_K_MAX_EFFECTS 사이의 새로운 값으로 세트된다.
상기한 유효 클래스 실시를 사용하여 유효 세트들을 계산하기 위하여, 전단은 GEM_IL_BUILD 페이스를 인용하기 전에 GEM_SE_INIT_EFFECTS_CLASSES를 호출하여야 한다.
이 실시는 유효에 대한 심볼 모델을 규정함으로써 유효에 대한 정보를 제공한다.
1. 변수들이 오버레이(overlay)되지 않는다.
2. 데이터 액세스 동작이 표준적인 형태(CT.006에 규정됨) 이외의 형태로 (기억을 위해) 유효 0을 갖거나(인출을 위해) 유효 0에 의존한다.
3. 호출들은 32 내지 GEM_SE_K_MAX_EFFECTS를 갖는다. ARGARD 파라미터는 마치 호출이 그 어드레스 피연산자에 기록된 것처럼 처리된다.
유효 클래스 0과 32 내지 GEM_SE_K_MAX_EFFECTS는 보존된다. 유효 0는 인용되는 변수들의 확인 될 수 없도록 메모리에 대한 인용문들을 나타낸다(포인터 디레퍼런스, 파라미터, 등)변수가 표준적인 형태로 데이터 액세스 연산자를 사용하여 최초로 인용될 때 그 변수에는 32 내지 GEM_SE_K_MAX_EFFECTS의 범위내에서 유효 클래스 번호가 할당된다. 이 번호는 심볼 노드의 유효 필드에 기록된다. 그 변수에 대한 인용 및 모든 후속 인용들은 유효 또는 종속(dependency) n을 갖는다.
실시는 실험, 테스팅등을 위한 몇가지 후크(hook)를 포함한다.
1. 유효 또는 종속들을 가질 수 있는 튜플들은 튜플의 유효 및 종속을 기록하기 위하여 전단에 보존된 한개 이상의 "유효 필드"(EFFECT, DEPENDENCIES, EFFECTS_2, 등)를 구비한다. 컴파일러에 의해 공급된 유효 클래스 콜백들은 GEM-SE_EFFECTS_SET의 제1워드를 나타내는 길이 32의 비트 백터로서 유효 필드를 해석한다. 즉, 필드의 비트 n이 참이면 루틴은 유효 클래스 n을 튜플의 계산된 유효에 부가한다.
2. 전단은 1과 GEM_SE_K_MAX_EFFECTS 사이의 유효 클래스 번호를 가변 심볼 노드의 유효 필드에 기록함으로써 변수에 대한 유효 클래스를 선정할 수 있다. 유효 클래스 루틴은 유효 필드가 제로가 아니면 유효 클래스를 할당하지 않는다.
3. 유효 클래스 1~32는 전단에 의한 사용을 위하여 보존된다. 이것은 유효 클래스에 대한 어떤 해석을 할당할 수 있다.
상기한 직선 종속 실시를 사용하기 위하여 전단은 GEM_DE_DATAFLOW 페이스를 인용하기 전에 GEM_SE_INIT_EFFECT_STACK를 호출하여야 한다. 이 실시는 무효성을 결정하기 위하여 GEM_SE_EFFECTS 및 GEM_SE_DEPENDENCIES 콜백에 의해 제공된 정보를 사용한다. 즉, GEM_SE_FIND EFFECT(X)는 GEM_SE_EFFECTS(Y) 및 GEM_SE_DEPENDENCIES(X)가 뮤효로 되지 않도록 가장 최근에 푸쉬된 튜플 Y를 복귀시켜야 한다.
[유도 변수]
본 발명의 한가지 특징에 따르면 컴파일러에서 유도 변수를 처리하는 개선된 방법이 제공된다. 먼저 유도 변수 및 유도 수식의 정의 및 검출에 대하여 설명한다.
정수 변수 V는 루프 L에서 발새하는 V에 대한 각각의 기억이 하기의 경우에 있을 경우에 루프 L의 유도변수라고 말하여 진다.
1. V가 실행될때 마다 동일한 크기 만큼 V를 증가(또는 감소)시킨다.
2. 루프를 통한 "완전한 트립(complete trip)" 시마다 1회씩 실행된다.
트립은 루프 상단으로의 역흐름될 경우에 "완료"된다. 예컨데, 하기의 코드는 유도 변수 V를 설명한다 :
라벨 L V-I
IF >10
GOTO LABEL M
ELSE
PRINT X
V=V+1
END IF
컴파일 기능에서, 유동변수를 찾는 것 외에, 유도 수식을 찾는데에도 또한 관심이 있다. 유도 수식은 유도 변수의 선형 함수로써 계산될 수 있는 수식이다.
하기의 프로그램을 생각한다.
DO I=1,000
X=1*8
T=1~4
A[I]=T*4
END DO
수식 "I*8", "I-4", "T" 및 "T*4"는 모두 이들이 I의 선형 함수로써 다시 계산될 수 있다는 점에서 유도 수식이다.
유도 변수에 기초한 몇가지 최적화의 간단한 설명으로써 하기의 프로그램 예를 생각한다.
I=1 ;
L : X=X+(4*I)
I=I+1
if I<=100 GOTO L
이것은 간단한 DO루프이고, I는 루프 제어 변수이다. 유도 수식 I*4는 루프를 통한 각 트립시에 4씩 증가한다는 것을 주의한다. 새로운 변수 I2를 도입함으로써 승산을 가산으로 대체할 수 있는데 이것은 비용이 더 적게드는 동작이다. 이것은 장시간 동안 컴파일러를 최적화하는데 사용되는 강도 저하로써 알려져 최적화이다.
I=1 ;
I2=4 ;
L : X=X+I2
I=I+1
I2=I2+4
if I<=100 GOTO L
앞에서는 한 개의 변수를 가졌지만 이제 우리는 두개의 변수(I와 I2)를 가지게 된다. 원래 루프 제어 변수는 I2의 항에서 I를 사용할 수 있도록 개주(recast)함으로써 완전히 제거될 수 있다.
I2=4 ;
L : X=X+I2
I2<=I2+4
if I2<=400 GOTO L
이러한 최적화는 유도 변수 제거로써 알려져 있다.
이러한 최적화(강도 저하 및 유도 변수 제거)는 유도 변수상에서 직접 동작한다. 이러한 최적화외에 유도 변수 검출은 자동 Inc/dec, 백터화, 루프 언롤링(loop unrolling), 등과 같은 다른 최적화에 정보를 제공한다.
제1도의 컴파일러에서 사용된 모델에서, 유도 변수는 루프중에 1회 이상 증가될 수 있다. 또한 변화의 수는 각 반복시마다 다를 수 있다. 사실상, 변화의 수는 특정 반복에서는 제로일 수 있다. 루프 불변 증가 값은 개개의 기억 사이에 차이가 있을 수 있지만 각각의 기억은 그것이 실행될 때마다 동일한 크기로 변수를 증가시켜야 한다.
기본 유도 변수, 유도 수식, 및 의사 유도 변수를 포함한 다른 특성들을 갖는 유도 변수에는 몇가지 다른 카테고리가 있다.
기본 유도 변수들은 가장 간단한 형태의 유도 변수이다. 이들은 루프 전체에 걸쳐서 적용되는 공지의 특성들을 갖는다. 모든 다른 유도 변수 및 수식들은 항상 기본 유도 변수의 선형 함수로써 만들어진다. 기본 유도 변수들은 일반적으로 I=I+q 또는 I=I+q의 형태로 수정되며, 여기에서 q는 루플변수이다. 그러나 보다 일반적으로 말하면, 배정이 I=f(I)의 형태로 될 필요가 있으며, 여기에서 f(I)는 1의 계수를 갖는 I의 선형 함수이다.
부록에 주어진 알고리즘에서, 특수 루프의 기본 유도 변수는 루프 상단의 세트에 의해 표시된다. 이 세트 이외에, 우리는 또한 루프를 통한 각 트립에서 실행될 수 없는 조건부 기억을 갖는 루프에서 기본 유도 변수의 세트르 유지하다. 이것은 벡터화를 금지시키며 강도 저하를 소망하는 만큼 이룩할 수 있다.
유도 수직은 유도 변수에 대한 참조이거나 다른 유도 수식의 선형 함수이다. 유도 수식들은 하기 형태들 중 한가지이어야 한다.
f(I)
f(I)+g(I) f(I)-f(I)
f(I)+E E+f(I)
f(I)-E E-f(I)
f(I)*E E*f(I)
여기에서 f(I)와 g(I)는 루프 L과 관련하여 기본 유도 변수 I로부터 유도된 유도 수식이고 E는 루프 L의 불변수이다. 만일 f(I)와 피연산자인 산술 연산자 사이의 I에 기억이 없으면 산술 연산자는 루프 L과 관련하여 기본 유도 변수로부터 유도된 유도 수식이다.
다른 카테고리는 의사 유도 변수이다. 어떤 조건하에서 변수는 모든, 그러나 루프를 통한 제1트립에서 유도 변수처럼 작용할 수 있다. 이들은 최초의 루프 반복을 필링(peling)함으로써 유도 변수로(그리고 이로써 벡터화로)될 수 있다. 이러한 변수들은 "의사 유도 변수"라고 한다. 이것은 루프내의 하나의 루프 상단을 통하여 값이 흐르는 다른 하나의 기억에 의해서만 달성될 때 발생한다.
예들을어서 ;
D=50
DO I=1, n
A[I]=D+…
D=I+4
루프를 토한 제1트립에서, D는 I에의 배정시 값 50을 갖는다. 후속 트립에서, D는 값 5,6,7 등을 갖는다. 루프를 1회 언롤링함으로써 후속 트립들은 백터화될 수 있다. 여기에 주어진 알고리즘은 의사 유도 변수인 유도 변수를 찾지 못한다는 것을 주의한다.
기본 유도 변수를 식별하기 위하여 컴파일러는 그것에 대한 모든 기억들을 인식할 수 있어야 한다. "기억을 앨리어스함(has aliased stores)" 속성이 없으면 이것을 보장하고 따라서 우리는 단지 "기억을 앨리어스함"을 갖지 않는 기본 유도 변수를 인식한다.
기본 유도 변수를 검출하는데는 잠재적인 유도 변수의 세트를 사용할 필요가 있다. 각 루프에 대하여 이것을 동적으로 행하는 것은 비용이 많이들어 복잡한 동작이다. 그 대신, 유리는 IDEF 세트를 구성하는데 사용되는 부작용 세트를 사용한다.
변수"X"는 X의 인출이 의존하는 모든 유효들이 S내에 있을 경우 IDEF 세트 S내에 있다고 말하여진다. 즉, X는 GET_VARIABLE_DEPENDENCIES(x)가 S의 서브 세트인 경우에만 IDEF 세트 S에 존재한다.
기본 유도 세트내의 X의 존재는 하기의 사항을 암시한다.
(a) X는 기본 유도 변수이다. 또는
(b) X는 루프 불변수이고 기본 유도 변수인 최소한 1개의 변수와 함께 IDEF 비트를 공유한다.
부족에서 알고리즘 설명은 알고리즘 설명을 간단히 한다는 관점에서 하기의 자유를 취한다 : (1) 선형 함수의 연속 부분의 수집은 오버 플로우를 일으킬 수 없다. (2) 모든 기억들은 변수를 완전하게 다시 규정한다.
부록에서 설명되고 있는 알고리즘은 루프에서 수정된 모든 변수들이 기본 유도 변수라고 가정함으로써 시작한다. 각 루프 상단은 기본 유도 변수 세트를 갖는다. 우리가 기본 유도 변수에 대한 요구 조건을 만족시키지 못하는 기억들을 찾았을때 우리는 루프 상단의 기본 IV 세트로부터 변수들을 제거한다.
유도 수식 및 유추된 유도 변수들이 항상 기본 IV함수이므로, 우리는 기본 IV의 인출이 유도 수식이 원자 형태이라고 말한다. 즉, 수식이 유도 특성을 갖게하기 위하여, 수식은 피연산자를 갖거나 기본 유도 변수의 인출이다.
앞에서 주어진 규칙들을 사용하여 유리는 기본 IV에 대한 가정과 기초하여 더 간단한 유도 수식으로부터 유도 수식들을 만든다. 유도 수식의 기본 IV는 항상 수식과 함께 유지된다. 따라서, 알고리즘이 구동된 후에 우리는 유추되어지는 기본 IV가 아직 루프의 기본 IV 세트에 있는지를 확인하기 위하여 검사함으로써 수식이 정말로 유도성인지 여부를 말할 수 있다.
부록에서 주어진 FIND_IV 알고리즘은 제1의 깊이 도미네이터 트리 워크인 데이타 흐름 페이스의 일부로된다. 하기 내용은 수행된는 튜플 처리의 개관이다 :
TUPLE[OPCODE]선택
[FETCH]
만일 베이스 심볼이 아직 기초 IV 후보자이면, 이 튜플을 유도성인 것으로 표시함.
[STORE]
V는 기억의 기본 심볼인 것으로 한다.
만일 기억되어 있는 값이 유도성이 아니면, 또는 기억되는 유도성 값의 기본 IV가 V가 아니면, 또는 기억된 값의 계수가 1이 아니면, 루프 상단의 기본 IV 세트로부터 V를 제거하고, 루프 상단의 기본 IV세트로부터 V를 제거하고, 기억을 유도성인 것으로 표시함.
[ADD,SUB,MUL,등]
만일 한개의 피연산자가 유도성이고 다른 피연산자가 루프 불변수이면, 이 튜플을 유도성인 것으로 표시함.
튜플 데이타 구조에 부가된 필드 및 흐름 노드에 부가된 필드는 유도 변수 검출을 제공하기 위하여 표 6a에서 설명한다.
[K 폴드(KFOLD) 루틴의 자동 발생]
앞에서 설명한 바와 같이, 제1도의 프로그래밍 언어 컴파일러는 소스 언어로 기록된 프로그램을 타겟 머신(25)의 기계어로 번역한다. 컴파일러는 컴파일되는 모듈(21)에 소스 언어의 놀리지(knowledge)를 통합 시키는 전달(20)과 타겟 머신(25)의 기계어의 놀리지를 통합시키는 후단(12)을 포함한다. 전단은 프로그램을 소수 언어로부터 ILG(55)의 중간 언어로 번역하고 후단은 프로그램을 중간 언어로부터 타겟 기계어로 번역한다.
중간 언어는 일반적으로 연산자의 수집(예컨대, 가산, 시프트, 비교, 인출, 기억 또는 탄젠트), 데이타 형태의 수집(예컨데, "부호화 32비트 정수", "IEEE S-포맷 부동점", 또는 "문자 스트링" 및 그러한 데이타 형태의 값에 대한 표시를 지정한다.
옵티마이저(26)에 포함된 최적화들중 하나는 일정한 수직 평가 루틴이다. 일정한 수식에 관련되는 소스코드 리스트의 일예는 제6도에 도시되어 있으며, 여기에서 A와 B는 상수이고 따라서 A+B도 상수이며 I와 J는 같은 상수와 동일하다. 컴파일러는 (A+B)를 계산하고 구동 시간에 A와 B의 인출을 개별적으로 세이브하여 ADD동작하여 세이브한다. 따라서 제6도의 코드의 I=A+B와 J=A+B식은 단순히 STORE #9, I 또는 STORE#9, J로서 표시된다. 이것은 상수들이 검출되고, 컴파일 시간에 계산되며 목적 코드 이미지에 중첩되기 때문에 "상수 중첩"이라고 알려져 이다. 이것을 행하기 위한 메카니즘은 옵티마이저(26)의 일부분이며 K폴드 루틴이라고 한다.
제1도의 컴파일러는 이들 상수식을 찾내기 위해 중간 언어의 식을 평가하기 위한 K폴드 루틴을 통합한다. 일반적으로, 중간 언어의 연산자 및 그 피연산자들의 값들이 주어질때 이 루틴은 이 값들에 인가될대 그 연산자에 의해 계산되는 동일한 값을 생성한다. 그러나 상수식 평가 루틴은 컴파일러에서 많은 응용을 갖는다. 예를들면
(a) 프로그램에 대해 발생된 머신 코드의 실행 속도는 프로그램의 일부 수식들이 프로그램이 실행될때 보다는 컴파일러 그 자체에 의해 평가될 수 있을 경우에 개선될 수 있다.
(b) 일부 소스 언어가 상수 값을 나타내기 위하여 수식을 상수 피연산자와 함께 사용하게 할 수 있다. 그러한 언어로 프로그램을 컴파일하는 것은 컴파일러에 의해 그 수식들을 평가할 것을 필요로 한다.
(c) 중간 언어에서 제공된 동작의 레퍼토리가 프로그래밍 언어에 의해 제공된 동작 또는 컴파일러가 실시되는 환경 보다 더 풍부한 경우, 컴파일러에 어떤 계산을 수행하는 가장 편리한 방법은 그 레퍼토리를 중간 언어의 수식으로 표현하고 그것을 상수식 평가 루틴으로 전송하는 것이다.
상수식 평가 루틴의 실행은 상당히 어려운 문제일 수 있다. IL은 수십개의 동작(예컨데, ADD, SUBT, COSINE, 등)을 가질 수 있고, 다른 데이타 형태(예컨데, INT32, NINT64, FLOATA, 등)를 생각할때 중간 언어는 수백 또는 수천개의 다른 연산자를 가질 수 있다. 평가 장치는 각 데이타 형태에 정확히 각 동작들을 적용시킬 수 있어야 하며, 그렇지 않으면 컴파일러는 그 기능을 완전하게 그리고 정확하게 수행하지 못한다. 특히 부동점 형태가 관련될 때에는 중간 언어로 표시되는 모든 동작들이 컴파일러가 실행하는 프로그래밍 언어에서 직접 이용할 수 없게 될 수도 있다. 결국, 상수식 평가 루틴은 수백개의 다른 경우를 포함하여 극히 길어질 수 있고 에러 발생율이 높다.
본 발명의 일실시예의 중요한 특징에 따르면, 중요한 것은 중간 언어의 연산자의 정확한 의미가 항상 간결하고 정확하게 지정될 수 있는 하나의 언어가 중간 언어 그 자체라는 점이다. 즉, 컴파일러 후단 그 자체는 중간 언어의 어떤 연산자를 정확히 실시하는 코드를 발생할 수 있어야 한다. 다시말하면 이것은 컴파일러 후단이 이미 각 중간 언어 연산자의 유효를 실현하는데 필요한 머신코드 명령들의 순서의 놀리지를 실시하고, 동일한 놀리지를 상수식 평가 루틴에서 다른 형태로 엔토드하도록 중복된다.
이 개념에 기초하여, 본 발명에 따르며, 상수식 평가 루틴의 기계적 발생은 간단하게 된다. 제1단계는 제1도의 새로운 컴파일러를 창조하는 것인데, 이것은 정규 컴파일러로서 동일한 후단(12)을 사용하지만 그 전단(20)은 후술되는 특수한 전단으로 교체된다.(등가적으로 후술되는 바와 같이 동작하는 컴파일러에 특수한 모드를 제공한다)
두번째로, 특수한 전단(20) 또는 특수한 동작 모드는 소스 프로그램(21)을 판독 및 번역하지 않는다. 그대신 다음과 같이 상수식 평가 루틴을 위한 중간 언어를 발생한다.
(a) 루틴은 인자 리스트에서 지정된 중간 언어 연산자에 기초한 경우를 선택하도록 조건 브랜치를 갖는다.
(b) 각각의 경우는 단일 연산자에 대한 코드를 포함한다. 루틴의 인자 리스트로부터 피연산자 값들이 인출되어 연산자를 그들에게 인가하고 그 결과를 복귀시킨다.
(c) 루틴이 중간 언어로 직접 발생되기 때문에 각 경우에 대한 코드는 인자 리스트로부터 피연산자를, 그 다음에 특수한 경우를 위한 중간 언어 연산자를, 그리고 그 다음에 그 결과를 복귀시키기 위한 중간 언어 연산자를 인출하도록 간단히 중간 언어 연산자로 구성된다.
세번째로, 이 중간 언어 그래프가 컴파일러 후단에 전송될때 이 그래프는 상수식 평가 루틴을 위한 머신 코드를 발생한다.
전술한 특수한 전단에서, 전단은 경우들이 발생되어야 하는 모든 연산자의 리스트를 포함할 수 있고, 각 경우에 대한 중간 언어를 기계적으로 발생할 수 있다.
그러나 처리는 가끔 발생하는 바와 같이 컴파일 후단이 이미 연산자 정보의 표를 이미 포함하고 있으면 더욱 간단해질 수 있다(예컨데, 이러한 표는 전단에 의해 발생된 중간 언어 그래프의 정확성을 체크하기 위해 사용될 수 있다.) 그 다음에는 특수한 전단이 어떤 경우가 발생되는지 결정하기 위하여 후단에 의해 이미 제공된 상기 표를 사용할 수 있다.
[타입 정의(type definition)]
제1도의 컴파일러는 GEM_TD 모듈이라고 하는 타입 정의 모듈을 사용한다. GEM_TD는 링커 또는 디버거에서 사용하는 목적 모듈에 통합되어질 프로그램 타입 정보를 구성함에 있어서 전단(20) 및 후단(12)에 의해 사용되는 메카니즘을 제공한다. 이 타입 지정 서비스는 전단(20)이 프로그램 심볼 및 타겟 목적 파일 요구에 무관한 방법으로 목적 모듈 빌더(29)에 대한 관련 타입 정보를 묘사하게 한다. 이 타입 지정 서비스는 컴파일러가 추상적 타입 지정 및 프로그램 심볼을 통합할 수 있도록 절차적인 "타입 문법"으로서 동작한다. 타입 지정 인터페이스는 이후에 규정되고 GEM_TD 서비스의 사용의 많은 예가 참조된다.
타입 정보 생성은 심볼 테이블(30) 생성의 환경에서 발생하고 전단(20)이 프로그램 타입 정보를 나타내는 업스트랙트(abstract)을 지정하게 한다. 목적 모듈 빌더(29)는 나중에 디버그 심볼 테이블 정보를 구성함에 있어서 이 정보를 사용한다.
GEM_TD 모듈은 전단(20)이 기본 타입 및 유추된 타입을 묘사하도록 하는 서비스 루틴을 제공한다. 이 루틴들은 전형적으로 지정 타입 정보를 묘사하는 내부 데이타 구조를 구성한다. 새로운 컴파일러 노드 형태(GEM_TDI)는 형태의 정보를 관리하도록 규정한다. 타입 노드 데이타 구조의 정의는 컴파일러(12)에 전용되고 전단(20)에 의해 변경되거나 시험되지 않는다. 타입을 규정할때 전단(20)은 타입을 규정하는 GEM_TD 루틴에 의해 "핸들"을 그 타입 노드로 복귀시킨다. 핸들은 전단이 어떤 타입을 프로그램 심볼과 통합되게 하지만 전단이 데이타 구조의 필드를 변경시키거나 시험하는 것을 금지시킨다.
타입 노드는 범위(sccope)에 의해 생성 및 관리되고, 타입 정보를 전송할때 전단(20)은 타입이 선언되어질 블록 노드를 지정하고 셀(shell)은 그 범위내에서 타입 노드를 관리할 책임을 갖는다. 셀은 타입이 규정되는 블록 노드에 기초한 리스트내의 타입 노드를 관리한다. 블록 노드 데이타 구조를 필드 TYPE_LIST HEAD와 TYPE_LIST_TAIL을 규정하도록 확장된다.
전단(20)은 타입 지정 서비스 루틴에 대한 온어 플라이(on-the-fly) 호출을 행하도록 선정되고 타입 정보를 발생하기 위해 전체 심볼 테이블을 거치는 통과를 만들도록 선정될 수 있다.
타입 규정후에 전단은 이 타입 정보를 그 타입의 심볼과 연합시켜야 한다. 심볼 노드는 심볼을 이 타입과 연합시키는데 사용되는 새로운 필드 DST_TYPE_INFO를 갖는다. 심볼의 DST_TYPE_INFO 필드는 GEM_TD 서비스에 의해 복귀된 타입 노드 핸들의 어드레스를 포함한다. 널의 DST_TYPE_INFO 값을 갖는 심볼 노드는 타입 정보를 갖지 않는 심볼에 대한 타겟 지정 작용을 갖는다.
제7도를 참조하면, 데이타 필드 및 관계가 하기의 함수에 대하여 설명된다.
int toy_procl)
{
float b,c ;
:
}
toy_proc에 대한 블록 노드(60)은 심볼 테이블(30)에서 엔트리(63,64,65)를 지지시하는 필드(61,62)(decl 리스트 포인터)를 포함한다. 또한 이것은 int 및 플로트에 대한 타입 리스트의 엔트리(68,69)를 지시하는 타입 리스트 포인터로서 작용하는 필드(66,67)를 포함한다. 엔드리(63,64,65)는 또한 대부분의 경우과 같이 int 및 플로트에 대한 엔트리(68,69)를 지시하는 포인터(70,71,72)를 갖는다.
GEM_TD 타입 지정 서비스는 전단(20)이 표준 및 유추된 타입을 규정하고 그 타입들을 프로그램 심볼과 연합시키도록 하는 루틴들도 구성된다. 컴파일러 후단(12)은 타겟 지정 디버스 심볼 테이블을 발생하도로 유효 타입 정의 및 그들의 심볼 노드 연합을 사용한다. 부울은 기본 타입으로서 생각되지 않음을 주의한다. 파스칼과 같은 언어를 위한 컴파일러는 참 및 거짓의 요소들을 포함하는 목록으로서 부울을 규정하여야 한다.
[멀티 패스 코드 발생기용의 활동 언어(action language)]
이제 코드 탬플리트(template)를 사용하여 코드 발생기(29)에 의해 후단(12)에서 코드 발생을 수행하는 방법을 설명한다. 코드 탬플리트의 선택 및 응용을 컴파일 처리중에 다른 4개의 시간에서 발생한다.
1. PATSELECT 페이스는 베스트 코드 템플리트를 선택하기 위하여 CONTEXT pass에서 패턴 매치를 행한다.(이 패턴 매치중에 UCOMP 및 DELAY 최적화 타스크(task)는 패턴 공정으로서 나란히 수행된다)
2. CONTEXT 패스의 TNASSIGN 및 TNLIFE 타스크는 식에 대한 평가 순서를 분석하고 코드 템플리트에 비로컬(nonlocal)한 수명 시간을 TN에 할당하도록 선택된 템플리트의 콘텍스트 활동을 사용한다.
3. TNBIND 통과는 코드 템플리트에 로컬한 수명 시간을 TN에 할당하도록 선택된 템플리트의 바인딩 활동을 사용한다.
4. 마지막으로, CODE 패스는 목적 코드의 발생을 안내하도록 선택된 템플리트의 코드 발생 활동을 사용한다.
템플리트은 컴파일중에 다른 시간에서 사용된다. 이것은 3개의 주성분으로 구성된다.
1. ILG 패턴-이것은 템플리트를 응용 가능한 ILG 구조에 정합시키는 템플리트 선택 공정을 안내한다.
2. 비지연 활동-이것은 CONTEXT, TNBIND 및 CODE 패스중에 정합된 ILG 구조의 처리를 결정한다. 비지연 활동은 템플리트이 각 패스에서 최초로 처리될때 수행된다. 그 결과 각 ILG노드의 템플리트 활동은 각 패스에 대해 1회씩 3개의 다른 시간에서 처리된다. 일부 활동들은 단지 하나의 패스에 대해 의미를 가지며 다른 패스에서는 무시된다. 다른 활동들은 1개 이상의 패스에서 의미를 갖지만 요구되는 처리는 각각의 패스마다 다르다.
3. 지연된 활동-이것은 또한 CONTEXT, TNBIND 및 CODE 패스중에 정합된 ILG 구조의 처리를 결정한다. 지연된 활동은 템플리트에 의해 계산된 결과가 다른 템플리트의 잎(leaf)으로서 최초 처리될때 각 패스에서 수행된다. 지연된 활동은 어드레스 모드를 갖는 VAX와 같은 타겟 머신에서 유용한다. RISC와 같은 간단한 레지스터 머신은 아마 지연된 활동의 많은 사용을 행하지 않을 것이다.
코드 발생 템플리트의 ILG패턴은 4편의 정보로 구성된다.
1. 템플리트의 발생된 코드에 의해 계산된 값의 표시를 엔코드하는 유효치 모드(블록에 주어진 예 참조)
2. 이 템플리트에 의해 부호화될 수 있는 ILG 노드의 배열을 묘사하는 패턴트리. 패턴트리 내부 노드는 IL 노드이고, 패턴트리의 나머지의 피연산자를 갖지 않는 IL 연산자 또는 값 모드 세트이다.
3. 부울 테스트의 시퀸스, 이들 모두는 패턴을 응용할 수 있게 하기 위해 참으로 평가되어야 한다.
4. 이 템플리트에 의해 발생된 코드의 코스트를 나타내는 정수.
패턴 또는 PATSELECT 페이스는 ILG 서브트리를 템플리트의 패턴과 정합한다. 1개 이상의 템플리트 패턴이 ILG 노드에서 응용될 수 잇으면 패턴 정합자는 어떤 하나가 가진 낮게 평가되는 코드 코스트로 인도된다는 것을 인식할때까지 다른 템플리트들 사이에서의 선정을 지연시킨다.
여기에서 3개의 다른 활동 해석기, 즉 CONTEXT 해석기, TNBIND 해석기 및 CODE 해석기가 있따. 각 템플리터의 활동은 적당한 해석기에 의해 컴파일러의 3개의 다른 패스에서 수행된다. 3개의 패스 모두에서 동일한 템플리트이 사용된다 하더라도 활동이 의미론은 페이스 종속성이며 따라서 다른 일들이 각 패스에서 수행된다. 많은 활동들은 3개의 패스중 하나에서만 의미를 가지며 이 활동들은 다른 두개의 패스에서는 아무것도 행하지 않는다. 다른 활동들은 1개 이상의 패스에서 의미를 갖미나 1개의 패스에서 활동의 의미론은 가끔 다른 패스에서 동일 의미론과 전혀 다르다. 그러나, 템플리트에서 단지 하나의 활동 시퀸스를 갖는 것은 이해를 매우 쉽게하고 여러가지 패스 사이에서 종속성을 유지를 쉽게 한다.
각 템플리트에 대한 활동 시퀸스는 2개의 부분, 즉 비지연 활동과 지연 활동으로 이루어진다. 선택된 ILG 노드의 패턴이 최초 처리될때에는 비지연 활동이 해석된다. ILG패턴이 다른 ILG패턴의 앞으로서 나중에 사용될때에는 지연 활동이 해석된다.
비지연 활동의 해석 개시시에 피연산자 변수의 표는 생성된다. 피연산자 변수는 임시명(TN), 즉 문자 또는 타겟 지정 어드레스 모드를 포함할 수 있다.
임시명은 각각 3개의 클래스, 즉, (1) 영구 TN, 및, (2) 지연 TN 및, (3) 로컬 TN 중 하나로 분할된다. TN의 클래스는 그 수명 시간 및 사용에 의해 결정된다.
각 TN은 할당 수명 시간을 가져야 한다. 할당 수명시간은 적당한 템플리트 활동에 의해 시작되며 TN 의 최후 사용으로 인도하는 모든 흐름 경로를 따라 연장한다. 영구 클래스의 TN들은 어떤 임의의 대량의 코드를 TN의 생성후에 미래에서 종결짓는 수명 시간을 가질 수 있다. 지연 클래스 TN의 수명은 템플리트의 지연 활동에서 시작하고 TN이 잎으로서 사용된 바로 뒤에 종결되어야 한다. 로컬 TN의 수명은 단일 패턴의 해석을 넘어서 연장되지 않는다.
TN의 클래스는 그것이 어떻게 처리될 것인지를 결정한다. 영구 클래스 TN은 CONTEXT 패스에서 1회 생성되고 동일한 TN 데이타 구조는 3개의패스 모두를 통하여 유지되며 TN의 복잡한 수명 시간 묘사를 기억하기 위해 사용된다. 지연 클래스 및 로컬 클래스 TN은 매우 제한된 기간의 수명 시간을 가져서 이들이 이 정보를 추적하기 위해 영구 데이타 구조를 가질 필요는 없다.
그 결과, 지연 클래스 및 로컬 클래스 TN의 TN 데이타 구조는 활동들을 해석할때 각 패스를 구성하고 각 패스에서 최후의 사용후에 즉시 제거된다. 각 패스에서 동일한 활동 시퀸스의 해석은 동일한 TN 데이타 구조를 보장하고 이들 클래스의 TN에 대하여 각 패스에서 구성된다.
다른 템플리트 활동의 대형 리스트 있을을 수 있다.이들 활동중의 일부는 타겟 머신 종속성이다. 부록은 제안된 또는 예시한 템플리트 활동의 리스트를 포함하고 있으며, 따라서 유저는 이들 코드 템플리트 예들에 의해 특수한 실시예에 대하여 무엇이 필요한지 결정할 수 있다.
[중간 언어 표시]
제1도는 컴퍼일러 골조(10)에서 사용되는 내부 표시는 심볼 테이블(30) 및 중간 언어 그래프(55)를 포함하며, 이들은 소스 모듈(21)의 구조, 데이타 및 코드를 나타내도록 전단(20)에 의해 생성된 데이타 구조이다. 이하에서는 IL 그래프(55)에서 사용되는 중간 언어 및 심볼 테이블(30)의 지정을 포함한 이들 데이타 구조의 소스적 성분인 노드를 설명한다. 제1도를 참조하여 설명된 컴파일러에서 전단(20)은 소스 모듈(21)에 포함된 프로그램의 블록, 루핀, 변수 문자 값등을 설명하기 위해 심볼 테이블(30)을 발생하고 실행 가능한 코드를 설명하기 위해 하나 이상의 중간 언어 그래프(55)를 발생한다. 이하에서 이들 내부 데이타 구조를 설명한다.
일반적인, 그리고 중간 언어의, 및 특히 심볼 테이블의 제1도의 컴파일러 설계는 VAX와 같은 "컴플렉스 명령 세트 컴퓨터"(CISC)로부터 PRISM, MIPS(32비트 RISC 머신)와 같은 "감소 명령 세트 컴퓨터"(RISC)까지 범위의 각종 아케텍쳐, 또는 진보된 64비트 RISC 아케텍쳐를 어드레스하고자한 것이다. 이 설계는 타겟 머신(25)의 아키텍쳐가 어떤 기본 특징을 갖는다고 가정한다. 제1바이트 기구 및 어드레스 가능성이 가정되고 2개의 상보적인 2진수 산술이 "리틀-엔디안(Littile-endian)" 비트 오더링을 갖는 것으로 가정한다. "합리적인(Reasonable)" 어드레스 표시가 또한 가정되는데, 즉 어드레스는 레지스터에 조화된다.
일반적으로, 전단(20)은 프로그램의 중간 표시 생성시에 타겟 아케텍쳐(25)의 상세에 대해 망각할 수 있다. 중간 표시의 대부분이 구성은 타겟 아케텍쳐(25)와 무관한 잘 규정된 의미를 갖는다. 여기에는, 그러나, 전단(20)을 실시하는데 관련되어야할 몇가지 이슈가 있다. 먼저, 하기 설명되는 바와같이 모든 데이타 형태가 모든 아케텍쳐에서 이용 가능한 것은 아니다. 둘째로, 산술 오버플로우 작용 및 "작은 정수" 산술의 표시는 이후 설명되는 바와같이 다른 아키텍쳐상에서 변화될 수 있다. 세째로, (산술 시프트 연산자와 같은) 일부 연산자의 작용은 기초 머신 명령이 특수 아키텍쳐상에서 규정되는 피연산자 값의 소범위(Subrange)에 대해서만 규정된다. 이 지정된범위외의 피연산자의 값에 대해서, 상기 연산자는 어떤 특수한 머신에 대하여는 잘 작용할 수 있지만 다른 머신들상에서는 다른 작용을 가질 수 있다. 마지막으로, 콘벤션의 호출은 다른 타겟 시스템(25)상에서 다르게 되어 전단(20)이 어떤 경우에 동일 소스 언어 구성에 대한 다른 중간 표시를 발생할 것을 요구한다.
용어 "중간 언어"는 실행 가능 코드를 지정하기 위한 추상적인 언어를 나타낸다. "중간 언어 그래프" (ILG) (55)는 이 언어로 표현된 특수 프로그램이다.
그래프(55)의 중간 언어는 구문론적 구조를 제공하는 포인터를 갖는 메모리내에 데이타 구조의 언어이다. 그러나 디버그 원조(aid)로서 컴파일러에 의해 기록된 IL 덤프용으로 사용되는 ILG에 대한 대략 축어적인 표시가 또한 있을 수 있다.
IL의 소스적인 개념은 제4도를 참조하여 상기 설명한 바와같은 튜플이고, ILG(55)는 실행될 동작을 나타내는 튜플(35)로 만들어진다. 이 튜플(35)은 여러가지 관계를 나타내는 포인터(예컨대, 피연산자 포인터 35)에 의해 함께 묶여진다. 가장 중요한 관계는 연산자-피연산자 관계(그 피연산자 각각에 대한 연산자로 부터의 포인터 38) 및 ILG의 각 기본 블록내의 모든 튜플상의 선형 오더링이며, 이것은 정상적인 실행 순서를 제공한다. 이 선형 오더는 블록내의 튜플수(40)에 의해, 그리고 루틴 또는 모들의 모든 블록을 결합하는 포인터에 의해 표시된다.
ILG(55)에 의해 규정되는 계산은 다음과 같다.
(1) ILG의 BIGIN 튜플에서 시작함.
(2) 선형 오더내의 각 튜플을 평가하고, 그 피연산자의 세이브된 결과를 인출하며 그 결과를 계산 및 세이브하고, 및 그것을 위해 규정될 수 있는 어떤 이차적인 활동을 수행함.("흐름 부울" 및 "조건부 선택" 연산자에 대한 이러한 간단한 평가에는 예외가 있다)
(3) 브랜치 튜플을 평가한 후에 그 브랜치 튜플에 의해 선택된 라벨 튜플에서의 평가를 계속함.
이러한 규칙은 IL 그래프(55)의 의미를 규정한다는 것을 이해하여야 한다. 코드 발생기(29)는 하기의 규칙에 의해 지정된 바와같이 그들의 종속성을 보존하는 한, ILG 에 의해 표시된 활동을 재배열하도록 허락된다.
(1) ILG(55)가 수식 및 그 실행이 수식을 평가함으로써 계산된 값에 영향을 주는 설명문을 포함하면, 수식에 대해 발생된 코드 및 설명문에 대해 발생된 코드는 설명문 및 수식이 ILG에서 발생된 것과 동일한 순서로 실행되어야 한다.
(2) ILG(55)가 그 실행이 어떤 공통 수식을 평가함으로써 계산된 값에 영향을 주는 2개의 설명문을 포함한다면, 2개의 설명문에 대해 발생된 코드는 설명문들이 ILG에서 발생된 것과 동일한 순서로 실행되어야 한다.
설명문의 실행이 어떤 수식의 평가에 의해 계산된 값에 영향을 줄때의 의문은 이후 설명되는 부착용 메카니즘을 참조하여 해결된다.
전단(20)에 의해 구성된 ILG(55)는 후단(12)에 의해 처리된 ILG와 동일하지 않다. 전단(20)는 콤팩트 IL 그래프를 발생하고, 후단(12)은 팽창된 IL 그래프를 처리한다. 후단(12)이 어떤 루틴에 대한 코드를 발생할 때, 그것이 행하는 첫번째 일은 그 루틴의 CILG를 EILG로 확장시키는 것이다. 두개의 모양 사이에는 몇가지 차이점이 있다. 첫째로, CIL은 EIL의 하위 레벨 튜플의 시퀸스로 팽창되는 "속기" 튜플을 제공한다. 둘째로 EIL 튜플을 나타내는 노드는 CIL 튜플을 나타내는 노드보다 훨씬 더 많은 필드를 갖는다. 추가적인 필드는 후단(12)에 의해 사용된 정보를 포함하지만, 이것은 CIL 노드이 필드로부터 IL 팽창기에 의해(또는 다른 후단 페이스에 의해) 계산될 수 있다. 세째로, CILG 및 EILG 상에는 다른 구조상의 제한이 있다. 이 정보가 일반적으로 CIL과 EIL에 모두 관련된다 하더라도 이 묘사는 콤팩트 IL에 관련된다.
심볼 테이블(30)의 구조는 컴파일되는 모듈(21)의 구조를 나타낸다. 테이블(30)의 중심(heart)이 블록, 루틴 및 모듈(21)의 어휘 범위를 나타내는 블록 노드의 트리일때, 트리 구조는 그들의 네스팅 관계(nesting relation)를 나타낸다. 각각의 블록 노드에는 그 블록내에서 선언되는 심볼 노드의 리스트가 관련된다. 심볼 노드는 변수, 라벨 또는 엔트리 포인트와 같은 모듈의 상징적 엔티티를 나티낸다. 컴파일되는 모듈(21)의 일정한 값들은 문자 노드에 의해 표시된다. 문자 노드는 심볼 테이블(30) 및 ILG(55)로부터 인용될 수 있다. 용어 문자 테이블은 또한 컴파일링에서 생성된 모든 문자 노드의 수집을 인용하기 위해 사용된다. 프레임 노드는 코드 및 데이타가 할당되는 기억 영역을 표시한다. 일반적으로 이들은 루틴의 스택프레임이거나 파라미터 리스트를 만들기 위해 사용된다. 각 파라미터 노드는 루틴내의 파라미터 심볼을 엔트리 포인트의 인자 리스트내 위치와 관련시킨다.
데이타 타입 :
그래프(55)에서 사용된 중간 표시는 적은 세트의 타입만을 갖는 추상 머신(25)에 대한 프로그램을 설명하고, 그 데이타 타입은 하기 리스트에서 설명된다. 이 데이타 타입들은 전단(20)에만 관련되는 모듈(21)의 소스 언어의 데이타 타입과 구별된다. 각각의 타겟 머신(25)에 대하여 각각의 소스 언어 데이타 타입을 나타내는데 사용되는 데이타 타입을 결정하는 것은 전단(20)이 해야할 일이다.
데이타 타입
널(Null)
표시(Representational)
스칼라
어드레스
부호 정수(Signed Integer)
무부호 정수(Unsigned Integer)
부동점
복소수(complex)
부울(Boolean)
널 테이타 타입은 값을 계산하지 않은 튜플의 타입인 특수한 데이타 타입이다. 표시 데이타 타입은 그 값이 타겟 머신 아키텍쳐에서 특정 표시를 갖고 있는 타입이다. 스칼라 데이타 타입은 그 값들이 메모리 위치 또는 레지스터의 작은 고정수로 표시될 수 있는 타입이다. 상기 스칼라 데이타 타입은 어드레스 데이타 타입 및 산술 데이타 타입으로 세분된다. 산술 타입은 적당한 수의 비트에 적합될 수 있는 것 보다는 다른 종류의 데이타를 나타내기 위해 사용될 수 있다. 특히 소스 언어 문자 및 논리 데이타 타입은 정수 데이타 타입으로 나타내어져야 한다. 여기에는 단일 어드레스 데이타 타입(ADDR)이 있다. 타입 ADDR의 값은 32 또는 64비트를 갖는 2진수 정수로서 표시된다.
부호 정수 데이타 타입 INT8, INT16, INT32 및 INT64가 있는데, 여기에서 INTX-1타입의 값은X-1비트를 갖는 부호 있는 2진수 정수로서 표시되고 따라서… (2X-1)…(X-1-1)의 범위에 있다. 타입 INT8은 또한 IBYTE로서 인용될 수 있다. 타입 INT16은 또한 IWORD로서 인용될 수 있다. 타입 INT32는 또한 ILONG로서 인용될 수 있다. 타입 INT64는 또한 IQUARD로서 인용될 수 있다. 어드레스와 동일한 수의 비트를 갖는 정수 타입은 또한 IADDR로서 인용될 수 있다. 타겟 아키텍쳐(INT32 또는 INT64)에 대해 지지되는 가장 큰 부호 정수 타입은 또한 IMAX로서 인용될 수 있다. 어떤 2진수 스케일링(scaling)(PL/I에서와 같이)은 전단에 의해 제공되어야 하며, 스케일링 2진수 데이타 타입에 대한 IL 규정은 없다.
무부호 정수 데이타 타입 UINT8, UNIT16, UINT34 및 UINT64가 있는데, 여기에서 타입 UNITX-1의 값은X-1비트를 갖는 부호 있는 2진수 정수로서 표시되고, 따라서 0…(2X-1)의 범위에 있다. 타입 UINT8은 또한 UBYTE 또는 CHAR8로서 인용될 수 있다. 타입 UINT16은 또한 UWORD 또는 CHAR16으로서 인용될 수 있다. 타입 UINT32 또한 ULONG 로서 인용될 수 있다. 타입 UINT64 또한 UQUAD로서 인용될 수 있다. 어드레스와 동일한 수의 비트를 갖는 무부호 정수 타입은 또한 UADDR로서 인용될 수 있다. 타겟 아키텍쳐(UINT43 또는 UINT64)에 대해 지지되는 가장 큰 무부호 정수 타입은 또한 UMAX로서 인용될 수 있다.
부동점 데이타 타입으로는 VAX 부동점 타입인 REALF, REALD, REALG 및 REALH와 IEEE 부동점 타입인 REALS, REALT, REALQ 및 REALE가 있다. 이들 모두가 어떤 특수한 타겟 아케텍쳐에서 반드시 지지되는 것은 아니다.
복소수 데이타 타입으로는 CMPLXE, CMPLXD, CMPLXG, CMPLXS 및 CMPLXT가 있다. 콤플렉스 값은 대응하는 실수 타입의 한쌍의 값으로써 표시되며, 이것은 복소수 값의 실수부와 허수부를 표시한다. 지지된 부동점 형태에 대응하는 복소수 타입만이 특수한 타겟 아케텍쳐에서 지지된다.
총계 데이타 타입의 값은 일련의 근접 요소들로 구성된다. 총계값은 그 보디(body), 요소들의 실제 순서, 길이 및 그 시퀸스내의 요소수에 특징이 있다.
총개 타입으로는
(a) 타입 CHAR8의 요소들을 갖는 문자 스트링 타입 STR8.
(b) 타입 CHAR16의 요소들을 갖는 연장된 문자 스트링 타입 STR16.
(c) 요소들이 가능한한 단단하게 묶여진 단일 비트인 비트 스트링 타입 BITS.
(d) 요소들이(유도 부호 디지트를 갖는, 바이트마다 2개씩 묶여진 4비트 BCD 디지트로서 표시된) 10진수 디지트인 PL/I 및 COBOL 10진수 스트링 타입 DECIMAL. (DECIMAL 값은 그 정확성, (유도 부호 디지트를 계수하지 않고) 그것이 포함하는 디지트의 수, 그 규모 및 그 소수점 후에 오는 것으로 간주되는 디지트의 수에 특징이 있다.
총계 값의 요소들은 제로에서 시작하여 번호 부여된다. (이것은 소스 프로그램 스트링 인덱스를 IL 스트링 인덱스로 번역할 때 많은 전단들이 1을 감산함을 주의한다.
스트링 오퍼레이션에서 처리될 수 있는 요소의 수에는 제한이 없다. 플래그는 길이가 65535 문자를 초과 하지 않도록 보장되는 문자 스트링 표시를 전단이 나타내도록 차후에 도입된다. 따라서 이것은 VAX 문자 스트링 명령으로 충분히 계산될 수 있다. 메모리에서 가변 길이 스트링 길이 워드는 아직은 단지 16비트일 것이다. 10지수 스트링은 모든 카겟 아티텍쳐상에서 31디지틀(플러스 부호 비트)로 제한한다.
각종 타겟 아키텍쳐에 대한 대표적인 타입 시스템의 상세의 일예는 표 6에 나타내었다.
단일 부울 데이타 타입(BOOL)이 있다. 이것은 프로그램의 실행중에 계산된 논리 값의 타입이다. 이것은 특정된 물리 표시를 갖지 않는다. 예를들어, 부울 값은 2진수 정수의 값, 프로세서 조건 코드의 값 또는 프로세서 프래그램 카운터의 값에 의해 표시된다. 특히, 타입 BOOL은 소스 언어로 나타낼 수 있는 어떤 논리 또는 부울 데이타 타입에 대응하지 않는다. 이들은 INT 또는 UINT 값으로서 표시되어야 하고 필요에 따라 타입 BOOL로 또는 타입 BOOL로부터 변환되어야 한다.
이제, 중간 언어내의 모든 튜플에 공통인 일반적인 특징 및 (중간 언어내의 루틴인) ILG(55)의 구조상의 특징에 대하여 설명한다.
ILG(55)는 IL 튜플 노드(일반적으로 단지 튜플이라고 함)로 구성된다. 모든 튜플들은 표 7에 목록된 필드를 포함한다. 속성이라고 하는 다른 필드들은 특수 종류의 튜플에서만 발생한다.
심볼 테이블 노드와는 달리, 이것은 전단(20)에 의한 사용을 위해 예비된 임의 크기의 스페이스로 할당될 수 있고, CIL 튜플 노드는 여기에서 특정된 필드만 포함한다. EIL 튜플 노드는 후단 (12)에 전용인 튜플노드 어드레스로부터의 네가티브 오프셋에 위치된 추가 필드를 포함한다.
ILG내의 하나의 튜플은 2가지의 다른 방법, 즉 피연산자로서 또는 속성으로서 다른 튜플을 인용할 수 있다. 연산자-피연산자 관계만을 생각할때, CILG는 지향된 아시클릭 그래프(directed acyclic graph : DAG)이고 EILG는 숲(즉, 트리의 집합)이다.
속성 포인터(39)는 ILG상에 추가 구조를 생성하고 또한 ILG 로부터 심볼 테이블(30)로의 참조를 허용한다. 가장 중요한 구조상의 관계는 다음 튜플 및 이전 튜플 속성 포인터에 의해 규정된 ILG의 선형 순서이다. CILG내의 모든 튜플들은 선형 순서에 의해 규정된 단일 리스트에서 발생한다. EILG의 튜플은 각 기본 블록마다 하나씩 원형 리스트의 집합에서 발생한다.
하기의 규칙은 ILG의 구에 적용된다. 전단(20)이 상기 규칙을 위반하는 CILG를 생성하면, 비록 후단이 그 위반들을 검출하고 컴파일링을 종료하고자 하더라도 그 결과는 예측 불능하다.
(a) 결과 형태가 NULL인 튜플은 설명문 튜플로서 인용되고, 결과 형태가 NULL이 아닌 튜플은 수식 튜플로서 인용된다.
(b) CIL에서 :
(i) 스칼라 또는 부울식 튜플은 하나 이상의 다른 튜플의 피연산자일 수 있다. 총계식 튜플은 정확히 하나의 다른 튜플의 피연산자로서 사용되어야 하고 동일한 기본 블록에 있어야 한다(하기 참조).
(ⅱ) 피연산자는 수신 튜플, 심볼 노드 또는 문자 노드일 수 있다.
(ⅲ) 피연산자로서 사용된 심볼 노드는 항상 타입 ADDR을 갖는다. 피연산자로서 사용된 문자 모드는 문자의 데이타 타입을 갖는다.
(ⅳ) 레지스터에 할당된 변수를 나타내는 심볼은 정상적인 감각으로는 어드레스를 갖지 않는다. 그러나, 그러한 심볼은 메모리로부터 판독하거나 메모리에 기록하는(FETCH 또는 STORE) 튜플의 어드레스 피연산자로서 사용될 수 있고, 이 경우에 튜플은 지시된 레지스터를 액세스한다.
(ⅴ) 심볼이 스택 프레임의 변수를 나타내면, 그 스택 프레임은 현재의 루틴 또는 심볼 테이블 블록 트리의 전신(ancestor)들중 하나와 연합되어야 하며, 그렇지 않으면 실행시에 스택 프레임을 찾아낼 방법이 없다.
(c) EIL에서 피연산자는 수식 튜플일 수 있고, 각각의 수직 튜플은 정확히 하나의 다른 튜플의 피연산자어야 한다.
(d) 설명문 튜플은 어떤 다른 튜플의 피연산자가 아닐 수 있다.
(e) 다른 튜플의 피연산자인 튜플은 ILG의 선형 오더링에서 그 튜플을 진행시켜야 한다. (EILG 에서 이것은 피연산자 및 연산자가 동일한 기본 블록에서 발생한다는 것을 의미한다.)
(f) 수식 튜플은 피연산자인 각각의 튜블을 지배하여야 한다. 즉, 도중에 그 튜플의 각 피연산자와 마주침이 없이 루틴의 각 지점으로부터 튜플로 가져가는 것은 불가능하다.
이 섹션에서의 다음 단락은 중간 언어에서 이용할 수 있는 동작의 종류 및 그 동작을 나타내는데 사용되는 연산자를 설명한다. 개개의 연산자는 모두 <REFERENCE>(파트_튜플_딕셔너리), 튜플 딕셔너리라고 부르는 데이타 구조에 수집된다. 딕셔너리내의 각 연산자는 구성된 포맷을 사용하여 기록된다. 표 8은 이 포맷에서의 메인 카테고리, 각각의 아래에 나타나는 정보, 및 정보를 나타내는데 사용된 포맷을 나타낸다.
튜플의 포맷 섹션은 피연산자의 수를 지정하고 허락된 연산자, 피연산자 및 단일 라인의 타입의 결과 타입을 지정한다.
OP 타입(타입 1,…타입 n) : 결과
여기에서 OP는 튜플 피연산자의 이름이고 "타입"은 허용 가능한 연산자 타입을 나타낸다. "타입"이 생각되면 연산자 타입은 NULL이어야 한다. 그렇지 않으면, 타입은 하기의 것중 하나이어야 한다.
(a) 특정 타입명(ADDR, BOOL, BITS, IADDR, 등)은 단지 특정 타입의 허락됨을 나타낸다.
(b) INT, UINT, REAL, CMPLX 또는 STR은 특정군에 속한 어떤 타입의 적법함을 나타낸다. 예를들어 CMPLX는 CMPLXF, COMPLXD, CMPLXG, CMPLXS 및 CMPLXT가 모두 허락됨을 의미하고 STR은 STR8 및 STR16이 허락됨을 의미한다.
(c) ALL은 NULL 이외의 어떤 타입이 적법함을 나타낸다.
(d) 문자 I,U,R,C,A,S, 및 B의 스트링은 그 문자들중 하나에 의해 표시된 군에 속하는 타입이 다음과 같이 허락됨을 나타낸다.
I INT A ADDR
U UINT S STR
R REAL B BIT
C CMPLX
식 "타입 1,…, 타입 n"는 튜플의 피연산자의 허용 가능한 타입을 나타낸다. 괄호내의 리스트가 생략되면 연산자는 피연산자를 취하지 않는다. 그렇지 않으면 튜플은 리스트내의 각 타입에 대하여 하나의 피연산자를 가져야 한다. 각 타입 i는 하기의 것중 하나이어야 한다.
(a) T는 피연산자 타입이 연산자 타입과 같은 것이어야 한다.
(b) 특정 타입 명(ADDR, BOOL, BITS, IADDR, 등)은 피연산자가 특정 타입을 가져야 함을 의미한다.
(c) 타입 코드 문자 I, U, R, C, A, S 및 B의 스트링은 타입 지정자에 대한 것과 동일한 의미를 갖는다. "어떤 정수"를 의미하는 타입 지정자를 갖는 피연산자는 일반적으로 발생 코드에서 타입 IMAX로 변환된을 주의한다. 따라서 프로그램 작용은 그러한 피연산자의 실제값이 타입 IMAX로 변환될 수 없는 경우에는 규정되지 않는다.
(d) 연산자 및 피연산자 타입 지정자가 REAL과 CMPLX 또는 STR과 CHAR이면, 실제 연산자 및 피연산자 타입은 일치되어야 한다. 예를들어, 타입 지정 "CADD.LCMPLX(T,REAL) :T"는 연산자 타입이 CMPLX인 경우 제2피연산자가 타입 REALF를 가져야 하고 연산자 타입이 CMPLXT인 경우 제2피연산자가 타입 REALS를 가져야 한다는 것을 나타낸다. 연산자 타입이 SB, 즉, 문자 스프링 또는 비트 스프링이고 피연산자 타입 지정자가 CHAR이면 피연산자 타입은 연산자 타입이 STR8인 경우 CHAR8이어야 하고 연산자 타입이 STR16인 경우 CHAR16이어야 하며, 연산자 타입이 BITS인 경우 IMAX이어야 한다. 즉, IMAX는 스트링 타입 BITS에 대응하는 문자 타입으로써 처리된다.
튜플의 실제 피연산자는 유효 타입이 피연산자 타입 리스트에 의해 지정된 타입과 일치하는 튜플 노드이어야 한다. CIL에서, 피연산자들은 항상 타입 ADDR을 갖는 것처럼 처리되는 심볼 노드이거나 그들의 데이타 타입 필드에 의해 지정된 타입을 갖는 것처럼 처리되는 문자 노드일 수 있다.
식 "Result"는 허용 가능한 결과 타입을 나타낸다. 만일 이것이 생략되면 연산자는 설명문 연산자이고 튜플의 결과 타입은 NULL이어야 한다. 그렇지 않으면 이것은 피연산자 타입 지정자와 같은 방법으로 정확히 해석된다.
어드레스 수식은 중간 언어에서의 인용문들중 하나이다. 어드레스 수식의 가장 간단항 형태는 심볼이다. 즉, 튜플 노드의 피연산자 필드는 그 심볼과 관련된 메모리 ㅇ드레스(또는 레지스터)를 나타내도록 심볼 노드의 어드레스를 포함한다. 어드레스 값은 또한 산술 값을 캐스팅함으로써, 또는 선증분 튜플, 후증분 튜플, 또는 하기 리스트의 튜플들중 하나를 평가함으로써 메모리("포인터 변수")로부터 그 어드레스 값을 인출함으로써 얻어질 수 있다.
[어드레스 계산 연산자]
데이타 액세스 튜플은 값이 메모리부터 로드되거나 메모리에 기억되게 하는 튜플이다. (여기에서 단어"메모리"는 타겟 CPU25의 레지스터 세트내의 레지스터를 포함한다. 레지스터와 CPU25의 정상 메모리 위치 사이의 유일한 차이는 레지스터의 "어드레스"가 데이타 엑세스 튜플에서만 사용될 수 있다는 점이다.) 데이타 액세스 연산자는 표 9에 리스트된다.
각각의 데이타 액세스 튜플에서, 제1피연산자는 어드레스 수식이다. 각각의 데이타 액세스 튜플은 또한 긴 단어 정수를 포함하는 오프셋 속성을 갖는다. 액세스되는 메모리 위치의 어드레스는 구동 시간 어드레스 피연산자와 컴파일-시상수 오프셋 속성의 합이다.
모든 데이타 액세스 튜플은 표10에 리스트된 일부 또는 모든 속성을 가질 것이다. 유효, 유효 2, 및 베이스 심볼 속성의 사용은 이후 "유효 표시를 위한 인터페이스" 섹션에서 보다 상세히 설명된다.
또 다른 타입의 인용문은 어레이 인용문이나 APLUS 및 AMINUS 튜플은 모드 어드레스 계산을 위해 충분하다. 그러나, 이들은 어드레스 계산의 의미에 대하여 어떠한 정보도 제공하지 않는다. 특히, 이들은 어레이 인용문 및 또는 소스 코드에 나타나는 첨자 수식에 대하여 어떠한 정보도 제공하지 않는다. 이 정보는 백터화를 위해 필요하다. 그러므로, IL은 특히 어레이 인용문을 묘사하는 튜플을 갖는다.
예를들어, 로컬 X : 벡터[20, 롱]으로서 표시되는 BLISS 백터가 주어지면 .X[.I]에 대한 인용문은 하기와 같이 표시될 수 있다.
$1 : FETCH.INT32(I) ;
$2 : SUBSCR.LADDR($1,[4],[0] ; POSITION=1) ;
$3 : FETCH.INT32(X, $2) ;
Var Y : 0.255의 팩 어레이[1…10, 1…10]로서 표시된 파스칼 어레이가 주어지면, 대입문 Y [I,J] : =Z는 하기와 같이 표시될 수 있다.
$1 : FETCH.INT32(J) ;
$2 : SUBSCR.LADDR($1,[1],[0] ; POSITION=1) ;
$3 : FETCH.INT32(I) ;
$4 : SUBSCR.LADDR($3,[10],$2 ; POSITION=2) ;
$5 : FETCH.UNIT8(Z) ;
$6 : STORE.UNIT8($4-11, $5) ;
기본 어레이 인용문 연산자는 AREF와 SUBSCR이다. AREF는 어레이내의 지정된 요소의 어드레스를 생성한다. SUBSCR은 어레이 요소의 오프셋을 계산한다.
제1피연산자 또는 AREF 튜플은 어레이의 베이스 어드레스를 나타내는 어드레스 수식이다. 제2연산자는 베이스 어드레스로부터 어레이의 요소로의 바이트 오프셋을 계산하는 SUBSCR 튜플이다. AREF 튜플은 SUBSCR 튜플의 값을 베이스 어드레스에 가산하여 색인된 요소의 어드레스를 계산한다. 사실, AREF (원점, 첨자)의 코드는 APLUS(원점, 첨자)의 코드와 동일하다.
SUBSCR 튜플은 어레이내의 하나의 디멘젼을 따라 요소의 오프셋을 계산한다.
그 피연산자는,
(a) 요소 색인.
첨자 수식이 개개의 인덱스들을 제로 원점을 위하여 정상화되지 않는다. 그 대신 어레이 표시의 비제로 하부 바운드를 표시하기 위한 원점 오프셋을 AREF 튜플의 어드레스 피연산자 또는 요소 어드레스를 사용하는 튜플의 오프셋 필드에 가산되어야 한다.
(b) 스트라이드.
이것은 디멘젼을 따르는 연속적인 요소의 어드레스간의 차이이다. 긴 단어의 간단한 벡터를 위하여, 스트라이드는 문자 4로 되겠지만, 다차원 어레이에 대하여 고차원의 "요소"들은 어레이의 행(또는 더 큰 교차단면)이 된다.
(c) 첨자 주식의 나머지(즉, 첨자 수식의 나머지 인덱스)에 대한 수식.
이것은 다른 SUBSCR 수식 또는 정수 상수 제로를 표시하는 문자 노드이어야 한다.
SUBSCR(인덱스, 스트라이드, 나머지)에 대한 코드는 ADD(MUL(인덱스, 스트라이드), 나머지)에 대한 코드와 동일하다.
SUBSCR 튜플은 또한 위치 속성을 가지며, 이것은 어레이 인용문의 첨자 리스트내에서 인덱스의 위치를 나타낸다. 위치 번호는 주어진 어레이에 대한 모든 인용문에서 동일한 첨자 위치를 식별한다. 가장 유효적인 벡터화에 있어서, 위치 1은 가장 빠르게 변하는 첨자이어야 하고 위치 2는 그 다음으로 가장 빠르게 변화하는 첨자이어야 한다.
어떤 다른 섹션에 정말로 적합하지 않은 수개의 튜플 연산자가 있다. 이들 잡다한 연산자들은 다음과 같다.
산술 튜플 :
산술 튜플은 "산술" 값, 즉 정수, 실수, 복소수를 관리하기 위해 사용된다. 이것은 가산 및 승산과 같은 통상적인 산술 동작 뿐만아니라 인출, 기억 및 변환을 포함한다.
VAX와 RISC 아케텍쳐의 시프트 명령은 서로 다르기 때문에 완전한 추상적 IL 시프트 연산자는 하나 또는 2개의 아케텍쳐 상에서 비효율적인 코드를 발생하도록 확실하게 될 것이다. 반면에 IL은 많은 소스 언어가 몇 종류의 시프트 연산자를 갖기 때문에 시프트를 지지하여야 한다. 절충안으로서 IL은 하기의 연산자를 제공한다(시프트 연산자는 어느 것도 산술 오버플로우 예외를 일으키지 않는다.)
(a) SHL, SHR 및 SHRA는 각각 좌측 시프트, 논리 우측 시프트 및 산술 우측 시프트를 행하고 포티지브 시프트 카운트를 요구한다.(즉, 그 작용은 시프트 카운트가 네가티브인 경우에는 규정되지 않는다.) 이들은 C시프트 연산자를 지지하고 RISC아키텍쳐 시프트 명령에 직접 맵한다.
(b) SH는 그 피연산자가 포지티브이면 좌측 시프트를 행하고, 그 피연산자가 네가티브이면 우측 시프트를 행한다. 이것은 BLISS 시프트 연산자를 지지하고, VAX 시프트 명령에 직접 맵한다.
(c) ROT는 회전 연산자이다. 비록 VAX와 RISC 아키텍쳐에서는 이것을 다르게 묘사하였지만, 모든 경우에서의 실제 작용은 카운트가 카운트 피연산자의 최하위 n비트에 의해 지정되는 좌회전으로 특징지어 질 수 있다. 여기에서 n은 레지스터 사이즈의 베이스 알고리즘이다.(예를 들어 VAX와 MIPS에서 회전 카운트는 카운트 피연산자의 최하위 5비트이다)
정수 오버플로우는 또 다른 특징으로 고려된다. 모든 타겟 머신에서 소스 언어의 의미론을 만족시키며 그 의미론에 의해 부과된 구속을 받는데 가능한한 효율적으로 되는 코드가 발생되도록, IL의 정수 산술에 대한 크기를 만족시키게 하는데는 문제가 있다. 특히, (VAX와 같은)일부 머신들은 바이트와 워드 산술을 양호하게 행하며 RISC 머신은 전형적으로 단지 긴 단어 산술만을 행한다. 모든 크기 변환을 행하는 것을 VAX상에서는 소비성일 뿐이지만, 트루 바이트 또는 워드를 에뮬레이트하는 것은 RISC머신에서 비효율적이다.
하기 규칙들은 충분한 호환성을 갖는 코드 발생기가 모든 타겟 머신에 대하여 합리적인 코드를 발생하게 하기 위한 것이다(하기 INT 타입에 대해 말하여진 모든 것은 UINT 타입에 동일하게 적용된다)
(a) 수식의 결과 타입이 INTX-1이면, 컴파일러는 y비트 산술로서 지시된 계산을 수행한다(여기에서 y≥x). 이것은 원래의 x비트 계산이 오버플로우되는 경우, x이상의 주요 비트를 갖는 y비트 결과를 발생한다. 예를 들면 ADD. INT16는 32비트 가산으로서 실시된다. 20000+30000은 16비트 가산으로서 수행될때는 오버플로우를 일으키지만 32비트 가산으로서 수행될때는 적법한 32비트 수 50000을 발생한다.
(b) 각각의 산술 연산자는 억제 오버플로우 플래그(이것은 튜플 결과 타입이 INT 또는 UNIT일때에만 의미를 갖는다)를 갖는다. 이 플래그가 세트되면, 튜플에 대해 발생된 코드는 계산 결과에 관계없이 어떤 종류의 오버플로우 조건도 보고하지 않으며, (그 결과가 XCVT 튜플의 피연산자로서 사용될 때를 제외하고)그 결과에서 있을 수 있는 무관한 고차 비트의 존재를 무시할 수 있다. 억제 오버플로우 플래그는 오버플로우가 어떤 방법으로도 발생할 수 없는 (LAND와 같은)튜플에서 규정됨을 유의한다. 이들 튜플에 대한 오버플로우의 억제는 특히 용이하다. 억제 오버플로우 플래그는 오버플로우되는 동작이 어의적으로 부정확한 상황에서 의도된다. 이것은 어떤 아키텍쳐에서 비용이 매우 많이 드는 코드를 야기할 수 있다. 예를 들면 VAX에서 여분의 코드는 오버플로우 검출을 억제하기 위해 요구된다. 따라서 동작이 오버플로우되는 무형의 것이거나 특수 동작이 결코 오버플로우될 수 없음을 전단이 인식하는 경우, 이 플래그는 클리어되어 컴파일러가 가장 효율적인 코드를 발생하도록 하여야 한다.
(c) 루틴 블록 노드는 검출 오버플로우 플래그를 갖는다. 이 플래그가 클리어되면 후단은 정수 산술 동작에서 오버플로우를 검출하기 위하여 코드를 발생할 필요가 없다. 그러나 이것이 보다 효율적이며, 즉 오버플로우 검출의 강제적인 억제가 특수 튜플에 억제 오버플로우 플래그를 세팅함으로써만 달성될 수 있는 경우에는 오버플로우를 검출하는 코드를 발생하는 것은 자유이다.
(d) 검출 오버플로우 플래그가 루틴 블록 노드에서 세트되면, 발생된 코드는 각각의 수식 트리에 대하여 그 수식에 대해 계산된 결과가 유효하거나 정수 오버플로우 예외가 표시되는 것을 보장하여야 한다. 이것은 오버플로우가 수식의 가능한 각각의 부수식(Subexpression)에서 검출되는 필요 조건이 아니다. 예를 들어서 A, B, C 및 X가 16비트 변수로서 A는 32767이고 B와 C는 1이라고 가정한다. 지령 X : A+B-C에서, 발생된 코드는 32비트 아키텍쳐를 사용하여 A+B-C를 계산하고, 그 다음에, 그 결과가 16비트 결과인지를 그 기억이전에 체크한다. 이것은, 16비트 산술에 의해 계산된 경우 동일한 수식이 정수 오버플로우 에러를 발생한다 하더라도 정확한 답 32767을 기억한다. 반면에, 지령 X : A+B는 값 32768을 정확히 계산하지만 그 다음에 그것을 X에 기억시키려고 할 때 오버플로우 예외를 발생한다. 오버플로우가 검출되어야 하는 장소의 수집은 명확하진 않지만 우측의 기억 및 루틴 호출에서의 인자를 반드시 포함한다.
(e) 피연산자의 값을 복귀시키고 그 표시의 어떤 잡다한 고치 비트들이 실제 피연산자의 부호화 일치하도록 하는 XCVi변환 연산자를 또한 통지한다. 예를 들어, E가 32비트 산술을 사용하여 평가된 UINT8 수식이라면, XCVT.UINT8(E : INT16)은 상위 8비트가 제로로되는 16비트 정수일 것이다. 일반적으로 E가 타입 T의 수식이면 XCVT.T(E : T)는 값의 표시가 그 정상적인 크기와 일치되게 하는데 사용될 수 있다.
(f) 어떤 수식에서 정수 피연산자의 표시가 피연산자의 정상 크기를 초과하는 상위 비트를 포함하면 발생된 코드는 충분히 표시된 값 또는 정상 크기에서의 값을 사용하도록 자유로워진다. 이것이 허용 불능일때, 전단은 그 표시로부터 원치않는 상위 비트를 버리도록 XCVT 튜플을 발생하여야 한다.
부동점 오버플로우 예외의 검출을 디세이블시키는 어떠한 메카니즘도 IL에는 없다. 부동점 오버플로우는 항상 예외 표시를 발생한다. 부동점 언더플로우의 표시는 루틴 레벨에서만 제어된다. 루틴 블록 노드는 검출 언더플로우 플래그를 갖는다. 이것이 세트되면, 컴파일러는 그 루틴에서 발생하는 어떤 부동점 언더플로우를 검출 및 보고하는 코드를 발생해야 한다. 그렇지 않으면, 발생된 코드는 부동점 언더플로우를 무시하여야 한다.
변환 연산자는 다른 산술 타입의 값에 관련되는 하나의 산술 타입의 값을 계산할 것이다. 실수-정수 변환을 위한 ROUND 및 TRUNC연산자, 실수-복소수 변환을 위한 CMPLX 연산자 및 복소수-실수 변환을 위한 REAL 및 IMAG 연산자는 모두 유사하다(ROUND와 TRUNC는 또한 실수 결과 타입으로써 규정된다).
CVT는 범용의 변환 연산자이다. 이것은 어떤 두개의 산술 타입 사이에서 변환을 행한다. 이것은 직접 행하여지는 유일한 변환이 UINT-INT, INT-REAL, 및 REAL-CMPLX(및 물론 INT16-INT32와 같은 타입내의 변환)이라는 것을 인식하는 것은 중요하다. 이것은 예를 들면 CMPLXG-UINT16 변환이 실제로 일련의 변환 CMPLXG-REALG, REALG-INT32, INT32-UINT16으로서 수행된다는 것을 의미한다. 이것은 VAX 파스칼의 작용이 아니며, VAX 파스칼은 실수-무부호의 직접적인 변환을 행한다.
XCVT는 정수 타입으로서만 처리되는 특수 연산자이다. CVT와 같이, 이것은 그 피연산자와 산술적으로 동일한 그 결과 타입의 값을 산출한다. 그러나, 이것은 피연산자 표시가 그 값과 산술적으로 동일하도록 피연산자의 표시 상위 비트를 첫번째로 변환시키는 특징을 갖는다.
예를 들어 하기의 식을 생각한다.
XCVT(ADD.UINT8([UINT9=255],[UINT=2]) : INT16).
수식이 32 비트 산술로써 계산되면 ADD의 결과는 레지스터가 포함하는 %X00000101(257)로 된다. XCVT는 그 다음에 이미 유효 16비트 부호 정수로 되어 있는 %X00000001(1)를 남기고 상위 비트를 디스카드한다.
CAST는 값이 아닌 비트 패턴을 다루기 때문에 변환 연산자가 아니다. CAST 튜플은 그 피연산자와 동일한 비트 패턴을 갖는 그 결과 타입의 값을 산출한다(만일 필요하다면 제로 비트의 잘라 줄이거나 연결시킨다).
또 다른 타입은 변수 수정 연산자이다. OPMOD(여기에서 OP는 ADD, LAND등임)로부터의 명칭을 갖는 연산자들은 모두 어드레스 피연산자 및 값 피연산자를 갖는다. 이들은 지정된 어드레스로부터 산술값을 인출하고, 그것과 값 피연산자 사이에서 지시된 동작을 수행하며, 동일 어드레스에서 결과적인 후단(back)을 기억한다. 이들은 또한 계산된 값을 산출하여, C ; s op=연산자를 실시하도록 의도된다. 예를 들어서, 코드 시퀸스
$1 : ADDMOD.REALF(X,[%F0.1]) ;
$2 : STORE.REALF(Y,$1) ;
는 다음과 같은 유효를 갖는다.
$1 : FETCH.REALF(X) ;
$2 : ADD.REALF($1,[%F0.1]) ;
$3 : STORE.REALF(X. $2) ;
$4 : STORE.REALF(Y, $2) ;
이 연산자들은 또한 OPMODA 및 OPMODX 형태를 가지며, 묶여진 어레이 요소 또는 비트 필드내의 값을 인출 갱신 및 교체한다.
PREINCR.PREINCRA 및 PREINCRX 연산자는 값 피연산자 대신 이들의 컴파일 시상수 증분값을 포함하는 속성 필드를 갖는다는 것을 제외하면 ADDMOD, ADDMODA 및 ADDMODX와 본질적으로 동일하다. 이들은 산술 변수 뿐만 아니라 어드레스(포인터 변수)에도 적용될 수 있다. 이들은 C의 선증분 및 선감분 연산자를 실시하도록 의도된다.
POSTINCR, POSTRINCRA 및 POSTRINCRX 연산자는 튜플의 값이 메모리 위치에 기억되어 있는 값이라기 보다는 그 갱신전에 메모리 위치가 유지하고 있는 값이라는 것을 제외하면, PREINCR 및 PREINCRX 튜플과 동일하다. 이들은 C의 후증분 및 후감분 연산자를 실시하도록 의도된다.
스트링 :
컴파일러의 스트링(또는 집합) 타입은 그 값들이 베이스 타입으로부터 값의 시퀸스인 타입이다. 이 타입들은 다음과 같다.
STR8, 8비트 문자의 시퀸스(타입 CHAR8).
STR16, 16비트 문자의 시퀸스(타입 CHAR16).
BITS, 단일 비트의 시퀸스.
DECIMAL, 십진수 디지트 및 관련 정밀도의 시퀸스.
문자 또는 비트 스트링 시퀸스의 요소들은 0에서부터 n-1까지 번호가 부여되어 있으며, 여기에서 n은 스트링 길이를 나타낸다. 8비트 문자 스트링이 어드레스 A에서 메모리에 표시되면, 어드레스 A에서의 바이트는 그 스트링의 첫번째 문자를 포함하고 어드레스 A+1에서의 바이트는 그 스트링이 두번째 문자를 포함하며, 이와 같이 하여 어드레스 A+n-1에서의 바이트는 그 스트링의 최종 문자를 포함하게 된다. 16비트 문자 스트링이 어드레스 A에서 메모리에 표시되면 어드레스 A에서의 워드는 그 스트링의 첫번째 문자를 포함하고, 어드레스 A+2에서의 워드는 그 스트링의 두번째 문자를 포함하며, 이와 같이 하여 어드레스 A+2(n-1)에서의 워드는 그 스트링의 최종 문자를 포함한다. 비트 스트링이 어드레스 A에서 메모리에 표시되면 그 스트링의 첫번째 8비트는 어드레스 A+1에서 그 바이트의 최하위 비트에서 최상위 비트까지 된다.
집합 값들은 일반적으로 레지스터에서 발생할 수 있는 스칼라 값과는 달리, 또는 머신 명령어에서의 문자 피연산자와 같이 메모리의 어디에서든지 표시되어야 한다. 그러나 중간 언어의 의미론적 모델은 스트링이 스칼라와 같이 인출되고, 관리되며 기억될 수 있다는 것이다. 컴파일러는 중간 스트링의 값을 유지하도록 템포러리를 할당하는 임무를 갖는다.
스트링 동작을 위해 발생된 코드는 피연산자들간에 오버랩이 있을 때에는 이 모델과 일치하여야 한다. 예를 들어서, IL 설명문 STOREF.STR8(A+1,[20], FETCHF.STR8(A,[20])은 20문자 스트링을 메모리의 한 위치로 이동시킨다. A에서 문자의 20개 카피를 만드는 것을 간단하지 않다.
스트링은 그 길이가 제로이면 비어있다고 말하여진다. 머리는 비어 있지 않은 스트링의 첫번째 요소를 복귀시키는 기능이 있고 꼬리는 비어있지 않은 스트링의 첫번째를 제외한 모든 요소들을 포함하는 스트링을 복귀시키는 기능이 있으며, 공백은 스트링이 비어 있으면 참이고 그렇지 않으면 거짓인 기능이 있는 것으로 한다. 이때 두개의 스트링 X와 Y간의 관계는 표준 비교 연산자(EQL, NEQ, LSS, LEQ, GTR, GEQ)에 의해 테스트될 때 다음과 같이 정의된다.
empty(X)∧empty(Y)이면 X=Y.
empty(X)∨empty(Y)이면 X<Y.
-empty(X)∧empty(Y)이면 X>Y.
-empty(X)∧-empty(Y)∧head(X)<head(Y)이면 X<Y.
-empty(X)∧-empty(Y)∧head(X)>head(Y)이면 X>Y.
-empty(X)∧-empty(Y)∧head(X)head(Y)이면 rel(X,Y)
=rel(tail(X),tail(Y))
어떤 언어(파스칼 등)내의 스트링 비교 연산자는 동일한 길이의 스트링상에서만 동작하여, 더긴 스트링의 길이에 비교하여 더 짧은 스트링을 패딩한다. 따라서, IL은 또한 패딩된 스트링 비교 연산자 EQLP, NEQP, LSSP, LEQP, GTRP 및 GEQP를 갖는다.
모든 스트링 연산자는 표 12에 리스트되어 있다.
부울(Boolean) :
표시적인 데이타 타입과는 달리, 부울 데이타 타입은 유일한 표시를 갖지 않는다. 프로그램 실행중에 부울 값들은 2진수 정수내의 어떤 비트 값에 의해 명백하게, 또는 취해지는 특수 코드 명로에 의해 암시적으로 표시될 수 있다. 유일한 표시가 없기 때문에 부울 데이타 타입은 IL에 부울 변수를 가질 수 없다. 그러나, 대부분의 소스 언어는 표시적인 값의 논리적 해석을 제공하며 많은 것이 논리적인 또는 부울 변수의 선언을 허용한다. 그러므로 연산는 부울값과 그들 소스 언어의 2진 표현 방식 사이에서 변환할 필요가 있다.
LBSET 연산자는 그 최소의 유효 비트를 테스트함으로써 부울로서 정수를 해석하고, NONZERO 연산자는 전체 정수가 0인지 아닌지를 테스트함으로써 부울로서의 정수를 해석한다. LSBIT연산자는 정수로서의 부울값을 비트 패턴 "00…00" 또는 "00…01"로 나타내고, ALLBITS 연산자는 정수로서의 부울값을 비트 패턴 "11…11"로 나타낸다. 이들 연산자는 다음과 같은 각종 소스언어에서의 부울값의 2진 표현 방식을 입증한다.
비록 부울값은 표현 방식을 가지지 않아 명목상의 리터럴 노드로 표현될 수 없을 지라도 모든 정규 IL 변환을 부울식에서 적용할 수 있게 하는 것이 대단히 바람직하다. 그러나 추위(12)는 2개의 특별한 리터럴 노드를 제공하며, 리터럴 노드의 어드레스는 전역변수(global variable) GEM $ ST_G_TRUE와 GEM $ ST-G-FALSE에 포함되어 있다. 이들 리터럴 노드는 정적 기억 장소에 사용될 수 없으나 ILG에서 피연산자로서 사용될 수 있다.
AND 및 OR 연산자를 포함하는 부울식은 두개의 상이의 방식, 즉 완전 계산(full evaluation) 및 흐름 또는 단락 계산 방식으로 계산될 수 있다. 완전 계산에서 두개의 피연산자는 실제의 모드 결과를 산출하기 위해 완전히 계산되어 피연산자로서 사용된 실제 모드값을 AND 또는 OR 명령에게 제공한다. 흐름 또는 단락 계산으로 제1피연산자는 계산된다. 만약 부울식의 값이 제1피연산자의 값에 의해 결정되며, 제2피연산자는 스킵된다. 그렇지 않으면 제2피연산자는 계산되고 부울식의 값은 제2피연산자의 값이 된다.
몇몇 소스언어는 AND 및 OR식의 완전 계산을 필요로 하고 다른 소스언어는 단락 계산을 필요로 하거나 (또는 단락 계산용의 특별한 연산자를 가지며), 나머지 소스언어는 컴파일러에 대한 선택을 제외하고는 계산의 종류를 특정하지 않는다. 3개의 연산자 세트는 이들 3가지 경우에 대하여 제공된다 ;
(1) LANCD 및 LORC("논리적 AND 조건" 및 "논리적 OR 조건")는 흐름 부울 연산자이다. 그들은 그들의 제1피연산자를 계산하면 그들의 제2피연산자의 계산을 바이패스할 수도 있다.
(2) LANDU 및 LORU("논리적 AND 무조건" 및 "논리 OR 무조건")은 완전 계산 부울 연산자이다. 그들은 명목 2진 연산자처럼 작용하여 2개의 완전히 계산된 피연산자가 식으로부터 결과치를 계산해낸다.
(3) LAND 및 LOR("논리 AND" 및 "논리 OR")은 계산의 종류나 피연산자의 차수를 특정하지 않는 CIL 연산자이다. IL 확장동안 그들은 LANDC과 LORC 또는 LANDU와 LORU 튜플(tuple)에 의해 고체될 수도 있다. 더욱이 그들이 LANDC와 LORC 튜플에 의해 교체되었을때 그들의 피연산자는 그들의 제1피연산자를 계산하는 값이 그들의 제2피연산자를 계산하는 값보다 크게 되도록 나타나면 상호 교환될 수 있다.
후단(12)는 LAND, LOR, LANDC 또는 LORC 튜플의 각 피연산자에 속하는 튜플을 식별할 수 있어야만 한다. CIL에서, FLOWMARK 튜플은 이러한 목적을 위하여 사용된다. 이들 튜플중 하나의 제1피연산자와 연관된 모든 튜플은 제2피연산자와 연관된 모든 튜플에 즉시 앞서야만 한다. 여기서 제2피연산자는 부울 연산자 튜플 자체에 즉시 앞서야만 한다. 이들 튜플의 하나중 임의의 피연산자와 연관된 제1튜플은 FLOWMARK 튜플에 의해 선행되어져야만 한다.
예컨대,
$1 : FLOWMARK ; ! 제1피연산자의 시작
$2 : FETCH(X) ;
$3 : GTR($2,[0]) ;
$4 : FLOWMARK ; ! 제2피연산자의 시작
$5 : FETCH(X) ;
$6 : LSS ($5,[0]) ;
$7 : LAND($3,$6) ; ! 연산자 튜플
선택 연산자는 부울 피연산자 값에 따라 임의의 타입의 두 값중 하나를 선정할 것이다. 논리 OR와 AND튜플처럼 3개의 선택 튜플이 있다 ;
(1) SELC는 그 제1피연산자가 참이냐 거짓이냐에 따라 제2 또는 제3피연산만을 평가할 것이다.
(2) SELU는 항상 그 피연산자 3개 모두를 평가할 것이고, 제2 또는 제3피연산중 어느 하나의 값을 선택할 것이다.
(3) SEL은 평가의 타입을 특정하지 않는 CIL 연산자이다. 그것은 IL 확장동안 SELC 또는 SELU 연산자에 의해 대체된다.
또한 논리 AND 및 OR 튜플처럼 SEL 및 SELC는 그들 피연산자와 연관된 튜플이 피연산자 치수로 연속되고 FLOWMARK 튜플에 선행할 것을 요구한다.
예컨대,
$1 : FLOWMARK ; ! 제 1피연산자의 시작
$2 : FETCH(X) ;
$ 3 : GTR($2,[0]) ;
$ 4 : FLOWMARK ; ! 제2피연산자의 시작
$ 5 : FETCH(X) ;
$ 6 : FLOWMARK ; ! 제3피연산자 시작
$7 : FETCH(X) ;
$8 : NEG($7) ;
$9 : SEL(#3, $5,$6) ; ! 연산자 튜플
또는
$1 : FLOWMARK ; ! 제 1피연산자의 시작
$2 : FETCH(X) ;
$ 3 : GEQ($2,[0]) ;
$ 4 : FLOWMARK ; ! 제2피연산자에 대한 코드 없음
$ 5 : FLOWMARK ; ! 제3피연산자 시작
$ 6 : FETCH(X) ;
$7 : SEL($3,[0],$6) ; ! 연산자 튜플…제2피연산자의 기록
모든 부울 연산자는 표 13에 수록하였다.
실행시간 체킹 ;
연산자를 체크하는 것은 프로그램의 실행중에 어떤 조건이 참이며, 그 조건이 참이 아니면 어떤 예외를 야기시키는지를 확인하는 것이다. ASSERT 연산자를 제외하고 모든 연산자의 체크는 그들 제1피연산자의 값을 복귀시킨다. 모든 튜플 체킹은 조건이 참이 아니면 신호로 알리도록 된 예외를 특정하는 조건 필드와 예외가 신호로 알려진 후 제어가 복귀되는지를 표시하는 연속될 수 있는 필드를 가진다. 만약 제어가 예외후에 튜플 체킹으로 복귀하면 그 튜플 체킹은 예외가 발생하지 않았다면 복귀되는 값과 동일한 값으로 복귀할 것이다. 연산자 체킹은 표 14에 수록되어 있다.
[흐름 제어]
ILG(55)은 기본 블럭으로 만들어진 것이다. 기본 블럭은 브랜치 타겟 튜플로 시작해서 브랜치 튜플 또는 흐름 종단 튜플로 종료하는 튜플의 시퀀스이다. 기본 블럭은 상기 시작시에만 진행되고, 원칙적으로 그 안의 모든 코드는 상기 종료시에 제어가 그 밖으로 빠져나오기 전에 실행된다(그러나 상술한 조건 계산을 참조).
CILG에서 기본 블럭은 끝과 끝이 연결되어 있다. 기본 블럭의 종료시에 브랜치 튜플은 제어가 그것으로부터 LABEL 튜플로 시작해야만 하는 기본 블럭으로 흘러가면 생략될 수도 있다. 유사하게 기본 블럭의 시작시에 LABEL 튜플은 그것에 브랜치가 없으면 생략될 수 있다(즉, 만약 후단이 브랜치 튜플에 의해 선행되지 않는 LABEL을 만나면 후단은 그것에 대해 브랜치를 삽입하고 ; 만약 후단이 브랜치 타겟 튜플에 의해 후속되지 않는 브랜치 튜플을 만나면 후단은 동기화된 라벨 심볼로 LABEL 튜플을 삽입한다). IL 확장 페이스는 그들 사이의 관계를 나타내기 위하여 각 기본 블럭에 대한 튜플의 순환 리스트를 개별적인 흐름 그래프 데이타 구조와 함께 제작한다.
기본 블럭내에서 흐름은 은연중에 선형 튜플 순서화를 따른다. 기본 블럭들간의 모든 흐름은 은연중에 흐르는 제어 튜플로 표현되고 ILG의 기본 블럭은 루틴의 의미에 영향을 미치지 않는 임의의 순서로 배열될 수 있다.
각 기본 블럭의 시작시에 브랜티 타겟 튜플은 심볼 테이블 내의 엔트리 심볼 노드 또는 라벨 심볼에 관한 포인터를 포함한다. 기본 블럭간의 제어 흐름은 브랜치 튜플의 속성인 데스티네이션 리스트(destination list)에 의해 표현된다. 데스티네이션 리스트의 각 노드는 라벨 심볼 도는 엔트리 심볼 노드를 지시하며, 이 라벨 심볼 또는 엔트리 심볼 노드는 제어가 그 기본 블럭과 함께 시작하는 기본 블럭에 전달될 수 있는지를 표시하기 위하여 동일 루틴의 일부 브랜티 타겟 튜플에 의해 또한 지시된다.
브랜치 타겟 튜플은 기본 블럭의 출발을 표시한다. 모든 브랜치 타겟 튜플은 다음과 같은 속성을 갖는다.
브랜치 튜플은 기본 블럭의 종료를 표시하고 그 후속자를 특정한다. 모든 브랜치 튜플은 다음과 같은 속성을 갖는다.
데스티네이션 리스트는 그들의 다음 필드에 의해 함께 연결된 데스티네이션 노드의 리스트이다. 브랜치 튜플의 데스트네이션 리시트 필드는 이러한 리스트의 제1데스티네이션 노드에 관한 포인터를 포함한다(데스티네이션 노드는 단 하나의 데스티네이션 리스트에서 발생할 수 있으며, 데스티네이션 리스트는 단 하나의 브랜치 튜플에 의해 지시될 수 있음을 주의하라. 비록 2개의 브랜치가 동일한 데스티네이션을 가지더라도, 그들은 동일하더라도 분명한 데스티네이션 리스트를 가져야만 한다) 각 데스티네이션 노드는 라벨 또는 엔트리 심볼 노드에 대한 포인터를 포함하는 타겟 필드를 갖는다. 데스티네이션 노드는 기본 블럭에 대한 제어의 포텐셜 트랜스퍼를 의미한다. 기본 블럭의 브랜치 타겟 튜플의 라벨 심볼 필드는 동일 심볼 노드에 대한 포인터를 포함한다. 2종류의 데스티네이션 노드가 있다. 대부분의 종류의 브랜치 튜플은 단일 데스티네이션 노드를 사용하고, 데스티네이션 리스트의 그 위치에 의거하여 데스티네이션을 선택한다. 그러나 BRSEL 튜플은 선택기 데스티네이션 노드를 사용하고 데스티네이션의 선택기가 튜플의 피연산자 값과 부합하는 데스티네이션을 선택한다. 선택기 데스티네이션 노드는 추가 필드의 로우 테스트와 하이 테스트, 2개의 긴단어 정수를 갖는다. 이것은 만약 피연산자 값이 데스티네이션의 로우 테스트와 하이 테스트 값 사이에 해당하며 피연산자 값과 부합한다.
데스티네이션 리스트와 함께 한세트의 데스티네이션을 특정하고 튜플 피연산자에 의거하여 그들중의 하나를 선정하는 정규 브랜치 연산자와 달리 간접 브랜치 연산자(JUMP 및 JUMPLOCAL)는 어드레스식(통상 라벨 변수)에 의해 특정된 어드레스로 전달되도록 제어를 야기시킨다. 이들은 goto 할당된 FORTRAN이나 라벨 변수를 통과한 PL/I에 사용되는 연산자이다.
후단은 그것이 루틴 흐름 그래프를 정확하게 세울 수 있도록 간접 브랜치 튜플의 가능한 데스티네이션을 알게할 필요가 있다. 그러므로 간접 브랜치 튜플은 정규 브랜치 연산자처럼 데스티네이션 리스트를 갖는다.
그러나 그들의 데스티네이션 리스트는 단일 데스티네이션(이것은 JUMP 튜플에 대해 선택적임) 만을 포함한다. 이 데스티네이션 노드의 타겟 라벨은 VBRANCH 튜플에 의해 즉시 계속되는 VLABEL 튜플은 식별한다. VBRANCH 튜플의 데스티네이션 리스트는 간접 브랜치의 이 루틴에서 실제로 가능한 모든 데스티네이션을 일람표로 만든다.
VLABEL 튜플과 VBRANCH 튜플의 조합은 가상 기본 블럭으로서 언급된다. 어떠한 코드도 이것에 대해 항상 발생되는 것이 아니다(이것이 VLABEL 및 VBRANCH 사이에 어떠한 다른 튜플도 존재해서는 아니된다는 이유이다). 이것은 제어가 간접 브랜치로부터 가상 블럭의 임의의 후속자로 통과할 수 있다는 사실을 나타내준다. 이것은 많은 간접 브랜치들이 동일한 세트의 가능한 데스티네이션을 가지면 단일의 가상 기본 블럭은 그들 모두의 가상 데스티네이션을 나타낼 수 있다는 장점을 가지고 있다.
모든 루틴에는 다른 하나의 가상 기본 블럭이 있다. 이것은 BEGIN 및 ENTRYPTR 튜플로 구성되는 블럭이다. 실행은 항상 ENTRY 튜플에서 시작하기 때문에 이것에 대해 어떠한 코드도 발생되지 않으나, 이것은 후단에 대한 루틴의 모든 엔트리 점을 확인한다.
기본 블럭은 브랜치 튜플 또는 흐름 종료 튜플과 함께 종료될 수 있다. 제어가 흐름 종료 튜플에 도달하면, 이것은 현재의 루틴을 완전히 떠난다. 흐름 종료 튜플은 현재 루틴의 데스티네이션으로 제어를 전송하지 않기 때문에 그들은 데스티네이션 리스트 및 타겟 심볼 속성을 가지지 않는다.
JUMP 연산자는 만약 이것이 데스티네이션 리스트를 갖지 않는다면 흐름 종료 연산자인 것이 효과적이다. 왜냐하면 그것은 현재의 루틴에서 어떠한 가능한 데스티네이션도 가지지 않는다는 것을 의미하기 때문이다. JUMPSYMBOL은 CIL에서 알려진 라벨로의 비지역적 goto를 나타내기 위하여 사용되는 흐름 종단 연산자이다 ; EIL에서는 이러한 비지역적 JUMP가 그것에 대신할 수 있다.
모든 흐름제어 연산자는 표 15에 수록되어 있다.
루틴 호출 및 파라미터 통과 ;
3가지 유형, 즉, 제어, 파라미터, 복귀값의 연결 규칙이 있다. "연결 규칙(linkage convention)"이라는 용어는 호출 루틴 및 호출된 루틴을 서로 적당하게 대화할 수 있게 하는 발생된 코드에 관한 모든 규칙을 말한다. 이들 규칙중의 일부는 코드 발생기(29)에 내장되어 있다. 다른 경우에는 호출 및 호출된 루틴에 대하여 일관성 있게 만들어져야만 하는 선택(choice)이 있다. 이들 선택중의 일부는 셀에 의해 만들어질 것이며(이것이 양 루틴에 액세스하면) ; 다른 것은 전단(20)에 의해 만들어지고 심볼표(30) 및 ILG(55)에서 인코드 되어야만 한다.
제어 연결 규칙은 호출된 루틴의 실행 문맥을 확립하고 제어를 호출 루틴으로 복귀시키기 위하여 호출 루틴으로부터 호출된 루틴으로 제어를 통과시키도록 실행되어야만 하는 명령들을 정의한다. 제어 연결 규칙은 호출된 루틴에 대한 엔트리 심볼 노드 및 호출 루틴의 INITCALL 및 CALL 튜플에 의해 결정된다. CALL 튜플의 피연산자가 외부 레퍼런스가 아닌 엔트리 심볼 노드에 관한 레퍼런스인 CALL 튜플은 확인된 호출이며, 라인에서 호출된 루틴을 번역하거나 또는 호출된 루틴의 주문된 카피를 발생시킬 정도까지 이것에 대한 연결을 선정하도록 완전히 자유롭다. 미식별의 호출에 관여하는 INITCALL 튜플의 호출 규칙 필드는 그 호출을 이용하기 위하여 제어 연결 규칙을 특정해야만 한다. 이 필드의 값은 열거된 유형의 GEM $ CALLING_CONVENTION로부터 온 것이어야만 한다. 이들 상수는 다음의 표에 정의되어 있다.
루틴 블럭 노드는 표준 엔트리 필드를 가지며, 이 필드는 이 루틴에 대하여 미식별된 호출에 의하여 호출될 이 루틴의 카피를 위하여 무선 제어 연결 규칙이 사용되는지를 특정한다. 이 필드의 값은 그 상수가 다음 표로 정의되는 열거된 유형의 GEM $ ENTRY_CONVENTION으로부터 온 것이어야만 한다.
파라미터 연결 규칙은 다른 유형이다. 루틴 호출은 호출된 루틴에 대해 이용할 수 있는 인자(argument)를 만든다. 그 인자 리스트는 약정에 의해 호축된 루틴과 호출 루틴 양자 모두에 알려진 위치(어드레스가 몇몇 표준 레지스터에 포함된 메모리 블럭내의 레지스터 또는 위치)에 있는 스칼라 값(종종 어드레스)의 수집이다.
호출된 루틴의 형식상의 파라미터는 파라미터 플래그 세트인 변수 심볼 노드에 의해 표현된다. 파라미터 심볼과 연관된 어드레스는 호출 루틴에 의해 특정된 기억 위치이거나 호출 루틴에 의해 통과된 데이타의 카피를 포함하는 지역적 기억 위치이다("어드레스"는 실제로 레지스터를 특정할 수 있음을 기억하라). 이것은 인자 리스트로부터 유래한 것이며, 메카니즘과 후술하는 파라미터 심볼의 의미 플래그로부터 유래한 것이다.
파라미터는 파라미터 변수와 연관된 어드레스가 호출 루틴에 의해 통과된 기억 위치(실제의 기억 위치)의 어드레스이면 바인드 의미론(bind semantics)을 가진다. 이것은 만약 컴파일러가 호출된 루틴(지역적 기억위치)에서 이것에 대한 기억을 할당하고, 필요할때 실제의 기억 위치와 지역적 기억 위치 사이의 카피를 발생시키면 카피 의미론은 가진다(바인드 의미론과 함께 파라미터의 지역적 기억 위치는 그 실제의 기억 위치와 동일하다.
컴파일러는 표 10-3에 수록된 플래그와 루틴 내의 파라미터의 관용적인 패턴에 근거하여 파라미터에 관한 카피의미론을 사용하는지 또는 바인드 의미론을 사용하는지를 선택할 것이다("별명 calias)효과들"은 CTO. 70, 데이타 억세스 모델에 언급되어 있다. 간략하게 설명하면 그들은 실제의 기억 위치가 파라미터 심볼을 통과하는 것을 제외한 다른 것에 액세스될 수 있는 통로이다. 이것은 실제의 기억 위치일 수 있는 비지역적 변수에 대한 직접 래퍼런스, 디레퍼런스 효과(dereference effects), 실제의 기억 위치에 액세스할 수 있는 다른 루틴에 대한 호출을 포함한다.
표 17은 그들이 각종 소스언어에 대해 설정될때의 파라미터 의미 플래그의 사용을 나타낸 것이다.
파라미터 메카니즘은 어떤 호출 루틴이 호출된 루틴으로 통과되기를 원하고 무엇이 인자 리스트에 실제로 기억되는지 그들 사이의 관계를 특정한다 인자 튜플은 메카니즘을 특정하는 메카니즘 필드를 가지며, 그 메카니즘에 의해 이 인자는 통과될 것이다. 이들 필드의 값은 그 상수가 표 18에 수록되어 있는 열거된 유형의 GEM $ MECHANISM으로부터 와야만 한다.
만약 파라미터 변수의 미지 사이즈의 플래그가 거짓이며, 그 파라미터의 사이즈는 컴파일 시간에서 알려지며 그 사이즈 필드에 의해 특정된다. 만약 미지의 사이즈가 참이면 그 파라미터의 사이즈는 컴파일 시간에서 알려지지 않는다. 미지 사이즈 파라미터의 사이즈는 만약 그것에 어레이, 스트링 또는 어드레스 및 길이(길이 파라미터와 연관된 레퍼런스) 메카니즘을 가지면 실행 시간에서 결정될 수 있다. 분리 길이 단어가 어드레스 및 길이 메카니즘과 함께 통과되고 파라미터가 기호군 데이타 타입을 가지면, 길이 인자는 바이트로서가 아니라 엘리먼트(비트 또는 캐릭터)의 파라미터 사이즈로서 해석된다. 더욱이 파라미터가 그 스트링 표현 방식이 변화하는 등의 캐릭터 스트링이면, 그 사이즈는 스트링의 현재의 사이즈가 아니라 최대 사이즈이며 스트링의 테스트 부분에만 공급되고 스트링 길이 단어 또는 널 터미네이터를 필요로 하는 공간에는 공급되지 않는다. 파라미터는 비록 컴파일러가 얼마나 많이 카피하는 지를 알지 못하더라도 카피 의미론을 가질 수 없다는 점에 주의하라. 만약 실제의 파라미터 사이즈가 컴파일 시간에서 알려져 있지 않고 실행 시간에서 컴파일러에 의해 계산될 수 없으면 전단은 바인드 의미론의 사용을 담보하기 위하여 파라미터의 머스트 바인드 플래그(must bind flag)를 설정해야만 한다.
다른 타입은 복귀값 연결 규칙이다. 호출된 루틴은 정보를 두가지 방법으로 그 호출기에 복귀시킬 수 있다. 첫번째 방법은 출력 파라미터를 사용하는 방법이다. 이것은 값보다는 메카니즘과 함께 통과되는 변수이므로 호출된 루틴은 하나의 값을 그 안에 기억할 수 있다. 두번째 방법은 복귀값으로 하는 방법이다. 복귀값은 호출된 루틴에 의해 계산되어 호출기로 "복귀"되는 값이다. 여기에서 복귀값은 특별한 결과 튜플을 통한 식의 값으로서 이용 가능하게 된다.
스칼라 값은 레지스터로 복귀될 수 있다. 예컨대, 거의 모든 우리의 언어는 표준 레지스터에서 연산 기능값을 복귀시킨다 ; 그리고, BLISS "출력 파라미터" 특징은 루틴이 임의 레지스터 값을 복귀시키도록 한다.
스트링을 복귀시키기 위한 루틴에 관하여는 복귀값에 대한 일시적인 버퍼를 할당하고 그 어드레스를 호출된 루틴으로 통과시키기 위하여 인자 리스트의 튜플과, 복귀값을 상기 버퍼에 기억시키기 위한 튜플과, 또 버퍼로부터 그 값을 검색하기 위한 호출기의 듀플이 존재하여야만 한다.
복귀된 스트링의 사이즈가 호출된 루틴에 의해 결정되면 호출기는 이것이 그 결과가 얼마나 큰지를 미리 알 수 없기 때문에 그 결과에 대한 공간을 바로 할당할 수 없다. 표 19에 수록된 메카니즘은 이러한 가능성을 제공한다. 이들 메카니즘은 특별한 튜플을 통하여 제공된다. 그러나 이들의 유용성은 타겟 환경의 호출표준에 좌우된다.
호출기는 (1) 호출된 루틴이 고정된 버퍼에 의해 하나의 값을 복귀시킬 것을 요구하고 ; 호출된 루틴이 스택상의 하나의 값을 복귀시킬 것을 요구하고 ; 호출된 루틴은 동적 스트링에 의해 하나의 값을 복귀시키는 것을 요구하나, 만약 호출된 루틴이 그렇게 선택하면 스택상에 복귀된 스트링을 받아들일 수 있다. 호출된 루틴은 고정된 버퍼 또는 만약 호출기가 이것을 필요로 하면 스택에 의해 동적 사이즈 결과를 복귀시키도록 항상 준비되어 있어야만 한다. 이것은 또한 동적 스트링 또는 호출기가 동적 스트링에 의한 결과를 요청하면 스택에 의해 결과를 복귀시키도록 준비되어 있어야만 한다. CIL에서 루틴 호출의 표현 방식이 이제 고려되어야 할 것이다. 절차나 기능을 호출하는 것에 포함된 많은 분명한 운영이 있다. 다음 단계중 어떤 것은 필수적이다 ;
(1) 인자 리스트에 대한 공간을 할당한다.
(2) 패스-바이-값 피연산자 식에 대한 공간을 할당한다.
(3) 설명자에 대한 공간을 할당한다.
(4) 인자 설명자를 만든다.
(5) 결과 값에 대한 공간을 할당(결과값 또는 출력 인자는 호출후까지 존재하지 않는 인자이다. IL에서 기능은 결과값과 함께 절차로서 처리될 것이다).
(6) 인자 리스트를 만든다.
(7) 루틴을 호출한다.
(8) 인자, 설명자, 인자 리스트에 할당된 공간을 릴리즈한다.
(9) 호출로부터 결과값을 얻는다.
(10) 결과값에 대해 할당된 공간을 비워둔다.
IL에서 취한 일반식 전략을 호출을 하는 것에 포함된 다른 운영에 관한 각각의 연산자를 제공하기 위한 것이나, 이들은 특정된 패선에 함께 연결될 것을 요구하기 위한 것이다. IL에서의 루틴 호출은 다음의 것으로 구성되어 있다 ;
1. 호출을 만들 액션 시리즈의 시작을 플래그하는 INITCALL문장
2. 인자 리스트를 구성할 인자 및 일시적 할당 문장의 시리즈
3. 호출된 루틴에 대한 제어의 전송에 실제로 영향을 미치는 명령문(CALL 또는 BPCALL)
4. 액세스 가능한 호출의 복귀값을 만드는 결과 튜플의 시리즈
INITCALL 및 명령문을 강제적이다 ; 인자 리스트 및 결과 튜플은 선택적이다. 호출에 포함된 모든 튜플은 동일한 기본 블럭에서 발생하여야만 하며, 어떤 결과 튜플은 어떠한 튜플도 간섭하지 않고 즉시 호출 튜플을 따라야만 한다. INITCALL과 호출 사이에서 무슨 튜플이 발생할 수 있는 가에 관하여 다른 어떠한 제약도 없다. 루틴 호출에 대한 IL은 다른 호출에 대한 인자 리스트 내부에 포함될 수 있다.
인자 리스트를 구성하는 것은 그 자체에 인자 리스트와, 인자의 어드레스 및 설명자와, 통과될 값을 유지하기 위한 템포러리와, 출력 인자에 관한 공간을 할당하는 것을 포함한다. 이것은 또한 할당된 공간을 초기화하는 것을 포함한다. 이들 활동은 인자 튜플과 함께 IL에서 특정된다. 모든 인자 튜플은 ARG로 시작하는 명칭을 가지며 표 20에 그 속성이 수록되어 있다.
호출 루틴이 통과를 위한 현족 기억 위치의 어드레스를 가지면 그 이름이 ARGADR로 시작하는 인자 튜플 중의 하나를 사용한다. 이들 튜플과 함께 실제 기억 위치의 어드레스는 인자 튜플의 피연산자록서 특정된다. 따라서 값 메카니즘은 이들 튜플과 함께 사용될 수 있다. 인자 리스트에서 이들 튜플 중의 하나의 발생은 호출된 루틴이 현재 루틴에 대해 알려진 기억 위치에서 판독하거나 또는 기록할 수 있도록 하기 때문에 이들 튜플은 종속성과 측면 효과를 가질 수 있으므로 오프셋, 효과, 효과 2를 가지고, 모든 메모리 레퍼런스 튜플에 사용된 기본 심볼 필드와 특별한 플래그 팜은 판독되고, 팜은 기록되며 컴파일러가 호출된 루틴이 기억 위치에서 판독 및 또는 기록하는 것을 가정할 수 있는지를 표시한다.
인자 튜플이 일반 메카니즘을 특정하면 설명자에 대한 공간을 할당하고 그 기본 어드레스 필드를 채우기 위하여 코드가 발생된다. 전단은 설명자에 초기화되도록 되어 있는 임의의 다른 필드를 명백하게 특정한다. 이것은 DSCFIEND 튜플을 사용한다. 이 DSCFIELD 튜플은 일반적인 메카니즘과 함께 선행하는 인자 튜플을 인용하고 그 인자에 대해 할당된 설명자의 필드에 기억되도록 된 값을 특정한다.
인자 블록의 구성 :
일부 RTL 연결은 인자의 접합이 인자 블럭으로 통과될 수 있다는 것을 필요로 한다. 인자 블럭의 어드레스는 통상의 레퍼런스 파라미터처럼 RTL루틴으로 통과된다. 이것은 3개의 특별한 튜플을 사용하여 달성된다.
(1) ARGBLOCK은 스택에 관한 특정 사이즈의 블럭을 할당하는 인자 튜플이며, 그 어드레스를 호출된 루틴으로 통과시킨다. 그 블럭은 BLKFIELD 튜플을 사용하여 초기화될 수 있다.
(2) BLKFIELD 튜플은 이것이 일반적 설명자 메카니즘으로 임의의 튜플을 인용하는 대신 선행하는 ARGBLOCK튜플을 인용하는 것을 제외하고는 DSCFIELD튜플과 같다. 이것은 하나의 값을 인자 블럭의 필드에 기억시킨다.
(3) ARGDEFINES는 이것이 어떠한 코드도 발생시키지 않는다는 것을 제외하고는 인자 튜플과 같다. 이것은 전단가 정규의 인자 튜플과 연관되지 않은 인자와 같은 측면 효과를 특정하게 한다. 특히 이것은 인자 블럭을 통과하도록 된 인자와 연관된 효과를 표시하기 위하여 사용될 수 있다.
기호군 값과 복귀시키기 위한 루틴에 대하여, 그것은 그 값을 그 호출기에 의해 할당된 위치에 기억시켜야만 한다. 그 이름이 ARGTMP로 시작하는 튜플은 특정 사이즈의 기억 블럭을 할당하며 그 어드레스를 호출된 루틴으로 통과시킬 것이다. 그들은 ARGADR 튜플이 현존하는 기억 블럭의 어드레스를 통과하고, ARGTMP 튜플이 그 호출에 특별히 할당된 템포러리의 어드레스를 통과하는 것을 제외하고는 ARGARD튜플과 동일함.
ARGBVUF, ARGSTK 및 ARGDYN 튜플은 템포러리를 할당할 것이고 동적 스트링 복귀값을 획득하기 위해 필요한 특별한 설명자를 통과할 것이다. 이들 튜플은 보통의 모든 인자 튜플 속성을 가지지만, 그들의 메카니즘 속성은 그 메카니즘이 동적 복귀값 메카니즘의 사용에 의해 함축되어 있기 때문에 무시된다.
그 명칭이 RESULT로 시작하는 튜플은 호출 루틴에 액세스 가능한 루틴 호출로부터 복귀값을 만들 것이다. 그들 효과는 일시적 위치 또는 레지스터로부터 출력 파라미터를 이동시키기 위한 것이다. 이들 위치 또는 레지스터에서 그들은 호출된 루틴에 의해 더욱 지속적인 템포러리로 복귀한다. 결과 튜플의 값은 이것이 검색되는 복귀값의 단순한 값이다. 호출에 대한 모든 결과 튜플은 호출 튜플을 즉시 뒤따라야만 한다.
바운드 절차 호출 :
바운드 절차 값 또는 BPV는 미지의 루틴을 호출하기 위해 필요한 정보를 나타낸다. 루틴은 다른 루틴에 할당된 변수를 스택하기 위한 엎레벨의 레퍼런스를 포함하기 때문에 바운드 절차값은 호출될 루틴의 코드 어드레스 뿐 아니라 이것에 대한 정적 연결을 구성할 충분한 정보를 통합하여야만 한다.
불행하게도 BPV는 상이한 소프트웨어 구조에서는 상당히 다르게 취급된다. 즉 그들이 어떻게 발생되고, 어떻게 표현되며, 어떻게 호출되고, 심지어 얼마나 큰지에 따라 다르게 취급된다. 그러므로 컴파일러는 지속적인 표현 방식을 제공하려고 시도하지 않을 것이다. 대신에 전단은 타겟 소프트웨어 구조에 따라 다른 코드를 발생시키도록 기대될 것이다.
(1) VAX, MIPS 소프트웨어 구조에서 BPV는 단순한 코드 어드레스 및 문맥값이며, 바운드 절차 호출은 문맥값을 특정 레지스터에 로드하고 코드 어드레스에 대해 호출을 행함으로써 수행된다. 그러므로 전단은 한쌍의 독립 어드레스값으로서 BPV를 나타내기 위한 책임이 있을 것이다. 코르 어드레스는 BPLINK튜플과 함께 획득된다. BPV에 대한 호출은 그 구조의 정적 연결 레지스터에서의 특별 레지스터 인자로서의 값에 의해 통과된 문맥값과 함께, 그 어드레스 피연산자가 코드 어드레스 값인 CALL로 표시된다.
(2) RISC 머신에 관하여는 모든 절차는 약간의 추가 정보와 함께 코드 어드레스를 포함하는 설명자에 의해 표시되며, BPV는 실행 시간에 구성되어 문맥 포인터를 로드하고 실제의 루틴을 호출하기 위하여 RTL 루틴의 어드레스와 문맥 포인터를 포함하는 특별한 설명자의 단순한 어드레스이다. 전단은 이러한 설명자 자체에 대한 공간을 할당해야만 할 것이고 이것을 안에 채우기 위하여 BPVAL 튜플을 사용하여야만 할 것이다. 그리고 BPV는 설명자의 어드레스에 의해 표현되고, BPV에 대한 호출은 그 어드레스에 대한 호출에 의해 나타내야만 한다.
후단(12)는 어떤 피라미터가 루틴의 각 엔트리 점에 대해 있는지를 알 필요가 있다. 전단(20)는 그 엔트리 점의 파라미터 리스트를 나타내는(그들의 필드에 의해 연결된) 파라미터 노드의 리스트에 최초의 노드와 최종 노드를 지시하도록 각 엔트리 심볼 노드의 파라미터 리스트와 파라미터 리스트 테일 필드를 설정함으로써 이것을 달성한다.
각 파라미터 노드는 엔트리 점을 포함하는 루틴의 파라미터 심볼 노드를 지시하는 심볼 필드와, 레지스터에 의해 통과되는 인자 위치와, 그들이 인자 튜플에서 행하는 것과 동일한 의미를 갖는 특정 레지스터 필드를 갖는다. 따라서 파라미터 노드의 리스트는 엔스리점의 모든 파라미터와 그들이 엔트리점의 어느 인자 리스트에서 발생하는지를 확인한다.
파라미터 심볼은 하나이상의 파라미터 리스트에서, 아마도 각각에 대하여 상이한 인자 위치와 함께 발생할 수도 있음에 주의하라, 그러나 파라미터 노드는 메카니즘 필드를 가지지 못하는데 그 이유는 그 메카니즘이 특정 인자 리스트에서의 발생이라기보다는 파라미터 심볼의 속성으로서 간주되기 때문이다.
RETURNREG 튜플은 특정 레지스터에 스칼라 값을 복귀시키고 RETURNSTK와 RETURNDYN 튜플은 PRISM호출 표준에 제공된 동적 스트링 복귀 메카니즘 중의 하나를 사용하는 스트링 값을 복귀시킨다. 인자 템포러리를 통하는 값을 복귀시키는 것과 하나의 값을 하나의 통상적인 출력 파라미터에 기억시키는 것 사이에는 어떠한 차이도 없기 때문에 인자 템포러리를 통한 값을 복귀시키기 위하여는 호출된 루틴에 대하여 특별한 튜플이 필요하지 않음을 주의하라.
파라미터 심볼과 연관된 어드레스는 파라미터의 지역적 기억 위치의 어드레스이다. 호출된 루틴은 DESCADDR 튜플을 사용함으로써 일반적 설명자 메카니즘과 함께 파라미터에 대한 설명자의 어드레스를 획득할 수 있다. 이것은 만약 그 사이즈가 인자 리스트에서 이용 가능하면(설명자에서 또는 개별적인 사이즈의 파라미터에서) SIZE 튜플을 이용하는 미지의 사이즈 파라미터의 실제 사이즈를 획득할 수 있다.
루틴 호출에 포함된 모든 연산자는 표지에 수록되어 있다.
기억 할당 및 영역화 :
어휘 블럭은 선언의 세트, 예컨대 루틴, 서브루틴, 기능 또는 시작 및 종료 블럭등이 타당한지에 관한 소스 프로그램의 범위이다. 심볼의 표에서 루틴의 어휘 구조는 그 루트가 루틴 블럭 노드인 영역 블럭 노드의 트리에 의해 표현된다. ILG에서의 각 기본 블럭은 단일 어휘 블럭에 속하는 코드를 포함한다. 기본 블럭의 시작시에 블랜치 타겟 튜플은 심볼의 표에서 대응 블럭노드를 지시하는 영역 블럭 필드를 갖는다. 루틴에서의 매 어휘 블럭은 독특한 영역 엔트리 기본 블럭을 가져야만 하며, 이것은 제어가 그 어휘 블럭의 외부에 있는 임의의 기본 블럭으로부터 통과할 수 있는 기본 블럭일 뿐이다. 이 영역 엔트리 기본 블럭은 브랜치 타겟 튜플내의 블럭 엔트리 플래그에 의해 식별된다.
CIL에서 변수 심볼에 대한 레퍼런스는 항상 기억장치(또는 레지스터의 명칭)의 어드레스를 생기게 한다.
1. 정적 변수는 그 기억 등급이 정적, 전역적 레퍼런스 또는 보존적인 경시다. 정적 변수는 번역 시간에서 약간의 PSECT에 위치하므로 이러한 변수에 대한 모든 레퍼런스는 동일한 위치를 인용할 것이다.
2. 지역적 변수는 그 기억 등급이 자동, 스택로칼, 레지스터 또는 선택된 레지스터이고, 그 미지 사이즈의 플래그가 거짓인 것이다. 지역적 변수는 그들 어휘 영역의 단일 실행동안에는 존재하며 만일 그들 어휘영역의 다중 사례가 동시에 실행될 수 있으며 다중 사례를 가질 수도 있다. 그들은 번역 시간에서 레지스터로 할당되거나 그들 루틴의 스택 프레임에 있는 기지의 위치로 할당된다.
3. 동적 변수는 지역적 변수와 동일한 기억 등급을 가졌으나 그 미지의 사이즈 플래그가 참인 것이다. 지역적 변수처럼 동적 변수는 그들 어휘 영역의 다중 사례(multiple instance)가 동시에 실행될 수 있으면 다중 사례로 가질 수 있다. 그들은 CREATE튜플에 의해 실행 시간에서 스택상에 할당되며 후단에 의해 발생된 관련 포인터 변수를 통하여 액세스된다.
4. 카피 의미론과 함께 파라미터는 그들 미지 사이즈의 플래그에 따라 지역적 또는 동적 변수처럼 행동한다.
5. 바인드 의미론과 함께 파라미터는 호출된 루틴에 전혀 할당되지 않는다. 그들은 실제의 기억 위치 어드레스를 유지하기 위하여 후단에 의해 발생된 관련 포인터 변수를 통해 액세스된다.
어휘 블럭에서의 튜플은 그 어휘 블럭 또는 심볼 테이블 블럭 트리의 임의의 선조에서 선언된 임의의 변수를 참조할 수 있다. 물론 현재의 루틴에는 변수를 참조하는 것에 대한 문제점은 전혀 없다. 다른 루핀의 정적 변수는 직접 참조될 수 있다. 다른 루틴의 지역적 동적 변수는 변수가 선언되는 스택 프레임을 위치시키기 위하여 "정적 체인"을 필요로 한다. 그러나 후단(12)는 만약 전단가 그 루틴 블럭과 별수를 정확하게 주를 단다면 코드를 발생시키고 정적 체인을 발생시켜 그것을 이용할 완전한 책임이 있다.
몇가지 종류의 동적 스택 할당이 있다.
1. 동적 변수에 대한 스택 기억은 CREATE 튜플에 의해 할당되며, 제어가 CREATE 튜플과 동일한 어휘 블럭에 있지 않는 기본 블럭으로 통과될때까지 CREATE 튜플의 실행으로부터 존재한다(이것은 동적 변수에 대한 CREATE 튜플이 기본 블럭에 할당되어야만 한다는 것을 의미한다. 이 기본 블럭의 영역 블럭은 변수가 선언된 블럭이다. 그렇지 않으면 이것의 동적 기억은 변수가 어휘적으로 영역내에 존재하는 동안 해체될 것이다).
2. 미지 사이즈의 카피 파라미터에 대한 스택 기억을 할당하기 위한 코드는 후속되는 ENTRY튜플에서 즉시 발생된다. ENTRY 튜플은 주 루틴 블럭에 존재해야만 하기 때문에 이 기억은 루틴이 복귀할때까지 존재한다.
3. 동적 템포러리는 기호군식(aggregate expression)의 값을 유지하기 위하여 후단에 의해 발생될 수도 있다.
4. 스택 공간은 기호군 ARGVALx 튜플에 대한 인자값을 유지하기 위해 할당되며, CALL 튜플의 실행시까지 ARGVALx 튜플의 실생으로부터 존재한다.
5. 스택 공간은 ARGVALx 튜플에 대한 복귀값을 유지하도록 할당된다. 이것은 복귀값을 호출하는 RESULTx 튜플의 평가시까지 ARGTMPx튜플의 실행으로부터 존재한다.
본 발명은 특정 실시예와 관련하여 기술되어 있으나, 이 설명을 제한하기 위한 의미로 해석해서는 안된다. 본 발명의 다른 실시예와 함께 각종 변형 실시예들은 본 명세서를 참조로 하면 당해 분야의 전문가에게 있어서 명백하다. 그러므로 첨부된 청구상은 본 발명의 진정한 범위에 해당하는 수정예 및 실시예를 망라할 것이다.
[표 1]
[표 2]
[표 3]
[표 4]
[표 5]
심볼표와 IL 루틴
[표 6]
특정 타겟 구조에 관한 표현 방식의 타입
[표 6a]
유도변수 검출을 위한 새로운 튜플 필드
[표7]
공통 튜플 필드
[표8]
튜플 사전에 기재된 항목
[표9]
데이타 액세스 연산자
[표10]
데이타 액세스 튜플의 속성
[표 11]
산술 연산자
[표 12]
문자 및 비트 문자열 연산자
[표13]
부울(Boolean) 연산자
[표 14]
체크 연산자
[표 15]
흐름 제어 연산기
[표 16]
COPY 및 BIND 의미론(Semantic)사이의 선택에 영향을 주는 라파미터 심벌 플래그
[표 17]
다양한 소오스 언어용 라파미터 의미론
플래그의 세팅
Note : IN, OUT 또는 IN OUT에 의해 명시된 바와같이, Ada 루틴 선언(declaration)에서 파라미터 명세서의 변형자이다.
[표 18>
GEM 메카니즘 열거 타입
[표 19]
동적 문자열 복귀 메카니즘
[표 20]
인자 튜플의 속성
[표 21]
루틴 호출, 인자 변화 및 수치값 복귀 연산자
[부록]
[인터프리터 제어 동작]
다음의 동작은 동작 인터프리터의 실행 플로우를 제어한다.
ACTION<Sresult-var-List> ; <temporary-var-list>는 템플리트 동작 시퀀스의 시작을 나타낸다. 이것은 피연산자 할당하는 동안 템플리트에서 처음 동작이어야만 한다. 두개의 var-lists의 내용은 템플리트의 레스트(rest) 동안 피연산자 변수를 명명하기 위해 사용되는 식별자의 공통 분리 시퀀스이다. 이들 var-list는 템플리트가 결과 피연산자나 변수를 임시 피연산자를 사용하지 않는 경우 비어있을 수 이다.
result-var-list에서 식별자는 결과 피연산자의 이름이다. 무효 콘텍스트에서 ILC 노드는 다른 수식이 1결과 피연산자를 갖는다면 0 결과 피연산자를 갖는다. 예외(exception)는 2개 또는 3개의 피연산자를 필요로 하는 스트링 결과치를 포함하여(문자별 보디를 어드레스화하기 위해 1, 스트링 길이에 대해 1 및 스트링 보디를 홀드하기 위해 1) : 복합 결과치는 두개의 피연산자를 필요로 한다(실성분에 대해 하나, 가상 성분에 대해 하나).
DELAY는 비지연 동작의 종료 및 지연 동작의 개시를 나타낸다. 지연 동작이 인터프리트될때, 현재 템플리트의 처리는 대응 ILG 서브트리(subtree)가 부모 서브트리(parent subtree)의 잎(leaf)처럼 사용될때까지 중지된다. 부모 서브트리의 템플리트가 대응 잎을 지연시키지 않을때, 해독은 지연 동작 다음의 동작까지 계속된다.
EXIT는 동작 시퀀스의 해독을 종결하며, 결과 피연산자를 복귀시키고, 잔여 피연산자 가변 및 로컬 TNs를 해제시키며, 이 동작 시퀀스가 지연되지 않은 템플리트로 해독을 재시작시키는 EXIT 동작을 해독한다.
END 동작은 동작 시퀀스의 종결을 나타낸다. 이것은 해독되지 않을시 동작을 실제로 하지 않는다. 전기 END 동작 어포레이션은 동작 시퀀스이 어휘 최종 성분으로 되어야 한다. 상기 동작은 ACTION 동작에서 선언된 피연산자 식별자의 범위의 종결을 뜻한다.
UNDELAY(leaf, opr1, opr2, …)는 지정된 패턴 "잎(leaf)"의 지연 콘텍스트 내용을 처리하게 한다. 전기 잎의 결과 피연산자는 피연산자 변수들 "opr1", "opr2"등으로 복제된다. 복제 피연산자의 수는 잎의 본형에서 결과 피연산자의 수와 같아야만 한다.
LABEL(name)은 동작 시퀀스에서 현위치를 라벨 짓도록 "명명(name)"한다.
GOTO(name)는 name에 의해 지정된 라벨 다음의 동작에서 연속 처리하고 인터프리터를 브랜치시킨다.
TN 할당 및 실시간 동작
INCREMENT LON()은 TNs의 실시간을 결정하기 위해 사용되는 선형 오더 수 클럭 변수를 증가시킨다.
USE(operand)는 지정된 피연산자 변수를 참조하게 한다. 이 동작은 피연산자가 연장되는 실시간을 사용하기 위해 템플리트에서 최종 위치를 표시하기 위해 사용된다.
ALLOCATE PERMANENT는 "Size" 바이트의 영구 클라스 TN을 지정된 "피연산자"
(operand, Size) 변수에 의해 창출되고 참조되어 진다. 상기 Size 파라미터가 소실되는 경우 TN의 사이즈는 현재 템플리트의 결과치 데이타 타입에 의해 결정된다. 이 동작은 CONTEXT 변화 동안 TN만을 창출한다. TNBIND 및 CODE 변화동안 처리되는 TN에 대한 설명은 SAVE TN 동작을 참조하라.
ALLOCATE DELAYED는 Size 바이트의 지연된 클라스 TN을 지정된 피연산자
(operand, Size) 변수로 창출시키고 참조시킨다. 상기 Size 파라미터가 소실되는 경우 TN의 사이즈는 현재 템플리트의 결과치 데이타 타입에 의해 결정된다. 이 동작은 CONTEXT, TNBIND 및 CODE 각각의 변화동안 TN을 창출한다. 이 동작은 비지연된 동작을 해독하는 동안 실행되지 않는다. 이 TN의 라이프 타임(수명)은 이 TN을 사용하는 결과치가 사용될때 종결된다.
ALLOCATE LOCAL은 Size 바이트의 지연된 클라스 TN을 지정된 피연산자
(operand, Size) 변수로 창출시키고 참조시킨다. 상기 Size 파라미터가 소실되는 경우 TN의 사이즈는 현재 템플리트의 결과치 데이타 타입에 의해 결정된다. 이 동작은 CONTEXT, TNBIND 및 CODE 변화동안 TN을 창출시킨다. 이 TN의 라이프타임은 그것의 창출과 마찬가지로 동일 템플리트에서 종결되어야만 한다.
FORCE REGISTER(operand) 피연산자 변수로 지정된 TN을 메모리내에서가 아닌 것처럼 표시한다. 통산 이것은 TN이 할당되지 않은때에 이용되는 레지스터가 없는 경우 레지스터에 할당하는 것을 의미한다.
FORCE MEMORY(operand) 피연산자 변수로 지정된 TN을 레지스터내가 아니어야만 함을 나타낸다. 통상 이것은 스택 위치로 할당되도록 보증한다.
MUST ALLOCATE(operand)는 피연산자 변수로 지정된 TN이 할당되어야만 함을 나타낸다.
Note : 이들 3개의 조건이 모순되고 전부 이행되지 않은 것처럼 TN과 동일한 3개의 FORCE REGISTER, FORCE MEMORY 및 MUST ALLOCATE가 행해지도록 하는 에러이다.
REFERENCE(operand1, operand2) 피연산자 1이 레지스터로 할당되면 피연산자 2는 동일 레지스터에 할당되고, 그렇지 않으면, 피연산자 2는 피연산자 1에 독립적으로 할당된다. 피연산자 2를 피연산자 1의 동일한 레지스터로 강제한다 하더라도 피연산자 1 및 피연산자 2의 실시간은 일치하지 않는다.
INCREMENT COST(number, operand)는 총 number로 피연산자에 의해 지정된 TN의 비할당 비용을 증가시킨다.
RESERVE RO(number)는 연속적인 레지스터 number를 레지스터 0로 시작하기 위해 남겨둔다.
TEST MEMORY(operad, label)는 지정된 피연산자 변수로 참조된 TN 테스트한다. 상기 TN이 메모리내에 있으면 동작 인터프리터는 비할당 TN이 메모리내에 있지 않는 것으로 간주해 CONTEXT 및 TNBIND를 변화시키는 동안 지정된 label로 부랜치하며 그렇지 않으면 그것들은 그 자신이 행해지는 FORCE MEMORY를 가진다.
TEST REGISTER(operand, label)는 지정된 피연산자 변수로 참조된 TN을 테스트한다. 상기 TN이 레지스터내에 있으면 동작 인터프리터는 비할당 TN이 레지스터내에 있는 것으로 간주해 CONTEXT 및 TNBIND를 변화시키는 동안 지정된 label로 브랜치하며 그렇지 않은 경우 FORCE MEMORY는 TN사에서 행해진다.
ILG 로드 및 저장 동작
LOAD LITERAL(Node, operad)는 지정된 피연산자 변수로 템플리트 패턴에 의해 매치되는 지정된 Node의 리터럴 값을 로드한다. Node가 LITREF가 아닌 경우 이것은 에러이다.
SAVE TN(operand, Node, field)는 참조를 피연산자 변수에 의해 지정된 영구 클라스 TN으로 저장한다. CONTEXT를 변화하는 동안 TN 포인터는 템플리트의 저장된 Node에 의해 매치된 ILG 튜플의 성분 field내에 저장된다. TUBIND 및 CODE를 변화하는 동안 이 정보는 지정된 Node의 지정된 field로부터 끄집어 낸다. 모든 연구 클라스 TN은 특정 ILG 필드에서 CONTEXT를 변화하는 동안 저장되어야만 하므로 동일한 TN은 TUBIND 및 CODE 변화동안 위치될 수 있다. 지연된 클라스 및 로컬 클라스 TN은 이것들이 절대 저장되지 않으므로 각각 변화되어 재창출된다.
SAVE OPERAND(operand, node, field reg, field base)는 지정된 피연산자 변수의 위치를 저장한다. 이 정보는 지정 Node에 의해 매치되는 ILG 튜플내에 저장된다. 레지스터 값은 성분 field reg내에 저장된다. 확정 레지스터 값들은 비할당이 발생하였거나 피연산자가 레지스터 대신 스택상에 할당된 것을 인코드한다. 피연산자가 스택에 할당되어진 경우, 스택 오프렛은 field base로 지정된 node성분내에 저장된다.
SAVE REGISTER(operand, Node, field)는 템플리트 패턴에 의해 매치된 지정 Node의 field내에 지정된 피연산자의 레지스터 수를 저장한다. 레지스터 수의 이 세트는 없는 레지스터가 할당되는 인코딩을 포함한다. 지정된 피연산자가 메모리 위치에 할당되는 경우 에러가 발생한다.
코드 방출 동작(Code Emitting Actions)
MOVE VALUE(oper-src, opr-dst)는 opr-src 피연산자에서 opr-dst로 값을 이동시키기 위한 코드를 발생시킨다. opr-src 및 opr-dst가 일치하는 경우 발생되는 코드는 없으며 이 동작은 상기의 둘을 일치시키기 위한 할당자로의 힌트이다.
EMIT(opcode, operand1, opernd2, …)는 지정된 opcode를 구성하고 명령의 어드레스 모드와 같이 지정된 피연산자 변수들을 사용하는 객체 명령(objedct instruction)을 출력한다.
MAKE Address Mode(opr-offset, opr-base, opr-index, opr-result)는 변수 "opr-result"에서 새로운 피연산자를 만든다. 이것은 "offset"과 같은 "opr-offset", 베이스 레지스터와 같은 "opr-base", VAX 어드레스 모드를 창출시키기 위한 인덱스 레지스터와 같은 "opr-index"를 사용하는 VAX 지정 동작이다. "opr-offset"이 소실되면 제로로 추정한다. "opr-offset"이 메모리 위치를 지정하는 경우 "opr-offset"은 제로를 지정해야만 하고, "opr-index"는 소실되어야 한다.
LOAD CONSTNAT(number, operand)는 지정된 리터럴 "number"를 나타내는 "피연산자"에서 새로운 어드레스 모드를 만든다. "number"는 리터럴 값이지 패턴에 의해 매치된 노드가 아님을 주의 바란다. LITREF ILG 노드의 값을 포함하는 어드레스 모드를 창출하기 위해 LOAD LITERAL 대신에 사용한다.
여기에 매우 단순한 추가 템플리트 및 매우 복잡한 어드레스 템프리트를 포함하는 여러 예가 있다. 이것들은 템플리트를 기입함에 있어 쉽거나 어려운 예를 제공해야 한다.
템프리트의 결과치 모드 및 패턴 매치의 값 모드의 세트들은 타겟 구조의 데이타 타입 특성을 이용한다. 이들 값 모드는 값이 인코드될 수 있는 다른 방법들을 열거한 것이다. 다양한 방법의 표현값을 명명하는 이 열거는 가상 머신에 의해 인코드될 수 있다.
VAX에 대한 예
RV(레지스터 값)
MV(간접 및 인덱싱이 없는 메모리 값)
MVIND(간접이지만 인텍싱은 없는 메모리 값)
MV1(바이트 콘텍스트를 갖는 메모리 값)
MV2(워어드 콘텍스트를 갖는 메모리 값)
MV4(긴 콘텍스트를 갖는 메모리 값)
MV8(4배의 콘텍스트를 갖는 메모리 값)
MV16(8배의 콘텍스트를 갖는 메모리 값)
AM(간접 및 인덱싱이 없는 어드레스 모드)
AMIND(간접이지만 인덱싱은 없는 어드레스 모드)
AMINX1(바이트 인덱싱을 갖는 어드레스 모드)
AMINX2(워어드 인덱싱을 갖는 어드레스 모드)
AMINX4(긴 인덱싱을 갖는 어드레스 모드)
AMINX8(4배의 인덱싱을 갖는 어드레스 모드)
AMINX16(8배의 인덱싱을 갖는 어드레스 모드)
PCFLOW(거짓 라벨 또는 참 라벨로 점프함으로써 나타낸 흐름 부울)
STRINGV(길이 및 메모리 어드레스 처럼 인코드된 스트링 값)
VARYV(길이 워어드의 어드레스 처럼 인코드된 가변 스트링 값)
VOID(측-효과만을 갖는 어퍼레이션에서 사용된 값은 없다)
VAX의 단순 ADDL3
결과치 모드 : RV
패턴 트리 :
0 : ADD, INT32, 1, 2
1 : LEAF{RV, MV, MVIND, MV4}
2 : LEAF{RV, MV, MVIND, MV4}
패턴테스트 :
없음
비용 : 2
동작 :
Actions(result ; leaf1, leaf2) ;
! "result" is the result temporay
! "leaf1" is LEAF 1 : (좌측 피연산자)
! "leaf2" is LEAF 2 : (우측 피연산자)
Undelay(1, leaf1) ;
Undelay(2, leaf2) ;
Use(leaf1) ;
Use(leaf2) ;
Increment_LON ;
Allocat_Permanent(result) ;
Save_TN(result, 0, ILG TN) ;
Emit(ADDL3, leaf1, leaf2, result) ;
Delay ;
Exit ;
End_Actions ;
주 : 상기 레지스터 할당기에서 사용되는 문제의 해를 구하는 경혐(heuristic)은 결과치 피연산자가 피연산자 1 또는 2중의 하나와 일치하게 할당되는 높은 가능성을 보증한다. 상기와 같은 할당(Allocation)은 ADDL3 대신에 ADDL2의 결과로 된다.
VAX의 단순 SUBL3
결과치 모드 : RV
패턴 트리 :
0 : SUB, INT32 1, 2
1 : LEAF{RV, MV, MVIND, MV4}
2 : LEAF{RV, MV, MVIND, MV4}
패턴테스트 :
없음
비용 : 2
동작 :
Actions(result ; leaf1, leaf2) ;
! "result" is the result temporay
! leaf1 is LEAF 1 : (좌측 피연산자)
! leaf2 is LEAF 2 : (우측 피연산자)
Undelay(1, leaf1) ;
Undelay(2, leaf2) ;
Use(leaf2) ;
Increment_LON ;
Use(leaf1) ;
Allocate_Permanent(result) ;
Save_TN(result, 0, ILG TN) ;
Emit(SUBL3, leaf2, leaf1, result) ;
Delay ;
Exit ;
End_Actions ;
주 : 피연산자 2를 사용한후 이지만 피연산자 1을 사용하기 전에 LON을 증가시키는 것은 피연산자 1 및 결과치 피연산자를 제공하는 레지스터 할당기의 경험적 가능성을 증가시키며 그 동일한 할당은 SUBL3 대신 SUBL2 명령에 따르게 된다.
VAX의 바이트 인덱스된 어드레스 모드
이 템플리트는 추가로 행해질 K(base-reg)[inedx-reg] 어드레스 모드를 발생시킨다. FAX FORTRAN 규칙을 따르는 상기 템플리트 2개의 피연산자를 홀드하기 위해 사용되는 레지스터를 조증하는 이 템플리트를 선택한다.
결과치 모드 : AMINX1
패턴 트리 :
0 : ADD, INT32 1, 2
1 : LITREF, INT32
2 : ADD, INT32 3, 4
3 : LEAF{RV}
4 : LEAF{RV}
패턴 테스트 :
NO_OVERFLOW(0) ;
NO_OVERFLOW(2) ;
비용 : 1
동작 :
Action(result ; index_reg, base_reg, leaf4, leaf3, lit) ;
! "result" is result address mode lit(base_reg)[index_reg]
! "index_reg"는 인덱스 스크레치 레지스터이다.
! "base_reg"는 베이스 스크레치 레지스터이다.
! "leaf4"는 LEAF 4 : (인덱스 잎)
! "leaf3"는 LEAF 3 : (베이스 잎)
Delay ;
! Force LEAF 4 : into a register
!
Undelay(4, leaf4) ;
Allocate_Delayed(index_reg) ;
Force_Register(index_reg) ;
Must_Allocate(index_reg) ;
Preference(leaf4, index_reg) ;
Save_Register(index_reg, 0, ILG_index_reg) ;
Move_Value(leaf4, index_reg) ;
Use(leaf4) ;
! Force LEAF 3 : into a register
!
Undelay(3, leaf3) ;
Allocate_Delayed(base_reg) ;
Force_Register(base_reg) ;
Must_Allocat(base_reg) ;
Preference(leaf3, base_reg) ;
Save_Register(base_reg, 0, ILG_Base_Reg) ;
Move_Value(leaf3, base_reg) ;
Use(leaf3) ;
! 어드레스 모드 lit(leaf3)[leaft]를 발생
!
Load_Literal(1, lit) ;
Make_Address_Mode(lit, base_reg, Index_reg, result) ;
Increment_LON ;
EXIT ;
End_Actions ;
주 : 레지스터로 LEAF를 강제하는 7동작은 아마 VAX의 공통 오퍼레이션이다. 마찬가지로 macro 동작은 이들 7동작들을 결합하는 효과를 가진다.
PRISM 교정 0.0의 추가를 위한 사용 MOVA
결과치 모드 : RV
패턴 트리 :
0 : ADD, INT64 1, 2
1 : LITREF, INT64
2 : LEAF{RV}
패턴 테스트 : Lit_14_Bit(1) ; ! 리터럴이 14bits 적합한 경우 계속
비용 : 1
동작 :
Action(result ; leaf2, reg2, reg_result, lit) ;
! "result" 는 result temporary
! "leaf2"는 LEAF2를 설명
! "reg2"는 LEAF2를 홀딩하기 위한 스크레치 레지스터
! "reg_result" 는 계산 결과용 스크레치 레지스터
! "lit"는 Literal 1 :
Undelay(2, leaf2) ;
Allocate_Local(reg2) ;
Force_Register(reg2) ;
Must_Allocat(reg2) ;
Save_Register(reg2, 0, ILG_reg_0) ;
Move_Value(leaf2, reg2) ;
Use(leaf2) ;
Use(reg2) ;
Allocate_Local(reg_result) ;
Force_Register(reg_result) ;
Must_Allocat(reg_result) ;
Save_Register(reg_result, 0, ILG_reg_temp) ;
Use(reg_result) ;
Increment_LON ;
Allocate_Local(result) ;
Save_TN(result, 0, ILG_TN) ;
Load_literal(1, lit) ;
Emit(MOVA_Move_Format, lit, reg2, reg_result) ;
Move_Value(reg_result, result) ;
Delay ;
Exit ;
End_Actions;
주 : 레지스터 할당기의 해를 구하는 경험은 leaf2 및 reg2가 동일한 레지스터를 얻을 수 있는 높은 가능성을 갖는 것을 보증하며, 또한, result 및 reg_result는 동일 레지스터를 가장 얻기 쉽다
VAX의 긴 콘텍스트 인덱싱
이 템플리트 가산에 의해 추가된 4로 승산을 행하기 위한 K(leaf3)[leaf6] 어드레스 모두를 생성한다. VAX PASCAL 규칙에 따르는 상기 본형은 레지스터가 두개의 피연산자를 홀드하기 위해 이용할 수 있다는 것을 보증하지 않는 이 템플리트를 선택한다. 레지스터가 이용 가능치 않다면 어드레스 모드는 임시 메모리를 사용해 시뮬레이트 된다.
결과치 모드 : AMINX4
패턴 트리 :
0 : ADD, INT32 1, 2
1 : LITREF, INT32
2 : ADD, INT32 3, 4
3 : LEAF{RV}
4 : MUL, INT32 5, 6
5 : LIT, INT32
6 : LEAF{RV}
패턴 테스트 :
NO_OVERFLOW(0) ;
NO_OVERFLOW(2) ;
NO_OVERFLOW(4) ;
NITERAL_4(5) ; ! 리터럴 값이 4인 경우 계속
비용 : 1
동작 :
Action(result ; index_reg, base_reg, leaf6, leaf3, lit, temp) ;
! "result"는 결과치 어드레스 모드
! "index_reg"는 인덱스 스크레치 레지스터
! "base_reg"는 베이스 스크레치 레지스터
! "leaf6"는 LEAF 6 : (index leaf)
! "leaf3"는 LEAF 3 : (base leaf)
! "lit" is LITREF 1 :
! "temp" is literal #2(No_Index case)
! or is(leaf3)[index_reg]
! (index_Has_Reg_Temp case)
Delay ;
Load_Literal(1, lit) ;
Undelay(6, leaf6) ;
Undelay(3, leaf3) ;
Allocate_Delayed(index_reg) ;
Increment_Cost(3, index_reg) ;
Preference(leaf6, index_reg) ;
Allocate_Delayed(base_reg) ;
Preference(leaf3, base_reg) ;
Increment_Lon ;
Test_Memory(index_reg, No_Index) ;
;
[부록]
[Basic 타입의 정의]
다음의 루틴은 GEM IL에 의해 정의된 대표적 타입에 대응하는 Basic 타입을 정의한다. GEM-TD-DEF-Basic 타입은 nil, 어드레스, 표시 및 비표시 정수, 부동 및 복합 타입들을 정의한다. GEM-TD-DEF-CHAR 타입은 베이스 타입의 수 상에서 정의된 문자를 정의한다.
상기의 부울은 베이직 타입을 고려하지 않는다는 것을 알아야 한다. 파스칼과 같은 컴파일러용 언어는 참 및 거짓 요소를 포함하는 목록처럼 부울을 정의한다.
TYPE_NODE=
GEM_TD_DEF_BASIC_TYPE(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
BASIC_TYPE : value)
basic 타입을 정수나 실수처럼 정의한다. DECL_BLK는 정의되는 타입의 블록노드이다 LOCATOR는 GEM 또는 외래 locator이며, LOCATOR(위치자)는 null locator로 할 수 있다. TYPE-NAME은 GEM-TYP 목록의 요소이여야 참을 정의하는 타입, 특히 포함되는 것들은, BOOL, BITS, STR8 및 STR16 GEM-TYP 요소들이다.
TYPE_NODE=
GEM_TD_DEF_CHAR_TYPE{
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VA_STR,
BASIC_TYPE : value)
문자들 basic 타입처럼 정의한다. 예로, 문자를 UINT8, INT8, UNIT16, UINT32, 등으로 할 수 있다. DECL-BLK는 정의되는 타입에서의 블록 노드이다. LOCATOR는 GEM 또는 외래 locator이며, nullocator로 할 수 있다. TYPE-NAME은 상기 타입을 설명하는 가변 스트링으로 null(정보의 부재) 상태로 할 수 있다. BASIC 타입은 사이즈 및 대표적 문자 세트를 정의하여 결정하는 타입이다.
이것은 GEM-TYP 블록의 요소이어야만 하여 사이즈 8, 16 및 32비트의 표시 및 비표시 정수로 제한된다.
문자 및 스트링 기호군의 정의
GEM-TD-DEF-STRING 및 GEM-TD-DEF-BITSTRING은 주어진 베이스 타입의 문자 및 비트 기호군을 정의한다.
TYPE_NODE=
GEM_TD_DEF_STRING(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
STRING_TYPE : value,
CHAR_TYPE : value,
STRING_LB : in GEM_NODE,
STRING_UB : in GEM_NODE)
STRING-타입의 문자 스트링을 정의한다. 상기 스트링의 소자들은 CHAR-TYPE에 의해 정의된 타입의 문자이며 상기 스트링은 하위 및 상위 스트링 바운드 LB 및 UB를 가진다. 상기 스트링 사이즈(요소들의 수)는 스트링 UB-스트링 LB+1이다. 불명한 사이즈의 문자 스트링은 스트링 LB 값보다 작은 스트링 UB에 의해 지시된다. DECL BLK는 정의되는 타입에 있어서의 블록 노드이다. LOCATOR는 GEM이나 외래 locator이며, null locator로 할 수도 있다. TYPE NAME은 상기 타입을 설명하는 가변 스트링으로 null(정보의 부재) 상태로 할수도 있다. STRING 타입은 스트링 표시로 목록 GEM STRING REPR의 멤버로 되는 것처럼 정의된다. CAHR-TYPE은 호출에 의해 GEM-TD-DEF-CHAR 타입으로 복귀되는 스트링 문자 타입에 의해 발생된 타입 노드로의 핸들이다. 스트링 UB 및 LB는 스트링의 상위 및 하우 바운드이다.
TYPE_NODE=
GEM_TD_DEF_BIRSTRING(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
BITSTRING_LB : in GEM_LITERAL_NODE,
BITSTRING_UB : in GEM_LITERAL_NODE)
BITSTRING-UB-BITSTRING-LB+1 요소를 구성하는 비트 스트링을 정의한다. 불명한 사이즈의 비트 스트링은 비트 스트링 LB 값보다 작은 비트스트링 UB값에 의해 지시된다. DECL BLK는 정의되는 타입에 있어서의 블록 노드이다. LOCATOR는 GEM 또는 외래 locator로 , null locator로 할 수 있다. TYPE NMAE은 상기 타입을 서명하는 가변 스트링으로 null 상태로 할 수도 있다. 비트 스트링 UB 및 비트 스트링 LB는 비트 스트링의 상위 및 하위 바운드이다.
[Typedefs 및 포인터의 정의]
GEM-TD-DEF-TYPEDEF는 존재하는 타입에 대한 새로운 이름 또는 symcnym를 정의한다. GEM-TD-DEF 포인터는 타입화 또는 비타입화된 포인터를 정의한다. 포인터와 관련된 상기 타입이 GEM 타입 정의 서비스로 지정된 그 타입 정보를 가진후 GEM-TD-SET-포인터 타입은 이전에 지정된 포인터의 타입을 정의한다.
TYPE_NODE=
GEM_TD_DEF_TYPEDEF(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
DEL_TYPE : value)
새로운 타입명을 정의하며 타입 노드 DEF-TYPE에 의해 표현된 상기 타입과 관련된다. DECL-BLK는 정의되는 타입에서의 블록 노드이다. LOCATOR는 GEM 또는 외래 locator이며, null locator로 할 수도 있다. TYPE-NAME는 상기 타입을 설명하는 가변 스트링으로 null 상태로 할 수도 있다. DEF-TYPE은 현존 타입 정의용으로 창출된 타입 노드이다.
TYPE_NODE=
GEM_TD_DEF_POINTER(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
POINTER_TYPE : value)
포인터 타입을 정의한다. POINTER-TYPE은 비타입된 포인터를 나타내는 현존 타입 정의 또는 null용 타입 노드로 할 수도 있다. TYPE-NAME은 상기 타입을 설명하는 가변 스트링으로 null 상태로 할 수도 있다. LOCATOR는 GEM 또는 외래 locator로, null locator로 할 수도 있다. DECL-BLK는 정의되는 타입에 있어서의 블록 노드이다.
TYPE_NODE=
GEM_TD_SET_POINT_TYPE(
POINTER_TYPE : value,
NEW_TYPE : value)
호출에 의해 GEM-TD-DEF-포인터로 창출된 현존 포인터 정의에 대해, 포인터와 관련된 상기 타입을 재정의한다. POINTER-TYPE은 포인터용으로 정의된 현존 타입 노드에 대한 핸들이다. NEW-TYPE는 현존 타입 정의로 창출된 타입 노드에 대한 핸들이다.
범위, 목록 및 세트의 정의
GEM-TD-DEF-RANGE, GEM-TD-DEF-ENUM, GEM-TD-ENUM-ELEMENT 및 GEM-TD-DEF-SET는 정의된 타입상에서 범위, 목록, 목록 요소 및 세트들을 정의한다.
TYPE_NODE=
GEM_TD_DEF_RANGE(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
RANGE_TYPE : value,
RANGE_LOW_VAL : in GEM_LITERAL_NODE,
RANGE_HIGH_VAL : in GEM_LITERAL_NODE)
범위 타입을 정의한다. 이 범위는 하치 타입, 범위 타입 및 리터럴 노드 RANGE-LOW-VAL 및 RANGE-HIGH-VAL에 의해 나타내지듯이 범위의 하위 및 고위값으로 정의된다. DECL-BLK는 정의되는 타입에 있어서의 블록 노드이며, LOCATOR은 GEM 또는 외래 locator이며, null locator로 할 수도 있다. TYPE NAME은 상기 타입을 설명하는 가변 스트링이며 null 상태로 할수도 있다. 범위 타입은 현존 베이직 타입 정의의 타입 로드에 핸들이다. RANGE-LOW-VAL 및 RANGE-HIGH-VAL은 범위내에서 하위 및 고위값을 나타내는 리터럴 노드에 대한 포인터이다.
TYPE_NODE=
GEM_TD_DEF_ENUM(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
ENUM_TYPE : value)
목록을 정의한다. 이 목록의 요소들은 루틴 GEM-TD-ENUM-ELEMENT를 호출하므로 정의된다. DECL BLK는 정의되는 타입에 있어서의 블록 노드이다. LOCATOR는 GEM 또는 외래 locator이며, null locator로도 할 수 있다. ENUM TYPE은 현존 베이직 타입 정의용으로 창출된 타입 로드에 대한 핸들이다. 전단(front-end)는 처음부터 마지막 오도에서 목록 요소들을 목록 정의에 적용해야만 한다.
TYPE_NODE=
GEM_TD_SET_ENUM_ELEMENT(
ENUM_TYPE : value,
LOCATOR : value,
ENUM_ELEMENT_NAME : in VS_STR,
ENUM_ELEMENT_VALUE : in GEM_LITERAL_NODE)
타입 노드 핸들 ENUM-TYPE으로 지시된 목록 및 값 ENUM_ELEMENT VALUE를 갖는 ENUM-ELEMENT-NAME으로 명명된 요소에 대한 정의이다. ENUM-TYPE은 목록에 대한 현존 타입 노드에 대한 핸들이며, LOCATOR는 GEM 또는 외래 locator이며, null locator로 할 수도 있다. ENUM-ELEMENT-NAME은 목록 요소를 정의하는 가변 스트링이다. ENUM-ELEMENT-VLAUE은 요소값을 정의하는 리터럴 노드이다.
TYPE_NODE=
GEM_TD_DEF_SET(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
SET_TYPE : value)
타입 노드 핸들 SET TYPE에 의해 정의된 타입 세트를 정의한다. DECL BLK는 정의되는 타입에 있어서의 블록 노드이다. LOCATOR는 GME 또는 외래 locator이며, null locator로 할 수도 있다. TYPE NAME은 상기 타입을 설명하는 가변 스트링으로 null 상태로 할 수도 있다. SET-TYPE은
оGEM_TD_DEF_BASIC_TYPE
оGEM_TD_DEF_CHAR_TYPE
оGEM_TD_DEF_ENUM
оGEM_TD_DEF_RANGE
оGEM_TD_TYPEDEF
에 의해 복귀되어진 핸들로 할 수도 있다.
Array의 정의
루틴 GEM_TD_DEF_ARRAY 및 GEM_TD_SET_ARRAY_BOUND는 어레이와 어레이 면적의 바운드를 정의하기 위해 사용될 수 있다. 어레이 면적의 바운드는 고정하거나, 조절 가능하게, 또는 추정하므로 정의될 수 있다.
TYPE_NODE=
GEM_TD_DEF_ARRAY(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
ARRAY_ELEMENT_TYPE : value,
ARRAY_DIM_COUNT : value)
ARRAY ELEMENT TYPE의 어레이를 정의한다. DECL-BLK는 비선언된 타입에 있어서의 블록 노드이다. LOCATOR는 GEM 또는 외래 locator이며, null locator로 할 수도 있다. TYPE-NAME은 상기 타입을 설명하는 가변 스트링으로 null 상태로 할 수도 있다. ARRAY-ELEMENT-TYPE은 어레이 요소에 타입을 정의하는 타입 노드에 대한 핸들이며, ARRAY-DIM-COUNT는 어레이 대한 면적의 수이다.
상기 면적 카운트는 리터럴 노드라기 보다 값처럼 전달된다는 것을 알아야 한다.
어레이 면적이 바운드 GEM-TD-SET-ARRAY-BOUND 루틴으로써 지정된다.
TYPE_NODE=
GEM_TD_DEF_ARRAY_BOUNDS(
ARRAY_TYPE : value
LOCATOR : value,
ARRAY_DIM : value,
DIM_LOW_BOUND : in GEM_NODE,
DIM_HIGH_BOUND : in GEM_NODE,
DIM_INDEX_TYPE : value,
DIM_STRIDE : in GEM_LITERAL_NODE)
어레이 타입 정의에 대해서는, 핸들 어레이 타입에 의해 지정되고, ARRAY-DIM에 의해 지시된 면적의 바운드를 세트시킨다. LOCATOR는 GEM 또는 외래 locator로서, null locator로 할 수도 있다. DIM-INDEX-LOW 및 DIM-INDEX-HIGH는 면적의 하위 바운드 및 상위 바운드를 정의한다. DIM-INDEX-TYPE는 어레이 면적의 인덱싱하기 위해 상기 티압을정의하는 타입 노드에 대한 핸들이다. DIM-STRIDE는 정의되는 면적의 연속적 요소들간의 바이트에서 그 사이즈를 정의한다. 블랭크 A상수 상위 또는 하위바운드는 리터럴 노드에 의해 지정된다. 비 상수 바운드는 값들의 위치를 정의하는 심볼노드에 의해 지시된다.
구조(변수 및 합집합)의 정의
다음읠 루틴은 변수와 합집합을 포함하는 구조를 정의하는데 사용된다. 이 구조는 하기의 루틴을 호출함으로써 정의되며, 변수 성분들을 가질 수 있다.
оGEM_TD_DEF_STRUCT
оGEM_TD_DEF_STRUCT_ELEMENT
оGEM_TD_DEF_STRUCT_SELETOR
оGEM_TD_DEF_STRUCT_VARIANT
оGEM_TD_DEF_SELECTOR_RANGE
оGEM_TD_DEF_SELECTOR_DEFAULT
оGEM_TD_DEF_UNION
оGEM_TD_DEF_UNION_MEMBER
TYPE_NODE=
GEM_TD_DEF_STRUCT(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
STRUCTURE_SYZE : in GEM_NODE)
구조 즉 레코드를 정의한다. DECL-BLK는 선언되어진 구조에 있어서 블록 노드이다. LOCATOR는 GEM 또는 외래 locator이며, null locator로 할 수도 있다. TYPE-NAME은 상기 타입을 설명하는 가변스트링으로 null 상태로 할 수도 있다. STRUCTURE-SIZE는 바이트에서 구조의 사이즈이다.
TYPE_NODE=
GEM_TD_SET_STRUCT_ELEMENT(
STRUCT_TYPE : value
VARIANT_PARENT : value,
LOCATOR : value,
ENEMENT_NAME : in VS_STR,
ENEMENT_TYPE : value,
ENEMENT_LOC_BYTE : in GEM_LITERAL_NODE,
ENEMENT_LOC_BIT : in GEM_LITERAL_NODE,
ELEMENT_SIZE : in GEM_LITERAL_NODE,
구조 정의 핸들 STRUCT-TYPE에 의해 정의된 구조의 요소를 정의한다. 상기 요소는 EMEMENT-NAME으로 명명되고 타입 노드 핸들 ELEMENT-TYPE에 의해 정의된 타입을 갖는다. 상기 요소가 변수군 아닌 경우 VARIANT-PARENT는 요소나 Null의 자신 데이타(immediate : 데이타 지정 방식) 부모 변수이다. LOCATOR는 GEM 또는 외래 locator로 null locator로 할수도 있다. 그 위치는 정의되는 구조의 루트에 비례하여 ELEMENT-LOC-BYTE 및 ELEMENT-LOC-BIT로 지정된다.
비트들에 있어서, 구조 요소의 사이즈는 ELEMENT SIZE에 의해 지정된다. ELEMENT-SIZE는 다음의 C 프로그램 플래그먼트에서 구조 요소를 C1 및 C2의 정의하기 위해 지정된다.
typedef struct ml{
char cl : 4 ;
char c2 : 4 ;
};
TYPE_NODE=
GEM_TD_DEF_STRUCT_SELECTOR(
STRUCT_TYPE : value
VARIANT_PARENT : value,
LOCATOR : value,
ELEMENT_NAME : in VS_STR,
ELEMENT_TYPE : value,
ELEMENT_LOC_BYTE : in GEM_LITERAL_NODE,
ELEMENT_LOC_BIT : in GEM_LITERAL_NODE,
ELEMENT_SIZE : in GEM_LITERAL_NODE,
레코드의 변수 성분에 대한 선택기를 정의한다. 이 선택기는 변수 구조를 결정하는 구조 요소이다. 상기 선택기 소자는 ELEMENT-NAME으로 명명되고 타입 노드 ELEMENT-TYPE에 의해 정의된 타입을 갖는다. 상기 요소가 변수군이 아닌 경우 VARIENT-PARENT는 선택이 요소나 null의 자신 데이타 부모 변수이다. LOCATOR는 GEM 또는 외래 locator이며, null locator로 할 수도 있다. 그 위치는 정의되는 구조의 루트에 비례하여 ELEMENT-LOC-TYPE 및 ELEMENT-LOC-BIT에 의해 지정된다. 비트들에 있어서, 구조 요소의 사이즈는 ELEMENT-SIZE에 의해 지정된다.
TYPE_NODE=
GEM_TD_DEF_STRUCT_VARIANT(
SELECTOR_TYPE : value,
LOCATOR : value)
변수 구조를 정의한다. SELECTOR-TYPE은 변수를 선택하는 타입 노드이다. LOCATOR는 GEM 또는 외래 locator로, null locator로 할 수도 있다. 변수를 선택하는 상기 선택기의 값들은 GEM-TD-SET-SELECTOR-RANGE 및 GEM-TO-SET-SELECTOR-DEFAULT 루틴에 의해 지정된다.
TYPE_NODE=
GEM;_TD_DEF_SELECTOR_RANGE(
VARIANT_TYPE : value,
LOCATOR : value,
RANGE_LOWER_BOUND : in GEM_LITERAL_NODE,
RANGE_UPPER_BOUND : in GEM_LITERAL_NODE)
변수 VARIANT-TYPE용 선택기 범위를 정의한다. LOCATOR는 GEM이나 외래 locator이며 null locator로 할 수도 있다. 단일 선택기 값을 정의할때, RANGE-UPPER-BOUND는 RANGE-LOWER-BOUND와 동일한 값을 가져야만 한다. 단일 선택기의 조합 및 범위 선택기들은 변수에 적용될 수 있다.
TYPE_NODE=
GEM_TD_DEF_SELECTOR_DEFAULT(
VARIANT_TYPE : value,
LOCATOR : value,
선택기의 모든 값들이 목록화되지 않았을때 기정 변수와 같은 UARIENT TYPE를 정의한다. LOCATOR는 GEM 또는 외래 locator이며 null locator로 할수도 있다. 스칼라 선택기 값을 정의할때 RANGE-UPPER-BOUND는 RANGE-LOWER-BOUND와 동일한 값을 가져야만 한다. 스칼라 선택기의 조합 및 범위들은 변수에 적용될 수도 있다.
TYPE_NODE=
GEM_TD_DEF_UNION(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
UNION_SIZE : in GEM_LITERAL_NODE,
합집합을 정의한다. DECL-BLK는 선언된 구조에서의 블록 노드이며, TYPE-NAME은 null 상태로 될수 있는 타입을 설명하는 가변 스트링이다. LOCATOR는 GEM 또는 외래 locator로, null locator로 할 수도 있다. UNION-SIZE는 바이트에서의 구조 사이즈이며, 합집합의 군집은 루틴 GEM-TD-SET-UNION-MEMBER로 호출되어 정의된다.
TYPE_NODE=
GEM_TD_SET_UNION_MEMBER(
UNION_TYPE : value,
LOCATOR : value,
MEMBER_NAME : in VS_STR,
MEMBER_TYPE : value,
타입 노드 UNION-TYPE으로 나타낸 합집합의 군집을 정의한다. UNION-TYPE은 상기 군집을 포함하는 합집합의 타입 노드이며, LOCATOR는 GEM 또는 외래 locator로 할수도 있다. MEMBER-NAME은 군집의 이름을 정의하는 가변 스트링이며, MEMBER-TYPE은 정의되는 군집의 타입 노드이다.
기능 및 루틴 파라미터의 정의
TYPE_NODE=
GEM_TD_DEF_FUNCTION_TYPE(
DECL_BLK : in_out GEM_BLOCK_NODE,
LOCATOR : value,
TYPE_NAME : in VS_STR,
FUNCTION_TYPE : value)
타입 노드 FUNCTION-TYPE에 의해 지정된 타입처럼 되는 절차 파라미터의 타입을 정의한다. 이것은 엔트리 심볼의 타입을 정의하는데 사용되지 않고 파라미터를 루틴으로 설명하는 것이다. DECL-BLK는 정의되는 타입에서의 블록노드이며, LOCATOR는 GEM 또는 외래 locator로 null locator로 할 수도 있다. TYPE NAME은 상기 타입을 설명하는 가변 스트링으로 null 상태로 할 수도 있다.
하기의 예들은 타입 및 심볼들의 수를 설명하는데 이 매카니즘을 GEM에 대해 상기 타입이나 심볼들을 설명하는데 사용된다. 파스칼 타입 부울은 GEM 타입 유니트 32상에서 목록처럼 정의되는 점을 숙지하기 바란다.
베이직 타입들의 예
main(){
int a ;
unsigned int jua ;
float x ;
double xx ;
char str()="Hello, world\n" ;
TYPINT32=GEM_TD_DEF_BASIC_TYPE(main_block, locator, 'int', GEM_TYP_KINT32) ;
TYPUINT32=GEM_TD_DEF_BASIC_TYPE(main_block, locator, 'unsigned int', GEM_TYPK_UINT32) ;
TYPREALF=GEM_TD_DEF_BASIC_TYPE(main_block, locator, 'float', GEM_TYP_KREALF) ;
TYPREALG=GEM_TD_DEF_BASIC_TYPE(main_block, locator, 'double', GEM_TYP_KREALG) ;
TYPCHAR8=GEM_TD_DEF_CHAR_TYPE(main_block, locator, 'char', GEM_TYP_KINT8) ;
TYPSTRING=GEM_TD_DEF_STRING(
main_block, locator,
'string'
GEM STRREP_K_ASCIZ,
TYPCHAR8,
litnode(len(str))) ;
부울 타입의 정의에 대한 예
procedure bt ;
boolean myflag;
TYPUINT32=GEM_TD_DEF_BASIC_TYPE(bt_block, locator, 'unsigned int', GEM_TYPK_UINT32) ;
TYPBOOL=GEM_TD_DEF_ENUM(bt_block, locator, 'boolean', TYPEUNIT32) ;
GEM_TD_SET_ENUM_ELEMENT(TYPBOOL, locator, 'false', litnode(val-0)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPBOOL, locator, 'true', litnode(val-1)) ;
문자 및 비트 기호군의 예
routine testit(parml,…)
begin
own status : bitvector(15),
flagbits : bitvector(8) ;
bind dbits=parml : bitvector() ;
end ;
TYPBITS1=GEM_TD_DEF_BITSTRING(testit_block, locator, 'bitvector', litnode(val=0), litnode(val=14)) ;
TYPBITS2=GEM_TD_DEF_BITSTRING(testit_block, locator, 'bitvector', litnode(val=0), litnode(val=7)) ;
TYPBITS3=GEM_TD_DEF_BITSTRING(testit_block, locator, 'bitvector',
포인터 및 타입 정의의 예
int echo(){
struct tnode{
}
typedef struct tnode ssval ;
tnode *tp ;
znode *zp ;
struct znodse{
}
TYPSTRUCT1=definition of structure tnode
! Define ssval as alias for tnode
TYPALIAS=GEM_TD_DEF_TYPEDEF(echo_block, locator, 'ssval', TYPSTRUCT1;
TYPPTR1=GEM_TD_DEF_POINTER(echo_block, locator, null, TYPSTRUCT1);
! Define an "anonymous" pointer, then structure znode, Finaly modify
! the pointer type.
TYPPTR2=GEM_TD_DEF_POINTER(echo_block_locator, 'pointer', null) ;
TYPSTRUCT2~definition of structure znode
GEM_TD_SET_POINTER_TPE(TYPPTR2, TYPSTRUCT2) ;
목록 및 세트 범위의 예
void myproc(){
type
dn1=0…6 ;
dn2=100…105 ;
dn3=66000…66001 ;
weekday=(mon, tue, wed, thu, fri) ;
t_typ=(int, re, boo) ;
var
s1 : set of dn1 ;
s2 : set of weekday ;
s3 : set of t_typ ;
! 범위 dn1을 정의
TYPUINT8=GEM_TD_DEF_BASIC_TYPE(myproc_block, locator, null,
GEM_TYP_K_UNIT8) ;
TYPRANGE1=GEM_TD_DEF_RANGE(myproc_block, locator, 'dn1', TYPUINT8,
litnode(val=0), litnode(val=6));
! 범위 dn2를 정의
TYPRANGE2=GEM_TD_DEF_RANGE(myproc_block, locator, 'dn2', TYPUINT8, litnode(val=100)…litnode(val=105)) ;
! 범위 dn3를 정의
TYPINT32=GEM_TD_DEF_BASIC_TYPE_(myproc_block, locator, null,
GEM_TYP_K_UINT32) ;
TYPRANGE=GEM_TD_DEF_RANGE(myproc_block, TYPINT32, 'dn3', litnode(val=66000), litnode(val=66001)) ;
TYPENUM1=GEM_TD_DEF_ENUM(myproc_block, locator, 'weekday', TYPUINT8) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM1, locator, 'mon', litnode(val=0)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM1, locator, 'tue', litnode(val=1)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM1, locator, 'wed', litnode(val=2)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM1, locator, 'thu', litnode(val=3)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM1, locator, 'fri', litnode(val=4)) ;
TYPENUM2=GEM_TD_DEF_ENUM(myproc_block, locator, 't_typ', TYPEUINT32) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM2, locator, 'int', litnode(val=0)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM2, locator, 're', litnode(val=1)) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM2, locator, 'boo', litnode(val=2)) ;
! vars s1, s2 및 s3에 대한 세트를 정의
TYPSET1=GEM_TD_DEF_SET(myproc_block,locator, 'set', TYPRANGE1) ;
TYPSET2=GEM_TD_DEF_SET(myproc_block, locator, 'set', TYPENUM1) ;
TYPSET3=GEM_TD_DEF_SET(myproc_block, locator, 'set', TYPENUM2) ;
어레이의 예
procedure dimmer ;
type
nd=record…
var
ary1 : array(1…10) of integer ;
ary2 : array(1…10, 100…110) of integer ;
ary3 : array(900…1700) of nd ;
ary4 : array('a'…'z') of nd ;
TYPSTRUCT1=Definition of record type nd.
! 어레이 'ary1'을 정의
TYPINT32=GEM_TD_DEF_BASIC_TYPE(dimmer_block, locator, null,
GEM_TYP_K_INT32) ;
TYPARRAY=GEM_TD_DEF_ARRAY(dimmer block, locator, null, TYPINT32, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 1,
litnode(val=1), litnode(var=10),
TYPINT32, litnode(value=4)) ;
! 어레이 'ary2'를 정의
TYPARRAY=GEM_TD_DEF_ARRAY(dimmer_block, locator, null, TYPINT32, 2) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 1,
litnode(val=1), litnode(val=10),
TYPINT32, litnode(val=4)) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 2,
litnode(val=100), litnode(val=110),
TYPINT32, litnode(val=40)) ;
! 역으로 ary2에 대한 어레이 명세는 하기와 같이 정의될 수 있다 :
TYPARRAY1=GEM_TD_DEF_ARRAY(dimmer_block, locator, null, TYPINT32, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY1, locator, 1,
litnode(val=100), litnode(val=110),
TYPINT32, litnode(value=4)) ;
TYPARRAY2=GEM_TD_DEF_ARRAY(dimmer_block, locator, null, TYPARRA1, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY2, locator, 1,
litnode(val=1), litnode(val=10),
TYPINT32, litnode(value=40)) ;
! 어레이 'ary3'를 정의
TYPARY=GEM_TD_DEF_ARRAY(dimmer_block, locator, null, TYPSTRUCT1, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 1,
litnode(val=900), litnode(val=1700),
TYPINT32, sizeof(nd)) ;
! 어레이 'ary4'를 정의
TYPCHAR=GEM_TD_DEF_CHAR_TYPE(dimmer_block, locator, null, GEM_TYP_KUINT8) ;
TYPARRAY=GEM_TD_DEF_ARRAY(dimmer_block,locator, TYPSTRUCT1, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 1,
litnode(val=97), litnode(val=122))
TYPCHAR, sizeof(nd)) ;
조절 가능한 어레이에 대한 정의의 예
subroutine x(cv, ary1, ary2, a, b)
character*(*)cv
dimension ary1(1 : 10, 1 : b)
dimension ary2(a : b, 1 : *)
TYPINT32=GEM_TD_DEF_BASIC_TYPE(x_block, locator, null, GEM_TYP_K_INT32) ;
TYPCHAR=GEM_TD_DEF_CHAR_TYPE(x_block, locator, null, GEM_TYP_K_INT8) ;
! 어레이 'cv'를 정의
TYPARRAY=GEM_TD_DEF_ARRAY(x_block, locator, null, TYPCHAR, 1) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPEARRAY, locator, 1,
litnode(val=1), litnode(val=1),
TYPINT32, litnode(val=1)) ;
! 어레이 'ary1'를 정의
TYPREALF=GEM_TD_DEF_BASIC_TYPE(x_block, locator, null, GEM_TYP_K_REALF)
TYPARRAY=GEM_TD_DEF_ARRAY(x_block, locator, TYPREALF, 2) ; 2, litnode(val=4)) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, 1, locator,
litnode(val=1), litnode(val=10),
TYPINT32, litnode(val=4)) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, 2, locator,
litnode(val=1), b_symbol,
TYPINT32, litnode(val=4)) ; ********
! 어레이 'sry2'를 정의
TYPARRAY=GEM_TD_DEF_ARRAY(x_block, locator, null, TYPREALF, TYPINT32, 2, litnode(val=4))
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 1,
a_symbol, b_symbol,
TYPINT3, litnode(val=4)) ;
GEM_TD_SET_ARRAY_BOUNDS(TYPARRAY, locator, 2,
litnode(val=1), litnode(val=1),
TYPINT32, litnode(val=4)) ;
구조 및 변수의 예
type
t_tpy=lit, re, ptr, v1, v2, v3) ;
ndp=@nd ;
nd=record
nxt : ndp ;
case tt : t_typ of
it : (iv : integer) ;
re : (rv : real) ;
ptr : (pv : ndp ; sum : integer) ;
otherwise : (i1 : integer ; i2 : real) ;
end ;
! 일예로 사용된 베이직 타입을 정의
TYPINT32=GEM_TD_DEF_BASIC_TYPE(typeit_block, locator, 'integer', GEM_TYP_KINT32) ;
TYPREALF=GEM_TD_DEF_BASIC_TYPE(typeit_block, locator, 'real', GEM_TYP_KREALF) ;
TYPNIL=GEM_TD_DEF_BASIC_TYPE(typeit_block, locator, null, GEM_TYP_K_NIL) ;
! ndp 포인터를 nd로 정의
TYPPTR=GEM_TD_DEF_POINTER(typeit_block, locator, 'ndp', TYPNIL) ;
! t-typ 목록을 정의
TYPENUM=GEM_TD_DEF_ENUM(myproc_node, locator, 't-typ', TYPINT32) ;
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 'it', litnode(val=0));
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 're', litnode(val=1));
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 'boo', litnode(val=2));
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 'v1', litnode(val=3));
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 'v2', litnode(val=4));
GEM_TD_SET_ENUM_ELEMENT(TYPENUM, locator, 'v3', litnode(val=5));
! 구조 정의 nd를 정의
TYPSTRUCT=GEM_TD_DEF_STRUCT(typeit_block, locator, 'nd', litnode(nd_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'nxt', TYPPTR, litnode(1byte(nxt)), litnode(1_bit(nxt)), litnode(bit_size(nxt)
! 변수 부분에 대한 선택기를 정의
TYPSEL=GEM_TD_DEF_STRUCT_SELECTOR(TYPSTRUCT, null, 'tt', TYPENUM,
litnode(1_byte(tt)), litnode(1_bit(tt)), litnode(bit_size(tt))) ;
! 디폴트를 포함하는 구조 변수들을 정의
V1=GEM_TD_DEF_STRUCT VARIANT(TYPSEL, locator) ;
GEM_TD_SET_SELECTOR_RAGE(V1, locator, litnode(val=0), litnode(val=0)
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V1, locator, 'iv', TYPINT,
litnode(1_byte(iv)), litnode(1_bit(iv)), litnode(bit_size(iv))
V2=GEM_TD_DEF_STRUCT VARIANT(TYPSEL, locator) ;
GEM_TD_SET_SELECTOR_RANGE(V2, locator, litnode(val=1), litnode(val=1)
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V2, locator, 'rv', TYPREALF,
litnode(1_byte(rv)), litnode(1_bit(rv)), litnode(bit_size(rv))
V3=GEM_TD_DEF_STRUCT VARIANT(TYPSEL, locator) ;
GEM_TD_SET_SELECTOR_RANGE(V3, locator, litnode(val=2), litnode(val=2)
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V3, locator, 'pv', TYPPTR,
litnode(1_byte(pv)), litnode(1_bit(pv)), litnode(bit_size(pv))
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V3, locator, 'sum', TYPPTR,
litnode(1_byte(sum)), litnode(1_bit(sum)), litnode(bit_size(sum)
V4=GEM_TD_DEF_STRUCT VARIANT(TYPSEL, locator) ;
GEM_TD_SET_SELECTORD_FAULT(V4, locator) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V4, locator, 'il', TYPINT, litnode(1_byte(il)),
litnode(1_bit(il)), litnode(bit_size(il)) :
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, V4, locator, 'i2', TYPINT, litnode(1_byte(i2)),
litnode(1_bit(i2)),
GEM_TD_SET_POINTER_TYPE(TYPPTR, TYPSTRUCT) ;
구조 및 합집합 정의의 예
main() {
struct dim3{
int x ;
int y ;
int z ;
} ;
union anon{
int ival ;
float fval ;
char *pval ;
struc dim3 loc ;
} ;
struct n1{
union anon a ;
union anon b ;
union anon c ;
} ;
struct n1 n11, n12, n13 ;
TYPINT32=GEM_TD_DEF_BASIC_TYPE(main_block, locator, 'int',
GEM_TYP_K_INT32) ;
TYPREALF=GEM_TD_DEF_BASIC_TYPE(main_block, locator, null,
GEM_TYP_K_INT3) ;
TYPCHAR=GEM_TD_DEF_CHAR_TYPE(main_block, locator, null,
GEM_TYP_K_UNIT8) ;
TYPPTR=GEM_TD_DEF_POINTER(main_block, locator, null, TYPCHAR) ;
! 구조 'dim3'를 정의
TYPSTRUCT=GEM_TD_DEF_STRUCT(main_block, locator, 'dim3', litnode(dim3_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'x', TYPINT32,
loc_byte(x), loc_bit(x), litnode(x_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'y', TYPINT32,
loc_byte(y), loc_bit(y), litnode(y_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'z', TYPINT32,
loc_byte(z), loc_bit(z), litnode(z_size)) ;
! 합집합 'anon'을 정의
TYPUNION=GEM_TD_DEF_UNION(main_block, locator, 'anon', litnode(anon_size)) ;
GEM_TD_SET_UNION_MEMBER(TYPUNION, locator, 'ival', TYPINT32) ;
GEM_TD_SET_UNION_MEMBER(TYPUNION, locator, 'fval', TYPREALF) ;
GEM_TD_SET_UNION_MEMBER(TYPUNION, locator, 'pval', TYPPTR) ;
GEM_TD_SET_UNION_MEMBER(TYPUNION,locator,'loc', TYPSTRUCT) ;
! 구조 'n1'를 정의
TYPSTRUCT=GEM_TD_DEF_STRUCT(main_block, locator, 'n1', litnode(n1_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'a', TYPUNION,
loc_byte(a), loc_bit(a),
litnode(anon_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'b', TYPUNION,
loc_byte(b), loc_bit(b),
litnode(anon_size)) ;
GEM_TD_SET_STRUCT_ELEMENT(TYPSTRUCT, null, locator, 'c', TYPUNION, loc_byte(a), loc_bit(b), litnode(anon_size)) ;
기능 파라미터 정의의 예
function x(function grin : real ;
procedure bearit) : liteger ;
TYPREALF=GEM_TD_DEF_BASIC_TYPE(x_block, locator, 'real',
GEM_TYP_K_REALF) ;
TYPNIL=GEM_TD_DEF_BASIC_TYPE(x_block, locator, null, GEM_TYP_K_NIL) ;
! 기능 파라미터 'grin'에 대한 타입을 정의
TYPPROC=GEM_TD_DEF_FUNCTION_TYPE(x_block, locator, null, TYPREALF) ;
! 절차 파라미터 'bearit'에 대한 타입을 정의
TYPFUNCT=GEM_TD_DEF_FUNCTION_TYPE(x_block, locator, null, TYPNIL) ;

Claims (17)

  1. 언어 특정상을 갖는 컴파일러 전단을 사용하여 고급 프로그래밍 언어의 소스 코드를 포함한 소스 코드 모듈을 액세스하는 단계와 ; 상기 소스 코드 모듈내의 단일 표현을 각각 나타내는 튜플들로 구성된 중간 언어의 흐름 그래프를 상기 컴파일러 전단에 의해 발생하는 단계와 ; 다른 튜플상의 효과를 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 효과의 표시를 상기 튜플에 포함시키는 단계와 ; 다른 튜플상의 종속성을 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 종속성의 표시를 상기 튜플에 포함시키는 단계를 포함한 것을 특징으로 하는 코드 번역 방법.
  2. 제1항에 있어서, 상기 튜플의 효과 또는 종속성의 상기 표시에 응답하여 옵티마이저에 의해 상기 흐름 그래프를 액세스함으로써 상기 코드를 최적화 하는 단계를 포함한 것을 특징으로 하는 코드 번역 방법.
  3. 제1항에 있어서, 상기 흐름 그래프를 정해진 순서의 상기 튜플들을 포함하는 블록들로 구성된 것을 특징으로 하는 코드 번역 방법.
  4. 제1항에 있어서, 상기 효과의 스택 및 상기 종속성의 스택을 생성하는 단계를 포함한 것을 특징으로 하는 코드 번역 방법.
  5. 제4항에 있어서, 상기 효과의 스택을 생성하는 단계는 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 단계를 포함한 것을 특징으로 하는 코드 번역 방법.
  6. 제5항에 있어서, 상기 효과의 스택을 생성하는 단계는 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 단계를 포함한 것을 특징으로 하는 번역 방법.
  7. 언어 특정성이 있는 컴파일러 전단을 사용하여 고급 프로그래밍 언어의 소스 코드를 포함하는 소스 코드 모듈을 액세싱 하는 수단과 ; 상기 소스 코드 모듈의 단일 표현을 각각 나타내는 튜플들로 구성된 중간 언어의 흐름 그래프를 발생하기 위한 상기 컴파일러 전단내의 수단을 포함하고 ; 다른 튜플상의 효과를 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 튜플 상기 효과의 표시를 포함하고 ; 다른 튜플상의 종속성을 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 튜플은 대하여 상기 튜플에 상기 종속성의 표시를 포함한 것을 특징으로 하는 코드 번역 장치.
  8. 제7항에 있어서, 상기 튜플내의 효과 또는 종속성의 상기 표시에 응답하여 옵티마이저에 의해 상기 흐름 그래프를 액세싱 함으로써 상기 코드를 최적화 하기 위한, 컴파일러 후단내의 수단을 포함한 것을 특징으로 하는 코드 번역 장치.
  9. 제7항에 있어서, 상기 플로우 그래프는 정해진 순서의 상기 튜플들을 포함한 블록들로 구성되는 것을 특징으로 하는 코드 번역 장치.
  10. 제7항에 있어서, 상기 효과의 스택 및 상기 종속성의 스택을 생성하는 수단을 포함한 것을 특징으로 하는 코드 번역 장치.
  11. 제10항에 있어서, 상기 효과의 스택을 생성하는 수단을 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 수단을 포함한 것을 특징으로 하는 코드 번역 장치.
  12. 제11항에 있어서, 상기 효과의 스택을 생성하는 수단을 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 수단을 포함한 것을 특징으로 하는 코드 번역 장치.
  13. 언어 특정성이 있는 컴파일러 전단을 사용하여 소스 코드 언어의 단일 표현을 각각 나타내는 튜플들로 구성된 중간 언어의 흐름 그래프를 발생하는 단계와 ; 다른 튜플상의 효과를 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 효과의 표시를 상기 튜플에 포함시키는 단계와 ; 다른 튜플상의 종속성을 갖는 표현을 나타내는 상기 각 튜플에 대하여 상기 종속성의 표시를 상기 튜플에 포함시키는 단계와 ; 상기 튜플내의 효과 또는 종속성의 표시에 응답하여 옵티마이저에 의해 상기 흐름 그래플 액세스 하는 단계를 포함하는 것을 특징으로 하는 컴파일러내의 코드 최적화 방법.
  14. 제13항에 있어서, 상기 플로우 그래프는 정해진 순서의 상기 튜플들을 포함하는 블록들로 구성된 것을 특징으로 하는 코드 최적화 방법.
  15. 제13항에 있어서, 상기 효과의 스택 및 상기 종속성의 스택을 생성하는 단계를 포함한 것을 특징으로 하는 코드 최적화 방법.
  16. 재15항에 있어서, 상기 효과의 스택을 생성하는 단계는 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 단계를 포함한 것을 특징으로 하는 코드 최적화 방법.
  17. 제16항에 있어서, 상기 효과의 스택을 생성하는 단계는 상기 튜플이 생성될때 상기 스택에 대한 상기 각 효과의 표시를 푸슁하는 단계를 포함한 것을 특징으로 하는 코드 최적화 방법.
KR1019920702690A 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스 KR950006607B1 (ko)

Applications Claiming Priority (11)

Application Number Priority Date Filing Date Title
US66246191A 1991-02-27 1991-02-27
US66248391A 1991-02-27 1991-02-27
US66247791A 1991-02-27 1991-02-27
US66272591A 1991-02-27 1991-02-27
US66246491A 1991-02-27 1991-02-27
US662,725 1991-02-27
US662,483 1991-02-27
US662,464 1991-02-27
US662,477 1991-02-27
US662,461 1991-02-27
PCT/US1992/001290 WO1992015944A1 (en) 1991-02-27 1992-02-18 Interface for representing effects in a multilanguage optimizing compiler

Publications (1)

Publication Number Publication Date
KR950006607B1 true KR950006607B1 (ko) 1995-06-19

Family

ID=27542049

Family Applications (5)

Application Number Title Priority Date Filing Date
KR1019920702691A KR950006608B1 (ko) 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러내의 상수 폴딩 메카니즘을 구성하는 방법
KR1019920702690A KR950006607B1 (ko) 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스
KR1019920702692A KR960003050B1 (ko) 1991-02-27 1992-02-18 중간 컴파일러 언어에 대한 심볼 테이블
KR1019920702694A KR950006609B1 (ko) 1991-02-27 1992-02-18 다중 패스코드 발생에 있어서 템플리트를 이용한 다중 언어 최적화 컴파일러
KR1019920702693A KR960003138B1 (ko) 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러의 유도 수식 분석

Family Applications Before (1)

Application Number Title Priority Date Filing Date
KR1019920702691A KR950006608B1 (ko) 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러내의 상수 폴딩 메카니즘을 구성하는 방법

Family Applications After (3)

Application Number Title Priority Date Filing Date
KR1019920702692A KR960003050B1 (ko) 1991-02-27 1992-02-18 중간 컴파일러 언어에 대한 심볼 테이블
KR1019920702694A KR950006609B1 (ko) 1991-02-27 1992-02-18 다중 패스코드 발생에 있어서 템플리트를 이용한 다중 언어 최적화 컴파일러
KR1019920702693A KR960003138B1 (ko) 1991-02-27 1992-02-18 다중 언어 최적화 컴파일러의 유도 수식 분석

Country Status (9)

Country Link
EP (5) EP0532731A1 (ko)
JP (5) JPH0762826B2 (ko)
KR (5) KR950006608B1 (ko)
AU (5) AU663493B2 (ko)
CA (5) CA2081473C (ko)
DE (1) DE69225281T2 (ko)
FI (2) FI924845A (ko)
NO (2) NO924114L (ko)
WO (5) WO1992015943A1 (ko)

Families Citing this family (21)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2847688B2 (ja) 1993-05-27 1999-01-20 松下電器産業株式会社 プログラム変換装置およびプロセッサ
DE69434967T2 (de) 1993-05-27 2008-01-17 Matsushita Electric Industrial Co., Ltd., Kadoma Programmumsetzungseinheit und verbesserter Prozessor für Adressierung
JP2755154B2 (ja) * 1994-02-23 1998-05-20 日本電気株式会社 プログラム変換処理装置およびプログラム変換処理方法
US5740469A (en) * 1995-04-24 1998-04-14 Motorola Inc. Apparatus for dynamically reading/writing multiple object file formats through use of object code readers/writers interfacing with generalized object file format interface and applications programmers' interface
CA2251369A1 (en) * 1998-10-26 2000-04-26 International Business Machines Corporation System and method for analyzing dependencies in a computer program
US7000222B1 (en) 1999-08-19 2006-02-14 International Business Machines Corporation Method, system, and program for accessing variables from an operating system for use by an application program
WO2007114722A1 (en) * 2006-03-30 2007-10-11 Intel Corporation An optimal floating-point expression translation method based on pattern matching
KR101314247B1 (ko) * 2009-09-03 2013-10-02 한국전자통신연구원 위성 관제 시스템에서 위성 관제 운용 자동화를 위한 언어변환장치 및 방법
US20130167144A1 (en) * 2009-09-04 2013-06-27 Bernd Mathiske Virtual Machine Persisted Within Itself
US8832672B2 (en) 2011-01-28 2014-09-09 International Business Machines Corporation Ensuring register availability for dynamic binary optimization
EP2687981B1 (en) * 2012-07-18 2017-12-27 MStar Semiconductor, Inc. Automated compiler specialisation for global optimisation
US20160019037A1 (en) * 2014-07-21 2016-01-21 Xamarin Inc. Managing parameter types for generic functions
US9183020B1 (en) 2014-11-10 2015-11-10 Xamarin Inc. Multi-sized data types for managed code
US9213638B1 (en) 2015-03-24 2015-12-15 Xamarin Inc. Runtime memory management using multiple memory managers
JP6481515B2 (ja) 2015-05-29 2019-03-13 富士通株式会社 情報処理装置、コンパイル方法、及びコンパイラプログラム
US10990073B2 (en) * 2016-08-30 2021-04-27 Mitsubishi Electric Corporation Program editing device, program editing method, and computer readable medium
CN108108169B (zh) * 2017-12-27 2020-11-03 广东小天才科技有限公司 一种基于Jenkins的多分支的构建方法及系统
JP7015207B2 (ja) * 2018-04-27 2022-02-02 株式会社日立製作所 ビジュアルプログラミングツールを用いてフローを作成することを支援する装置および方法
JP7163697B2 (ja) * 2018-09-28 2022-11-01 富士通株式会社 生成プログラム,情報処理装置及び生成方法
KR102165928B1 (ko) * 2019-12-04 2020-10-14 서울대학교 산학협력단 전자 장치, 전자 장치의 컴파일링 방법 및 전자 장치의 동작 방법
CN116360788A (zh) * 2023-02-17 2023-06-30 深圳市亿维自动化技术有限公司 结构化文本编程语言的编译方法、编译器及电子设备

Family Cites Families (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4667290A (en) * 1984-09-10 1987-05-19 501 Philon, Inc. Compilers using a universal intermediate language

Also Published As

Publication number Publication date
CA2081475A1 (en) 1992-08-28
WO1992015943A1 (en) 1992-09-17
AU653799B2 (en) 1994-10-13
CA2081449C (en) 1999-04-13
EP0526622A1 (en) 1993-02-10
WO1992015942A1 (en) 1992-09-17
JPH06501583A (ja) 1994-02-17
NO924115L (no) 1992-12-18
WO1992015944A1 (en) 1992-09-17
WO1992015941A1 (en) 1992-09-17
KR950006609B1 (ko) 1995-06-19
FI924846A (fi) 1992-10-26
FI924846A0 (fi) 1992-10-26
KR950006608B1 (ko) 1995-06-19
JPH06501580A (ja) 1994-02-17
JPH06501581A (ja) 1994-02-17
CA2081449A1 (en) 1992-08-28
CA2081473A1 (en) 1992-08-28
JPH0762826B2 (ja) 1995-07-05
JPH0769832B2 (ja) 1995-07-31
AU658399B2 (en) 1995-04-13
AU1442292A (en) 1992-10-06
NO924114L (no) 1992-12-18
NO924114D0 (no) 1992-10-23
AU1569892A (en) 1992-10-06
CA2081473C (en) 1999-04-06
AU1420492A (en) 1992-10-06
DE69225281D1 (de) 1998-06-04
JPH0769833B2 (ja) 1995-07-31
KR960003050B1 (ko) 1996-03-04
CA2081477C (en) 1992-08-28
CA2081475C (en) 1998-05-05
EP0532731A1 (en) 1993-03-24
KR960003138B1 (ko) 1996-03-05
AU1429292A (en) 1992-10-06
EP0526621A1 (en) 1993-02-10
WO1992015945A1 (en) 1992-09-17
JPH06501582A (ja) 1994-02-17
FI924845A0 (fi) 1992-10-26
AU1439792A (en) 1992-10-06
CA2081477A1 (en) 1992-08-28
JPH06501579A (ja) 1994-02-17
DE69225281T2 (de) 1999-01-07
AU663493B2 (en) 1995-10-12
EP0529049A1 (en) 1993-03-03
EP0528008A1 (en) 1993-02-24
EP0529049B1 (en) 1998-04-29
JPH0762825B2 (ja) 1995-07-05
AU663311B2 (en) 1995-10-05
FI924845A (fi) 1992-10-26
NO924115D0 (no) 1992-10-23
JPH0769834B2 (ja) 1995-07-31
CA2081476A1 (en) 1992-08-28
AU663310B2 (en) 1995-10-05

Similar Documents

Publication Publication Date Title
KR950006607B1 (ko) 다중 언어 최적화 컴파일러내의 표시 효과용 인터페이스
US5613117A (en) Optimizing compiler using templates corresponding to portions of an intermediate language graph to determine an order of evaluation and to allocate lifetimes to temporary names for variables
US5577253A (en) Analyzing inductive expressions in a multilanguage optimizing compiler
US5659753A (en) Interface for symbol table construction in a multilanguage optimizing compiler
US5836014A (en) Method of constructing a constant-folding mechanism in a multilanguage optimizing compiler
US5493675A (en) Compiler back end calling predetermined front end routines that use effect and dependency indicators to provide information to the compiler to determine the validity of an optimization
IE920608A1 (en) Interface for symbol table construction in a multilanguage¹optimizing compiler

Legal Events

Date Code Title Description
A201 Request for examination
G160 Decision to publish patent application
E701 Decision to grant or registration of patent right
GRNT Written decision to grant
FPAY Annual fee payment

Payment date: 19980428

Year of fee payment: 4

LAPS Lapse due to unpaid annual fee