| author | |
| committer | |
| log | 69df00f657c567339d0d39c50381eaec4fab32a4 |
| tree | 5349ca48e39be02749ae379fb0f5df05b4955b49 |
| parent | 9410b11ca663231e367e3adfd668979c4b870a41 |
| parent | 5c2e463ecd9070638fa623b3e5856188e4550a78 |
| signature |
LLVM: Miscellaneous improvements to Builder3 files changed, 217 insertions(+), 93 deletions(-)
src/codegen/llvm.zig+31-38| ... | @@ -1046,7 +1046,7 @@ pub const Object = struct { | ... | @@ -1046,7 +1046,7 @@ pub const Object = struct { |
| 1046 | 1046 | ||
| 1047 | fn genCmpLtErrorsLenFunction(o: *Object) !void { | 1047 | fn genCmpLtErrorsLenFunction(o: *Object) !void { |
| 1048 | // If there is no such function in the module, it means the source code does not need it. | 1048 | // If there is no such function in the module, it means the source code does not need it. |
| 1049 | const name = o.builder.stringIfExists(lt_errors_fn_name) orelse return; | 1049 | const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return; |
| 1050 | const llvm_fn = o.builder.getGlobal(name) orelse return; | 1050 | const llvm_fn = o.builder.getGlobal(name) orelse return; |
| 1051 | const mod = o.module; | 1051 | const mod = o.module; |
| 1052 | const errors_len = mod.global_error_set.count(); | 1052 | const errors_len = mod.global_error_set.count(); |
| ... | @@ -1087,7 +1087,7 @@ pub const Object = struct { | ... | @@ -1087,7 +1087,7 @@ pub const Object = struct { |
| 1087 | for (object.extern_collisions.keys()) |decl_index| { | 1087 | for (object.extern_collisions.keys()) |decl_index| { |
| 1088 | const global = object.decl_map.get(decl_index) orelse continue; | 1088 | const global = object.decl_map.get(decl_index) orelse continue; |
| 1089 | // Same logic as below but for externs instead of exports. | 1089 | // Same logic as below but for externs instead of exports. |
| 1090 | const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue; | 1090 | const decl_name = object.builder.strtabStringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue; |
| 1091 | const other_global = object.builder.getGlobal(decl_name) orelse continue; | 1091 | const other_global = object.builder.getGlobal(decl_name) orelse continue; |
| 1092 | if (other_global.toConst().getBase(&object.builder) == | 1092 | if (other_global.toConst().getBase(&object.builder) == |
| 1093 | global.toConst().getBase(&object.builder)) continue; | 1093 | global.toConst().getBase(&object.builder)) continue; |
| ... | @@ -1117,7 +1117,7 @@ pub const Object = struct { | ... | @@ -1117,7 +1117,7 @@ pub const Object = struct { |
| 1117 | for (export_list) |exp| { | 1117 | for (export_list) |exp| { |
| 1118 | // Detect if the LLVM global has already been created as an extern. In such | 1118 | // Detect if the LLVM global has already been created as an extern. In such |
| 1119 | // case, we need to replace all uses of it with this exported global. | 1119 | // case, we need to replace all uses of it with this exported global. |
| 1120 | const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue; | 1120 | const exp_name = object.builder.strtabStringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue; |
| 1121 | 1121 | ||
| 1122 | const other_global = object.builder.getGlobal(exp_name) orelse continue; | 1122 | const other_global = object.builder.getGlobal(exp_name) orelse continue; |
| 1123 | if (other_global.toConst().getBase(&object.builder) == global_base) continue; | 1123 | if (other_global.toConst().getBase(&object.builder) == global_base) continue; |
| ... | @@ -1662,7 +1662,7 @@ pub const Object = struct { | ... | @@ -1662,7 +1662,7 @@ pub const Object = struct { |
| 1662 | const subprogram = try o.builder.debugSubprogram( | 1662 | const subprogram = try o.builder.debugSubprogram( |
| 1663 | file, | 1663 | file, |
| 1664 | try o.builder.metadataString(ip.stringToSlice(decl.name)), | 1664 | try o.builder.metadataString(ip.stringToSlice(decl.name)), |
| 1665 | try o.builder.metadataStringFromString(function_index.name(&o.builder)), | 1665 | try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)), |
| 1666 | line_number, | 1666 | line_number, |
| 1667 | line_number + func.lbrace_line, | 1667 | line_number + func.lbrace_line, |
| 1668 | debug_decl_type, | 1668 | debug_decl_type, |
| ... | @@ -1763,12 +1763,12 @@ pub const Object = struct { | ... | @@ -1763,12 +1763,12 @@ pub const Object = struct { |
| 1763 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { | 1763 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { |
| 1764 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { | 1764 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { |
| 1765 | if (!std.mem.eql(u8, lib_name, "c")) { | 1765 | if (!std.mem.eql(u8, lib_name, "c")) { |
| 1766 | break :decl_name try self.builder.fmt("{s}|{s}", .{ decl_name, lib_name }); | 1766 | break :decl_name try self.builder.strtabStringFmt("{s}|{s}", .{ decl_name, lib_name }); |
| 1767 | } | 1767 | } |
| 1768 | } | 1768 | } |
| 1769 | } | 1769 | } |
| 1770 | 1770 | ||
| 1771 | break :decl_name try self.builder.string(decl_name); | 1771 | break :decl_name try self.builder.strtabString(decl_name); |
| 1772 | }; | 1772 | }; |
| 1773 | 1773 | ||
| 1774 | if (self.builder.getGlobal(decl_name)) |other_global| { | 1774 | if (self.builder.getGlobal(decl_name)) |other_global| { |
| ... | @@ -1791,7 +1791,7 @@ pub const Object = struct { | ... | @@ -1791,7 +1791,7 @@ pub const Object = struct { |
| 1791 | if (decl_var.is_weak_linkage) global_index.setLinkage(.extern_weak, &self.builder); | 1791 | if (decl_var.is_weak_linkage) global_index.setLinkage(.extern_weak, &self.builder); |
| 1792 | } | 1792 | } |
| 1793 | } else if (exports.len != 0) { | 1793 | } else if (exports.len != 0) { |
| 1794 | const main_exp_name = try self.builder.string( | 1794 | const main_exp_name = try self.builder.strtabString( |
| 1795 | mod.intern_pool.stringToSlice(exports[0].opts.name), | 1795 | mod.intern_pool.stringToSlice(exports[0].opts.name), |
| 1796 | ); | 1796 | ); |
| 1797 | try global_index.rename(main_exp_name, &self.builder); | 1797 | try global_index.rename(main_exp_name, &self.builder); |
| ... | @@ -1802,7 +1802,7 @@ pub const Object = struct { | ... | @@ -1802,7 +1802,7 @@ pub const Object = struct { |
| 1802 | 1802 | ||
| 1803 | return updateExportedGlobal(self, mod, global_index, exports); | 1803 | return updateExportedGlobal(self, mod, global_index, exports); |
| 1804 | } else { | 1804 | } else { |
| 1805 | const fqn = try self.builder.string( | 1805 | const fqn = try self.builder.strtabString( |
| 1806 | mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod)), | 1806 | mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod)), |
| 1807 | ); | 1807 | ); |
| 1808 | try global_index.rename(fqn, &self.builder); | 1808 | try global_index.rename(fqn, &self.builder); |
| ... | @@ -1831,7 +1831,7 @@ pub const Object = struct { | ... | @@ -1831,7 +1831,7 @@ pub const Object = struct { |
| 1831 | exports: []const *Module.Export, | 1831 | exports: []const *Module.Export, |
| 1832 | ) link.File.UpdateExportsError!void { | 1832 | ) link.File.UpdateExportsError!void { |
| 1833 | const gpa = mod.gpa; | 1833 | const gpa = mod.gpa; |
| 1834 | const main_exp_name = try o.builder.string( | 1834 | const main_exp_name = try o.builder.strtabString( |
| 1835 | mod.intern_pool.stringToSlice(exports[0].opts.name), | 1835 | mod.intern_pool.stringToSlice(exports[0].opts.name), |
| 1836 | ); | 1836 | ); |
| 1837 | const global_index = i: { | 1837 | const global_index = i: { |
| ... | @@ -1899,7 +1899,7 @@ pub const Object = struct { | ... | @@ -1899,7 +1899,7 @@ pub const Object = struct { |
| 1899 | // Until then we iterate over existing aliases and make them point | 1899 | // Until then we iterate over existing aliases and make them point |
| 1900 | // to the correct decl, or otherwise add a new alias. Old aliases are leaked. | 1900 | // to the correct decl, or otherwise add a new alias. Old aliases are leaked. |
| 1901 | for (exports[1..]) |exp| { | 1901 | for (exports[1..]) |exp| { |
| 1902 | const exp_name = try o.builder.string(mod.intern_pool.stringToSlice(exp.opts.name)); | 1902 | const exp_name = try o.builder.strtabString(mod.intern_pool.stringToSlice(exp.opts.name)); |
| 1903 | if (o.builder.getGlobal(exp_name)) |global| { | 1903 | if (o.builder.getGlobal(exp_name)) |global| { |
| 1904 | switch (global.ptrConst(&o.builder).kind) { | 1904 | switch (global.ptrConst(&o.builder).kind) { |
| 1905 | .alias => |alias| { | 1905 | .alias => |alias| { |
| ... | @@ -2887,7 +2887,7 @@ pub const Object = struct { | ... | @@ -2887,7 +2887,7 @@ pub const Object = struct { |
| 2887 | const is_extern = decl.isExtern(zcu); | 2887 | const is_extern = decl.isExtern(zcu); |
| 2888 | const function_index = try o.builder.addFunction( | 2888 | const function_index = try o.builder.addFunction( |
| 2889 | try o.lowerType(zig_fn_type), | 2889 | try o.lowerType(zig_fn_type), |
| 2890 | try o.builder.string(ip.stringToSlice(if (is_extern) | 2890 | try o.builder.strtabString(ip.stringToSlice(if (is_extern) |
| 2891 | decl.name | 2891 | decl.name |
| 2892 | else | 2892 | else |
| 2893 | try decl.fullyQualifiedName(zcu))), | 2893 | try decl.fullyQualifiedName(zcu))), |
| ... | @@ -3077,7 +3077,7 @@ pub const Object = struct { | ... | @@ -3077,7 +3077,7 @@ pub const Object = struct { |
| 3077 | const decl_ty = mod.intern_pool.typeOf(decl_val); | 3077 | const decl_ty = mod.intern_pool.typeOf(decl_val); |
| 3078 | 3078 | ||
| 3079 | const variable_index = try o.builder.addVariable( | 3079 | const variable_index = try o.builder.addVariable( |
| 3080 | try o.builder.fmt("__anon_{d}", .{@intFromEnum(decl_val)}), | 3080 | try o.builder.strtabStringFmt("__anon_{d}", .{@intFromEnum(decl_val)}), |
| 3081 | try o.lowerType(Type.fromInterned(decl_ty)), | 3081 | try o.lowerType(Type.fromInterned(decl_ty)), |
| 3082 | llvm_addr_space, | 3082 | llvm_addr_space, |
| 3083 | ); | 3083 | ); |
| ... | @@ -3103,7 +3103,7 @@ pub const Object = struct { | ... | @@ -3103,7 +3103,7 @@ pub const Object = struct { |
| 3103 | const is_extern = decl.isExtern(mod); | 3103 | const is_extern = decl.isExtern(mod); |
| 3104 | 3104 | ||
| 3105 | const variable_index = try o.builder.addVariable( | 3105 | const variable_index = try o.builder.addVariable( |
| 3106 | try o.builder.string(mod.intern_pool.stringToSlice( | 3106 | try o.builder.strtabString(mod.intern_pool.stringToSlice( |
| 3107 | if (is_extern) decl.name else try decl.fullyQualifiedName(mod), | 3107 | if (is_extern) decl.name else try decl.fullyQualifiedName(mod), |
| 3108 | )), | 3108 | )), |
| 3109 | try o.lowerType(decl.ty), | 3109 | try o.lowerType(decl.ty), |
| ... | @@ -4570,7 +4570,7 @@ pub const Object = struct { | ... | @@ -4570,7 +4570,7 @@ pub const Object = struct { |
| 4570 | } | 4570 | } |
| 4571 | 4571 | ||
| 4572 | fn getCmpLtErrorsLenFunction(o: *Object) !Builder.Function.Index { | 4572 | fn getCmpLtErrorsLenFunction(o: *Object) !Builder.Function.Index { |
| 4573 | const name = try o.builder.string(lt_errors_fn_name); | 4573 | const name = try o.builder.strtabString(lt_errors_fn_name); |
| 4574 | if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function; | 4574 | if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function; |
| 4575 | 4575 | ||
| 4576 | const zcu = o.module; | 4576 | const zcu = o.module; |
| ... | @@ -4607,7 +4607,7 @@ pub const Object = struct { | ... | @@ -4607,7 +4607,7 @@ pub const Object = struct { |
| 4607 | const target = zcu.root_mod.resolved_target.result; | 4607 | const target = zcu.root_mod.resolved_target.result; |
| 4608 | const function_index = try o.builder.addFunction( | 4608 | const function_index = try o.builder.addFunction( |
| 4609 | try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), | 4609 | try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), |
| 4610 | try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(ip)}), | 4610 | try o.builder.strtabStringFmt("__zig_tag_name_{}", .{fqn.fmt(ip)}), |
| 4611 | toLlvmAddressSpace(.generic, target), | 4611 | toLlvmAddressSpace(.generic, target), |
| 4612 | ); | 4612 | ); |
| 4613 | 4613 | ||
| ... | @@ -4730,7 +4730,7 @@ pub const DeclGen = struct { | ... | @@ -4730,7 +4730,7 @@ pub const DeclGen = struct { |
| 4730 | 4730 | ||
| 4731 | const debug_global_var = try o.builder.debugGlobalVar( | 4731 | const debug_global_var = try o.builder.debugGlobalVar( |
| 4732 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), // Name | 4732 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), // Name |
| 4733 | try o.builder.metadataStringFromString(variable_index.name(&o.builder)), // Linkage name | 4733 | try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name |
| 4734 | debug_file, // File | 4734 | debug_file, // File |
| 4735 | debug_file, // Scope | 4735 | debug_file, // Scope |
| 4736 | line_number, | 4736 | line_number, |
| ... | @@ -6169,7 +6169,7 @@ pub const FuncGen = struct { | ... | @@ -6169,7 +6169,7 @@ pub const FuncGen = struct { |
| 6169 | const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); | 6169 | const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); |
| 6170 | const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); | 6170 | const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); |
| 6171 | const sign_prefix = if (is_signed_int) "" else "un"; | 6171 | const sign_prefix = if (is_signed_int) "" else "un"; |
| 6172 | const fn_name = try o.builder.fmt("__float{s}{s}i{s}f", .{ | 6172 | const fn_name = try o.builder.strtabStringFmt("__float{s}{s}i{s}f", .{ |
| 6173 | sign_prefix, | 6173 | sign_prefix, |
| 6174 | compiler_rt_operand_abbrev, | 6174 | compiler_rt_operand_abbrev, |
| 6175 | compiler_rt_dest_abbrev, | 6175 | compiler_rt_dest_abbrev, |
| ... | @@ -6239,7 +6239,7 @@ pub const FuncGen = struct { | ... | @@ -6239,7 +6239,7 @@ pub const FuncGen = struct { |
| 6239 | const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); | 6239 | const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); |
| 6240 | const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns"; | 6240 | const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns"; |
| 6241 | 6241 | ||
| 6242 | const fn_name = try o.builder.fmt("__fix{s}{s}f{s}i", .{ | 6242 | const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{ |
| 6243 | sign_prefix, | 6243 | sign_prefix, |
| 6244 | compiler_rt_operand_abbrev, | 6244 | compiler_rt_operand_abbrev, |
| 6245 | compiler_rt_dest_abbrev, | 6245 | compiler_rt_dest_abbrev, |
| ... | @@ -6637,7 +6637,7 @@ pub const FuncGen = struct { | ... | @@ -6637,7 +6637,7 @@ pub const FuncGen = struct { |
| 6637 | .return_type = .void_type, | 6637 | .return_type = .void_type, |
| 6638 | }); | 6638 | }); |
| 6639 | 6639 | ||
| 6640 | const subprogram = try o.builder.debugSubprogram( | 6640 | self.scope = try o.builder.debugSubprogram( |
| 6641 | self.file, | 6641 | self.file, |
| 6642 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), | 6642 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), |
| 6643 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)), | 6643 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)), |
| ... | @@ -6655,13 +6655,6 @@ pub const FuncGen = struct { | ... | @@ -6655,13 +6655,6 @@ pub const FuncGen = struct { |
| 6655 | o.debug_compile_unit, | 6655 | o.debug_compile_unit, |
| 6656 | ); | 6656 | ); |
| 6657 | 6657 | ||
| 6658 | const lexical_block = try o.builder.debugLexicalBlock( | ||
| 6659 | subprogram, | ||
| 6660 | self.file, | ||
| 6661 | line_number, | ||
| 6662 | 1, | ||
| 6663 | ); | ||
| 6664 | self.scope = lexical_block; | ||
| 6665 | self.base_line = decl.src_line; | 6658 | self.base_line = decl.src_line; |
| 6666 | const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder); | 6659 | const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder); |
| 6667 | self.wip.debug_location = .{ | 6660 | self.wip.debug_location = .{ |
| ... | @@ -8117,7 +8110,7 @@ pub const FuncGen = struct { | ... | @@ -8117,7 +8110,7 @@ pub const FuncGen = struct { |
| 8117 | 8110 | ||
| 8118 | fn getLibcFunction( | 8111 | fn getLibcFunction( |
| 8119 | self: *FuncGen, | 8112 | self: *FuncGen, |
| 8120 | fn_name: Builder.String, | 8113 | fn_name: Builder.StrtabString, |
| 8121 | param_types: []const Builder.Type, | 8114 | param_types: []const Builder.Type, |
| 8122 | return_type: Builder.Type, | 8115 | return_type: Builder.Type, |
| 8123 | ) Allocator.Error!Builder.Function.Index { | 8116 | ) Allocator.Error!Builder.Function.Index { |
| ... | @@ -8171,7 +8164,7 @@ pub const FuncGen = struct { | ... | @@ -8171,7 +8164,7 @@ pub const FuncGen = struct { |
| 8171 | .gt => "gt", | 8164 | .gt => "gt", |
| 8172 | .gte => "ge", | 8165 | .gte => "ge", |
| 8173 | }; | 8166 | }; |
| 8174 | const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev }); | 8167 | const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev }); |
| 8175 | 8168 | ||
| 8176 | const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32); | 8169 | const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32); |
| 8177 | 8170 | ||
| ... | @@ -8329,7 +8322,7 @@ pub const FuncGen = struct { | ... | @@ -8329,7 +8322,7 @@ pub const FuncGen = struct { |
| 8329 | const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, ""); | 8322 | const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, ""); |
| 8330 | return self.wip.cast(.bitcast, result, llvm_ty, ""); | 8323 | return self.wip.cast(.bitcast, result, llvm_ty, ""); |
| 8331 | }, | 8324 | }, |
| 8332 | .add, .sub, .div, .mul => try o.builder.fmt("__{s}{s}f3", .{ | 8325 | .add, .sub, .div, .mul => try o.builder.strtabStringFmt("__{s}{s}f3", .{ |
| 8333 | @tagName(op), compilerRtFloatAbbrev(float_bits), | 8326 | @tagName(op), compilerRtFloatAbbrev(float_bits), |
| 8334 | }), | 8327 | }), |
| 8335 | .ceil, | 8328 | .ceil, |
| ... | @@ -8350,7 +8343,7 @@ pub const FuncGen = struct { | ... | @@ -8350,7 +8343,7 @@ pub const FuncGen = struct { |
| 8350 | .sqrt, | 8343 | .sqrt, |
| 8351 | .tan, | 8344 | .tan, |
| 8352 | .trunc, | 8345 | .trunc, |
| 8353 | => try o.builder.fmt("{s}{s}{s}", .{ | 8346 | => try o.builder.strtabStringFmt("{s}{s}{s}", .{ |
| 8354 | libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits), | 8347 | libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits), |
| 8355 | }), | 8348 | }), |
| 8356 | }; | 8349 | }; |
| ... | @@ -8614,7 +8607,7 @@ pub const FuncGen = struct { | ... | @@ -8614,7 +8607,7 @@ pub const FuncGen = struct { |
| 8614 | const operand_llvm_ty = try o.lowerType(operand_ty); | 8607 | const operand_llvm_ty = try o.lowerType(operand_ty); |
| 8615 | const dest_llvm_ty = try o.lowerType(dest_ty); | 8608 | const dest_llvm_ty = try o.lowerType(dest_ty); |
| 8616 | 8609 | ||
| 8617 | const fn_name = try o.builder.fmt("__trunc{s}f{s}f2", .{ | 8610 | const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{ |
| 8618 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | 8611 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 8619 | }); | 8612 | }); |
| 8620 | 8613 | ||
| ... | @@ -8648,7 +8641,7 @@ pub const FuncGen = struct { | ... | @@ -8648,7 +8641,7 @@ pub const FuncGen = struct { |
| 8648 | 8641 | ||
| 8649 | const dest_bits = dest_ty.scalarType(mod).floatBits(target); | 8642 | const dest_bits = dest_ty.scalarType(mod).floatBits(target); |
| 8650 | const src_bits = operand_ty.scalarType(mod).floatBits(target); | 8643 | const src_bits = operand_ty.scalarType(mod).floatBits(target); |
| 8651 | const fn_name = try o.builder.fmt("__extend{s}f{s}f2", .{ | 8644 | const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{ |
| 8652 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | 8645 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 8653 | }); | 8646 | }); |
| 8654 | 8647 | ||
| ... | @@ -9644,7 +9637,7 @@ pub const FuncGen = struct { | ... | @@ -9644,7 +9637,7 @@ pub const FuncGen = struct { |
| 9644 | const target = zcu.root_mod.resolved_target.result; | 9637 | const target = zcu.root_mod.resolved_target.result; |
| 9645 | const function_index = try o.builder.addFunction( | 9638 | const function_index = try o.builder.addFunction( |
| 9646 | try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), | 9639 | try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), |
| 9647 | try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}), | 9640 | try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}), |
| 9648 | toLlvmAddressSpace(.generic, target), | 9641 | toLlvmAddressSpace(.generic, target), |
| 9649 | ); | 9642 | ); |
| 9650 | 9643 | ||
| ... | @@ -9909,16 +9902,16 @@ pub const FuncGen = struct { | ... | @@ -9909,16 +9902,16 @@ pub const FuncGen = struct { |
| 9909 | // Use a manual loop over a softfloat call instead. | 9902 | // Use a manual loop over a softfloat call instead. |
| 9910 | const float_bits = scalar_ty.floatBits(target); | 9903 | const float_bits = scalar_ty.floatBits(target); |
| 9911 | const fn_name = switch (reduce.operation) { | 9904 | const fn_name = switch (reduce.operation) { |
| 9912 | .Min => try o.builder.fmt("{s}fmin{s}", .{ | 9905 | .Min => try o.builder.strtabStringFmt("{s}fmin{s}", .{ |
| 9913 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | 9906 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), |
| 9914 | }), | 9907 | }), |
| 9915 | .Max => try o.builder.fmt("{s}fmax{s}", .{ | 9908 | .Max => try o.builder.strtabStringFmt("{s}fmax{s}", .{ |
| 9916 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | 9909 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), |
| 9917 | }), | 9910 | }), |
| 9918 | .Add => try o.builder.fmt("__add{s}f3", .{ | 9911 | .Add => try o.builder.strtabStringFmt("__add{s}f3", .{ |
| 9919 | compilerRtFloatAbbrev(float_bits), | 9912 | compilerRtFloatAbbrev(float_bits), |
| 9920 | }), | 9913 | }), |
| 9921 | .Mul => try o.builder.fmt("__mul{s}f3", .{ | 9914 | .Mul => try o.builder.strtabStringFmt("__mul{s}f3", .{ |
| 9922 | compilerRtFloatAbbrev(float_bits), | 9915 | compilerRtFloatAbbrev(float_bits), |
| 9923 | }), | 9916 | }), |
| 9924 | else => unreachable, | 9917 | else => unreachable, |
| ... | @@ -10323,7 +10316,7 @@ pub const FuncGen = struct { | ... | @@ -10323,7 +10316,7 @@ pub const FuncGen = struct { |
| 10323 | 10316 | ||
| 10324 | // TODO: Address space | 10317 | // TODO: Address space |
| 10325 | const variable_index = | 10318 | const variable_index = |
| 10326 | try o.builder.addVariable(try o.builder.string("__zig_err_name_table"), .ptr, .default); | 10319 | try o.builder.addVariable(try o.builder.strtabString("__zig_err_name_table"), .ptr, .default); |
| 10327 | variable_index.setLinkage(.private, &o.builder); | 10320 | variable_index.setLinkage(.private, &o.builder); |
| 10328 | variable_index.setMutability(.constant, &o.builder); | 10321 | variable_index.setMutability(.constant, &o.builder); |
| 10329 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 10322 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
src/codegen/llvm/Builder.zig+174-50| ... | @@ -24,14 +24,18 @@ attributes_extra: std.ArrayListUnmanaged(u32), | ... | @@ -24,14 +24,18 @@ attributes_extra: std.ArrayListUnmanaged(u32), |
| 24 | 24 | ||
| 25 | function_attributes_set: std.AutoArrayHashMapUnmanaged(FunctionAttributes, void), | 25 | function_attributes_set: std.AutoArrayHashMapUnmanaged(FunctionAttributes, void), |
| 26 | 26 | ||
| 27 | globals: std.AutoArrayHashMapUnmanaged(String, Global), | 27 | globals: std.AutoArrayHashMapUnmanaged(StrtabString, Global), |
| 28 | next_unnamed_global: String, | 28 | next_unnamed_global: StrtabString, |
| 29 | next_replaced_global: String, | 29 | next_replaced_global: StrtabString, |
| 30 | next_unique_global_id: std.AutoHashMapUnmanaged(String, u32), | 30 | next_unique_global_id: std.AutoHashMapUnmanaged(StrtabString, u32), |
| 31 | aliases: std.ArrayListUnmanaged(Alias), | 31 | aliases: std.ArrayListUnmanaged(Alias), |
| 32 | variables: std.ArrayListUnmanaged(Variable), | 32 | variables: std.ArrayListUnmanaged(Variable), |
| 33 | functions: std.ArrayListUnmanaged(Function), | 33 | functions: std.ArrayListUnmanaged(Function), |
| 34 | 34 | ||
| 35 | strtab_string_map: std.AutoArrayHashMapUnmanaged(void, void), | ||
| 36 | strtab_string_indices: std.ArrayListUnmanaged(u32), | ||
| 37 | strtab_string_bytes: std.ArrayListUnmanaged(u8), | ||
| 38 | |||
| 35 | constant_map: std.AutoArrayHashMapUnmanaged(void, void), | 39 | constant_map: std.AutoArrayHashMapUnmanaged(void, void), |
| 36 | constant_items: std.MultiArrayList(Constant.Item), | 40 | constant_items: std.MultiArrayList(Constant.Item), |
| 37 | constant_extra: std.ArrayListUnmanaged(u32), | 41 | constant_extra: std.ArrayListUnmanaged(u32), |
| ... | @@ -194,11 +198,6 @@ pub const CmpPredicate = enum(u6) { | ... | @@ -194,11 +198,6 @@ pub const CmpPredicate = enum(u6) { |
| 194 | icmp_sle = 41, | 198 | icmp_sle = 41, |
| 195 | }; | 199 | }; |
| 196 | 200 | ||
| 197 | pub const StrtabString = struct { | ||
| 198 | offset: usize, | ||
| 199 | size: usize, | ||
| 200 | }; | ||
| 201 | |||
| 202 | pub const Type = enum(u32) { | 201 | pub const Type = enum(u32) { |
| 203 | void, | 202 | void, |
| 204 | half, | 203 | half, |
| ... | @@ -2136,6 +2135,122 @@ pub const CallConv = enum(u10) { | ... | @@ -2136,6 +2135,122 @@ pub const CallConv = enum(u10) { |
| 2136 | } | 2135 | } |
| 2137 | }; | 2136 | }; |
| 2138 | 2137 | ||
| 2138 | pub const StrtabString = enum(u32) { | ||
| 2139 | none = std.math.maxInt(u31), | ||
| 2140 | empty, | ||
| 2141 | _, | ||
| 2142 | |||
| 2143 | pub fn isAnon(self: StrtabString) bool { | ||
| 2144 | assert(self != .none); | ||
| 2145 | return self.toIndex() == null; | ||
| 2146 | } | ||
| 2147 | |||
| 2148 | pub fn slice(self: StrtabString, builder: *const Builder) ?[]const u8 { | ||
| 2149 | const index = self.toIndex() orelse return null; | ||
| 2150 | const start = builder.strtab_string_indices.items[index]; | ||
| 2151 | const end = builder.strtab_string_indices.items[index + 1]; | ||
| 2152 | return builder.strtab_string_bytes.items[start..end]; | ||
| 2153 | } | ||
| 2154 | |||
| 2155 | const FormatData = struct { | ||
| 2156 | string: StrtabString, | ||
| 2157 | builder: *const Builder, | ||
| 2158 | }; | ||
| 2159 | fn format( | ||
| 2160 | data: FormatData, | ||
| 2161 | comptime fmt_str: []const u8, | ||
| 2162 | _: std.fmt.FormatOptions, | ||
| 2163 | writer: anytype, | ||
| 2164 | ) @TypeOf(writer).Error!void { | ||
| 2165 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| | ||
| 2166 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); | ||
| 2167 | assert(data.string != .none); | ||
| 2168 | const string_slice = data.string.slice(data.builder) orelse | ||
| 2169 | return writer.print("{d}", .{@intFromEnum(data.string)}); | ||
| 2170 | if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_| | ||
| 2171 | return writer.writeAll(string_slice); | ||
| 2172 | try printEscapedString( | ||
| 2173 | string_slice, | ||
| 2174 | if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_| | ||
| 2175 | .always_quote | ||
| 2176 | else | ||
| 2177 | .quote_unless_valid_identifier, | ||
| 2178 | writer, | ||
| 2179 | ); | ||
| 2180 | } | ||
| 2181 | pub fn fmt(self: StrtabString, builder: *const Builder) std.fmt.Formatter(format) { | ||
| 2182 | return .{ .data = .{ .string = self, .builder = builder } }; | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | fn fromIndex(index: ?usize) StrtabString { | ||
| 2186 | return @enumFromInt(@as(u32, @intCast((index orelse return .none) + | ||
| 2187 | @intFromEnum(StrtabString.empty)))); | ||
| 2188 | } | ||
| 2189 | |||
| 2190 | fn toIndex(self: StrtabString) ?usize { | ||
| 2191 | return std.math.sub(u32, @intFromEnum(self), @intFromEnum(StrtabString.empty)) catch null; | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | const Adapter = struct { | ||
| 2195 | builder: *const Builder, | ||
| 2196 | pub fn hash(_: Adapter, key: []const u8) u32 { | ||
| 2197 | return @truncate(std.hash.Wyhash.hash(0, key)); | ||
| 2198 | } | ||
| 2199 | pub fn eql(ctx: Adapter, lhs_key: []const u8, _: void, rhs_index: usize) bool { | ||
| 2200 | return std.mem.eql(u8, lhs_key, StrtabString.fromIndex(rhs_index).slice(ctx.builder).?); | ||
| 2201 | } | ||
| 2202 | }; | ||
| 2203 | }; | ||
| 2204 | |||
| 2205 | pub fn strtabString(self: *Builder, bytes: []const u8) Allocator.Error!StrtabString { | ||
| 2206 | try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, bytes.len); | ||
| 2207 | try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1); | ||
| 2208 | try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1); | ||
| 2209 | |||
| 2210 | const gop = self.strtab_string_map.getOrPutAssumeCapacityAdapted(bytes, StrtabString.Adapter{ .builder = self }); | ||
| 2211 | if (!gop.found_existing) { | ||
| 2212 | self.strtab_string_bytes.appendSliceAssumeCapacity(bytes); | ||
| 2213 | self.strtab_string_indices.appendAssumeCapacity(@intCast(self.strtab_string_bytes.items.len)); | ||
| 2214 | } | ||
| 2215 | return StrtabString.fromIndex(gop.index); | ||
| 2216 | } | ||
| 2217 | |||
| 2218 | pub fn strtabStringIfExists(self: *const Builder, bytes: []const u8) ?StrtabString { | ||
| 2219 | return StrtabString.fromIndex( | ||
| 2220 | self.strtab_string_map.getIndexAdapted(bytes, StrtabString.Adapter{ .builder = self }) orelse return null, | ||
| 2221 | ); | ||
| 2222 | } | ||
| 2223 | |||
| 2224 | pub fn strtabStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!StrtabString { | ||
| 2225 | try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1); | ||
| 2226 | try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str, fmt_args))); | ||
| 2227 | try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1); | ||
| 2228 | return self.strtabStringFmtAssumeCapacity(fmt_str, fmt_args); | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | pub fn strtabStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) StrtabString { | ||
| 2232 | self.strtab_string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable; | ||
| 2233 | return self.trailingStrtabStringAssumeCapacity(); | ||
| 2234 | } | ||
| 2235 | |||
| 2236 | pub fn trailingStrtabString(self: *Builder) Allocator.Error!StrtabString { | ||
| 2237 | try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1); | ||
| 2238 | try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1); | ||
| 2239 | return self.trailingStrtabStringAssumeCapacity(); | ||
| 2240 | } | ||
| 2241 | |||
| 2242 | pub fn trailingStrtabStringAssumeCapacity(self: *Builder) StrtabString { | ||
| 2243 | const start = self.strtab_string_indices.getLast(); | ||
| 2244 | const bytes: []const u8 = self.strtab_string_bytes.items[start..]; | ||
| 2245 | const gop = self.strtab_string_map.getOrPutAssumeCapacityAdapted(bytes, StrtabString.Adapter{ .builder = self }); | ||
| 2246 | if (gop.found_existing) { | ||
| 2247 | self.strtab_string_bytes.shrinkRetainingCapacity(start); | ||
| 2248 | } else { | ||
| 2249 | self.strtab_string_indices.appendAssumeCapacity(@intCast(self.strtab_string_bytes.items.len)); | ||
| 2250 | } | ||
| 2251 | return StrtabString.fromIndex(gop.index); | ||
| 2252 | } | ||
| 2253 | |||
| 2139 | pub const Global = struct { | 2254 | pub const Global = struct { |
| 2140 | linkage: Linkage = .external, | 2255 | linkage: Linkage = .external, |
| 2141 | preemption: Preemption = .dso_preemptable, | 2256 | preemption: Preemption = .dso_preemptable, |
| ... | @@ -2179,19 +2294,23 @@ pub const Global = struct { | ... | @@ -2179,19 +2294,23 @@ pub const Global = struct { |
| 2179 | return &builder.globals.values()[@intFromEnum(self.unwrap(builder))]; | 2294 | return &builder.globals.values()[@intFromEnum(self.unwrap(builder))]; |
| 2180 | } | 2295 | } |
| 2181 | 2296 | ||
| 2182 | pub fn name(self: Index, builder: *const Builder) String { | 2297 | pub fn name(self: Index, builder: *const Builder) StrtabString { |
| 2183 | return builder.globals.keys()[@intFromEnum(self.unwrap(builder))]; | 2298 | return builder.globals.keys()[@intFromEnum(self.unwrap(builder))]; |
| 2184 | } | 2299 | } |
| 2185 | 2300 | ||
| 2186 | pub fn strtab(self: Index, builder: *const Builder) StrtabString { | 2301 | pub fn strtab(self: Index, builder: *const Builder) struct { |
| 2302 | offset: u32, | ||
| 2303 | size: u32, | ||
| 2304 | } { | ||
| 2187 | const name_index = self.name(builder).toIndex() orelse return .{ | 2305 | const name_index = self.name(builder).toIndex() orelse return .{ |
| 2188 | .offset = 0, | 2306 | .offset = 0, |
| 2189 | .size = 0, | 2307 | .size = 0, |
| 2190 | }; | 2308 | }; |
| 2191 | 2309 | ||
| 2192 | return .{ | 2310 | return .{ |
| 2193 | .offset = builder.string_indices.items[name_index], | 2311 | .offset = builder.strtab_string_indices.items[name_index], |
| 2194 | .size = builder.string_indices.items[name_index + 1] - builder.string_indices.items[name_index], | 2312 | .size = builder.strtab_string_indices.items[name_index + 1] - |
| 2313 | builder.strtab_string_indices.items[name_index], | ||
| 2195 | }; | 2314 | }; |
| 2196 | } | 2315 | } |
| 2197 | 2316 | ||
| ... | @@ -2243,7 +2362,7 @@ pub const Global = struct { | ... | @@ -2243,7 +2362,7 @@ pub const Global = struct { |
| 2243 | return .{ .data = .{ .global = self, .builder = builder } }; | 2362 | return .{ .data = .{ .global = self, .builder = builder } }; |
| 2244 | } | 2363 | } |
| 2245 | 2364 | ||
| 2246 | pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void { | 2365 | pub fn rename(self: Index, new_name: StrtabString, builder: *Builder) Allocator.Error!void { |
| 2247 | try builder.ensureUnusedGlobalCapacity(new_name); | 2366 | try builder.ensureUnusedGlobalCapacity(new_name); |
| 2248 | self.renameAssumeCapacity(new_name, builder); | 2367 | self.renameAssumeCapacity(new_name, builder); |
| 2249 | } | 2368 | } |
| ... | @@ -2282,7 +2401,7 @@ pub const Global = struct { | ... | @@ -2282,7 +2401,7 @@ pub const Global = struct { |
| 2282 | } | 2401 | } |
| 2283 | } | 2402 | } |
| 2284 | 2403 | ||
| 2285 | fn renameAssumeCapacity(self: Index, new_name: String, builder: *Builder) void { | 2404 | fn renameAssumeCapacity(self: Index, new_name: StrtabString, builder: *Builder) void { |
| 2286 | const old_name = self.name(builder); | 2405 | const old_name = self.name(builder); |
| 2287 | if (new_name == old_name) return; | 2406 | if (new_name == old_name) return; |
| 2288 | const index = @intFromEnum(self.unwrap(builder)); | 2407 | const index = @intFromEnum(self.unwrap(builder)); |
| ... | @@ -2333,11 +2452,11 @@ pub const Alias = struct { | ... | @@ -2333,11 +2452,11 @@ pub const Alias = struct { |
| 2333 | return &builder.aliases.items[@intFromEnum(self)]; | 2452 | return &builder.aliases.items[@intFromEnum(self)]; |
| 2334 | } | 2453 | } |
| 2335 | 2454 | ||
| 2336 | pub fn name(self: Index, builder: *const Builder) String { | 2455 | pub fn name(self: Index, builder: *const Builder) StrtabString { |
| 2337 | return self.ptrConst(builder).global.name(builder); | 2456 | return self.ptrConst(builder).global.name(builder); |
| 2338 | } | 2457 | } |
| 2339 | 2458 | ||
| 2340 | pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void { | 2459 | pub fn rename(self: Index, new_name: StrtabString, builder: *Builder) Allocator.Error!void { |
| 2341 | return self.ptrConst(builder).global.rename(new_name, builder); | 2460 | return self.ptrConst(builder).global.rename(new_name, builder); |
| 2342 | } | 2461 | } |
| 2343 | 2462 | ||
| ... | @@ -2385,11 +2504,11 @@ pub const Variable = struct { | ... | @@ -2385,11 +2504,11 @@ pub const Variable = struct { |
| 2385 | return &builder.variables.items[@intFromEnum(self)]; | 2504 | return &builder.variables.items[@intFromEnum(self)]; |
| 2386 | } | 2505 | } |
| 2387 | 2506 | ||
| 2388 | pub fn name(self: Index, builder: *const Builder) String { | 2507 | pub fn name(self: Index, builder: *const Builder) StrtabString { |
| 2389 | return self.ptrConst(builder).global.name(builder); | 2508 | return self.ptrConst(builder).global.name(builder); |
| 2390 | } | 2509 | } |
| 2391 | 2510 | ||
| 2392 | pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void { | 2511 | pub fn rename(self: Index, new_name: StrtabString, builder: *Builder) Allocator.Error!void { |
| 2393 | return self.ptrConst(builder).global.rename(new_name, builder); | 2512 | return self.ptrConst(builder).global.rename(new_name, builder); |
| 2394 | } | 2513 | } |
| 2395 | 2514 | ||
| ... | @@ -3814,11 +3933,11 @@ pub const Function = struct { | ... | @@ -3814,11 +3933,11 @@ pub const Function = struct { |
| 3814 | return &builder.functions.items[@intFromEnum(self)]; | 3933 | return &builder.functions.items[@intFromEnum(self)]; |
| 3815 | } | 3934 | } |
| 3816 | 3935 | ||
| 3817 | pub fn name(self: Index, builder: *const Builder) String { | 3936 | pub fn name(self: Index, builder: *const Builder) StrtabString { |
| 3818 | return self.ptrConst(builder).global.name(builder); | 3937 | return self.ptrConst(builder).global.name(builder); |
| 3819 | } | 3938 | } |
| 3820 | 3939 | ||
| 3821 | pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void { | 3940 | pub fn rename(self: Index, new_name: StrtabString, builder: *Builder) Allocator.Error!void { |
| 3822 | return self.ptrConst(builder).global.rename(new_name, builder); | 3941 | return self.ptrConst(builder).global.rename(new_name, builder); |
| 3823 | } | 3942 | } |
| 3824 | 3943 | ||
| ... | @@ -8331,6 +8450,10 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8331,6 +8450,10 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8331 | .variables = .{}, | 8450 | .variables = .{}, |
| 8332 | .functions = .{}, | 8451 | .functions = .{}, |
| 8333 | 8452 | ||
| 8453 | .strtab_string_map = .{}, | ||
| 8454 | .strtab_string_indices = .{}, | ||
| 8455 | .strtab_string_bytes = .{}, | ||
| 8456 | |||
| 8334 | .constant_map = .{}, | 8457 | .constant_map = .{}, |
| 8335 | .constant_items = .{}, | 8458 | .constant_items = .{}, |
| 8336 | .constant_extra = .{}, | 8459 | .constant_extra = .{}, |
| ... | @@ -8351,6 +8474,9 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8351,6 +8474,9 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8351 | try self.string_indices.append(self.gpa, 0); | 8474 | try self.string_indices.append(self.gpa, 0); |
| 8352 | assert(try self.string("") == .empty); | 8475 | assert(try self.string("") == .empty); |
| 8353 | 8476 | ||
| 8477 | try self.strtab_string_indices.append(self.gpa, 0); | ||
| 8478 | assert(try self.strtabString("") == .empty); | ||
| 8479 | |||
| 8354 | if (options.name.len > 0) self.source_filename = try self.string(options.name); | 8480 | if (options.name.len > 0) self.source_filename = try self.string(options.name); |
| 8355 | 8481 | ||
| 8356 | if (options.triple.len > 0) { | 8482 | if (options.triple.len > 0) { |
| ... | @@ -8423,6 +8549,10 @@ pub fn clearAndFree(self: *Builder) void { | ... | @@ -8423,6 +8549,10 @@ pub fn clearAndFree(self: *Builder) void { |
| 8423 | for (self.functions.items) |*function| function.deinit(self.gpa); | 8549 | for (self.functions.items) |*function| function.deinit(self.gpa); |
| 8424 | self.functions.clearAndFree(self.gpa); | 8550 | self.functions.clearAndFree(self.gpa); |
| 8425 | 8551 | ||
| 8552 | self.strtab_string_map.clearAndFree(self.gpa); | ||
| 8553 | self.strtab_string_indices.clearAndFree(self.gpa); | ||
| 8554 | self.strtab_string_bytes.clearAndFree(self.gpa); | ||
| 8555 | |||
| 8426 | self.constant_map.clearAndFree(self.gpa); | 8556 | self.constant_map.clearAndFree(self.gpa); |
| 8427 | self.constant_items.shrinkAndFree(self.gpa, 0); | 8557 | self.constant_items.shrinkAndFree(self.gpa, 0); |
| 8428 | self.constant_extra.clearAndFree(self.gpa); | 8558 | self.constant_extra.clearAndFree(self.gpa); |
| ... | @@ -8467,6 +8597,10 @@ pub fn deinit(self: *Builder) void { | ... | @@ -8467,6 +8597,10 @@ pub fn deinit(self: *Builder) void { |
| 8467 | for (self.functions.items) |*function| function.deinit(self.gpa); | 8597 | for (self.functions.items) |*function| function.deinit(self.gpa); |
| 8468 | self.functions.deinit(self.gpa); | 8598 | self.functions.deinit(self.gpa); |
| 8469 | 8599 | ||
| 8600 | self.strtab_string_map.deinit(self.gpa); | ||
| 8601 | self.strtab_string_indices.deinit(self.gpa); | ||
| 8602 | self.strtab_string_bytes.deinit(self.gpa); | ||
| 8603 | |||
| 8470 | self.constant_map.deinit(self.gpa); | 8604 | self.constant_map.deinit(self.gpa); |
| 8471 | self.constant_items.deinit(self.gpa); | 8605 | self.constant_items.deinit(self.gpa); |
| 8472 | self.constant_extra.deinit(self.gpa); | 8606 | self.constant_extra.deinit(self.gpa); |
| ... | @@ -8660,14 +8794,14 @@ pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Erro | ... | @@ -8660,14 +8794,14 @@ pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Erro |
| 8660 | return function_attributes; | 8794 | return function_attributes; |
| 8661 | } | 8795 | } |
| 8662 | 8796 | ||
| 8663 | pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!Global.Index { | 8797 | pub fn addGlobal(self: *Builder, name: StrtabString, global: Global) Allocator.Error!Global.Index { |
| 8664 | assert(!name.isAnon()); | 8798 | assert(!name.isAnon()); |
| 8665 | try self.ensureUnusedTypeCapacity(1, NoExtra, 0); | 8799 | try self.ensureUnusedTypeCapacity(1, NoExtra, 0); |
| 8666 | try self.ensureUnusedGlobalCapacity(name); | 8800 | try self.ensureUnusedGlobalCapacity(name); |
| 8667 | return self.addGlobalAssumeCapacity(name, global); | 8801 | return self.addGlobalAssumeCapacity(name, global); |
| 8668 | } | 8802 | } |
| 8669 | 8803 | ||
| 8670 | pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Global.Index { | 8804 | pub fn addGlobalAssumeCapacity(self: *Builder, name: StrtabString, global: Global) Global.Index { |
| 8671 | _ = self.ptrTypeAssumeCapacity(global.addr_space); | 8805 | _ = self.ptrTypeAssumeCapacity(global.addr_space); |
| 8672 | var id = name; | 8806 | var id = name; |
| 8673 | if (name == .empty) { | 8807 | if (name == .empty) { |
| ... | @@ -8686,18 +8820,18 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo | ... | @@ -8686,18 +8820,18 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Glo |
| 8686 | 8820 | ||
| 8687 | const unique_gop = self.next_unique_global_id.getOrPutAssumeCapacity(name); | 8821 | const unique_gop = self.next_unique_global_id.getOrPutAssumeCapacity(name); |
| 8688 | if (!unique_gop.found_existing) unique_gop.value_ptr.* = 2; | 8822 | if (!unique_gop.found_existing) unique_gop.value_ptr.* = 2; |
| 8689 | id = self.fmtAssumeCapacity("{s}.{d}", .{ name.slice(self).?, unique_gop.value_ptr.* }); | 8823 | id = self.strtabStringFmtAssumeCapacity("{s}.{d}", .{ name.slice(self).?, unique_gop.value_ptr.* }); |
| 8690 | unique_gop.value_ptr.* += 1; | 8824 | unique_gop.value_ptr.* += 1; |
| 8691 | } | 8825 | } |
| 8692 | } | 8826 | } |
| 8693 | 8827 | ||
| 8694 | pub fn getGlobal(self: *const Builder, name: String) ?Global.Index { | 8828 | pub fn getGlobal(self: *const Builder, name: StrtabString) ?Global.Index { |
| 8695 | return @enumFromInt(self.globals.getIndex(name) orelse return null); | 8829 | return @enumFromInt(self.globals.getIndex(name) orelse return null); |
| 8696 | } | 8830 | } |
| 8697 | 8831 | ||
| 8698 | pub fn addAlias( | 8832 | pub fn addAlias( |
| 8699 | self: *Builder, | 8833 | self: *Builder, |
| 8700 | name: String, | 8834 | name: StrtabString, |
| 8701 | ty: Type, | 8835 | ty: Type, |
| 8702 | addr_space: AddrSpace, | 8836 | addr_space: AddrSpace, |
| 8703 | aliasee: Constant, | 8837 | aliasee: Constant, |
| ... | @@ -8711,7 +8845,7 @@ pub fn addAlias( | ... | @@ -8711,7 +8845,7 @@ pub fn addAlias( |
| 8711 | 8845 | ||
| 8712 | pub fn addAliasAssumeCapacity( | 8846 | pub fn addAliasAssumeCapacity( |
| 8713 | self: *Builder, | 8847 | self: *Builder, |
| 8714 | name: String, | 8848 | name: StrtabString, |
| 8715 | ty: Type, | 8849 | ty: Type, |
| 8716 | addr_space: AddrSpace, | 8850 | addr_space: AddrSpace, |
| 8717 | aliasee: Constant, | 8851 | aliasee: Constant, |
| ... | @@ -8727,7 +8861,7 @@ pub fn addAliasAssumeCapacity( | ... | @@ -8727,7 +8861,7 @@ pub fn addAliasAssumeCapacity( |
| 8727 | 8861 | ||
| 8728 | pub fn addVariable( | 8862 | pub fn addVariable( |
| 8729 | self: *Builder, | 8863 | self: *Builder, |
| 8730 | name: String, | 8864 | name: StrtabString, |
| 8731 | ty: Type, | 8865 | ty: Type, |
| 8732 | addr_space: AddrSpace, | 8866 | addr_space: AddrSpace, |
| 8733 | ) Allocator.Error!Variable.Index { | 8867 | ) Allocator.Error!Variable.Index { |
| ... | @@ -8741,7 +8875,7 @@ pub fn addVariable( | ... | @@ -8741,7 +8875,7 @@ pub fn addVariable( |
| 8741 | pub fn addVariableAssumeCapacity( | 8875 | pub fn addVariableAssumeCapacity( |
| 8742 | self: *Builder, | 8876 | self: *Builder, |
| 8743 | ty: Type, | 8877 | ty: Type, |
| 8744 | name: String, | 8878 | name: StrtabString, |
| 8745 | addr_space: AddrSpace, | 8879 | addr_space: AddrSpace, |
| 8746 | ) Variable.Index { | 8880 | ) Variable.Index { |
| 8747 | const variable_index: Variable.Index = @enumFromInt(self.variables.items.len); | 8881 | const variable_index: Variable.Index = @enumFromInt(self.variables.items.len); |
| ... | @@ -8756,7 +8890,7 @@ pub fn addVariableAssumeCapacity( | ... | @@ -8756,7 +8890,7 @@ pub fn addVariableAssumeCapacity( |
| 8756 | pub fn addFunction( | 8890 | pub fn addFunction( |
| 8757 | self: *Builder, | 8891 | self: *Builder, |
| 8758 | ty: Type, | 8892 | ty: Type, |
| 8759 | name: String, | 8893 | name: StrtabString, |
| 8760 | addr_space: AddrSpace, | 8894 | addr_space: AddrSpace, |
| 8761 | ) Allocator.Error!Function.Index { | 8895 | ) Allocator.Error!Function.Index { |
| 8762 | assert(!name.isAnon()); | 8896 | assert(!name.isAnon()); |
| ... | @@ -8769,7 +8903,7 @@ pub fn addFunction( | ... | @@ -8769,7 +8903,7 @@ pub fn addFunction( |
| 8769 | pub fn addFunctionAssumeCapacity( | 8903 | pub fn addFunctionAssumeCapacity( |
| 8770 | self: *Builder, | 8904 | self: *Builder, |
| 8771 | ty: Type, | 8905 | ty: Type, |
| 8772 | name: String, | 8906 | name: StrtabString, |
| 8773 | addr_space: AddrSpace, | 8907 | addr_space: AddrSpace, |
| 8774 | ) Function.Index { | 8908 | ) Function.Index { |
| 8775 | assert(ty.isFunction(self)); | 8909 | assert(ty.isFunction(self)); |
| ... | @@ -8803,10 +8937,10 @@ pub fn getIntrinsic( | ... | @@ -8803,10 +8937,10 @@ pub fn getIntrinsic( |
| 8803 | const allocator = stack.get(); | 8937 | const allocator = stack.get(); |
| 8804 | 8938 | ||
| 8805 | const name = name: { | 8939 | const name = name: { |
| 8806 | const writer = self.string_bytes.writer(self.gpa); | 8940 | const writer = self.strtab_string_bytes.writer(self.gpa); |
| 8807 | try writer.print("llvm.{s}", .{@tagName(id)}); | 8941 | try writer.print("llvm.{s}", .{@tagName(id)}); |
| 8808 | for (overload) |ty| try writer.print(".{m}", .{ty.fmt(self)}); | 8942 | for (overload) |ty| try writer.print(".{m}", .{ty.fmt(self)}); |
| 8809 | break :name try self.trailingString(); | 8943 | break :name try self.trailingStrtabString(); |
| 8810 | }; | 8944 | }; |
| 8811 | if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function; | 8945 | if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function; |
| 8812 | 8946 | ||
| ... | @@ -10366,13 +10500,13 @@ fn printEscapedString( | ... | @@ -10366,13 +10500,13 @@ fn printEscapedString( |
| 10366 | if (need_quotes) try writer.writeByte('"'); | 10500 | if (need_quotes) try writer.writeByte('"'); |
| 10367 | } | 10501 | } |
| 10368 | 10502 | ||
| 10369 | fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void { | 10503 | fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void { |
| 10370 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); | 10504 | try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1); |
| 10371 | if (name.slice(self)) |id| { | 10505 | if (name.slice(self)) |id| { |
| 10372 | const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)}); | 10506 | const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)}); |
| 10373 | try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count); | 10507 | try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, id.len + count); |
| 10374 | } | 10508 | } |
| 10375 | try self.string_indices.ensureUnusedCapacity(self.gpa, 1); | 10509 | try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1); |
| 10376 | try self.globals.ensureUnusedCapacity(self.gpa, 1); | 10510 | try self.globals.ensureUnusedCapacity(self.gpa, 1); |
| 10377 | try self.next_unique_global_id.ensureUnusedCapacity(self.gpa, 1); | 10511 | try self.next_unique_global_id.ensureUnusedCapacity(self.gpa, 1); |
| 10378 | } | 10512 | } |
| ... | @@ -11893,7 +12027,7 @@ pub fn metadataString(self: *Builder, bytes: []const u8) Allocator.Error!Metadat | ... | @@ -11893,7 +12027,7 @@ pub fn metadataString(self: *Builder, bytes: []const u8) Allocator.Error!Metadat |
| 11893 | return @enumFromInt(gop.index); | 12027 | return @enumFromInt(gop.index); |
| 11894 | } | 12028 | } |
| 11895 | 12029 | ||
| 11896 | pub fn metadataStringFromString(self: *Builder, str: String) Allocator.Error!MetadataString { | 12030 | pub fn metadataStringFromStrtabString(self: *Builder, str: StrtabString) Allocator.Error!MetadataString { |
| 11897 | if (str == .none or str == .empty) return MetadataString.none; | 12031 | if (str == .none or str == .empty) return MetadataString.none; |
| 11898 | return try self.metadataString(str.slice(self).?); | 12032 | return try self.metadataString(str.slice(self).?); |
| 11899 | } | 12033 | } |
| ... | @@ -14045,17 +14179,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -14045,17 +14179,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 14045 | try bitcode.writeVBR(@as(u32, @intCast(slice.len)), 6); | 14179 | try bitcode.writeVBR(@as(u32, @intCast(slice.len)), 6); |
| 14046 | } | 14180 | } |
| 14047 | 14181 | ||
| 14048 | try bitcode.alignTo32(); | 14182 | try bitcode.writeBlob(self.metadata_string_bytes.items); |
| 14049 | |||
| 14050 | for (1..self.metadata_string_map.count()) |metadata_string_index| { | ||
| 14051 | const metadata_string: MetadataString = @enumFromInt(metadata_string_index); | ||
| 14052 | const slice = metadata_string.slice(self); | ||
| 14053 | for (slice) |c| { | ||
| 14054 | try bitcode.writeBits(c, 8); | ||
| 14055 | } | ||
| 14056 | } | ||
| 14057 | |||
| 14058 | try bitcode.alignTo32(); | ||
| 14059 | } | 14183 | } |
| 14060 | 14184 | ||
| 14061 | for ( | 14185 | for ( |
| ... | @@ -15069,7 +15193,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -15069,7 +15193,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 15069 | const Strtab = ir.Strtab; | 15193 | const Strtab = ir.Strtab; |
| 15070 | var strtab_block = try bitcode.enterTopBlock(Strtab); | 15194 | var strtab_block = try bitcode.enterTopBlock(Strtab); |
| 15071 | 15195 | ||
| 15072 | try strtab_block.writeAbbrev(Strtab.Blob{ .blob = self.string_bytes.items }); | 15196 | try strtab_block.writeAbbrev(Strtab.Blob{ .blob = self.strtab_string_bytes.items }); |
| 15073 | 15197 | ||
| 15074 | try strtab_block.end(); | 15198 | try strtab_block.end(); |
| 15075 | } | 15199 | } |
src/codegen/llvm/bitcode_writer.zig+12-5| ... | @@ -139,6 +139,17 @@ pub fn BitcodeWriter(comptime types: []const type) type { | ... | @@ -139,6 +139,17 @@ pub fn BitcodeWriter(comptime types: []const type) type { |
| 139 | try self.writeBits(charTo6Bit(c), 6); | 139 | try self.writeBits(charTo6Bit(c), 6); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | pub fn writeBlob(self: *BcWriter, blob: []const u8) Error!void { | ||
| 143 | const blob_word_size = std.mem.alignForward(usize, blob.len, 4); | ||
| 144 | try self.buffer.ensureUnusedCapacity(blob_word_size + 1); | ||
| 145 | self.alignTo32() catch unreachable; | ||
| 146 | |||
| 147 | const slice = self.buffer.addManyAsSliceAssumeCapacity(blob_word_size / 4); | ||
| 148 | const slice_bytes = std.mem.sliceAsBytes(slice); | ||
| 149 | @memcpy(slice_bytes[0..blob.len], blob); | ||
| 150 | @memset(slice_bytes[blob.len..], 0); | ||
| 151 | } | ||
| 152 | |||
| 142 | pub fn alignTo32(self: *BcWriter) Error!void { | 153 | pub fn alignTo32(self: *BcWriter) Error!void { |
| 143 | if (self.bit_count == 0) return; | 154 | if (self.bit_count == 0) return; |
| 144 | 155 | ||
| ... | @@ -256,11 +267,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { | ... | @@ -256,11 +267,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { |
| 256 | .char6 => try self.bitcode.write6BitChar(adapter.get(param, field_name)), | 267 | .char6 => try self.bitcode.write6BitChar(adapter.get(param, field_name)), |
| 257 | .blob => { | 268 | .blob => { |
| 258 | try self.bitcode.writeVBR(param.len, 6); | 269 | try self.bitcode.writeVBR(param.len, 6); |
| 259 | try self.bitcode.alignTo32(); | 270 | try self.bitcode.writeBlob(param); |
| 260 | for (param) |x| { | ||
| 261 | try self.bitcode.writeBits(x, 8); | ||
| 262 | } | ||
| 263 | try self.bitcode.alignTo32(); | ||
| 264 | }, | 271 | }, |
| 265 | .array_fixed => |len| { | 272 | .array_fixed => |len| { |
| 266 | try self.bitcode.writeVBR(param.len, 6); | 273 | try self.bitcode.writeVBR(param.len, 6); |