Intermediate Representation
The AodhML IR is a lower-level, type-annotated representation used for optimization and code generation.
IR Design
The IR is based on Static Single Assignment (SSA) form with basic blocks:
// Example AodhML source:
fn add(a: i32, b: i32) -> i32 {
let c = a + b
return c
}
// Lowered IR:
func @add(%a: i32, %b: i32) -> i32 {
entry:
%c = add.i32 %a, %b
ret.i32 %c
}
IR Instructions
| Instruction | Description |
|---|---|
const.<type> <value> | Load constant |
add.<type> %a, %b | Arithmetic addition |
sub.<type> %a, %b | Arithmetic subtraction |
mul.<type> %a, %b | Arithmetic multiplication |
div.<type> %a, %b | Arithmetic division |
load <ptr> | Load from memory |
store <ptr>, <value> | Store to memory |
alloca <type> | Stack allocation |
call <func>(<args>) | Function call |
br <label> | Unconditional branch |
br.cond <cond>, <true>, <false> | Conditional branch |
ret.<type> <value> | Return value |
ret.void | Void return |
Tensor IR
Tensor operations have specialized IR instructions:
// Tensor creation
%t = tensor.zeros [3, 4] : f32
%r = tensor.randn [64, 128] : f32
// Tensor operations
%c = tensor.add %a, %b
%d = tensor.matmul %a, %b
%e = tensor.reshape %a, [12]
// Tensor metadata
%s = tensor.shape %t // Returns [3, 4]
%n = tensor.numel %t // Returns 12
Optimization Passes
The IR optimizer runs several passes:
- Constant folding: Evaluate constant expressions at compile time
- Dead code elimination: Remove unreachable code
- Common subexpression elimination: Avoid redundant computations
- Inlining: Inline small functions
- Tensor fusion: Fuse consecutive tensor operations