# perf2cfg

perf2cfg annotates a control-flow graph (CFG) file with profiling information
from simpleperf data files. A CFG file can be generated by the Android Runtime
compiler using the `--dump-cfg=<cfg-file>` option. The tool outputs an
annotated CFG file with the following added information:
- Methods are annotated with their contribution relative to the total profile.
- Basic blocks and assembly instructions are annotated with their contribution
  relative to the method profile.
- Basic blocks are colored according to their contribution to the method
  profile.

The tool does not modify any input files and assumes the input CFG file can be
parsed by c1visualizer. The input files must have all been generated for the
same architecture.

## Usage

```
usage: perf2cfg [-h|--help] --cfg CFG --perf-data PERF_DATA [PERF_DATA ...]
                [--output-file OUTPUT_FILE] [-e|--events EVENTS]
                [--primary-event PRIMARY_EVENT]

Annotates a CFG file with profiling information from simpleperf data files.

optional arguments:
  -h, --help            Show this help message and exit.
  --output-file OUTPUT_FILE
                        A path to the output CFG file.
  -e EVENTS, --events EVENTS
                        A comma-separated list of events only to use for
                        annotating a CFG (default: use all events found in
                        perf data). An error is reported if the events are not
                        present in perf data.
  --primary-event PRIMARY_EVENT
                        The event to be used for basic blocks hotness analysis
                        (default: cpu-cycles). Basic blocks are color
                        highlighted according to their hotness. An error is
                        reported if the primary event is not present in perf
                        data.

required arguments:
  --cfg CFG             The CFG file to annotate.
  --perf-data PERF_DATA [PERF_DATA ...]
                        The perf data files to extract information from.
```

### Examples

Annotate a CFG file:
```
perf2cfg --cfg art.cfg --perf-data perf.data
```

Annotate a CFG file with multiple simpleperf data files:
```
perf2cfg --cfg art.cfg \
    --perf-data perf_event1.data perf_event2.data perf_event3.data
```

Color basic blocks according to cache-misses events:
```
perf2cfg --cfg art.cfg --perf-data perf.data \
    --primary-event cache-misses
```

Display a subset of events from the simpleperf data file:
```
perf2cfg --cfg art.cfg --perf-data perf.data \
    --events cpu-cycles,cache-misses
```

## Method annotations

Once the annotated CFG file has been opened in c1visualizer, method annotations
can be seen by enabling the "Show Package Names" and "Sort List of
Compilations" options in the top-left "Compiled Methods" panel.

## Basic block coloring

perf2cfg implements basic block coloring by adding specific flags to the output
CFG file. These flags have the following names and meanings:
- `LO` (low): the basic block is responsible for 1 to 10% of its method primary
  event.
- `MO` (moderate): for 10 to 30%.
- `CO` (considerable): for 30 to 50%
- `HI` (high): for 50 to 100%.

To use this feature, custom flags have to be defined in c1visualizer:
1. Open c1visualizer.
2. Click on the "Tools" menu entry and "Options" to open the options window.
3. Click on the "Control Flow Graph" button if it isn't already selected.
4. On the right of the "Flags" list, click on the "New" button.
5. Enter "LO" in the text field and press "OK".
6. Select the newly created flag in the list and click on the color picker
   button.
7. Select an appropriate color and press "OK".
8. Repeat steps 4 to 7 for the remaining flags (MO, CO, and HI).

Alternatively, flags can be defined by editing a properties file located at:
`~/.c1visualizer/dev/config/Preferences/at/ssw/visualizer/cfg/options/CfgPreferences.properties`.
The directory hierarchy and the file itself might have to be created.

Replace the file contents with the following line to use a yellow to red
gradient:
```
flagsPreference=LO(255,210,0);MO(253,155,5);CO(253,100,5);HI(245,40,5)
```

For colorblind people, this green gradient can be used as an alternative:
```
flagsPreference=LO(235,235,50);MO(210,210,40);CO(185,185,25);HI(155,155,15)
```

## Hacking

A diagram of the finite state machine used to parse the input CFG file can be
generated with the following command (requires Graphviz):
```
dot -Tpng doc/FSM.dot -o doc/FSM.png
```
