-
Notifications
You must be signed in to change notification settings - Fork 0
Compiler Pipeline
The Kura compiler lowers source code through multiple phases of parsing, semantic analysis, optimization and IR lowering.
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef llvm fill:#bbf7d0,stroke:#22c55e,stroke-width:2px,color:#000000;
classDef vulkan fill:#fecdd3,stroke:#e11d48,stroke-width:2px,color:#000000;
classDef opengl fill:#fed7aa,stroke:#ea580c,stroke-width:2px,color:#000000;
classDef dx fill:#bfdbfe,stroke:#2563eb,stroke-width:2px,color:#000000
%% Source Code
SOURCE_CODE["Source Code\n(kui)"]
PARSE_TREE[Parse Tree]
SOURCE_CODE --> PARSE_TREE
%% AST
AST["Abstract Syntax Tree\n(AST)"]
PARSE_TREE --> AST
ANALYZED_AST["Analyzed AST"]
AST --> ANALYZED_AST
TYPED_AST["Typed AST"]
ANALYZED_AST --> TYPED_AST
%% IRs
UI_IR["UI\n(IR)"]
RENDER_IR["Render\n(IR)"]
UI_IR ---> RENDER_IR
EXPRESSION_IR["Expression\n(IR)"]
TYPED_AST --> UI_IR
TYPED_AST --> EXPRESSION_IR
VULKAN[Vulkan]
VULKAN_IR["Vulkan\n(IR)"]
RENDER_IR --> VULKAN_IR
VULKAN_IR --> VULKAN
OPENGL[OpenGL]
OPENGL_IR["OpenGL\n(IR)"]
RENDER_IR --> OPENGL_IR
OPENGL_IR --> OPENGL
DX[DirectX]
DX_IR["DirectX\n(IR)"]
RENDER_IR --> DX_IR
DX_IR --> DX
LLVM_IR["LLVM\n(IR)"]
MACHINE_CODE[Machine Code]
EXPRESSION_IR --> LLVM_IR
LLVM_IR --> MACHINE_CODE
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
class RENDER_IR,EXPRESSION_IR,UI_IR compiler
class OPENGL,OPENGL_IR opengl;
class VULKAN,VULKAN_IR vulkan;
class DX,DX_IR dx;
class LLVM_IR,MACHINE_CODE llvm;
Kura's compiler uses multiple specialized intermediate representations (IRs), and the pipeline is split between multiple phases.
Kura uses multiple specialized intermediate representations (IRs) to separate different compiler responsibilities into dedicated stages.
This allows the compiler to independently optimize:
- executable logic
- reactive UI behavior
- rendering operations
- backend-specific rendering targets
Each IR focuses on a specific domain of the compilation pipeline, allowing the compiler to perform domain-specific analysis, optimization and lowering.
The Kura compiler is broadly separated into three major stages:
| Stage | Responsibilities |
|---|---|
| Frontend | Parsing, semantic analysis and type analysis |
| Middle-end | IR generation and optimization |
| Backend | LLVM lowering and rendering backend generation |
Kura performs optimization throughout these stages, and different optimizations get applied depending on the IR getting processed, including:
- AST simplification
- expression optimization
- reactive dependency optimization
- layout optimization
- render batching
- backend-specific lowering optimizations
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
SOURCE_CODE["Source Code\n(kui)"]
PARSE_TREE[Parse Tree]
SOURCE_CODE --> PARSE_TREE
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
The Kura compiler will first parse Kura source code into a Parse Tree (PT).
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
PARSE_TREE["Parse Tree\n(PT)"]
AST["Abstract Syntax Tree\n(AST)"]
PARSE_TREE --> AST
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
Once the Kura compiler builds the parse tree, the compiler will then convert it into an Abstract Syntax Tree (AST)
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
%% AST
AST["Abstract Syntax Tree\n(AST)"]
ANALYZED_AST["Analyzed AST"]
AST --> ANALYZED_AST
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
After the construction of the AST, the compiler will then analyze the AST and identify symbols, scope, references and bindings - among other things.
This becomes the Analyzed AST
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
ANALYZED_AST["Analyzed AST"]
TYPED_AST["Typed AST"]
ANALYZED_AST --> TYPED_AST
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
The compiler will then resolve expression types, implicit coercions, generic instantiations and other semantic type information.
This becomes the Typed AST
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef llvm fill:#bbf7d0,stroke:#22c55e,stroke-width:2px,color:#000000;
TYPED_AST["Typed AST"]
%% IRs
EXPRESSION_IR["Expression\n(IR)"]
TYPED_AST --> EXPRESSION_IR
LLVM_IR["LLVM\n(IR)"]
MACHINE_CODE[Machine Code]
EXPRESSION_IR --> LLVM_IR
LLVM_IR --> MACHINE_CODE
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
class RENDER_IR,EXPRESSION_IR,UI_IR compiler
class OPENGL,OPENGL_IR opengl;
class VULKAN,VULKAN_IR vulkan;
class DX,DX_IR dx;
class LLVM_IR,MACHINE_CODE llvm;
From the Typed AST, the compiler will generate an Expression IR.
The Expression IR is a high-level intermediate representation of executable Kura logic and expression evaluation.
The Expression IR represents:
- control flow
- function calls
- expression evaluation
- state mutation
- closures
- runtime operations
You can find more information about these instructions in Core IR.
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef llvm fill:#bbf7d0,stroke:#22c55e,stroke-width:2px,color:#000000;
classDef vulkan fill:#fecdd3,stroke:#e11d48,stroke-width:2px,color:#000000;
classDef opengl fill:#fed7aa,stroke:#ea580c,stroke-width:2px,color:#000000;
classDef dx fill:#bfdbfe,stroke:#2563eb,stroke-width:2px,color:#000000
TYPED_AST["Typed AST"]
UI_IR["UI\n(IR)"]
TYPED_AST --> UI_IR
class SOURCE_CODE,AST,PARSE_TREE,ANALYZED_AST,TYPED_AST parser
class RENDER_IR,EXPRESSION_IR,UI_IR compiler
class OPENGL,OPENGL_IR opengl;
class VULKAN,VULKAN_IR vulkan;
class DX,DX_IR dx;
class LLVM_IR,MACHINE_CODE llvm;
From the Typed AST, the compiler will generate a UI IR.
The UI IR is a high-level intermediate representation of the UI hierarchy, reactive state relationships and component structure.
The UI IR represents:
- UI hierarchy
- reactive dependencies
- component invalidation
- event propagation
- layout ownership
- state bindings
This enables the compiler to analyze reactive state relationships and generate efficient invalidation and update behavior.
graph LR
classDef parser fill:#fef08a,stroke:#eab308,stroke-width:2px,color:#000000;
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef llvm fill:#bbf7d0,stroke:#22c55e,stroke-width:2px,color:#000000;
classDef vulkan fill:#fecdd3,stroke:#e11d48,stroke-width:2px,color:#000000;
classDef opengl fill:#fed7aa,stroke:#ea580c,stroke-width:2px,color:#000000;
classDef dx fill:#bfdbfe,stroke:#2563eb,stroke-width:2px,color:#000000
RENDER_IR["Render\n(IR)"]
UI_IR["UI\n(IR)"]
UI_IR ---> RENDER_IR
VULKAN[Vulkan]
VULKAN_IR["Vulkan\n(IR)"]
RENDER_IR --> VULKAN_IR
VULKAN_IR --> VULKAN
OPENGL[OpenGL]
OPENGL_IR["OpenGL\n(IR)"]
RENDER_IR --> OPENGL_IR
OPENGL_IR --> OPENGL
DX[DirectX]
DX_IR["DirectX\n(IR)"]
RENDER_IR --> DX_IR
DX_IR --> DX
class RENDER_IR,UI_IR compiler
class OPENGL,OPENGL_IR opengl;
class VULKAN,VULKAN_IR vulkan;
class DX,DX_IR dx;
From the UI IR, the compiler will then generate a Render IR.
The Render IR is a lower-level rendering representation derived from the UI IR.
The Render IR is responsible for:
- layout computation
- draw operations
- compositing
- clipping
- batching
- invalidation handling
- GPU resource preparation
The Render IR abstracts rendering behavior away from the underlying graphics backend. This allows Kura to target multiple rendering APIs through dedicated backend IRs like:
See Render IR for more details.
graph LR
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef opengl fill:#fed7aa,stroke:#ea580c,stroke-width:2px,color:#000000;
RENDER_IR["Render\n(IR)"]
OPENGL[OpenGL]
OPENGL_IR["OpenGL\n(IR)"]
OPENGL_IR --> OPENGL
RENDER_IR --> OPENGL_IR
class RENDER_IR,UI_IR compiler
class OPENGL,OPENGL_IR opengl;
The OpenGL IR contains all the necessary instructions for rendering the UI using OpenGL.
You can find out more about OpenGL specific instructions in OpenGL IR.
graph LR
classDef vulkan fill:#fecdd3,stroke:#e11d48,stroke-width:2px,color:#000000;
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
RENDER_IR["Render\n(IR)"]
VULKAN[Vulkan]
VULKAN_IR["Vulkan\n(IR)"]
RENDER_IR --> VULKAN_IR
VULKAN_IR --> VULKAN
class VULKAN,VULKAN_IR vulkan;
class RENDER_IR,UI_IR compiler
The Vulkan IR contains all the necessary instructions for rendering the UI using Vulkan.
You can find out more about Vulkan specific instructions in Vulkan IR.
graph LR
classDef compiler fill:#fde047,stroke:#ca8a04,stroke-width:2px,color:#000000;
classDef dx fill:#bfdbfe,stroke:#2563eb,stroke-width:2px,color:#000000
RENDER_IR["Render\n(IR)"]
DX[DirectX]
DX_IR["DirectX\n(IR)"]
DX_IR --> DX
RENDER_IR --> DX_IR
class DX,DX_IR dx;
class RENDER_IR,UI_IR compiler
The DirectX IR contains all the necessary instructions for rendering the UI using DirectX.
You can find out more about DirectX specific instructions in DirectX IR.
Because the Render IR gets lowered into backend-specific IRs, this compilation architecture can be extended to support any number of graphics APIs.