Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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