| ... | @@ -411,7 +411,7 @@ pub const Function = struct { | ... | @@ -411,7 +411,7 @@ pub const Function = struct { |
| 411 | pub fn deinit(f: *Function, gpa: mem.Allocator) void { | 411 | pub fn deinit(f: *Function, gpa: mem.Allocator) void { |
| 412 | f.allocs.deinit(gpa); | 412 | f.allocs.deinit(gpa); |
| 413 | f.locals.deinit(gpa); | 413 | f.locals.deinit(gpa); |
| 414 | f.free_locals.deinit(gpa); | 414 | deinitFreeLocalsMap(gpa, &f.free_locals); |
| 415 | f.blocks.deinit(gpa); | 415 | f.blocks.deinit(gpa); |
| 416 | f.value_map.deinit(); | 416 | f.value_map.deinit(); |
| 417 | f.object.code.deinit(); | 417 | f.object.code.deinit(); |
| ... | @@ -4285,8 +4285,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4285,8 +4285,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4285 | const gpa = f.object.dg.gpa; | 4285 | const gpa = f.object.dg.gpa; |
| 4286 | var cloned_map = try f.value_map.clone(); | 4286 | var cloned_map = try f.value_map.clone(); |
| 4287 | defer cloned_map.deinit(); | 4287 | defer cloned_map.deinit(); |
| 4288 | var cloned_frees = try f.free_locals.clone(gpa); | 4288 | var cloned_frees = try cloneFreeLocalsMap(gpa, &f.free_locals); |
| 4289 | defer cloned_frees.deinit(gpa); | 4289 | defer deinitFreeLocalsMap(gpa, &cloned_frees); |
| 4290 | | 4290 | |
| 4291 | for (liveness_condbr.then_deaths) |operand| { | 4291 | for (liveness_condbr.then_deaths) |operand| { |
| 4292 | try die(f, inst, Air.indexToRef(operand)); | 4292 | try die(f, inst, Air.indexToRef(operand)); |
| ... | @@ -4299,7 +4299,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4299,7 +4299,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4299 | try writer.writeAll(" else "); | 4299 | try writer.writeAll(" else "); |
| 4300 | f.value_map.deinit(); | 4300 | f.value_map.deinit(); |
| 4301 | f.value_map = cloned_map.move(); | 4301 | f.value_map = cloned_map.move(); |
| 4302 | f.free_locals.deinit(gpa); | 4302 | deinitFreeLocalsMap(gpa, &f.free_locals); |
| 4303 | f.free_locals = cloned_frees.move(); | 4303 | f.free_locals = cloned_frees.move(); |
| 4304 | for (liveness_condbr.else_deaths) |operand| { | 4304 | for (liveness_condbr.else_deaths) |operand| { |
| 4305 | try die(f, inst, Air.indexToRef(operand)); | 4305 | try die(f, inst, Air.indexToRef(operand)); |
| ... | @@ -4362,18 +4362,19 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4362,18 +4362,19 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4362 | const old_value_map = f.value_map; | 4362 | const old_value_map = f.value_map; |
| 4363 | f.value_map = try old_value_map.clone(); | 4363 | f.value_map = try old_value_map.clone(); |
| 4364 | const old_free_locals = f.free_locals; | 4364 | const old_free_locals = f.free_locals; |
| 4365 | f.free_locals = try f.free_locals.clone(gpa); | 4365 | f.free_locals = try cloneFreeLocalsMap(gpa, &f.free_locals); |
| 4366 | | | |
| 4367 | for (liveness.deaths[case_i]) |operand| { | | |
| 4368 | try die(f, inst, Air.indexToRef(operand)); | | |
| 4369 | } | | |
| 4370 | | 4366 | |
| 4371 | defer { | 4367 | defer { |
| 4372 | f.value_map.deinit(); | 4368 | f.value_map.deinit(); |
| 4373 | f.free_locals.deinit(gpa); | 4369 | deinitFreeLocalsMap(gpa, &f.free_locals); |
| 4374 | f.value_map = old_value_map; | 4370 | f.value_map = old_value_map; |
| 4375 | f.free_locals = old_free_locals; | 4371 | f.free_locals = old_free_locals; |
| 4376 | } | 4372 | } |
| | 4373 | |
| | 4374 | for (liveness.deaths[case_i]) |operand| { |
| | 4375 | try die(f, inst, Air.indexToRef(operand)); |
| | 4376 | } |
| | 4377 | |
| 4377 | try genBody(f, case_body); | 4378 | try genBody(f, case_body); |
| 4378 | } else { | 4379 | } else { |
| 4379 | for (liveness.deaths[case_i]) |operand| { | 4380 | for (liveness.deaths[case_i]) |operand| { |
| ... | @@ -6933,3 +6934,29 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb { | ... | @@ -6933,3 +6934,29 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb { |
| 6933 | .lbt = f.liveness.iterateBigTomb(inst), | 6934 | .lbt = f.liveness.iterateBigTomb(inst), |
| 6934 | }; | 6935 | }; |
| 6935 | } | 6936 | } |
| | 6937 | |
| | 6938 | /// A naive clone of this map would create copies of the ArrayList which is |
| | 6939 | /// stored in the values. This function additionally clones the values. |
| | 6940 | fn cloneFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) !LocalsMap { |
| | 6941 | var cloned = try map.clone(gpa); |
| | 6942 | const values = cloned.values(); |
| | 6943 | var i: usize = 0; |
| | 6944 | errdefer { |
| | 6945 | cloned.deinit(gpa); |
| | 6946 | while (i > 0) { |
| | 6947 | i -= 1; |
| | 6948 | values[i].deinit(gpa); |
| | 6949 | } |
| | 6950 | } |
| | 6951 | while (i < values.len) : (i += 1) { |
| | 6952 | values[i] = try values[i].clone(gpa); |
| | 6953 | } |
| | 6954 | return cloned; |
| | 6955 | } |
| | 6956 | |
| | 6957 | fn deinitFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) void { |
| | 6958 | for (map.values()) |*value| { |
| | 6959 | value.deinit(gpa); |
| | 6960 | } |
| | 6961 | map.deinit(gpa); |
| | 6962 | } |