diff --git a/ARCH.md b/ARCH.md new file mode 100644 index 0000000..dcc7dae --- /dev/null +++ b/ARCH.md @@ -0,0 +1,69 @@ +# Tiny Compiler Architecture + +The Tiny compiler is an optimizing compiler for the Tiny language, designed with a modular architecture that transforms source code through several intermediate representations (IR) before generating machine code. + +## Architecture Overview + +The compiler pipeline consists of the following stages: + +1. **Tokenizer & Parser**: Converts raw source code into an Abstract Syntax Tree (AST). +2. **IR Generation**: Transforms the AST into a Single Static Assignment (SSA) based Intermediate Representation. +3. **Optimizations**: Performs passes such as Common Subexpression Elimination (CSE) and copy propagation on the SSA IR. +4. **Register Allocation**: Maps virtual registers to a limited set of physical registers, including support for register spilling. +5. **Code Generation**: Emits ARM64 assembly for Linux or macOS. + +## Graph Visualization + +The Tiny compiler includes a built-in feature to visualize the IR as a control-flow graph in the DOT format. This is useful for debugging and understanding the compiler's internal state. + +### CLI Usage + +The primary way to generate a graph is by using the `--graph` flag when running the compiler: + +```bash +cargo run -- run my_program.tiny --graph output.dot +``` + +You can also enable domination labels to visualize the dominance relationships between basic blocks: + +```bash +cargo run -- run my_program.tiny --graph output.dot --enable-dom-labels +``` + +### Programmatic Usage + +If you are extending the compiler or using its internal modules, you can generate the DOT graph string programmatically using the `Graph` struct. + +1. **Initialize the `Graph`**: + ```rust + use tiny::ir::visualization::graph::Graph; + + // Set print_dom_labels to true if you want domination labels + let mut graph = Graph::new(true, None); + ``` + +2. **Load the Program**: + ```rust + // Assuming you have a ProgramContext + graph.load_program(&program_context); + ``` + +3. **Build the DOT String**: + The `build()` method generates the complete DOT format string. + ```rust + let dot_output = graph.build(); + ``` + +4. **Write to File**: + ```rust + use std::fs::File; + use std::io::Write; + + let mut file = File::create("output.dot").expect("Unable to create file"); + file.write_all(dot_output.as_bytes()).expect("Unable to write data"); + ``` + +Once you have the `.dot` file, you can visualize it using tools like Graphviz: +```bash +dot -Tpng output.dot -o output.png +```