atomics A.0a: lib + IR ops + recognizer, emit bails (lock commit)
Stream A (atomics) foundation. Net-new atomic load/store codegen path, wired end-to-end except LLVM emission, which deliberately bails loudly so the example locks to a clean diagnostic (A.0b turns it green — cadence: no commit both adds a test and makes it pass). - library/modules/std/atomic.sx: Ordering enum, Atomic($T) transparent wrapper (init/load/store, seq_cst-only for now), atomic_load/atomic_store #builtin intrinsics. Opt-in import, NOT in the universal std facade (Ordering in the prelude grows every program's type table + churns 37 .ir snapshots). - IR: atomic_load/atomic_store ops + AtomicOrdering (all 5) + structs (inst.zig); print arms; comptime_vm arms reuse load/store (single-thread correct); recognizer tryLowerAtomicIntrinsic (const-ordering + scalar-size guards, both loud); emit dispatch -> emitAtomicLoad/Store bail via comptime_failed. - examples/1700-atomics-load-store.sx locked to the bail diagnostic. Full ordering surface (a.load(.acquire)) blocked on comptime-constant ordering propagation (comptime enum value params) — A.0.5, migrated not legacy.
This commit is contained in:
@@ -15,6 +15,8 @@ const FieldAccess = ir_inst.FieldAccess;
|
||||
const EnumInit = ir_inst.EnumInit;
|
||||
const Subslice = ir_inst.Subslice;
|
||||
const Store = ir_inst.Store;
|
||||
const AtomicLoad = ir_inst.AtomicLoad;
|
||||
const AtomicStore = ir_inst.AtomicStore;
|
||||
const Conversion = ir_inst.Conversion;
|
||||
const GlobalId = ir_inst.GlobalId;
|
||||
const GlobalSet = ir_inst.GlobalSet;
|
||||
@@ -363,6 +365,29 @@ pub const Ops = struct {
|
||||
self.e.advanceRefCounter();
|
||||
}
|
||||
|
||||
// ── Atomics ───────────────────────────────────────────
|
||||
// A.0a (Stream A) lock: the IR ops, lowering, and comptime VM are wired,
|
||||
// but LLVM emission deliberately BAILS LOUDLY (clean diagnostic + build
|
||||
// abort via `comptime_failed`) rather than silently emitting a non-atomic
|
||||
// load/store. A.0b replaces these bodies with the real builders:
|
||||
// load: LLVMBuildLoad2 + LLVMSetOrdering + LLVMSetAlignment
|
||||
// store: LLVMBuildStore + LLVMSetOrdering + LLVMSetAlignment
|
||||
// (ordering via an explicit sx-tag → LLVMAtomicOrdering switch).
|
||||
pub fn emitAtomicLoad(self: Ops, instruction: *const Inst, a: AtomicLoad) void {
|
||||
_ = a;
|
||||
std.debug.print("error: atomic load LLVM emission not yet implemented (Stream A, A.0b)\n", .{});
|
||||
self.e.comptime_failed = true;
|
||||
// Keep emit from crashing downstream: yield an undef of the result type.
|
||||
self.e.mapRef(c.LLVMGetUndef(self.e.toLLVMType(if (instruction.ty == .void) .i64 else instruction.ty)));
|
||||
}
|
||||
|
||||
pub fn emitAtomicStore(self: Ops, a: AtomicStore) void {
|
||||
_ = a;
|
||||
std.debug.print("error: atomic store LLVM emission not yet implemented (Stream A, A.0b)\n", .{});
|
||||
self.e.comptime_failed = true;
|
||||
self.e.advanceRefCounter();
|
||||
}
|
||||
|
||||
// ── Globals ───────────────────────────────────────────
|
||||
pub fn emitGlobalGet(self: Ops, instruction: *const Inst, gid: GlobalId) void {
|
||||
const llvm_global = self.e.global_map.get(gid.index()) orelse {
|
||||
|
||||
Reference in New Issue
Block a user