lib/choir/src/compiler/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const choir = @import("../root.zig");
 3 const ir = choir.ir;
 4 const dialects = choir.dialects;
 5 const extensions = choir.extensions;
 6 
 7 pub const default_compiler_dialects = [_][]const u8{
 8     "builtin",
 9     "arith",
10     "memref",
11     "scf",
12     "func",
13 };
14 
15 pub const ContextOptions = struct {
16     context_limits: ir.Context.Limits,
17     packages: []const extensions.PackageExtension = &.{},
18     preload_dialects: []const []const u8 = &default_compiler_dialects,
19     preload_all_choir_dialects: bool = false,
20 };
21 
22 pub const Session = struct {
23     allocator: std.mem.Allocator,
24     ctx: ir.Context,
25     extension_registry: extensions.ExtensionRegistry,
26     live: bool = true,
27 
28     pub fn init(allocator: std.mem.Allocator, options: ContextOptions) !Session {
29         var ctx = try ir.Context.init(allocator, options.context_limits);
30         errdefer ctx.deinit(allocator);
31 
32         try registerCoreDialects(&ctx);
33 
34         var extension_registry = extensions.ExtensionRegistry.init(allocator);
35         errdefer extension_registry.deinit();
36         for (options.packages) |package| {
37             try extension_registry.registerPackage(&ctx, package);
38         }
39         try preloadRequestedDialects(&ctx, options);
40 
41         return .{
42             .allocator = allocator,
43             .ctx = ctx,
44             .extension_registry = extension_registry,
45         };
46     }
47 
48     pub fn deinit(self: *Session) void {
49         if (!self.live) return;
50         self.extension_registry.deinit();
51         self.ctx.deinit(self.allocator);
52         self.live = false;
53     }
54 
55     pub fn context(self: *Session) *ir.Context {
56         return &self.ctx;
57     }
58 
59     pub fn extensionRegistry(self: *Session) *extensions.ExtensionRegistry {
60         return &self.extension_registry;
61     }
62 };
63 
64 pub fn initContext(allocator: std.mem.Allocator, options: ContextOptions) !ir.Context {
65     var ctx = try ir.Context.init(allocator, options.context_limits);
66     errdefer ctx.deinit(allocator);
67 
68     try registerCoreDialects(&ctx);
69     for (options.packages) |package| {
70         try package.registerContext(&ctx);
71     }
72     try preloadRequestedDialects(&ctx, options);
73 
74     return ctx;
75 }
76 
77 fn registerCoreDialects(ctx: *ir.Context) !void {
78     try ctx.requireRegistered();
79     try dialects.registerChoirDialect(ctx);
80 }
81 
82 fn preloadRequestedDialects(ctx: *ir.Context, options: ContextOptions) !void {
83     if (options.preload_all_choir_dialects) {
84         inline for (dialects.choir_registry.entries) |entry| {
85             _ = try ctx.getOrLoadDialect(entry.name);
86         }
87     }
88 
89     for (options.preload_dialects) |name| {
90         _ = try ctx.getOrLoadDialect(name);
91     }
92 }