mem: Steps 5-7 — context-identifier rebind + interp ctx bootstrap
Step 5 — `context` resolves through `current_ctx_ref`. The compile-time
emit of the default GPA into the `context` global is gone; entry points
already bind `current_ctx_ref` to `&__sx_default_context` and every
sx-to-sx call forwards it. `allocViaContext` sources from
`current_ctx_ref` too. `matchContextAllocCall` is kept as a comptime
escape hatch: the ct_module spun up by `evalComptimeString` doesn't get
the full Allocator/CAllocator/Context type registration so the protocol-
dispatch chain wouldn't run in the interp; codegen also wins from the
direct libc malloc/free.
Step 6 — `push Context.{...}` stack-discipline rewrite. Allocates a
fresh `Context` slot, binds `current_ctx_ref` to it for the body's
lexical scope, restores on exit. No global, no walk.
Step 7 — interp parity. `defaultContextValue()` builds the Context
aggregate (CAllocator thunks for alloc/dealloc, null data) on demand.
`interp.call` bootstraps slot_ptr(0) when an entry function with
implicit ctx is called sans args; `materializeCtxArg` dereferences the
caller's slot_ptr into the aggregate at every sx-to-sx call boundary so
the callee's `load(ref_0)` lands on the value; `load` of an aggregate
is a passthrough. `.global_addr` of `__sx_default_context` returns the
aggregate directly so exported entries' first-line `global_addr(...)`
runs cleanly in `#run`.
`ct_lowering` inherits `implicit_ctx_enabled` + `has_implicit_ctx` so
functions lowered into the ct module carry ctx like their main-module
twins.
152/152 example tests pass. Snapshots regen.
This commit is contained in:
@@ -164,6 +164,37 @@ pub const Interpreter = struct {
|
||||
self.hooks.deinit();
|
||||
}
|
||||
|
||||
// ── Implicit Context ──────────────────────────────────────────
|
||||
|
||||
/// Build the default Context aggregate for top-level interp calls.
|
||||
/// Mirrors the static `__sx_default_context` LLVM global: a Context
|
||||
/// whose `allocator` field is the stateless CAllocator inline-protocol
|
||||
/// value (alloc/dealloc thunks bottom out at libc malloc/free).
|
||||
fn defaultContextValue(self: *Interpreter) Value {
|
||||
const tbl_ptr: *const @import("types.zig").TypeTable = &self.module.types;
|
||||
const tbl = @constCast(tbl_ptr);
|
||||
const alloc_thunk_name = tbl.internString("__thunk_CAllocator_Allocator_alloc");
|
||||
const dealloc_thunk_name = tbl.internString("__thunk_CAllocator_Allocator_dealloc");
|
||||
|
||||
var alloc_fn: Value = .null_val;
|
||||
var dealloc_fn: Value = .null_val;
|
||||
for (self.module.functions.items, 0..) |func, i| {
|
||||
if (func.name == alloc_thunk_name) alloc_fn = .{ .func_ref = FuncId.fromIndex(@intCast(i)) };
|
||||
if (func.name == dealloc_thunk_name) dealloc_fn = .{ .func_ref = FuncId.fromIndex(@intCast(i)) };
|
||||
}
|
||||
|
||||
const allocator_fields = self.alloc.alloc(Value, 3) catch unreachable;
|
||||
allocator_fields[0] = .null_val; // CAllocator receiver — stateless
|
||||
allocator_fields[1] = alloc_fn;
|
||||
allocator_fields[2] = dealloc_fn;
|
||||
const allocator_val: Value = .{ .aggregate = allocator_fields };
|
||||
|
||||
const ctx_fields = self.alloc.alloc(Value, 2) catch unreachable;
|
||||
ctx_fields[0] = allocator_val;
|
||||
ctx_fields[1] = .null_val;
|
||||
return .{ .aggregate = ctx_fields };
|
||||
}
|
||||
|
||||
// ── Heap operations ────────────────────────────────────────────
|
||||
|
||||
fn heapAlloc(self: *Interpreter, size: usize) Value.HeapPtr {
|
||||
@@ -367,9 +398,23 @@ pub const Interpreter = struct {
|
||||
var frame = Frame.initSized(self.alloc, total_refs);
|
||||
defer frame.deinit();
|
||||
|
||||
// Bind parameters as initial refs (indices 0..N-1)
|
||||
// Implicit-context bootstrap: when an entry point with implicit
|
||||
// ctx is called without an explicit ctx arg, materialise the
|
||||
// default context in a fresh slot and bind slot_ptr(0) to ref 0.
|
||||
// This is the interp-side equivalent of FFI-inbound wrappers
|
||||
// installing `&__sx_default_context` at function entry.
|
||||
var skip_first: u32 = 0;
|
||||
if (func.has_implicit_ctx and args.len + 1 == func.params.len) {
|
||||
const ctx_val = self.defaultContextValue();
|
||||
const slot = frame.allocSlot(self.alloc);
|
||||
frame.storeSlot(slot, ctx_val);
|
||||
frame.setRef(0, .{ .slot_ptr = slot });
|
||||
skip_first = 1;
|
||||
}
|
||||
|
||||
// Bind parameters as initial refs (indices skip_first..N-1)
|
||||
for (args, 0..) |arg, i| {
|
||||
frame.setRef(@intCast(i), arg);
|
||||
frame.setRef(@intCast(i + skip_first), arg);
|
||||
}
|
||||
|
||||
// Start at the entry block (index 0)
|
||||
@@ -536,6 +581,10 @@ pub const Interpreter = struct {
|
||||
}
|
||||
return .{ .value = slot_val };
|
||||
},
|
||||
// The implicit __sx_ctx arrives as an aggregate after
|
||||
// materializeCtxArg dereferences the caller's slot_ptr.
|
||||
// `load(ref_0)` then naturally yields the Context value.
|
||||
.aggregate => return .{ .value = ptr },
|
||||
else => return error.CannotEvalComptime,
|
||||
}
|
||||
},
|
||||
@@ -667,6 +716,14 @@ pub const Interpreter = struct {
|
||||
// its own slot table and read garbage.
|
||||
args[i] = self.materializeForCall(frame, frame.getRef(ref));
|
||||
}
|
||||
// The implicit __sx_ctx is logically a `*Context` but the
|
||||
// interp can't dereference cross-frame slot_ptrs. Materialise
|
||||
// args[0] to the loaded Context aggregate so the callee can
|
||||
// treat its slot 0 as the value directly.
|
||||
const callee_func = self.module.getFunction(c.callee);
|
||||
if (callee_func.has_implicit_ctx and args.len >= 1) {
|
||||
args[0] = self.materializeCtxArg(frame, args[0]);
|
||||
}
|
||||
const result = try self.call(c.callee, args);
|
||||
return .{ .value = result };
|
||||
},
|
||||
@@ -1020,8 +1077,18 @@ pub const Interpreter = struct {
|
||||
const val = try self.getGlobal(gid);
|
||||
return .{ .value = val };
|
||||
},
|
||||
.global_addr => {
|
||||
// Address-of-global not meaningful in interpreter
|
||||
.global_addr => |gid| {
|
||||
// The implicit-context default global is the only global
|
||||
// whose address sees runtime use. Return the Context
|
||||
// aggregate directly so `load(args[0])` yields it via the
|
||||
// aggregate-passthrough branch of the `.load` handler.
|
||||
if (gid.index() < self.module.globals.items.len) {
|
||||
const global = &self.module.globals.items[gid.index()];
|
||||
const name = self.module.types.getString(global.name);
|
||||
if (std.mem.eql(u8, name, "__sx_default_context")) {
|
||||
return .{ .value = self.defaultContextValue() };
|
||||
}
|
||||
}
|
||||
return error.CannotEvalComptime;
|
||||
},
|
||||
.func_ref => |fid| {
|
||||
@@ -1114,7 +1181,11 @@ pub const Interpreter = struct {
|
||||
const args = self.alloc.alloc(Value, ci.args.len) catch return error.CannotEvalComptime;
|
||||
defer self.alloc.free(args);
|
||||
for (ci.args, 0..) |ref, i| {
|
||||
args[i] = frame.getRef(ref);
|
||||
args[i] = self.materializeForCall(frame, frame.getRef(ref));
|
||||
}
|
||||
const target = self.module.getFunction(fid);
|
||||
if (target.has_implicit_ctx and args.len >= 1) {
|
||||
args[0] = self.materializeCtxArg(frame, args[0]);
|
||||
}
|
||||
const result = try self.call(fid, args);
|
||||
return .{ .value = result };
|
||||
@@ -1232,6 +1303,17 @@ pub const Interpreter = struct {
|
||||
/// emitted by `struct_gep` / `index_gep`) into the resolved parent value.
|
||||
/// Slot indices are frame-local; a slice passed across a call would otherwise
|
||||
/// read its data_ptr out of the callee's slot table.
|
||||
/// Resolve the implicit __sx_ctx arg to its loaded Context value so
|
||||
/// callees can treat their own slot 0 as the aggregate directly
|
||||
/// (no cross-frame slot_ptr indirection).
|
||||
fn materializeCtxArg(self: *Interpreter, frame: *Frame, val: Value) Value {
|
||||
_ = self;
|
||||
return switch (val) {
|
||||
.slot_ptr => |slot| frame.loadSlot(slot),
|
||||
else => val,
|
||||
};
|
||||
}
|
||||
|
||||
fn materializeForCall(self: *Interpreter, frame: *Frame, val: Value) Value {
|
||||
switch (val) {
|
||||
.aggregate => |fields| {
|
||||
|
||||
128
src/ir/lower.zig
128
src/ir/lower.zig
@@ -1014,11 +1014,6 @@ pub const Lowering = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-initialize context with default GPA at the start of main()
|
||||
if (std.mem.eql(u8, name, "main")) {
|
||||
self.emitDefaultContextInit();
|
||||
}
|
||||
|
||||
// Lower the function body (set target_type to return type for implicit returns)
|
||||
const saved_target = self.target_type;
|
||||
self.target_type = if (ret_ty != .void) ret_ty else null;
|
||||
@@ -1907,6 +1902,18 @@ pub const Lowering = struct {
|
||||
.enum_tag => |et| break :blk self.builder.constInt(@intCast(et.tag), et.ty),
|
||||
}
|
||||
}
|
||||
// `context` resolves to a load through the lowering's
|
||||
// current `__sx_ctx` pointer. Every sx function (and
|
||||
// every `push Context.{...}` body) sets `current_ctx_ref`
|
||||
// to a `*Context` it owns, so this is one indirection.
|
||||
if (self.implicit_ctx_enabled and std.mem.eql(u8, id.name, "context")) {
|
||||
if (self.current_ctx_ref != Ref.none) {
|
||||
const ctx_ty = self.module.types.findByName(self.module.types.internString("Context")) orelse {
|
||||
break :blk self.emitError("context", node.span);
|
||||
};
|
||||
break :blk self.builder.load(self.current_ctx_ref, ctx_ty);
|
||||
}
|
||||
}
|
||||
// Check globals (#run constants)
|
||||
if (self.global_names.get(id.name)) |gi| {
|
||||
break :blk self.builder.emit(.{ .global_get = gi.id }, gi.ty);
|
||||
@@ -5013,7 +5020,11 @@ pub const Lowering = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// Pattern-match context.allocator.alloc/dealloc → heap_alloc/heap_free
|
||||
// Pattern-match context.allocator.alloc/dealloc → heap_alloc/heap_free.
|
||||
// The comptime interp doesn't register the full Allocator
|
||||
// protocol in ct_module, so the protocol-dispatch chain it
|
||||
// would otherwise emit can't run. Codegen also benefits —
|
||||
// direct libc malloc/free, no thunk indirection.
|
||||
if (self.matchContextAllocCall(fa, args.items)) |ref| return ref;
|
||||
|
||||
// Type constructor call: Sx(f32).user(0.5) — obj is a call that returns a type
|
||||
@@ -5459,15 +5470,18 @@ pub const Lowering = struct {
|
||||
/// allocators.sx, so the fallback exists strictly for the bootstrapping
|
||||
/// edge case.
|
||||
fn allocViaContext(self: *Lowering, size_ref: Ref, void_ptr_ty: TypeId) Ref {
|
||||
const ctx_gi = self.global_names.get("context") orelse {
|
||||
if (!self.implicit_ctx_enabled or self.current_ctx_ref == Ref.none) {
|
||||
return self.builder.emit(.{ .heap_alloc = .{ .operand = size_ref } }, void_ptr_ty);
|
||||
}
|
||||
const ctx_ty = self.module.types.findByName(self.module.types.internString("Context")) orelse {
|
||||
return self.builder.emit(.{ .heap_alloc = .{ .operand = size_ref } }, void_ptr_ty);
|
||||
};
|
||||
const ctx_ty_info = self.module.types.get(ctx_gi.ty);
|
||||
const ctx_ty_info = self.module.types.get(ctx_ty);
|
||||
if (ctx_ty_info != .@"struct" or ctx_ty_info.@"struct".fields.len < 1) {
|
||||
return self.builder.emit(.{ .heap_alloc = .{ .operand = size_ref } }, void_ptr_ty);
|
||||
}
|
||||
const allocator_ty = ctx_ty_info.@"struct".fields[0].ty;
|
||||
const ctx = self.builder.emit(.{ .global_get = ctx_gi.id }, ctx_gi.ty);
|
||||
const ctx = self.builder.load(self.current_ctx_ref, ctx_ty);
|
||||
const allocator = self.builder.structGet(ctx, 0, allocator_ty);
|
||||
// #inline Allocator protocol layout: { ctx, alloc_fn_ptr, dealloc_fn_ptr }.
|
||||
// field 0 = receiver ctx, field 1 = alloc fn-ptr.
|
||||
@@ -5512,16 +5526,18 @@ pub const Lowering = struct {
|
||||
return new_args;
|
||||
}
|
||||
|
||||
/// Pattern-match `context.allocator.alloc(size)` → heap_alloc,
|
||||
/// `context.allocator.dealloc(ptr)` → heap_free.
|
||||
/// Pattern-match `context.allocator.alloc(size)` → heap_alloc and
|
||||
/// `context.allocator.dealloc(ptr)` → heap_free. Required because the
|
||||
/// comptime interpreter doesn't get a full type/protocol registration
|
||||
/// of the Allocator chain; the protocol-dispatch lowering would
|
||||
/// produce IR that the interp can't execute. Codegen wins from this
|
||||
/// short-circuit too (libc malloc/free direct, no thunk indirection
|
||||
/// for the trivial default-context case).
|
||||
fn matchContextAllocCall(self: *Lowering, fa: ast.FieldAccess, call_args: []const Ref) ?Ref {
|
||||
// fa is the callee field_access: expecting .alloc or .dealloc
|
||||
if (!std.mem.eql(u8, fa.field, "alloc") and !std.mem.eql(u8, fa.field, "dealloc")) return null;
|
||||
// fa.object should be `context.allocator` — another field_access
|
||||
if (fa.object.data != .field_access) return null;
|
||||
const inner = fa.object.data.field_access;
|
||||
if (!std.mem.eql(u8, inner.field, "allocator")) return null;
|
||||
// inner.object should be `context` — an identifier
|
||||
if (inner.object.data != .identifier) return null;
|
||||
if (!std.mem.eql(u8, inner.object.data.identifier.name, "context")) return null;
|
||||
|
||||
@@ -5530,7 +5546,6 @@ pub const Lowering = struct {
|
||||
const ptr_void = self.module.types.ptrTo(.void);
|
||||
return self.builder.emit(.{ .heap_alloc = .{ .operand = call_args[0] } }, ptr_void);
|
||||
} else {
|
||||
// dealloc
|
||||
if (call_args.len < 1) return null;
|
||||
return self.builder.emit(.{ .heap_free = .{ .operand = call_args[0] } }, .void);
|
||||
}
|
||||
@@ -6171,23 +6186,30 @@ pub const Lowering = struct {
|
||||
}
|
||||
|
||||
fn lowerPush(self: *Lowering, ps: *const ast.PushStmt) void {
|
||||
// push context_expr { body }
|
||||
// → save = global_get(context), global_set(context, new_val), body, global_set(context, save)
|
||||
const gi = self.global_names.get("context") orelse {
|
||||
// No context global — just lower the body without push/pop
|
||||
// push Context.{...} { body } — allocates a fresh Context on the
|
||||
// stack frame, rebinds the lowering's `current_ctx_ref` to it for
|
||||
// the body's lexical scope, then restores. No global, no walk.
|
||||
if (!self.implicit_ctx_enabled) {
|
||||
self.lowerBlock(ps.body);
|
||||
return;
|
||||
}
|
||||
const ctx_ty = self.module.types.findByName(self.module.types.internString("Context")) orelse {
|
||||
self.lowerBlock(ps.body);
|
||||
return;
|
||||
};
|
||||
// Save current context
|
||||
const save = self.builder.emit(.{ .global_get = gi.id }, gi.ty);
|
||||
// Lower the new context value
|
||||
const saved_ctx_ref = self.current_ctx_ref;
|
||||
defer self.current_ctx_ref = saved_ctx_ref;
|
||||
|
||||
const saved_target = self.target_type;
|
||||
self.target_type = ctx_ty;
|
||||
const ctx_val = self.lowerExpr(ps.context_expr);
|
||||
// Store into context global
|
||||
self.builder.emitVoid(.{ .global_set = .{ .global = gi.id, .value = ctx_val } }, .void);
|
||||
// Lower the body
|
||||
self.target_type = saved_target;
|
||||
|
||||
const slot = self.builder.alloca(ctx_ty);
|
||||
self.builder.store(slot, ctx_val);
|
||||
self.current_ctx_ref = slot;
|
||||
|
||||
self.lowerBlock(ps.body);
|
||||
// Restore saved context
|
||||
self.builder.emitVoid(.{ .global_set = .{ .global = gi.id, .value = save } }, .void);
|
||||
}
|
||||
|
||||
fn lowerMultiAssign(self: *Lowering, ma: *const ast.MultiAssign) void {
|
||||
@@ -6419,6 +6441,12 @@ pub const Lowering = struct {
|
||||
ct_lowering.main_file = null; // no main file filtering
|
||||
ct_lowering.comptime_param_nodes = self.comptime_param_nodes;
|
||||
ct_lowering.fn_ast_map = self.fn_ast_map; // share AST map for lazy resolution
|
||||
// Inherit the implicit-ctx switch: the parent program uses
|
||||
// Context, so functions lowered into ct_module must carry
|
||||
// __sx_ctx too (otherwise the inserted code's `context.X`
|
||||
// reads can't resolve through current_ctx_ref).
|
||||
ct_lowering.implicit_ctx_enabled = self.implicit_ctx_enabled;
|
||||
ct_module.has_implicit_ctx = self.implicit_ctx_enabled;
|
||||
|
||||
// Lower only the functions reachable from this expression.
|
||||
// For a call like build_format(fmt), we need build_format's AST.
|
||||
@@ -10419,52 +10447,6 @@ pub const Lowering = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Auto-initialize the global `context` with a default GPA allocator at the start of main().
|
||||
/// Emits IR instructions equivalent to:
|
||||
/// __default_gpa : GPA = .{ alloc_count = 0 };
|
||||
/// context = Context.{ allocator = GPA.create(@__default_gpa), data = null };
|
||||
fn emitDefaultContextInit(self: *Lowering) void {
|
||||
// Look up the context global
|
||||
const ctx_gi = self.global_names.get("context") orelse return;
|
||||
const ctx_ty = ctx_gi.ty;
|
||||
|
||||
// Look up GPA type
|
||||
const gpa_ty = self.module.types.findByName(self.module.types.internString("GPA")) orelse return;
|
||||
// Look up Allocator type
|
||||
const alloc_ty = self.module.types.findByName(self.module.types.internString("Allocator")) orelse return;
|
||||
|
||||
// Get GPA→Allocator thunks
|
||||
const thunks = self.getOrCreateThunks("Allocator", "GPA");
|
||||
if (thunks.len < 2) return;
|
||||
|
||||
// 1. Stack-allocate GPA with alloc_count = 0
|
||||
const gpa_slot = self.builder.alloca(gpa_ty);
|
||||
const zero = self.builder.constInt(0, .s64);
|
||||
const gpa_val = self.builder.emit(.{ .struct_init = .{
|
||||
.fields = self.alloc.dupe(Ref, &.{zero}) catch return,
|
||||
} }, gpa_ty);
|
||||
self.builder.store(gpa_slot, gpa_val);
|
||||
|
||||
// 2. Build Allocator inline protocol value: { ctx: *void, alloc_fn, dealloc_fn }
|
||||
const void_ptr_ty = self.module.types.ptrTo(.void);
|
||||
const gpa_ptr = gpa_slot; // alloca already gives us *GPA, all pointers are compatible
|
||||
const alloc_fn = self.builder.emit(.{ .func_ref = thunks[0] }, void_ptr_ty);
|
||||
const dealloc_fn = self.builder.emit(.{ .func_ref = thunks[1] }, void_ptr_ty);
|
||||
|
||||
const alloc_val = self.builder.emit(.{ .struct_init = .{
|
||||
.fields = self.alloc.dupe(Ref, &.{ gpa_ptr, alloc_fn, dealloc_fn }) catch return,
|
||||
} }, alloc_ty);
|
||||
|
||||
// 3. Build Context struct: { allocator, data: null }
|
||||
const null_ptr = self.builder.constNull(void_ptr_ty);
|
||||
const ctx_val = self.builder.emit(.{ .struct_init = .{
|
||||
.fields = self.alloc.dupe(Ref, &.{ alloc_val, null_ptr }) catch return,
|
||||
} }, ctx_ty);
|
||||
|
||||
// 4. Store into context global
|
||||
self.builder.emitVoid(.{ .global_set = .{ .global = ctx_gi.id, .value = ctx_val } }, .void);
|
||||
}
|
||||
|
||||
fn emitModuleConst(self: *Lowering, ci: ModuleConstInfo) Ref {
|
||||
switch (ci.value.data) {
|
||||
.int_literal => |lit| {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
a 0 : Foo{a: 0, b: 42, c: 0, d: 17}
|
||||
a 0 : Foo{a: 0, b: 42, c: 1, d: 17}
|
||||
a 1 : Foo{a: 1, b: 42, c: 8, d: 17}
|
||||
b: Foo{a: 1, b: 0, c: 101, d: 0}
|
||||
b: Foo{a: 1, b: 1, c: 101, d: 1}
|
||||
Pack{a: 1, b: 0, c: 3, d: 5, f: 9, v: 100, x: 3.500000}
|
||||
|
||||
@@ -50,38 +50,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -313,14 +285,6 @@ jni.cont8: ; preds = %jni.miss7, %jni.con
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
@@ -329,10 +293,10 @@ if.then.0: ; preds = %entry
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 0
|
||||
%alloca = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 0
|
||||
store ptr null, ptr %gep, align 8
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 1
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 1
|
||||
store i64 0, ptr %gepN, align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
store { ptr, i64 } { ptr @str.4, i64 3 }, ptr %allocaN, align 8
|
||||
@@ -364,20 +328,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,21 +258,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call i32 @read_int(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca i32, align 4
|
||||
store i32 %call, ptr %allocaN, align 4
|
||||
%alloca = alloca i32, align 4
|
||||
store i32 %call, ptr %alloca, align 4
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,21 +258,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call i64 @read_long(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %call, ptr %allocaN, align 8
|
||||
%alloca = alloca i64, align 8
|
||||
store i64 %call, ptr %alloca, align 8
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,21 +258,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call double @read_double(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca double, align 8
|
||||
store double %call, ptr %allocaN, align 8
|
||||
%alloca = alloca double, align 8
|
||||
store double %call, ptr %alloca, align 8
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,21 +258,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call i1 @read_bool(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca i1, align 1
|
||||
store i1 %call, ptr %allocaN, align 1
|
||||
%alloca = alloca i1, align 1
|
||||
store i1 %call, ptr %alloca, align 1
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,21 +258,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call ptr @get_window(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %call, ptr %allocaN, align 8
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %call, ptr %alloca, align 8
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -283,21 +255,13 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
if.then.0: ; preds = %entry
|
||||
%call = call i32 @call_static_max(ptr @__sx_default_context, ptr null, ptr null)
|
||||
%allocaN = alloca i32, align 4
|
||||
store i32 %call, ptr %allocaN, align 4
|
||||
%alloca = alloca i32, align 4
|
||||
store i32 %call, ptr %alloca, align 4
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
@@ -336,20 +300,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -288,14 +260,6 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
@@ -304,10 +268,10 @@ if.then.0: ; preds = %entry
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 0
|
||||
%alloca = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 0
|
||||
store ptr null, ptr %gep, align 8
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 1
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 1
|
||||
store i64 0, ptr %gepN, align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
store { ptr, i64 } { ptr @str.2, i64 3 }, ptr %allocaN, align 8
|
||||
@@ -339,20 +303,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -48,38 +48,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -286,14 +258,6 @@ jni.cont: ; preds = %jni.miss, %entry
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%gload = load i1, ptr @g_should_call, align 1
|
||||
br i1 %gload, label %if.then.0, label %if.merge.1
|
||||
|
||||
@@ -302,10 +266,10 @@ if.then.0: ; preds = %entry
|
||||
br label %if.merge.1
|
||||
|
||||
if.merge.1: ; preds = %if.then.0, %entry
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 0
|
||||
%alloca = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 0
|
||||
store ptr null, ptr %gep, align 8
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 1
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 1
|
||||
store i64 0, ptr %gepN, align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
store { ptr, i64 } { ptr @str.2, i64 3 }, ptr %allocaN, align 8
|
||||
@@ -337,20 +301,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare ptr @sx_jni_env_tl_get() #0
|
||||
|
||||
|
||||
@@ -51,38 +51,10 @@ entry:
|
||||
declare ptr @GPA.init(ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca i64, align 8
|
||||
store i64 %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%add = add i64 %loadN, 1
|
||||
store i64 %add, ptr %gep, align 8
|
||||
%loadN = load i64, ptr %allocaN, align 8
|
||||
%call = call ptr @malloc(i64 %loadN)
|
||||
ret ptr %call
|
||||
}
|
||||
declare ptr @GPA.alloc(ptr, ptr, i64) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
%alloca = alloca ptr, align 8
|
||||
store ptr %1, ptr %alloca, align 8
|
||||
%allocaN = alloca ptr, align 8
|
||||
store ptr %2, ptr %allocaN, align 8
|
||||
%load = load ptr, ptr %alloca, align 8
|
||||
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
|
||||
%loadN = load i64, ptr %gep, align 8
|
||||
%sub = sub i64 %loadN, 1
|
||||
store i64 %sub, ptr %gep, align 8
|
||||
%loadN = load ptr, ptr %allocaN, align 8
|
||||
call void @free(ptr %loadN)
|
||||
ret void
|
||||
}
|
||||
declare void @GPA.dealloc(ptr, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @Arena.add_chunk(ptr, ptr, i64) #0
|
||||
@@ -362,14 +334,6 @@ declare i64 @build_options() #0
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
call void @__sx_objc_selector_init()
|
||||
%alloca = alloca { i64 }, align 8
|
||||
store { i64 } zeroinitializer, ptr %alloca, align 8
|
||||
%si = insertvalue { ptr, ptr, ptr } undef, ptr %alloca, 0
|
||||
%siN = insertvalue { ptr, ptr, ptr } %si, ptr @__thunk_GPA_Allocator_alloc, 1
|
||||
%siN = insertvalue { ptr, ptr, ptr } %siN, ptr @__thunk_GPA_Allocator_dealloc, 2
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } undef, { ptr, ptr, ptr } %siN, 0
|
||||
%siN = insertvalue { { ptr, ptr, ptr }, ptr } %siN, ptr null, 1
|
||||
store { { ptr, ptr, ptr }, ptr } %siN, ptr @context, align 8
|
||||
%load = load ptr, ptr @OBJC_SELECTOR_REFERENCES_init, align 8
|
||||
call void @objc_msgSend(ptr null, ptr %load)
|
||||
%loadN = load ptr, ptr @OBJC_SELECTOR_REFERENCES_init, align 8
|
||||
@@ -378,10 +342,10 @@ entry:
|
||||
call void @objc_msgSend(ptr null, ptr %loadN)
|
||||
%loadN = load ptr, ptr @OBJC_SELECTOR_REFERENCES_release, align 8
|
||||
call void @objc_msgSend(ptr null, ptr %loadN)
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 0
|
||||
%alloca = alloca { ptr, i64 }, align 8
|
||||
%gep = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 0
|
||||
store ptr null, ptr %gep, align 8
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %allocaN, i32 0, i32 1
|
||||
%gepN = getelementptr inbounds { ptr, i64 }, ptr %alloca, i32 0, i32 1
|
||||
store i64 0, ptr %gepN, align 8
|
||||
%allocaN = alloca { ptr, i64 }, align 8
|
||||
store { ptr, i64 } { ptr @str, i64 3 }, ptr %allocaN, align 8
|
||||
@@ -413,20 +377,6 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
|
||||
entry:
|
||||
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
|
||||
ret ptr %call
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
|
||||
entry:
|
||||
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare ptr @objc_msgSend(ptr, ptr)
|
||||
|
||||
declare i64 @write(i32, ptr, i64)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user