diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-09-28 20:33:50 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-09-28 20:33:50 -0700 |
| commit | 7efc2a06264170632e56256a5fad97e945768056 (patch) | |
| tree | f96446fade460810afbdf4ccc003be2069e378de /src | |
| parent | 51a40f9a666085b53353f65f017bcf9bf18daaa3 (diff) | |
| download | zig-7efc2a06264170632e56256a5fad97e945768056.tar.gz zig-7efc2a06264170632e56256a5fad97e945768056.zip | |
AstGen: improved logic for nodeMayNeedMemoryLocation
* `@as` and `@bitCast` no longer unconditionally return `true` from
this function; they forward the question to their sub-expression.
* fix `@splat` incorrectly being marked as needing a memory location
(this function returns a SIMD vector; it definitely does not want a
memory location).
Makes AstGen generate slightly nicer ZIR, which in turn generates
slightly nicer AIR, generating slightly nicer machine code in debug
builds.
It also means I can procrastinate implementing the bitcast_result_ptr
ZIR instruction semantic analysis :^)
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 26 | ||||
| -rw-r--r-- | src/BuiltinFn.zig | 26 |
2 files changed, 37 insertions, 15 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 847860630a..24a73539b3 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -8271,17 +8271,31 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool } }, - .builtin_call, - .builtin_call_comma, - .builtin_call_two, - .builtin_call_two_comma, - => { + .builtin_call_two, .builtin_call_two_comma => { + const builtin_token = main_tokens[node]; + const builtin_name = tree.tokenSlice(builtin_token); + // If the builtin is an invalid name, we don't cause an error here; instead + // let it pass, and the error will be "invalid builtin function" later. + const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false; + switch (builtin_info.needs_mem_loc) { + .never => return false, + .always => return true, + .forward1 => node = node_datas[node].rhs, + } + }, + + .builtin_call, .builtin_call_comma => { + const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; const builtin_token = main_tokens[node]; const builtin_name = tree.tokenSlice(builtin_token); // If the builtin is an invalid name, we don't cause an error here; instead // let it pass, and the error will be "invalid builtin function" later. const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false; - return builtin_info.needs_mem_loc; + switch (builtin_info.needs_mem_loc) { + .never => return false, + .always => return true, + .forward1 => node = params[1], + } }, } } diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig index 8f23ec86d7..e1f4f5bd16 100644 --- a/src/BuiltinFn.zig +++ b/src/BuiltinFn.zig @@ -110,10 +110,19 @@ pub const Tag = enum { Vector, }; +pub const MemLocRequirement = enum { + /// The builtin never needs a memory location. + never, + /// The builtin always needs a memory location. + always, + /// The builtin forwards the question to argument at index 1. + forward1, +}; + tag: Tag, -/// `true` if the builtin call can take advantage of a result location pointer. -needs_mem_loc: bool = false, +/// Info about the builtin call's ability to take advantage of a result location pointer. +needs_mem_loc: MemLocRequirement = .never, /// `true` if the builtin call can be the left-hand side of an expression (assigned to). allows_lvalue: bool = false, /// The number of parameters to this builtin function. `null` means variable number @@ -148,7 +157,7 @@ pub const list = list: { "@as", .{ .tag = .as, - .needs_mem_loc = true, + .needs_mem_loc = .forward1, .param_count = 2, }, }, @@ -184,7 +193,7 @@ pub const list = list: { "@bitCast", .{ .tag = .bit_cast, - .needs_mem_loc = true, + .needs_mem_loc = .forward1, .param_count = 2, }, }, @@ -248,7 +257,7 @@ pub const list = list: { "@call", .{ .tag = .call, - .needs_mem_loc = true, + .needs_mem_loc = .always, .param_count = 3, }, }, @@ -410,7 +419,7 @@ pub const list = list: { "@field", .{ .tag = .field, - .needs_mem_loc = true, + .needs_mem_loc = .always, .param_count = 2, .allows_lvalue = true, }, @@ -699,7 +708,6 @@ pub const list = list: { "@splat", .{ .tag = .splat, - .needs_mem_loc = true, .param_count = 2, }, }, @@ -714,7 +722,7 @@ pub const list = list: { "@src", .{ .tag = .src, - .needs_mem_loc = true, + .needs_mem_loc = .always, .param_count = 0, }, }, @@ -869,7 +877,7 @@ pub const list = list: { "@unionInit", .{ .tag = .union_init, - .needs_mem_loc = true, + .needs_mem_loc = .always, .param_count = 3, }, }, |
