vcpr - code compressor for vbcc (c) in 2020 by Volker Barthelmann


@section Introduction

    vcpr is a code compressor which scans the assembly output of
    vbcc and tries to reduce code size of the generated code by
    moving common code sequences into separate subroutines. As a
    trade-off, the code will usually run slower.

    Like the compiler vbcc it is split into a target independent and a
    target dependent part. However there may be code-generators for vbcc
    which do not have a corresponding compressor.

    This document only deals with the target independent parts of vcpr.
    Be sure to read all the documents for your machine.


@section Usage

    Usually @command{vcpr} will be called by a frontend. However if you call it
    directly, it has to be done like this:

@example
    vcpr [options] input-file output-file
@end example

    The following options are supported:

@table @option
    @item -quiet
                      Do not print the copyright notice.

    @item -debug=<n>
                  Set debug-level to <n>.
@end table


    Note that depending on the target @command{vbcc} may insert hints into the
    generated code. Assembly code that was not generated by @command{vbcc}
    may not work correctly after running it through @command{vcpr}.


@section Known problems

@itemize @minus
    @item still in early development
@end itemize

@section Backend Interface

@subsection Building @code{vcpr}

To write a backend for @code{vcpr}, the file @code{compress.c} has to be created
in the machine subdirectory. The executable @code{vcpr<target>} can be built
using:

@example
    make TARGET=<target> bin/vcpr<target>
@end example

@subsection Basic Function

@code{vcpr} first reads the assembly source into a linked list of lines. It will
call a backend function for each line to parse the line and fill in necessary
information.

The frontend looks for identical code sequences and calculates the
savings that can be obtained by outlining the code. If code sequences are found
that provide enough savings, they will be moved to subroutines using functions
provided by the backend.

Lines have to be textually identical to be considered for outlining. One exception
are labels. The following sequences are considered equal as long as the labels
are not used anywhere else:

@example

  a
  bne l1
  b
l1:
  c

  a
  bne l2
  b
l2:
  c
@end example

Currently, @code{vcpr} only supports code sequences with one label.

@subsection Data Types

The main data type relevant for the backend represents the attributed source lines:

@example
typedef struct line @{
  ...
  char *code;
  int flags;
  int size;
  ...
  int l1,l2;
@} line;
@end example

The following members are relevant to the backend:

@code{code} points to the assembly text of the line.

@code{size} contains the (estimated) size of the instruction.

@code{l1, l2} specify up to two labels referenced by this instruction.

@code{flags} specifies the type of instruction and can be a combination of:

@itemize
@item @code{LABDEF}: This line defines a label.
@item @code{LABUSE}: This line references a label.
@item @code{BARRIER}: This line must not be moved into a subroutine.
@item @code{LBARRIER}: Used by the frontend.
@end itemize

@subsection Backend Variables

The following variables have to be defined and initialized by the backend:

@itemize

@item @code{const char tg_copyright[]}
A copyright string.

@item @code{int minsave;}
The minimum size units saved by outlining a function. Should at least be larger
than the size of the code for a subroutine call.

@end itemize

@subsection Backend Functions

The following functions have to be provided by the backend:

@itemize

@item @code{void parse_line(char *s,line *p);}

This function parses assembly line @code{s} and has to fill the
members @code{flags}, @code{l1}, @code{l2} and @code{size} of the line structure
@code{p}.

@item @code{add_header(line *after);}

This function creates a line for the header of outlined code and inserts it into the
line list.

@item @code{add_ret(line *after);}

This function adds a return line and inserts it into the line list.

@item @code{add_jsr(line *after);}

This function adds a subroutine call to the subroutine corresponding to the last
call of @code{add_header()}.

@end itemize

@subsection Frontend Functions 

The following functions are provided by the frontend and can be used by the
backend:

@itemize

@item @code{void *mymalloc(size_t sz);}

Allocate memory.

@item @code{int new_label(void);}

Create a new unused label number.

@item @code{line *new_line(void);}

Create a new line.

@item @code{void insert_line(line *after, line *new);}

Insert a line into the line list at a specified position.

@end itemize
