Some ideas for helper scripts for analyzing mir dumps.
The dump files generated by llc -print-after-all tend to be rather large and this results in a number of problems. When comparing two runs simply launching your favorite diff tool on two files in the range of ~100k lines is not ideal. Diffing one pass and a subsequent one requires copy&paste to put the fragments in different files. When searching for e.g. registers it is easy to accidentally get a match outside the current pass of interest.
A more sophisticated approach would be to develop a simple python library that creates an in-memory representation of the dump file. E.g. the dump file is represented by a DumpFile object and then you have Fragment objects that reference an interval of lines of this DumpFile. The Fragment class can then be specialized into Pass, Function and BasicBlock. Defining some operations (like compare, view and diff) on the fragments allows for a rather flexible framework that can be used to build custom tools to ease the task of dump analysis by eliminating cumbersome and error prone manual steps.
Example usage
int dot(int *a, int *b, int n) { int sum = 0; for (int i = 0; i < n; i++) sum += a[i] * b[i]; return sum; } $ clang --target=riscv32 dot.c -O4 -S -mllvm -print-after-all 2> dump.txt # Get an overview of where changes occurred $ utils/dumptool --primary=dump.txt --list-pruned * 0 riscv-isel *dot [ *bb.0 *bb.1 *bb.2 *bb.3 ] * 4 slotindexes *dot [ *bb.0 *bb.1 *bb.2 *bb.3 ] * 5 stack-coloring *dot [ *bb.0 *bb.1 *bb.2 *bb.3 ] * 10 machine-sink *dot [ *bb.0 *bb.4 bb.1 *bb.2 bb.3 ] * 21 unreachable-mbb-elimination *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 22 livevars *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 23 phi-node-elimination *dot [ bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 24 twoaddressinstruction *dot [ bb.0 bb.1 bb.2 bb.3 bb.4 ] * 25 slotindexes *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 26 liveintervals *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 27 register-coalescer *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 30 livedebugvars *dot [ bb.0 bb.1 bb.2 bb.3 bb.4 ] * 35 virtregrewriter *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 38 machine-cp *dot [ *bb.0 *bb.1 *bb.2 *bb.3 *bb.4 ] * 44 shrink-wrap *dot [ bb.0 bb.1 bb.2 *bb.3 *bb.4 *bb.5 ] * 47 branch-folder *dot [ *bb.0 *bb.1 *bb.2 ] * 50 postrapseudos *dot [ *bb.0 bb.1 *bb.2 ] * 64 machine-sanmd dot [ bb.0 bb.1 bb.2 ] * 65 stack-frame-layout dot [ bb.0 bb.1 bb.2 ] * 70 unpack-mi-bundles dot [ bb.0 bb.1 bb.2 ] # Examine bb.4 of function dot after machine-sink $ utils/dumptool --primary=dump.txt --primary-frag=10/dot/bb.4 --view # Diff function dot before and after machine sink $ utils/dumptool --primary=dump.txt --secondary=dump.txt --primary-frag=9/dot --secondary-frag=10/dot --diff