\section{Machine code finalization}
\label{sec:CodeFin}

Code finalization is the phase of a back end that allocates space in a
procedure-activation record (usually a stack frame) and introduces certain
prologue and epilogue code that is best deferred till the very end of
compilation.  The Machine-SUIF [[fin]] pass is responsible for this final
translation work.  It typically takes care of adding code to save and
restore callee-saved registers, for example.  Earlier translation and
optimization passes use symbolic references to stack-frame locations and
leave it to the [[fin]] pass to replace these with effective-address
operands based on a stack- or frame-pointer.

This section introduces two classes used by the [[fin]] pass.  Class
[[CodeFin]] is the framework on which we hang the target-dependent aspects
of code finalization.  Its virtual methods are hooks that allow
machine-specific subclasses to customize the finalization phase.  Class
[[StackFrameInfoNote]] is a custom annotation class that provides a way for
earlier passes affecting the code at a procedure's entry and exits to
record their effects so that the [[fin]] pass knows what to do.  The key
for notes of class [[StackFrameInfoNote]] is [[k_stack_frame_info]].


\subsection{Class [[CodeFin]]}

We present two views of the [[CodeFin]] class.  Readers interested in the
OPI's code finalization facilities for an existing target should read only
the first three subsections.  The remaining subsections contain information
relevant to readers interested in defining a [[CodeFin]] subclass for a new
target.


\subsubsection{OPI for code finalization}

The following class defines a [[CodeFin]] object.

<<class [[CodeFin]]>>=
class CodeFin {
  public:
    virtual ~CodeFin() { }

    virtual void init(OptUnit *unit);
    virtual void analyze_opnd(Opnd) = 0;
    virtual void layout_frame() = 0;
    virtual Opnd replace_opnd(Opnd) = 0;

    virtual void make_header_trailer() = 0;

    List<Instr*>& header()  { return _header; }
    List<Instr*>& trailer() { return _trailer; }

<<[[CodeFin]] protected parts>>
};
@

A rundown of the methods declared above:

\begin{itemize}
\item [[init]] is called when treatement of a procedure begins.  It
initializes per-procedure variables.
\item [[analyze_opnd]] is called on each operand in a pre-scan of the
IR.  It can be used to detect which callee-saved registers are in use,
and to catalog local variables that need to be allocated in the
activation record.
\item [[layout_frame]] is the hook that performs dialect-specific layout
of the activation record.
\item [[replace_opnd]] is used in rewriting instructions to replace
variable occurrences by effective addresses in the frame.  Its argument
is such a variable operand, and its result is the replacement operand.
\item [[make_header_trailer]] is called to perform dialect-specific
creation of prologue and epilogue code sequences.  Methods [[header]]
and [[trailer]] can then retrieve the respective code sequences.
\end{itemize}


\subsubsection{Generating a target-specific [[CodeFin]] object}

To access the [[CodeFin]] object in the prevailing context, call this
function:

<<function [[target_code_fin]]>>=
CodeFin *target_code_fin();
@


\subsubsection{Class [[StackFrameInfoNote]]}

We attach a [[k_stack_frame_info]] note to the body of each [[OptUnit]].
This note has a custom class:

<<class [[StackFrameInfoNote]]>>=
class StackFrameInfoNote : public Note {
 public:
    StackFrameInfoNote() : Note(note_list_any()) { }
    StackFrameInfoNote(const StackFrameInfoNote &other)
	: Note(other) { }
    StackFrameInfoNote(const Note& note) : Note(note) { }

    bool get_is_leaf() const;
    void set_is_leaf(bool is_leaf);

    bool get_is_varargs() const;
    void set_is_varargs(bool is_varargs);

    int get_frame_size() const;
    void set_frame_size(int frame_size);

    int get_frame_offset() const;
    void set_frame_offset(int frame_offset);

    int get_max_arg_area() const;
    void set_max_arg_area(int max_arg_area);
};
@

Conceptually, a [[StackFrameInfoNote]] instance has the following fields:

\begin{itemize}
\item [[is_leaf]] is [[true]] if this procedure does not contain any call
      instructions. 
\item [[is_varargs]] is [[true]] if this procedure is a is declared with a
      variable number of arguments (either through [[varargs.h]] or
      [[stdarg.h]]).
\item [[framesize]] records the total size of the stack frame in
      bytes, if known; [[0]] otherwise.
\item [[frameoffset]] records the frame offset, also in bytes.  It's
      interpretation is architecture dependent.
\item [[max_arg_area]] records the maximum size of the call argument area
      in bytes for procedures that are not leaves.
\end{itemize}

The [[framesize]] and [[frameoffset]] cannot actually be known before the
finalization pass, so it may seem pointless to record them in an annotation
if the [[fin]] pass is the last to run.  Once in a while, it is useful to
reoptimize after finalization has taken place.  In that case, a second pass
of finalization is needed, and these fields of the [[StackFrameInfoNote]]
help [[fin]] restart where it left off.


\subsubsection{Specializing [[CodeFin]] for a target}

As explained above, the [[CodeFin]] class does not provide a public
constructor.  This is because the base class does not actually define a
[[CodeFin]] object for any specific target.  You develop a [[CodeFin]]
object for a specific target (or class of targets) by creating a derived
class of [[CodeFin]].  The [[CodeFinAlpha]] class found in the [[alpha]]
library is an example of such a derived class.

The non-public parts of [[CodeFin]] contain only instance fields for use by
the public methods.  There are variables to hold values from the
[[StackFrameInfoNote]] during the [[fin]] pass.  There is a map giving the
frame location for each local symbol.  There is a set per register bank
that is used for collecting the registers that need to be saved, if any,
and there are the lists that will carry prologue and epilogue code during
finalization.

<<[[CodeFin]] protected parts>>=
  protected:
    // Properties of current procedure, initialized by init()
    //
    OptUnit *cur_unit;

    bool is_leaf;
    bool is_varargs;
    int max_arg_area;

    Map<Sym*,int> frame_map;			// variables -> frame offsets

  private:
    List<Instr*> _header;			// header instructions, reversed
    List<Instr*> _trailer;			// trailer instructions
@


\subsection{Header file for module [[code_fin.h]]}

The interface file has the following layout:

<<code\_fin.h>>=
/* file "machine/code_fin.h" */

<<Machine-SUIF copyright>>

#ifndef MACHINE_CODE_FIN_H
#define MACHINE_CODE_FIN_H

#include <machine/copyright.h>

#ifndef SUPPRESS_PRAGMA_INTERFACE
#pragma interface "machine/code_fin.h"
#endif

#include <machine/substrate.h>
#include <machine/machine_ir.h>
#include <machine/note.h>

<<class [[StackFrameInfoNote]]>>

<<class [[CodeFin]]>>

<<function [[target_code_fin]]>>

#endif /* MACHINE_CODE_FIN_H */
@
