Skip to content

[proposal] Mark external function as pure #5838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pfgithub opened this issue Jul 10, 2020 · 5 comments
Open

[proposal] Mark external function as pure #5838

pfgithub opened this issue Jul 10, 2020 · 5 comments
Labels
accepted This proposal is planned. optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@pfgithub
Copy link
Contributor

Right now, there is no way to tell llvm to optimize external functions as if they were pure

godbolt example: https://godbolt.org/z/7xbo8r

godbolt screenshot

It would be useful if there was a way to mark external functions as pure to allow repeated calls to be optimized away

@Vexu Vexu added optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. labels Jul 10, 2020
@Vexu Vexu added this to the 0.8.0 milestone Jul 10, 2020
@andrewrk andrewrk added the accepted This proposal is planned. label May 19, 2021
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 20, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Apr 9, 2023
@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0 Jun 29, 2023
@uniboi
Copy link

uniboi commented Sep 11, 2024

I think this would fit nicely into the callconvention configuration proposed in #21209, for example like extern fn square(n: i64) callconv(.C : .{ .pure = true }) i64;.

@mlugg
Copy link
Member

mlugg commented Sep 11, 2024

No, function purity is not related to calling convention.

@wooster0
Copy link
Contributor

It would also be nice if additionally only specific calls of an external function could be marked as pure, for example if you don't care whether there are side effects (maybe because it doesn't affect you) or if a function will not have side effects with specific input (e.g. behave_pure: bool).

This proposal doesn't propose specific syntax for Zig. If Zig had tags/annotations/attributes it might use those but because it doesn't have them for now I would propose adding a pure keyword, which can only appear after extern, after the library name, if any:

extern fn "library" pure square(num: c_int) callconv(.C) c_int;

Alternatively it could go after the parameters, before the return type.

To mark only specific calls of an external function as pure I propose:

@call(.pure, square, .{ 3 });

Calling non-external functions this way would be a compile error.

This could for example be used in the standard library to perhaps allow the compiler to optimize away unused memory allocations by marking call sites like this as pure:

const slice = posix.mmap(

Status quo:

~$ cat x.zig
const std = @import("std");

pub fn main() void {
    _ = std.heap.page_allocator.alloc(u8, 1) catch return;
}
~$ zig build-exe x.zig -OReleaseFast && strace ./x 2>&1 | grep mmap
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f23fb1cb000
~$

@mlugg
Copy link
Member

mlugg commented Sep 11, 2024

Ehhh, I don't think reserving pure as a keyword is a good idea. As a general rule, we try to minimise keywords, and when they do exist we want to get a lot of "bang for our buck" (e.g. inline is reserved as a keyword, but that gives us a whole bunch of constructs). This pure keyword would reserve a short identifier (=> more likely people want to use it), to have exactly one usage, which is itself a very rare usage.

@wooster0
Copy link
Contributor

I completely agree, it's just that I can't really think of any other way to specify it considering that you can't combine it with any existing constructs such as align, addrspace, linksection, or callconv. You need a new construct as far as I can tell. If not a keyword I guess you could introduce some other syntax using sigils or something but not sure how readable that would be.

@andrewrk andrewrk modified the milestones: 0.14.0, 0.15.0 Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

6 participants