Skip to content

WIP - MLIR Integration#3

Merged
ngmachado merged 8 commits intomainfrom
MLIR-fresh
Sep 1, 2025
Merged

WIP - MLIR Integration#3
ngmachado merged 8 commits intomainfrom
MLIR-fresh

Conversation

@ngmachado
Copy link
Contributor

@ngmachado ngmachado commented Aug 26, 2025

This pull request adds experimental support for MLIR (Multi-Level Intermediate Representation) to the build system and compiler frontend, enabling Ora source files to be lowered to MLIR IR. The changes include new build steps for MLIR, integration of MLIR libraries, a demo executable, and a prototype command for MLIR emission. Additionally, a simplified example contract is provided for testing.

MLIR Integration and Build System Enhancements:

  • Added functions buildMlirLibraries and linkMlirLibraries to build.zig to build MLIR from a vendored LLVM submodule and link it to executables, including platform-specific flags and Ninja build support for faster builds. [1] [2] [3]
  • Introduced a new MLIR demo executable (mlir_demo) and build step, which runs a sample pipeline from Ora source to MLIR IR.
  • Added Zig module and C bindings for MLIR C API in src/mlir/c.zig and context management in src/mlir/context.zig. [1] [2]

Compiler Frontend and CLI Improvements:

  • Implemented the mlir subcommand in src/main.zig to run the frontend pipeline and emit MLIR, with error handling and output to stdout. Updated usage documentation accordingly. [1] [2] [3]

Demo and Example Updates:

  • Added examples/demos/mlir_demo.zig as a demo for lowering Ora to MLIR, including lexing, parsing, and MLIR module emission.
  • Simplified the ora-example/smoke.ora contract for easier testing with the new MLIR pipeline.

@vercel
Copy link

vercel bot commented Aug 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
ora Ready Ready Preview Comment Sep 1, 2025 8:19pm

@ngmachado ngmachado self-assigned this Aug 26, 2025
@ngmachado ngmachado added the enhancement New feature or request label Aug 26, 2025
@ngmachado ngmachado requested a review from Copilot August 26, 2025 21:13
@ngmachado ngmachado linked an issue Aug 26, 2025 that may be closed by this pull request
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request introduces experimental MLIR (Multi-Level Intermediate Representation) support to the Ora compiler, enabling the lowering of Ora source code to MLIR IR through a modular architecture. The implementation includes comprehensive build system integration, a new CLI command for MLIR emission, and a well-structured codebase organized into specialized modules for different aspects of MLIR lowering.

Key changes include:

  • Added modular MLIR lowering system with separate files for types, expressions, statements, declarations, memory management, symbols, and locations
  • Integrated MLIR libraries into the build system with CMake-based compilation from a vendored LLVM submodule
  • Added mlir CLI subcommand and demo executable for testing MLIR functionality

Reviewed Changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/mlir/types.zig Comprehensive type mapping system for converting Ora types to MLIR types with support for all primitive and complex types
src/mlir/symbols.zig Symbol table and parameter mapping infrastructure for scope management and variable tracking
src/mlir/statements.zig Statement lowering system for converting Ora statements to MLIR operations including control flow
src/mlir/mod.zig Main module file that exports all MLIR components and provides convenient type aliases
src/mlir/memory.zig Memory region management for different Ora storage types (storage, memory, tstore, stack)
src/mlir/lower.zig Core lowering logic with extensive duplication that should be refactored to use the modular components
src/mlir/locations.zig Location tracking system for preserving source information in MLIR operations
src/mlir/expressions.zig Expression lowering system for arithmetic, comparison, logical, and bitwise operations
src/mlir/emit.zig MLIR module emission utilities for writing to files
src/mlir/dialect.zig Ora dialect operations and helper functions for MLIR operation creation
src/mlir/declarations.zig Declaration lowering for functions, contracts, structs, enums, and global variables
src/mlir/context.zig MLIR context management with dialect registration
src/mlir/c.zig C bindings for MLIR API access
src/main.zig Added mlir subcommand for experimental MLIR emission
ora-example/smoke.ora Simplified contract example for testing MLIR functionality
examples/demos/mlir_demo.zig Demo executable showing Ora to MLIR conversion pipeline
build.zig Added MLIR library building and linking with CMake integration and Ninja support

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@@ -0,0 +1,1540 @@
// TODO: This file contains duplicated code that should be moved to modular files
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains extensive code duplication with the modular MLIR files. The TODO comments indicate that ParamMap, LocalVarMap, StorageMap, and various lowering functions should be moved to their respective modules (symbols.zig, memory.zig, expressions.zig, statements.zig, declarations.zig). This creates maintenance burden and potential inconsistencies. Consider refactoring this file to use the modular components instead of duplicating the implementation.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +18
pub fn toMlirType(self: *const TypeMapper, ora_type: anytype) c.MlirType {
if (ora_type.ora_type) |ora_ty| {
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter ora_type uses anytype which makes the API unclear and error-prone. Consider using a specific type like lib.ast.type_info.OraType or creating a union type that encompasses all valid input types. This would provide better type safety and clearer API documentation.

Suggested change
pub fn toMlirType(self: *const TypeMapper, ora_type: anytype) c.MlirType {
if (ora_type.ora_type) |ora_ty| {
pub fn toMlirType(self: *const TypeMapper, ora_type: *const lib.ast.type_info.OraType) c.MlirType {
if (ora_type) |ora_ty| {

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +60
// Default to i256 for unknown types
return c.mlirIntegerTypeGet(self.ctx, 256);
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaulting to i256 for unknown types could mask type errors and lead to incorrect behavior. Consider returning an error or using a more explicit approach when the type cannot be determined, such as a Result type or explicit error handling.

Suggested change
// Default to i256 for unknown types
return c.mlirIntegerTypeGet(self.ctx, 256);
// Return error for unknown types instead of defaulting to i256
return Error.UnknownType;

Copilot uses AI. Check for mistakes.
},
else => {
// For other literal types, return a default value
const ty = c.mlirIntegerTypeGet(self.ctx, 256);
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The literal value 256 appears multiple times throughout the codebase for bit width. Consider defining a named constant like DEFAULT_INTEGER_BITS = 256 to improve maintainability and make the intent clearer.

Suggested change
const ty = c.mlirIntegerTypeGet(self.ctx, 256);
const ty = c.mlirIntegerTypeGet(self.ctx, DEFAULT_INTEGER_BITS);

Copilot uses AI. Check for mistakes.

/// Lower block body by processing all statements
pub fn lowerBlockBody(self: *const StatementLowerer, b: lib.ast.Statements.BlockNode, block: c.MlirBlock) void {
std.debug.print("DEBUG: Processing block with {d} statements\n", .{b.statements.len});
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statements should be removed or replaced with proper logging before production. These statements will clutter the output and may impact performance.

Suggested change
std.debug.print("DEBUG: Processing block with {d} statements\n", .{b.statements.len});
// Removed debug print: Processing block with {d} statements

Copilot uses AI. Check for mistakes.
.Stack => {
// For stack variables, we return the value directly from our local variable map
// This is handled differently in the identifier lowering
@panic("Stack variables should not use createLoadOperation");
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using @panic for invalid input handling is not ideal for API design. Consider returning an error type instead to allow callers to handle this case gracefully. This would make the API more robust and testable.

Suggested change
@panic("Stack variables should not use createLoadOperation");
return error.InvalidStorageType;

Copilot uses AI. Check for mistakes.
Comment on lines +770 to +772
// For now, panic on complex callee expressions
std.debug.print("DEBUG: Unhandled callee type: {s}\n", .{@tagName(call.callee.*)});
@panic("Complex callee expressions not yet supported");
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using @panic for unimplemented features can cause unexpected crashes. Consider returning an error or creating a placeholder implementation that logs the limitation and returns a reasonable default value.

Suggested change
// For now, panic on complex callee expressions
std.debug.print("DEBUG: Unhandled callee type: {s}\n", .{@tagName(call.callee.*)});
@panic("Complex callee expressions not yet supported");
// For now, log and return a default value for complex callee expressions
std.debug.print("DEBUG: Unhandled callee type: {s}\n", .{@tagName(call.callee.*)});
std.debug.print("WARNING: Complex callee expressions not yet supported. Returning default value.\n", .{});
return c.MlirValue{};

Copilot uses AI. Check for mistakes.
scope_idx -= 1;
}
// If symbol not found, add it to current scope
try self.addSymbol(name, c.mlirValueGetType(value), "stack", null);
Copy link

Copilot AI Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded string "stack" should be replaced with a proper enum value or constant to maintain consistency with the MemoryRegion enum used elsewhere in the codebase.

Suggested change
try self.addSymbol(name, c.mlirValueGetType(value), "stack", null);
try self.addSymbol(name, c.mlirValueGetType(value), lib.ast.Statements.MemoryRegion.Stack, null);

Copilot uses AI. Check for mistakes.
@ngmachado ngmachado merged commit 9471a58 into main Sep 1, 2025
7 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Move all Ora features to Lower IR

2 participants