Skip to content

Commit

Permalink
Merge pull request ziglang#21214 from mlugg/branch-hint-and-export
Browse files Browse the repository at this point in the history
Implement `@branchHint` and new `@export` usage
  • Loading branch information
mlugg authored Aug 27, 2024
2 parents d9147b9 + 4c0f021 commit d3c6f71
Show file tree
Hide file tree
Showing 266 changed files with 2,443 additions and 1,808 deletions.
36 changes: 12 additions & 24 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -4340,6 +4340,13 @@ comptime {
{#see_also|@sizeOf|@typeInfo#}
{#header_close#}

{#header_open|@branchHint#}
<pre>{#syntax#}@branchHint(hint: BranchHint) void{#endsyntax#}</pre>
<p>Hints to the optimizer how likely a given branch of control flow is to be reached.</p>
<p>{#syntax#}BranchHint{#endsyntax#} can be found with {#syntax#}@import("std").builtin.BranchHint{#endsyntax#}.</p>
<p>This function is only valid as the first statement in a control flow branch, or the first statement in a function.</p>
{#header_close#}

{#header_open|@breakpoint#}
<pre>{#syntax#}@breakpoint() void{#endsyntax#}</pre>
<p>
Expand Down Expand Up @@ -4767,23 +4774,13 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
{#header_close#}

{#header_open|@export#}
<pre>{#syntax#}@export(declaration, comptime options: std.builtin.ExportOptions) void{#endsyntax#}</pre>
<p>
Creates a symbol in the output object file.
</p>
<p>
<code>declaration</code> must be one of two things:
</p>
<ul>
<li>An identifier ({#syntax#}x{#endsyntax#}) identifying a {#link|function|Functions#} or a
{#link|variable|Container Level Variables#}.</li>
<li>Field access ({#syntax#}x.y{#endsyntax#}) looking up a {#link|function|Functions#} or a
{#link|variable|Container Level Variables#}.</li>
</ul>
<pre>{#syntax#}@export(comptime ptr: *const anyopaque, comptime options: std.builtin.ExportOptions) void{#endsyntax#}</pre>
<p>Creates a symbol in the output object file which refers to the target of <code>ptr</code>.</p>
<p><code>ptr</code> must point to a global variable or a comptime-known constant.</p>
<p>
This builtin can be called from a {#link|comptime#} block to conditionally export symbols.
When <code>declaration</code> is a function with the C calling convention and
{#syntax#}options.linkage{#endsyntax#} is {#syntax#}Strong{#endsyntax#}, this is equivalent to
When <code>ptr</code> points to a function with the C calling convention and
{#syntax#}options.linkage{#endsyntax#} is {#syntax#}.Strong{#endsyntax#}, this is equivalent to
the {#syntax#}export{#endsyntax#} keyword used on a function:
</p>
{#code|export_builtin.zig#}
Expand Down Expand Up @@ -5252,15 +5249,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
</p>
{#header_close#}

{#header_open|@setCold#}
<pre>{#syntax#}@setCold(comptime is_cold: bool) void{#endsyntax#}</pre>
<p>
Tells the optimizer that the current function is (or is not) rarely called.

This function is only valid within function scope.
</p>
{#header_close#}

{#header_open|@setEvalBranchQuota#}
<pre>{#syntax#}@setEvalBranchQuota(comptime new_quota: u32) void{#endsyntax#}</pre>
<p>
Expand Down
2 changes: 1 addition & 1 deletion doc/langref/export_builtin.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
comptime {
@export(internalName, .{ .name = "foo", .linkage = .strong });
@export(&internalName, .{ .name = "foo", .linkage = .strong });
}

fn internalName() callconv(.C) void {}
Expand Down
4 changes: 2 additions & 2 deletions doc/langref/test_functions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .Stdcall
extern "kernel32" fn ExitProcess(exit_code: u32) callconv(WINAPI) noreturn;
extern "c" fn atan2(a: f64, b: f64) f64;

// The @setCold builtin tells the optimizer that a function is rarely called.
// The @branchHint builtin can be used to tell the optimizer that a function is rarely called ("cold").
fn abort() noreturn {
@setCold(true);
@branchHint(.cold);
while (true) {}
}

Expand Down
22 changes: 11 additions & 11 deletions lib/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,27 @@ const is_freestanding = switch (native_os) {

comptime {
if (is_freestanding and is_wasm and builtin.link_libc) {
@export(wasm_start, .{ .name = "_start", .linkage = .strong });
@export(&wasm_start, .{ .name = "_start", .linkage = .strong });
}

if (builtin.link_libc) {
@export(strcmp, .{ .name = "strcmp", .linkage = .strong });
@export(strncmp, .{ .name = "strncmp", .linkage = .strong });
@export(strerror, .{ .name = "strerror", .linkage = .strong });
@export(strlen, .{ .name = "strlen", .linkage = .strong });
@export(strcpy, .{ .name = "strcpy", .linkage = .strong });
@export(strncpy, .{ .name = "strncpy", .linkage = .strong });
@export(strcat, .{ .name = "strcat", .linkage = .strong });
@export(strncat, .{ .name = "strncat", .linkage = .strong });
@export(&strcmp, .{ .name = "strcmp", .linkage = .strong });
@export(&strncmp, .{ .name = "strncmp", .linkage = .strong });
@export(&strerror, .{ .name = "strerror", .linkage = .strong });
@export(&strlen, .{ .name = "strlen", .linkage = .strong });
@export(&strcpy, .{ .name = "strcpy", .linkage = .strong });
@export(&strncpy, .{ .name = "strncpy", .linkage = .strong });
@export(&strcat, .{ .name = "strcat", .linkage = .strong });
@export(&strncat, .{ .name = "strncat", .linkage = .strong });
} else if (is_msvc) {
@export(_fltused, .{ .name = "_fltused", .linkage = .strong });
@export(&_fltused, .{ .name = "_fltused", .linkage = .strong });
}
}

// Avoid dragging in the runtime safety mechanisms into this .o file,
// unless we're trying to test this file.
pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
@setCold(true);
@branchHint(.cold);
_ = error_return_trace;
if (builtin.is_test) {
std.debug.panic("{s}", .{msg});
Expand Down
8 changes: 4 additions & 4 deletions lib/compiler/aro/aro/Driver/Filesystem.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const builtin = @import("builtin");
const is_windows = builtin.os.tag == .windows;

fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 {
@setCold(true);
@branchHint(.cold);
for (entries) |entry| {
if (mem.eql(u8, entry.path, path)) {
const len = @min(entry.contents.len, buf.len);
Expand All @@ -16,7 +16,7 @@ fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8)
}

fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
@setCold(true);
@branchHint(.cold);
if (mem.indexOfScalar(u8, name, '/') != null) {
@memcpy(buf[0..name.len], name);
return buf[0..name.len];
Expand All @@ -35,7 +35,7 @@ fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, pa
}

fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
@setCold(true);
@branchHint(.cold);
for (entries) |entry| {
if (mem.eql(u8, entry.path, path)) {
return entry.executable;
Expand All @@ -45,7 +45,7 @@ fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
}

fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
@setCold(true);
@branchHint(.cold);
var buf: [std.fs.max_path_bytes]u8 = undefined;
var fib = std.heap.FixedBufferAllocator.init(&buf);
const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false;
Expand Down
10 changes: 5 additions & 5 deletions lib/compiler/aro/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,12 @@ fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error {
}

pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void {
@setCold(true);
@branchHint(.cold);
return p.errExtra(tag, tok_i, .{ .str = str });
}

pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void {
@setCold(true);
@branchHint(.cold);
const tok = p.pp.tokens.get(tok_i);
var loc = tok.loc;
if (tok_i != 0 and tok.id == .eof) {
Expand All @@ -407,12 +407,12 @@ pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diag
}

pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void {
@setCold(true);
@branchHint(.cold);
return p.errExtra(tag, tok_i, .{ .none = {} });
}

pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void {
@setCold(true);
@branchHint(.cold);
return p.errExtra(tag, p.tok_i, .{ .none = {} });
}

Expand Down Expand Up @@ -638,7 +638,7 @@ fn pragma(p: *Parser) Compilation.Error!bool {

/// Issue errors for top-level definitions whose type was never completed.
fn diagnoseIncompleteDefinitions(p: *Parser) !void {
@setCold(true);
@branchHint(.cold);

const node_slices = p.nodes.slice();
const tags = node_slices.items(.tag);
Expand Down
8 changes: 4 additions & 4 deletions lib/compiler/resinator/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ fn cliDiagnosticsToErrorBundle(
gpa: std.mem.Allocator,
diagnostics: *cli.Diagnostics,
) !ErrorBundle {
@setCold(true);
@branchHint(.cold);

var bundle: ErrorBundle.Wip = undefined;
try bundle.init(gpa);
Expand Down Expand Up @@ -468,7 +468,7 @@ fn diagnosticsToErrorBundle(
diagnostics: *Diagnostics,
mappings: SourceMappings,
) !ErrorBundle {
@setCold(true);
@branchHint(.cold);

var bundle: ErrorBundle.Wip = undefined;
try bundle.init(gpa);
Expand Down Expand Up @@ -559,7 +559,7 @@ fn flushErrorMessageIntoBundle(wip: *ErrorBundle.Wip, msg: ErrorBundle.ErrorMess
}

fn errorStringToErrorBundle(allocator: std.mem.Allocator, comptime format: []const u8, args: anytype) !ErrorBundle {
@setCold(true);
@branchHint(.cold);
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(allocator);
errdefer bundle.deinit();
Expand All @@ -574,7 +574,7 @@ fn aroDiagnosticsToErrorBundle(
fail_msg: []const u8,
comp: *aro.Compilation,
) !ErrorBundle {
@setCold(true);
@branchHint(.cold);

var bundle: ErrorBundle.Wip = undefined;
try bundle.init(gpa);
Expand Down
Loading

0 comments on commit d3c6f71

Please sign in to comment.