authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-28 20:33:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-28 20:33:50-07:00
log7efc2a06264170632e56256a5fad97e945768056
treef96446fade460810afbdf4ccc003be2069e378de
parent51a40f9a666085b53353f65f017bcf9bf18daaa3

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 :^)

2 files changed, 37 insertions(+), 15 deletions(-)

src/AstGen.zig+20-6
...@@ -8271,17 +8271,31 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool...@@ -8271,17 +8271,31 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool
8271 }8271 }
8272 },8272 },
82738273
8274 .builtin_call,8274 .builtin_call_two, .builtin_call_two_comma => {
8275 .builtin_call_comma,8275 const builtin_token = main_tokens[node];
8276 .builtin_call_two,8276 const builtin_name = tree.tokenSlice(builtin_token);
8277 .builtin_call_two_comma,8277 // If the builtin is an invalid name, we don't cause an error here; instead
8278 => {8278 // let it pass, and the error will be "invalid builtin function" later.
8279 const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false;
8280 switch (builtin_info.needs_mem_loc) {
8281 .never => return false,
8282 .always => return true,
8283 .forward1 => node = node_datas[node].rhs,
8284 }
8285 },
8286
8287 .builtin_call, .builtin_call_comma => {
8288 const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
8279 const builtin_token = main_tokens[node];8289 const builtin_token = main_tokens[node];
8280 const builtin_name = tree.tokenSlice(builtin_token);8290 const builtin_name = tree.tokenSlice(builtin_token);
8281 // If the builtin is an invalid name, we don't cause an error here; instead8291 // If the builtin is an invalid name, we don't cause an error here; instead
8282 // let it pass, and the error will be "invalid builtin function" later.8292 // let it pass, and the error will be "invalid builtin function" later.
8283 const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false;8293 const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false;
8284 return builtin_info.needs_mem_loc;8294 switch (builtin_info.needs_mem_loc) {
8295 .never => return false,
8296 .always => return true,
8297 .forward1 => node = params[1],
8298 }
8285 },8299 },
8286 }8300 }
8287 }8301 }
src/BuiltinFn.zig+17-9
...@@ -110,10 +110,19 @@ pub const Tag = enum {...@@ -110,10 +110,19 @@ pub const Tag = enum {
110 Vector,110 Vector,
111};111};
112112
113pub const MemLocRequirement = enum {
114 /// The builtin never needs a memory location.
115 never,
116 /// The builtin always needs a memory location.
117 always,
118 /// The builtin forwards the question to argument at index 1.
119 forward1,
120};
121
113tag: Tag,122tag: Tag,
114123
115/// `true` if the builtin call can take advantage of a result location pointer.124/// Info about the builtin call's ability to take advantage of a result location pointer.
116needs_mem_loc: bool = false,125needs_mem_loc: MemLocRequirement = .never,
117/// `true` if the builtin call can be the left-hand side of an expression (assigned to).126/// `true` if the builtin call can be the left-hand side of an expression (assigned to).
118allows_lvalue: bool = false,127allows_lvalue: bool = false,
119/// The number of parameters to this builtin function. `null` means variable number128/// The number of parameters to this builtin function. `null` means variable number
...@@ -148,7 +157,7 @@ pub const list = list: {...@@ -148,7 +157,7 @@ pub const list = list: {
148 "@as",157 "@as",
149 .{158 .{
150 .tag = .as,159 .tag = .as,
151 .needs_mem_loc = true,160 .needs_mem_loc = .forward1,
152 .param_count = 2,161 .param_count = 2,
153 },162 },
154 },163 },
...@@ -184,7 +193,7 @@ pub const list = list: {...@@ -184,7 +193,7 @@ pub const list = list: {
184 "@bitCast",193 "@bitCast",
185 .{194 .{
186 .tag = .bit_cast,195 .tag = .bit_cast,
187 .needs_mem_loc = true,196 .needs_mem_loc = .forward1,
188 .param_count = 2,197 .param_count = 2,
189 },198 },
190 },199 },
...@@ -248,7 +257,7 @@ pub const list = list: {...@@ -248,7 +257,7 @@ pub const list = list: {
248 "@call",257 "@call",
249 .{258 .{
250 .tag = .call,259 .tag = .call,
251 .needs_mem_loc = true,260 .needs_mem_loc = .always,
252 .param_count = 3,261 .param_count = 3,
253 },262 },
254 },263 },
...@@ -410,7 +419,7 @@ pub const list = list: {...@@ -410,7 +419,7 @@ pub const list = list: {
410 "@field",419 "@field",
411 .{420 .{
412 .tag = .field,421 .tag = .field,
413 .needs_mem_loc = true,422 .needs_mem_loc = .always,
414 .param_count = 2,423 .param_count = 2,
415 .allows_lvalue = true,424 .allows_lvalue = true,
416 },425 },
...@@ -699,7 +708,6 @@ pub const list = list: {...@@ -699,7 +708,6 @@ pub const list = list: {
699 "@splat",708 "@splat",
700 .{709 .{
701 .tag = .splat,710 .tag = .splat,
702 .needs_mem_loc = true,
703 .param_count = 2,711 .param_count = 2,
704 },712 },
705 },713 },
...@@ -714,7 +722,7 @@ pub const list = list: {...@@ -714,7 +722,7 @@ pub const list = list: {
714 "@src",722 "@src",
715 .{723 .{
716 .tag = .src,724 .tag = .src,
717 .needs_mem_loc = true,725 .needs_mem_loc = .always,
718 .param_count = 0,726 .param_count = 0,
719 },727 },
720 },728 },
...@@ -869,7 +877,7 @@ pub const list = list: {...@@ -869,7 +877,7 @@ pub const list = list: {
869 "@unionInit",877 "@unionInit",
870 .{878 .{
871 .tag = .union_init,879 .tag = .union_init,
872 .needs_mem_loc = true,880 .needs_mem_loc = .always,
873 .param_count = 3,881 .param_count = 3,
874 },882 },
875 },883 },