Skip to content

Compiler Pipeline

tazz edited this page Jun 4, 2026 · 3 revisions

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;
Loading

Kura's compiler uses multiple specialized intermediate representations (IRs), and the pipeline is split between multiple phases.

Why Multiple Intermediate Representations (IRs)?

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.

Compiler Stages

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

The Parsing Stage

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
Loading

The Kura compiler will first parse Kura source code into a Parse Tree (PT).

The Abstract Syntax Tree (AST)

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
Loading

Once the Kura compiler builds the parse tree, the compiler will then convert it into an Abstract Syntax Tree (AST)

The Analyzed 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
Loading

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

The Typed 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
Loading

The compiler will then resolve expression types, implicit coercions, generic instantiations and other semantic type information.

This becomes the Typed AST

Expression 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;

  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;
Loading

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.

UI 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;
Loading

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.

Render 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

  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;
Loading

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.

OpenGL IR

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;
Loading

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.

Vulkan 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
Loading

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.

DirectX 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
Loading

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.

Graphics Backend Extensions

Because the Render IR gets lowered into backend-specific IRs, this compilation architecture can be extended to support any number of graphics APIs.

Clone this wiki locally