
# NLR

This program reads a trace and tries to build loop nests that
reproduce the input data. Details of the algorithm can be found in
"Prediction and Trace Compression of Data Access Addresses through
Nested Loop Recognition", by Alain Ketterlin and Philippe Clauss, at
CGO'2008.


# Authors and License

Please direct all questions and remarks to:

- Alain Ketterlin (<alain@unistra.fr>)
- Philippe Clauss (<clauss@icps.u-strasbg.fr>)

Licensing information can be found in the [LICENSE](./LICENSE) file
that comes with the source distribution.

Feel free to contact any of the authors if you have any question or
need some specific feature. Also, if you do any serious thing with
this code, please let us know by sending a short description of what
you did.


# Download

The latest version of NLR is available from
<https://icps.u-strasbg.fr/nlr/> (current version is
[nlr-0.7.tar.gz](./nlr-0.7.tar.gz)).


# Build from source

To build the executable (named `nlr`), just type `make`. There should
be no warning, no error. You need a C99 compliant compiler. I've tried
this on various Linux distributions, with no problem. If you have
trouble compiling `nlr`, or get warnings or errors, please send me
(Alain) the compiler's output (and problematic lines of code if you
changed the source). The code is probably Unix-specific, you're on
your own if you try to compile this on another system.


# Documentation

The details of the algorithm can be found in the CGO paper mentioned
earlier. The tool has a (slightly outdated) man-page, visible with:

```
    man ./nlr.1
```

Invoking "`./nlr -h`" also gives a summary of command line options.


# Basic usage

NLR tries to find loops producing the given trace. For instance, given
input:

```
    1
    2
    3
    4
```

NLR will produce the following loop:

```
    for i0 = 0 to 3
      val 0x1 + 1*i0
```

The algorithm has a parameter indicating the maximal length of a loop
body (in terms of loops and values). The "`-k`" option assigns a value
different from the default 1. For instance, with input:

```
    a 1
    b 2
    a 3
    b 4
    a 5
    b 6
```

a call to "`./nlr -k 2`" (or any larger value) will produce:

```
    for i0 = 0 to 2
      val a , 0x1 + 2*i0
      val b , 0x2 + 2*i0
```

whereas "`./nlr -k 1`" (or "`./nlr`" with no option) will output (a
stylized version of) the input trace.

It is customary to use a relatively large value for first experiments
("`-k 100`" or so), but higher values have a strong effect on run-time
with inputs displaying no or little linear regularity.

Since it was initially used to process traces of memory addresses, NLR
prints affine functions with an hexadecimal constant and decimal
factors of loop indices. Using "`-a none`" prints every number in
decimal ("`-a all`" prints all numbers in hexadecimal).

Another useful option is "`-g`" whose argument is a bitset: value 1
requests a progress counter to be printed, value 2 prints timing and
volume information at the end of the run.

# Caveats

NLR is not really set up to be used as a library. If you have such a
requirement, please contact the authors for help. (Or start with the
`nlr.c` file's `main` function, which is a thin wrapper around the
algorithm itself.)

If you do this, be advised that the code uses global data at several
places (for efficiency purposes), which probably makes it hard to use
as-is in a multithreaded setting.

Also, the software is currently full of dead-code, hacks etc. For any
usage other than running it on some traces and look at the output
please contact me, as I have various other versions that may help you
more than this one.
