Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions ARCH.md
Original file line number Diff line number Diff line change
@@ -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
```
Loading