Honors Compilers
description
Transcript of Honors Compilers
Honors CompilersHonors Compilers
Addressing of Local VariablesAddressing of Local Variables
Mar 19Mar 19thth, 2002, 2002
Procedure frameProcedure frame
Assume stack builds downAssume stack builds downParameters Parameters stored by callerstored by caller
Return point Return point stored by calleestored by calleeSaved regs Saved regs stored by calleestored by calleeOld frame ptr Old frame ptr stored by calleestored by calleeFRAME PTR FRAME PTR local variables local variables STACK PTR STACK PTR
Passing ParametersPassing Parameters
Parameters can be passed three waysParameters can be passed three waysIn registersIn registersOn the stack, addressed by stack ptr on On the stack, addressed by stack ptr on
entryentryIn memory, referenced by an argument ptrIn memory, referenced by an argument ptr
Cannot pass all parameters in registersCannot pass all parameters in registersSo use method 2 or 3 as a backupSo use method 2 or 3 as a backup
Addressing ParametersAddressing Parameters
Parameters in registersParameters in registersEither keep them in the register and use Either keep them in the register and use
therethereOr store as a local variableOr store as a local variable
Parameters on stackParameters on stackAddress using the frame pointerAddress using the frame pointer
Parameters referenced by arg ptrParameters referenced by arg ptrReference via arg ptr, possibly have to save Reference via arg ptr, possibly have to save
arg ptr as a local variable if not leaf arg ptr as a local variable if not leaf procedureprocedure
Local VariablesLocal Variables
If a local variable is of fixed size, it If a local variable is of fixed size, it can be addressed directly using a can be addressed directly using a fixed offset from the frame pointer or fixed offset from the frame pointer or stack pointerstack pointer
For a variable of dynamic size (e.g. a For a variable of dynamic size (e.g. a local array with dynamic bounds), we local array with dynamic bounds), we use a hidden pointeruse a hidden pointer
Addressing a Variable Length Addressing a Variable Length ObjectObject
ParametersParametersReturn pointReturn pointOld frame ptr Old frame ptr frame ptr frame ptrFixed part of stackFixed part of stackDynamic objectDynamic objectDynamic object Dynamic object stack ptr stack ptr
For each dynamic object we put a pointer For each dynamic object we put a pointer into the fixed part of the stack. This into the fixed part of the stack. This pointer can be addressed as a normal pointer can be addressed as a normal fixed length local variable.fixed length local variable.
Variables in BlocksVariables in Blocks
Consider simple caseConsider simple case{int a,b,c ….. }{int a,b,c ….. }{int a,d,e ….. }{int a,d,e ….. }
First, the clash of a’s is a compile time First, the clash of a’s is a compile time issue, not a run-time issueissue, not a run-time issueFor example, rename to a1, a2For example, rename to a1, a2
Now just include a1,b,c,a2,d,e in Now just include a1,b,c,a2,d,e in parent frame and address of parent parent frame and address of parent frame ptrframe ptr
Can overlap the sets of variablesCan overlap the sets of variables
Variables in Blocks Variables in Blocks (continued)(continued)
Consider this caseConsider this case{int a[10000]; ….}{int a[10000]; ….}{int b[10000]; ….}{int b[10000]; ….}lots more code herelots more code here
Now do we really want to have Now do we really want to have 10000 int’s allocated throughout the 10000 int’s allocated throughout the procedure?procedure?
Perhaps notPerhaps not
Variables in Blocks Variables in Blocks (continued)(continued)
So in this case {int a[10000]; ….} we So in this case {int a[10000]; ….} we could consider using a different could consider using a different techniquetechnique
Allocate *int in enclosing frame (call it __a)Allocate *int in enclosing frame (call it __a)On block entry:On block entry:
Save stack pointer in some local variableSave stack pointer in some local variableDecrement stack pointer by 10000Decrement stack pointer by 10000Copy stack ptr to __aCopy stack ptr to __aAddress indirectly through __aAddress indirectly through __a
On block exitOn block exitRestore stack ptr from saved locationRestore stack ptr from saved location
Up Level AddressingUp Level Addressing
PROC outer = (INT x) INT : (PROC outer = (INT x) INT : ( INT a;INT a;
INT b;INT b;PROC inner = (INT y) INT : (PROC inner = (INT y) INT : ( INT c;INT c;
……c := a + b;c := a + b;…)…)
…)…) How do we address a and b from inside How do we address a and b from inside
innerinner
Stack FramesStack Frames
Inner could be recursiveInner could be recursiveStack frame for outer (has a and b)Stack frame for outer (has a and b)Stack frame for innerStack frame for innerStack frame for innerStack frame for innerStack frame for innerStack frame for innerStack frame for innerStack frame for innerStack frame for inner (references a,b)Stack frame for inner (references a,b)
How does inner frame find the outer How does inner frame find the outer frame?frame?
If we know frame ptr of outer, we can If we know frame ptr of outer, we can address off that, in the usua fashion.address off that, in the usua fashion.
A Horrible SolutionA Horrible Solution
The Saved frame pointer links each The Saved frame pointer links each frame to the previous one.frame to the previous one.
Mark each frame with e.g. name of Mark each frame with e.g. name of procedure it is forprocedure it is for
Trace back frame pointer links until Trace back frame pointer links until you get to the frame you need outer.you get to the frame you need outer.
Then get the variable you wantThen get the variable you want
Some ObservationsSome Observations
Label each procedure with its static Label each procedure with its static nesting level (in our example, outer nesting level (in our example, outer = 1, inner = 2)= 1, inner = 2)
You can only see one stack frame at You can only see one stack frame at most at each static levelmost at each static level
The one you can see is the nearest The one you can see is the nearest one in the dynamic call chain.one in the dynamic call chain.
The one you can see always The one you can see always statically encloses you at some level.statically encloses you at some level.
More ObservationsMore Observations
A level N procedure can callA level N procedure can callAnother level N procedureAnother level N procedureA procedure at level 1 .. N-1A procedure at level 1 .. N-1
This is an uplevel callThis is an uplevel callA procedure at level N+1A procedure at level N+1
This is a downlevel callThis is a downlevel callYou cannot call a level N+2 procedureYou cannot call a level N+2 procedure
The Uplevel Addressing The Uplevel Addressing ProblemProblem
If you are an N level procedure, you If you are an N level procedure, you can reference your own variables at can reference your own variables at level Nlevel N
The variables of the immediately The variables of the immediately enclosing N-1 level procedureenclosing N-1 level procedure
The variables of the immediately The variables of the immediately enclosing N-2 level procedureenclosing N-2 level procedure
Etc.Etc.
How to Find Up Level How to Find Up Level VariablesVariables
For a level N procedureFor a level N procedureWe need the address of the level N We need the address of the level N
frameframeThat’s the local frame pointer, no problemThat’s the local frame pointer, no problem
The address of the nearest enclosing N-The address of the nearest enclosing N-1 level frame (statically enclosing us)1 level frame (statically enclosing us)
The address of the nearest enclosing N-The address of the nearest enclosing N-2 level frame (statically enclosing us)2 level frame (statically enclosing us)
One Solution, Static LinksOne Solution, Static Links
Pass an extra param on every callPass an extra param on every callCalled the static linkCalled the static linkIf you are calling a level N procedure, If you are calling a level N procedure,
this is the address of the nearest level this is the address of the nearest level N-1 procedure frameN-1 procedure frame
This static link is stored in the local This static link is stored in the local stack frame at a fixed offset that stack frame at a fixed offset that everyone knows.everyone knows.
How to Use The Static LinkHow to Use The Static Link
To address your own variables, use To address your own variables, use the frame pointer.the frame pointer.
To address at N-1, use the static linkTo address at N-1, use the static linkTo address at N-2, use the static link To address at N-2, use the static link
to locate the N-1 frame, and then to locate the N-1 frame, and then load its static link to locate the N-2 load its static link to locate the N-2 frameframe
Etc.Etc.
How to Set The Static LinkHow to Set The Static Link
Assume you are a level N procedureAssume you are a level N procedureTo call a level N+1 procedure, pass your To call a level N+1 procedure, pass your
frame pointerframe pointerTo call a level N procedure, pass a copy To call a level N procedure, pass a copy
of the static link that was given to you of the static link that was given to you siblings must share the same static siblings must share the same static parent)parent)
To call a level Q procedure (Q < N), find To call a level Q procedure (Q < N), find the address of the level Q-1 frame and the address of the level Q-1 frame and pass that (see previous slide).pass that (see previous slide).
More on Static LinksMore on Static Links
When calling a global procedure (level When calling a global procedure (level 1)1)No need to pass a static linkNo need to pass a static linkIn practice many calls are to global In practice many calls are to global
proceduresproceduresThe expression that fetches a level Q The expression that fetches a level Q
static link can be recognized as a CSEstatic link can be recognized as a CSEAnd for example, if many variables are And for example, if many variables are
referenced at level 3, the level 3 frame referenced at level 3, the level 3 frame pointer can end up in a local register.pointer can end up in a local register.
Another Solution: Global Another Solution: Global DisplayDisplay
Maintain a global tableMaintain a global tableLength of table = max static nesting Length of table = max static nesting
level of program (can set a reasonable level of program (can set a reasonable max/measure)max/measure)
Within a level N procedure, entries 1-N Within a level N procedure, entries 1-N are defined, Nth entry is copy of frame are defined, Nth entry is copy of frame pointer.pointer.
Entry Q is frame pointer for statically Entry Q is frame pointer for statically enclosing level Q procedure = most enclosing level Q procedure = most recently called level Q procedure recently called level Q procedure
Using the Global DisplayUsing the Global Display
To access local variables in level Q To access local variables in level Q procedure:procedure:Simply use the Q’th entry of the global Simply use the Q’th entry of the global
display as the frame pointerdisplay as the frame pointer
Maintaining The Global Maintaining The Global DisplayDisplay
Nothing needs to be done by callerNothing needs to be done by callerNo additional parameter passedNo additional parameter passedThe called level N procedure on entry:The called level N procedure on entry:
Establish frame pointer as usualEstablish frame pointer as usualSave N’th level entry of global displaySave N’th level entry of global displaySet N’th level entry to copy of frame ptrSet N’th level entry to copy of frame ptr
The called level N procedure on exitThe called level N procedure on exitRestore N’th level entry of global displayRestore N’th level entry of global display
Notes on Global DisplayNotes on Global Display
In a tasking program, you need a In a tasking program, you need a separate global display for each task separate global display for each task (not needed with static link method)(not needed with static link method)
Global display can be stored in registersGlobal display can be stored in registersBut that’s not a very good use of But that’s not a very good use of
registers, better solution is to simply let registers, better solution is to simply let frequently referenced entries from frequently referenced entries from display migrate into registers as display migrate into registers as needed.needed.
Optimizing Global DisplayOptimizing Global Display
If a procedure has no nested procedures, If a procedure has no nested procedures, then no one will ever need then no one will ever need itsits entry in the entry in the display, so don’t bother to set it. And of display, so don’t bother to set it. And of course that means no need to restore.course that means no need to restore.
The invariant then becomesThe invariant then becomes N’th entry of global display contains the frame N’th entry of global display contains the frame
pointer of the most recently called procedure pointer of the most recently called procedure that contains at least one nested procedure.that contains at least one nested procedure.
So overhead only for calling a procedure So overhead only for calling a procedure with at least one nested procedure.with at least one nested procedure.
Local DisplaysLocal Displays
Classical Algol methodClassical Algol methodWithin each stack frame keep a local Within each stack frame keep a local
display consisting of entries 1 to N of display consisting of entries 1 to N of a global display value.a global display value.
Using a Local DisplayUsing a Local Display
To access variables in the current To access variables in the current level N procedure, use frame pointer level N procedure, use frame pointer as usual, which is the same as level as usual, which is the same as level N of the local display.N of the local display.
To access variables in level Q (Q < N) To access variables in level Q (Q < N) procedure, access Qth entry of local procedure, access Qth entry of local display.display.
Maintaining Local DisplayMaintaining Local Display
When entering a level N procedure, you When entering a level N procedure, you are being called from a procedure at are being called from a procedure at level N-1 or higher (never from N-2).level N-1 or higher (never from N-2).
That means that the callers stack frame That means that the callers stack frame always has the N-1 entries you need for always has the N-1 entries you need for your local display, so copy them.your local display, so copy them.
Establish a frame pointer as usual, and Establish a frame pointer as usual, and store as the N’th entry of the local store as the N’th entry of the local display.display.
Procedure ParametersProcedure Parameters
Go back to our Inner/Outer exampleGo back to our Inner/Outer exampleSuppose that both inner and outer are Suppose that both inner and outer are
recursiverecursiveSuppose that both inner and outer Suppose that both inner and outer
pass procedure parameterspass procedure parametersA given procedure value is not just a A given procedure value is not just a
code address, but also the code address, but also the environment at the time that it is environment at the time that it is passed.passed.
More on Procedure ValuesMore on Procedure Values
Basically a procedure value is a Basically a procedure value is a pointer to the code of the procedure, pointer to the code of the procedure, as well as the status of the as well as the status of the invocation stack for any up level invocation stack for any up level references it might have.references it might have.
Form of procedure value depends on Form of procedure value depends on the way that up level referencing is the way that up level referencing is handled.handled.
Storing a Procedure ValueStoring a Procedure Value
For static links, we just need the address For static links, we just need the address of the procedure frame, since the static of the procedure frame, since the static links from that frame can recreate the links from that frame can recreate the necessary up level addressing necessary up level addressing information.information.
For local display, the procedure frame is For local display, the procedure frame is also sufficient, since the entire up level also sufficient, since the entire up level addressing information is stored in addressing information is stored in frame.frame.
For global display, need at least entries For global display, need at least entries 1..N-1 of the global display to be stored1..N-1 of the global display to be stored
Comparison of MethodsComparison of Methods
Local DisplayLocal DisplayNever used any moreNever used any moreClearly dominated by other methodsClearly dominated by other methodsToo bad no one told IntelToo bad no one told Intel
X86 implements local display in hardwareX86 implements local display in hardwareEnter x,4 means call a 4Enter x,4 means call a 4thth level procedure level procedure
and includes copying the local display from and includes copying the local display from the stack frame of the caller to the stack the stack frame of the caller to the stack frame of the called function.sframe of the called function.s
Static Links vs Global DisplayStatic Links vs Global Display
Static LinksStatic LinksNo overhead for calling global procedureNo overhead for calling global procedureEfficient representation of procedure Efficient representation of procedure
valuevalueGlobal DisplayGlobal Display
No overhead for calling procedure with No overhead for calling procedure with no nested proceduresno nested procedures
Awkward representation of procedure Awkward representation of procedure valuevalue
Static Links vs Global DisplayStatic Links vs Global Display
Global display probably more efficientGlobal display probably more efficientOnly large procedures have nested Only large procedures have nested
procedures insideprocedures insideAll leaf procedures have no nested All leaf procedures have no nested
proceduresproceduresBut mess with procedure parameters nastyBut mess with procedure parameters nasty
Ada is carefully designed so that no call Ada is carefully designed so that no call to a procedure parameter ever modifies to a procedure parameter ever modifies the display, so that displays need not be the display, so that displays need not be kept.kept.
ClosuresClosures
This entire model assumes that stack This entire model assumes that stack frames are created on entry, and frames are created on entry, and destroyed on exit from a procedure destroyed on exit from a procedure in a stack like manner (hence the in a stack like manner (hence the name)name)
This works for almost everything, but This works for almost everything, but there is one case which is a problemthere is one case which is a problem
Upward funarg problemUpward funarg problem
Suppose that a procedure outer has a Suppose that a procedure outer has a return type that is itself a procedurereturn type that is itself a procedure
Suppose this procedure outer has a Suppose this procedure outer has a nested procedure, innernested procedure, inner
Suppose that outer returns inner as Suppose that outer returns inner as the returned resultthe returned result
Suppose that inner references a Suppose that inner references a variable of outervariable of outer
An ExampleAn Example
MODE INTP = PROC (REAL) REAL;MODE INTP = PROC (REAL) REAL;PROC compose = (INTP a, b) INTP : PROC compose = (INTP a, b) INTP :
(REAL q) REAL : a (b (q));(REAL q) REAL : a (b (q));INTP sqrtsin = compose (sqrt, sin);INTP sqrtsin = compose (sqrt, sin);REAL result = sqrtsin (0.345);REAL result = sqrtsin (0.345);
The body of sqrtsin references local The body of sqrtsin references local parameters a, b from an enclosing parameters a, b from an enclosing procproc
By the time we call sqrtsin, these By the time we call sqrtsin, these parameters are long goneparameters are long gone
Closures in Algol-68Closures in Algol-68
Are not implemented in full Are not implemented in full generalitygenerality
In particular cannot have upward In particular cannot have upward funargsfunargs
Allows simple use of stack framesAllows simple use of stack frames
How to Implement ClosuresHow to Implement Closures
Allocate stack frames on heapAllocate stack frames on heapDon’t remove stack frames on Don’t remove stack frames on
leaving a procedureleaving a procedureThat way things stay around and are That way things stay around and are
available to reference when neededavailable to reference when neededNeed general garbage collection to Need general garbage collection to
clean up stack frames eventuallyclean up stack frames eventually