• No results found

Standardized Linkages

In document Engineering A Compiler pdf (Page 195-198)

callerarp saved ptr. ret. address ret. value parameters - level 2 arp - locals callerarp saved ptr. ret. address ret. value parameters - level 1 locals callerarp saved ptr. ret. address ret. value parameters level 0 level 0 level 1 level 2 level 3 Display b - -

Figure 7.8: Using a display

Figure 7.8 shows this situation.

Using a global display, the cost of non-local access is independent ofx−y. The compiler knowsy, so the overhead consists of a minor address calculation (see Section 8.5) and an extra load operation. This still leaves an inequity be- tween the cost of local access and the cost of non-local access, but the difference is smaller than with access links and it is entirely predictable.

To maintain a global display, the compiler must add code to both the proce- dure call and its corresponding return. On call, the procedure should store the display entry for its lexical level in itsar, and replace that entry in the global display with its ownarp. On return, it should restore the value from itsarto the global display. This simple scheme takes one more slot in the global display than is strictly necessary, but this is a small price to pay for the simplicity of the update scheme.

As an improvement, the compiler can omit the code to update the display in any procedure that, itself, calls no other procedures. This eliminates some of the wasted display updates. It does not eliminate all of them. If the procedure never calls a procedure that is more deeply nested, then it can omit the display update, because execution can only reach a more deeply nested procedure by passing through some intervening procedure that calls down the lexical nesting tree and will, therefore, preserve the appropriatearp.

7.6

Standardized Linkages

The procedure linkage is a social contract between the compiler, the operating system, and the target machine that clearly divides responsibility for naming, for allocation of resources, for addressability, and for protection. The procedure linkage ensures interoperability of procedures between the user’s code, as trans- lated by the compiler, and the operating system’s routines. Typically, all of the compilers for a given combination of target machine and operating system use the same procedure linkage.

epilog prolog pre-call post-return epilog prolog ? ? * H H H H H Y procedure p procedure q

Figure 7.9: A standard procedure linkage

environments found at call sites that invoke it. Assume that procedurephas an integer parameter x. Different calls top may bindx to a local variable stored in the calling procedure’s stack frame, to a global variable, to an element of some static array, and to the result of evaluating an integer expression such as

y+2. Because the procedure linkage specifies how to evaluate and storexin the calling procedure, and how to accessxin the called procedure, the compiler can generate code for the body of the called procedure that ignores the differences between the run-time environments at the different calls top. As long as all the procedures obey the linkage convention, the details will mesh together to create the seamless transfer of values promised by the source-language specification.

The linkage convention is, of necessity, machine dependent. For example, the linkage convention implicitly contains information such as the number of registers available on the target machine, and the mechanism for executing a call and a return.

Figures 7.9 shows how the pieces of a standard procedure linkage fit together. Each procedure has a prolog sequence and an epilog sequence. Each call site includes both apre-call sequence and apost-return sequence.

pre-call The pre-call sequence is responsible for setting up the called proce- dure’s ar. It allocates space for the basic ar and fills in each of the locations. This includes evaluating each actual parameter to a value or an address as appropriate, and storing the value in the parameter’s designated slot in the ar. It also stores the return address, the calling procedure’s arp, and, if necessary, the address of the space reserved for a return value in their designated locations in the ar.

The caller cannot know how much space to reserve for the called proce- dure’s local variables. Thus, it can only allocate space for the basic portion of the called procedure’s ar. The remaining space must be allocated by the called procedure’s prolog code.2

2The alternative is to arrange a link-time mechanism to place this information in a place

7.6. STANDARDIZED LINKAGES 187 post-return The post-call sequence must undo the actions of the pre-call se- quence. It completes the process by deallocating the called procedure’s ar. If any call-by-reference parameters need to be returned to registers, the post-return sequence restores them.

prolog Each procedure’s prolog performs the same basic set of actions. It completes the task of constructing the called procedure’s run-time envi- ronment. The prolog extends the procedure’s basicarto create space for local variables, and initializes them as necessary. If the procedure contains references to a procedure-specific static data area, the prolog may need to establish addressability by loading the appropriate label into a register. If the compiler is using a display to access local-variables of other pro- cedures, the prolog updates the display entry for its lexical level. This involves saving the current entry for that level into thearand storing the currentarp into the display.

epilog A procedure’s epilog code undoes some of the actions of the prolog. It may need to deallocate the space used for local variables. It must restore the caller’sarpand jump to the return address. If the procedure returns a value, that value is actually stored by code generated for the return statement (whether the return is explicit or implicit).

This is, however, just a general framework for building the linkage convention. Figure 7.10 shows one possible division of labor between the caller and the callee. It includes most of the details that the linkage convention must handle. It does not mention either a display or access links.

To manage a display, the prolog sequence in the called procedure saves the current display record for its own level into itsarand stores its own arpinto that slot in the display. This establishes the display pointer for any call that it makes to a more deeply nested procedure. If the procedure makes no calls, or only calls less nested procedures, it can skip this step. To manage access links, the pre-call sequence in the calling procedure

computes the appropriate first access link for the called procedure and saves it into the access link slot in the called procedure’sar. This can be the caller’s ownarp (if the callee is nested inside the caller), the caller’s access link (if the callee is at the same lexical level as the caller), or some link up the caller’s access link chain (if the callee is declared at an outer lexical level).

As long as the called procedure is known at compile time, maintaining either a display or access links is reasonably efficient.

One critical issue in the procedure linkage is preserving values kept in reg- isters. This can be done by saving them in the pre-call sequence and restoring

is easy. If ars are allocated in the heap, the compiler writer may elect to use a separately allocated block of memory to hold the local variables.

Caller Callee pre-call sequence prolog sequence

allocate basicar preserve callee-save registers evaluate & store parameters extend arfor local data Call store return address &arp find static data area

save caller-save registers initialize locals jump to callee fall through to code post-return sequence epilog sequence

deallocate basicar restore callee-save registers Return restore caller-save registers discard local data

restore reference parameters restore caller’sarp jump to return address

Figure 7.10: One possible division of responsibility in a linkage

them in the post-call sequence; this convention is called callee-saves. The al- ternative is to save them in the prolog sequence and restore them in the epilog sequence; this convention is called caller-saves. With callee saves, the enreg- istered values are stored in the calling procedure’s ar. With caller saves, the enregistered values are stored in the called procedure’s ar.

Each convention has arguments in its favor. The procedure that saves and restores registers needs only to preserve a subset of the enregistered values. In caller saves, the pre-call sequence only needs to save a value if it is used after the call. Similarly, in callee saves, the prolog only needs to save a value if the procedure actually uses the register that contains it. The linkage convention can specify that all registers are caller-saves, that all registers are callee-saves, or it can divide the register set into some caller-saves and some callee-saves registers. For any specific division of responsibility, we can construct programs where the division fits well and programs where it does not. Many modern systems divide the register set evenly between these two conventions.

In document Engineering A Compiler pdf (Page 195-198)