Skip to content

seanptmaher/ir1-grapher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ir1-grapher

This library graphs SBCL ir1 and outputs graphviz.

This has been committed as a contrib module for SBCL, under contrib/sb-graph 🎉

As of now, it is stil unfinished. There are a few tweaks that are needed to improve useablility, in particular, I think the rendering could be done a lot better, with subgraphs, to make it a lot more readable. Also to make it more readable, I’m planning on implementing rainbow-parens-esque arrow + label color randomization.

How do I use it during compiler tracing?

To load the system, you can call (asdf:load-system :ir1-grapher) once you have either loaded ir1-grapher.asd manually, or placed the folder inside your ASDF load path.

Because of the way it hooks in the compiler, you shouldn’t actually have to do anything after loading it except turning on trace output of the compiler (SBCL), and adding :sb-graph to sb-c::*compile-trace-targets*. Turning on the tracing can be done by calling (compile-file "file" :trace-file t), and adding :sb-graph to sb-c::*compile-trace-targets* can be done however you want. After compilation is done, alongside the normal trace file, SBCL is hooked into writing a series of .dot files, which contain the graphviz DOT representation of all the components compiled. If you set *compile-progress* to T, it will print out progress information, and will tell you when and where it writes out the graphviz files.

How do I use the system interactively?

If you ran into a compiler error, and want to graph the still-in-memory code interactively, you can do so with the following functions:

(make-and-dfs object distance)

This function takes an ir1 object object, and integer distance, and returns a graph object with every node up to distance hops away from object in its dfs-table. Each object is tagged with a “codename”, visible as a hex digit in braces at the start of each graph node.

Then, to operate on the graph interactively, you can use:

(interactively-graph graph &optional filename)

This function takes a graph and a filename, and sets the current working graph to it, and the current output file to the filename. When calling output and expand, the graph will be written to filename.

(output)

This function outputs the current working graph to a string, and if interactively-graph was called with a filename, writes it to that file.

(expand codename)

After you’ve rendered the graph, if you want to add a node to the dfs-table (thus expanding the amount of the in-memory objects rendered), call this function with the codename of the new object you’d like to add. Example: (expand "A").

If you passed a filename to interactively-graph, this function will then write the render to file automatically.

(get-node codename)

Returns the object tied to codename from the current interactive graph.

And if you don’t want to use interactively-graph:

(render-graph graph)

Given a graph with objects in its dfs-table, returns a string of the rendering of the graph in DOT.

Does the same thing as output, but without using interactively-graph.

(expand-graph-codename graph codename)

Given a graph and codename, put the node tied to codename into the dfs-table of the graph.

Does the same thing as expand, but without using interactively-graph.

(get-node-from-codename graph codename)

Return the node tied to codename in graph.

Does the same thing as node, but without using interactively-graph.

What good is interactively-graph if I need to run dot every time the graph gets output?

That’s where render-on-change.sh comes in. Run render-on-change.sh with two arguments. First is the input DOT file, and second is the output SVG file. If you want to export to a different format, just modify the -Tsvg of the script.

Help! It’s saying there’s a package locking error.

Run (sb-ext:unlock-package :sb-c) in the REPL, or compile SBCL with --with-sb-devel (if you’re doing compiler work, you should probably do this anyways). In src/package.lisp, there’s a (sb-ext:unlock-package :sb-c) statement, but it seems to not work as expected.

But what if the compiler breaks your library, or I want to muck around with it?

hooking.lisp contains all the code that is used to hook the compiler directly, and graphing.lisp goes from the compiler data structures to the graphviz DOT format.

Right now, I’m assuming that the only place that the compiler will ever call sb-c::ir2-convert for each component is inside %compile-component, and only one time. If this becomes no longer true, then the hooking location/manner will have to be modified.

After the .dot files get output, how do I render them?

dot -T<output-format> input.dot > output. For example, dot -Tsvg trace-1-DEFUNFOO.dot > out.svg.

Can I see an example?

Yes, look at the example/ folder. It contains the dot output when running (compile-file "testfile" :trace-file t).

About

Graph SBCL IR1 and output graphviz DOT

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published