From 19691c0b174f283ffe5b6c3fe8533ef458736064 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 15 Sep 2021 12:37:32 -0700 Subject: stage2: implement `@fence` --- src/codegen/c.zig | 12 ++++++++++++ src/codegen/llvm.zig | 9 +++++++++ src/codegen/llvm/bindings.zig | 8 ++++++++ 3 files changed, 29 insertions(+) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index ff49b18f7b..a2e2d7b20d 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -842,6 +842,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM .breakpoint => try airBreakpoint(o), .unreach => try airUnreach(o), + .fence => try airFence(o, inst), // TODO use a different strategy for add that communicates to the optimizer // that wrapping is UB. @@ -1439,6 +1440,17 @@ fn airBreakpoint(o: *Object) !CValue { return CValue.none; } +fn airFence(o: *Object, inst: Air.Inst.Index) !CValue { + const atomic_order = o.air.instructions.items(.data)[inst].fence; + const writer = o.writer(); + + try writer.writeAll("zig_fence("); + try writeMemoryOrder(writer, atomic_order); + try writer.writeAll(");\n"); + + return CValue.none; +} + fn airUnreach(o: *Object) !CValue { try o.writer().writeAll("zig_unreachable();\n"); return CValue.none; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index b28c371466..569f857caa 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1059,6 +1059,7 @@ pub const FuncGen = struct { .array_to_slice => try self.airArrayToSlice(inst), .cmpxchg_weak => try self.airCmpxchg(inst, true), .cmpxchg_strong => try self.airCmpxchg(inst, false), + .fence => try self.airFence(inst), .struct_field_ptr => try self.airStructFieldPtr(inst), .struct_field_val => try self.airStructFieldVal(inst), @@ -2005,6 +2006,14 @@ pub const FuncGen = struct { return null; } + fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + const atomic_order = self.air.instructions.items(.data)[inst].fence; + const llvm_memory_order = toLlvmAtomicOrdering(atomic_order); + const single_threaded = llvm.Bool.fromBool(self.single_threaded); + _ = self.builder.buildFence(llvm_memory_order, single_threaded, ""); + return null; + } + fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*const llvm.Value { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index b4bd91708d..3fed3ca879 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -522,6 +522,14 @@ pub const Builder = opaque { Else: *const Value, Name: [*:0]const u8, ) *const Value; + + pub const buildFence = LLVMBuildFence; + extern fn LLVMBuildFence( + B: *const Builder, + ordering: AtomicOrdering, + singleThread: Bool, + Name: [*:0]const u8, + ) *const Value; }; pub const IntPredicate = enum(c_uint) { -- cgit v1.2.3