authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-10 20:30:15-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
log7ec7fe53597a70a3f2c9f040d7da978ae3a52a6b
treed5a50df9e0d541a0300967b3d1a02752f35b6054
parentff8a49448c70ffe73826c7987522ed63fddd654f

llvm: cleanup init


2 files changed, 259 insertions(+), 223 deletions(-)

src/codegen/llvm.zig+129-157
...@@ -35,7 +35,7 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;...@@ -35,7 +35,7 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
3535
36const Error = error{ OutOfMemory, CodegenFail };36const Error = error{ OutOfMemory, CodegenFail };
3737
38pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {38pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
39 var llvm_triple = std.ArrayList(u8).init(allocator);39 var llvm_triple = std.ArrayList(u8).init(allocator);
40 defer llvm_triple.deinit();40 defer llvm_triple.deinit();
4141
...@@ -208,7 +208,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {...@@ -208,7 +208,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
208 };208 };
209 try llvm_triple.appendSlice(llvm_abi);209 try llvm_triple.appendSlice(llvm_abi);
210210
211 return llvm_triple.toOwnedSliceSentinel(0);211 return llvm_triple.toOwnedSlice();
212}212}
213213
214pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {214pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
...@@ -602,160 +602,137 @@ pub const Object = struct {...@@ -602,160 +602,137 @@ pub const Object = struct {
602 }602 }
603603
604 pub fn init(gpa: Allocator, options: link.Options) !Object {604 pub fn init(gpa: Allocator, options: link.Options) !Object {
605 var builder = Builder{
606 .gpa = gpa,
607 .use_lib_llvm = options.use_lib_llvm,
608
609 .llvm_context = llvm.Context.create(),
610 .llvm_module = undefined,
611 };
612 errdefer builder.llvm_context.dispose();
613
614 builder.initializeLLVMTarget(options.target.cpu.arch);
615
616 builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context);
617 errdefer builder.llvm_module.dispose();
618
619 const llvm_target_triple = try targetTriple(gpa, options.target);605 const llvm_target_triple = try targetTriple(gpa, options.target);
620 defer gpa.free(llvm_target_triple);606 defer gpa.free(llvm_target_triple);
621607
622 var error_message: [*:0]const u8 = undefined;608 var builder = try Builder.init(.{
623 var target: *llvm.Target = undefined;609 .allocator = gpa,
624 if (llvm.Target.getFromTriple(llvm_target_triple.ptr, &target, &error_message).toBool()) {610 .use_lib_llvm = options.use_lib_llvm,
625 defer llvm.disposeMessage(error_message);611 .name = options.root_name,
626612 .target = options.target,
627 log.err("LLVM failed to parse '{s}': {s}", .{ llvm_target_triple, error_message });613 .triple = llvm_target_triple,
628 return error.InvalidLlvmTriple;614 });
629 }615 errdefer builder.deinit();
630
631 builder.llvm_module.setTarget(llvm_target_triple.ptr);
632 var opt_di_builder: ?*llvm.DIBuilder = null;
633 errdefer if (opt_di_builder) |di_builder| di_builder.dispose();
634616
635 var di_compile_unit: ?*llvm.DICompileUnit = null;617 var target_machine: *llvm.TargetMachine = undefined;
618 var target_data: *llvm.TargetData = undefined;
619 if (builder.useLibLlvm()) {
620 if (!options.strip) {
621 switch (options.target.ofmt) {
622 .coff => builder.llvm.module.?.addModuleCodeViewFlag(),
623 else => builder.llvm.module.?.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
624 }
625 builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true);
626
627 // Don't use the version string here; LLVM misparses it when it
628 // includes the git revision.
629 const producer = try builder.fmt("zig {d}.{d}.{d}", .{
630 build_options.semver.major,
631 build_options.semver.minor,
632 build_options.semver.patch,
633 });
636634
637 if (!options.strip) {635 // We fully resolve all paths at this point to avoid lack of source line info in stack
638 switch (options.target.ofmt) {636 // traces or lack of debugging information which, if relative paths were used, would
639 .coff => builder.llvm_module.addModuleCodeViewFlag(),637 // be very location dependent.
640 else => builder.llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),638 // TODO: the only concern I have with this is WASI as either host or target, should
641 }639 // we leave the paths as relative then?
642 const di_builder = builder.llvm_module.createDIBuilder(true);640 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
643 opt_di_builder = di_builder;641 const compile_unit_dir = blk: {
644642 const path = d: {
645 // Don't use the version string here; LLVM misparses it when it643 const mod = options.module orelse break :d ".";
646 // includes the git revision.644 break :d mod.root_pkg.root_src_directory.path orelse ".";
647 const producer = try std.fmt.allocPrintZ(gpa, "zig {d}.{d}.{d}", .{645 };
648 build_options.semver.major,646 if (std.fs.path.isAbsolute(path)) break :blk path;
649 build_options.semver.minor,647 break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was
650 build_options.semver.patch,
651 });
652 defer gpa.free(producer);
653
654 // We fully resolve all paths at this point to avoid lack of source line info in stack
655 // traces or lack of debugging information which, if relative paths were used, would
656 // be very location dependent.
657 // TODO: the only concern I have with this is WASI as either host or target, should
658 // we leave the paths as relative then?
659 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
660 const compile_unit_dir = blk: {
661 const path = d: {
662 const mod = options.module orelse break :d ".";
663 break :d mod.root_pkg.root_src_directory.path orelse ".";
664 };648 };
665 if (std.fs.path.isAbsolute(path)) break :blk path;649 const compile_unit_dir_z = try builder.gpa.dupeZ(u8, compile_unit_dir);
666 break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was650 defer builder.gpa.free(compile_unit_dir_z);
667 };651
668 const compile_unit_dir_z = try gpa.dupeZ(u8, compile_unit_dir);652 builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit(
669 defer gpa.free(compile_unit_dir_z);653 DW.LANG.C99,
670654 builder.llvm.di_builder.?.createFile(options.root_name, compile_unit_dir_z),
671 di_compile_unit = di_builder.createCompileUnit(655 producer.toSlice(&builder).?,
672 DW.LANG.C99,656 options.optimize_mode != .Debug,
673 di_builder.createFile(options.root_name, compile_unit_dir_z),657 "", // flags
674 producer,658 0, // runtime version
675 options.optimize_mode != .Debug,659 "", // split name
676 "", // flags660 0, // dwo id
677 0, // runtime version661 true, // emit debug info
678 "", // split name662 );
679 0, // dwo id663 }
680 true, // emit debug info
681 );
682 }
683
684 const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug)
685 .None
686 else
687 .Aggressive;
688664
689 const reloc_mode: llvm.RelocMode = if (options.pic)665 const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug)
690 .PIC666 .None
691 else if (options.link_mode == .Dynamic)667 else
692 llvm.RelocMode.DynamicNoPIC668 .Aggressive;
693 else
694 .Static;
695
696 const code_model: llvm.CodeModel = switch (options.machine_code_model) {
697 .default => .Default,
698 .tiny => .Tiny,
699 .small => .Small,
700 .kernel => .Kernel,
701 .medium => .Medium,
702 .large => .Large,
703 };
704669
705 // TODO handle float ABI better- it should depend on the ABI portion of std.Target670 const reloc_mode: llvm.RelocMode = if (options.pic)
706 const float_abi: llvm.ABIType = .Default;671 .PIC
707672 else if (options.link_mode == .Dynamic)
708 const target_machine = llvm.TargetMachine.create(673 llvm.RelocMode.DynamicNoPIC
709 target,674 else
710 llvm_target_triple.ptr,675 .Static;
711 if (options.target.cpu.model.llvm_name) |s| s.ptr else null,676
712 options.llvm_cpu_features,677 const code_model: llvm.CodeModel = switch (options.machine_code_model) {
713 opt_level,678 .default => .Default,
714 reloc_mode,679 .tiny => .Tiny,
715 code_model,680 .small => .Small,
716 options.function_sections,681 .kernel => .Kernel,
717 float_abi,682 .medium => .Medium,
718 if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,683 .large => .Large,
719 );684 };
720 errdefer target_machine.dispose();
721685
722 const target_data = target_machine.createTargetDataLayout();686 // TODO handle float ABI better- it should depend on the ABI portion of std.Target
723 errdefer target_data.dispose();687 const float_abi: llvm.ABIType = .Default;
688
689 target_machine = llvm.TargetMachine.create(
690 builder.llvm.target.?,
691 builder.target_triple.toSlice(&builder).?.ptr,
692 if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
693 options.llvm_cpu_features,
694 opt_level,
695 reloc_mode,
696 code_model,
697 options.function_sections,
698 float_abi,
699 if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,
700 );
701 errdefer target_machine.dispose();
724702
725 builder.llvm_module.setModuleDataLayout(target_data);703 target_data = target_machine.createTargetDataLayout();
704 errdefer target_data.dispose();
726705
727 if (options.pic) builder.llvm_module.setModulePICLevel();706 builder.llvm.module.?.setModuleDataLayout(target_data);
728 if (options.pie) builder.llvm_module.setModulePIELevel();
729 if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model);
730707
731 if (options.opt_bisect_limit >= 0) {708 if (options.pic) builder.llvm.module.?.setModulePICLevel();
732 builder.llvm_context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));709 if (options.pie) builder.llvm.module.?.setModulePIELevel();
733 }710 if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model);
734711
735 try builder.init();712 if (options.opt_bisect_limit >= 0) {
736 errdefer builder.deinit();713 builder.llvm.context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
737 builder.source_filename = try builder.string(options.root_name);714 }
738 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }});
739 builder.target_triple = try builder.string(llvm_target_triple);
740715
741 if (std.debug.runtime_safety) {716 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }});
742 const rep = target_data.stringRep();717 if (std.debug.runtime_safety) {
743 defer llvm.disposeMessage(rep);718 const rep = target_data.stringRep();
744 std.testing.expectEqualStrings(719 defer llvm.disposeMessage(rep);
745 std.mem.span(rep),720 std.testing.expectEqualStrings(
746 builder.data_layout.toSlice(&builder).?,721 std.mem.span(rep),
747 ) catch unreachable;722 builder.data_layout.toSlice(&builder).?,
723 ) catch unreachable;
724 }
748 }725 }
749726
750 return Object{727 return .{
751 .gpa = gpa,728 .gpa = gpa,
752 .builder = builder,729 .builder = builder,
753 .module = options.module.?,730 .module = options.module.?,
754 .llvm_module = builder.llvm_module,731 .llvm_module = builder.llvm.module.?,
755 .di_map = .{},732 .di_map = .{},
756 .di_builder = opt_di_builder,733 .di_builder = builder.llvm.di_builder,
757 .di_compile_unit = di_compile_unit,734 .di_compile_unit = builder.llvm.di_compile_unit,
758 .context = builder.llvm_context,735 .context = builder.llvm.context,
759 .target_machine = target_machine,736 .target_machine = target_machine,
760 .target_data = target_data,737 .target_data = target_data,
761 .target = options.target,738 .target = options.target,
...@@ -770,15 +747,10 @@ pub const Object = struct {...@@ -770,15 +747,10 @@ pub const Object = struct {
770 }747 }
771748
772 pub fn deinit(self: *Object, gpa: Allocator) void {749 pub fn deinit(self: *Object, gpa: Allocator) void {
773 if (self.di_builder) |dib| {750 self.di_map.deinit(gpa);
774 dib.dispose();751 self.di_type_map.deinit(gpa);
775 self.di_map.deinit(gpa);
776 self.di_type_map.deinit(gpa);
777 }
778 self.target_data.dispose();752 self.target_data.dispose();
779 self.target_machine.dispose();753 self.target_machine.dispose();
780 self.llvm_module.dispose();
781 self.context.dispose();
782 self.decl_map.deinit(gpa);754 self.decl_map.deinit(gpa);
783 self.named_enum_map.deinit(gpa);755 self.named_enum_map.deinit(gpa);
784 self.type_map.deinit(gpa);756 self.type_map.deinit(gpa);
...@@ -845,7 +817,7 @@ pub const Object = struct {...@@ -845,7 +817,7 @@ pub const Object = struct {
845 .mutability = .constant,817 .mutability = .constant,
846 .init = str_init,818 .init = str_init,
847 };819 };
848 try o.builder.llvm_globals.append(o.gpa, str_global);820 try o.builder.llvm.globals.append(o.gpa, str_global);
849 const str_global_index = try o.builder.addGlobal(.none, global);821 const str_global_index = try o.builder.addGlobal(.none, global);
850 try o.builder.variables.append(o.gpa, variable);822 try o.builder.variables.append(o.gpa, variable);
851823
...@@ -875,7 +847,7 @@ pub const Object = struct {...@@ -875,7 +847,7 @@ pub const Object = struct {
875 .mutability = .constant,847 .mutability = .constant,
876 .init = error_name_table_init,848 .init = error_name_table_init,
877 };849 };
878 try o.builder.llvm_globals.append(o.gpa, error_name_table_global);850 try o.builder.llvm.globals.append(o.gpa, error_name_table_global);
879 _ = try o.builder.addGlobal(.none, global);851 _ = try o.builder.addGlobal(.none, global);
880 try o.builder.variables.append(o.gpa, variable);852 try o.builder.variables.append(o.gpa, variable);
881853
...@@ -941,7 +913,7 @@ pub const Object = struct {...@@ -941,7 +913,7 @@ pub const Object = struct {
941913
942 llvm_global.replaceAllUsesWith(other_llvm_global);914 llvm_global.replaceAllUsesWith(other_llvm_global);
943 deleteLlvmGlobal(llvm_global);915 deleteLlvmGlobal(llvm_global);
944 object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global;916 object.builder.llvm.globals.items[@intFromEnum(global)] = other_llvm_global;
945 }917 }
946 object.extern_collisions.clearRetainingCapacity();918 object.extern_collisions.clearRetainingCapacity();
947919
...@@ -960,7 +932,7 @@ pub const Object = struct {...@@ -960,7 +932,7 @@ pub const Object = struct {
960 other_llvm_global.replaceAllUsesWith(llvm_global);932 other_llvm_global.replaceAllUsesWith(llvm_global);
961 try global.takeName(&object.builder, other_global);933 try global.takeName(&object.builder, other_global);
962 deleteLlvmGlobal(other_llvm_global);934 deleteLlvmGlobal(other_llvm_global);
963 object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global;935 object.builder.llvm.globals.items[@intFromEnum(other_global)] = llvm_global;
964 // Problem: now we need to replace in the decl_map that936 // Problem: now we need to replace in the decl_map that
965 // the extern decl index points to this new global. However we don't937 // the extern decl index points to this new global. However we don't
966 // know the decl index.938 // know the decl index.
...@@ -2765,7 +2737,7 @@ pub const Object = struct {...@@ -2765,7 +2737,7 @@ pub const Object = struct {
2765 .global = @enumFromInt(o.builder.globals.count()),2737 .global = @enumFromInt(o.builder.globals.count()),
2766 .init = llvm_init,2738 .init = llvm_init,
2767 };2739 };
2768 try o.builder.llvm_globals.append(o.gpa, llvm_global);2740 try o.builder.llvm.globals.append(o.gpa, llvm_global);
2769 _ = try o.builder.addGlobal(.none, global);2741 _ = try o.builder.addGlobal(.none, global);
2770 try o.builder.variables.append(o.gpa, variable);2742 try o.builder.variables.append(o.gpa, variable);
27712743
...@@ -2908,7 +2880,7 @@ pub const Object = struct {...@@ -2908,7 +2880,7 @@ pub const Object = struct {
2908 };2880 };
2909 }2881 }
29102882
2911 try o.builder.llvm_globals.append(o.gpa, llvm_fn);2883 try o.builder.llvm.globals.append(o.gpa, llvm_fn);
2912 gop.value_ptr.* = try o.builder.addGlobal(fqn, global);2884 gop.value_ptr.* = try o.builder.addGlobal(fqn, global);
2913 try o.builder.functions.append(o.gpa, function);2885 try o.builder.functions.append(o.gpa, function);
2914 return global.kind.function;2886 return global.kind.function;
...@@ -3017,7 +2989,7 @@ pub const Object = struct {...@@ -3017,7 +2989,7 @@ pub const Object = struct {
3017 llvm_global.setUnnamedAddr(.True);2989 llvm_global.setUnnamedAddr(.True);
3018 }2990 }
30192991
3020 try o.builder.llvm_globals.append(o.gpa, llvm_global);2992 try o.builder.llvm.globals.append(o.gpa, llvm_global);
3021 gop.value_ptr.* = try o.builder.addGlobal(name, global);2993 gop.value_ptr.* = try o.builder.addGlobal(name, global);
3022 try o.builder.variables.append(o.gpa, variable);2994 try o.builder.variables.append(o.gpa, variable);
3023 return global.kind.variable;2995 return global.kind.variable;
...@@ -4553,7 +4525,7 @@ pub const DeclGen = struct {...@@ -4553,7 +4525,7 @@ pub const DeclGen = struct {
4553 // TODO: How should this work then the address space of a global changed?4525 // TODO: How should this work then the address space of a global changed?
4554 llvm_global.replaceAllUsesWith(new_global);4526 llvm_global.replaceAllUsesWith(new_global);
4555 new_global.takeName(llvm_global);4527 new_global.takeName(llvm_global);
4556 o.builder.llvm_globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] =4528 o.builder.llvm.globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] =
4557 new_global;4529 new_global;
4558 llvm_global.deleteGlobal();4530 llvm_global.deleteGlobal();
4559 llvm_global = new_global;4531 llvm_global = new_global;
...@@ -4699,7 +4671,7 @@ pub const FuncGen = struct {...@@ -4699,7 +4671,7 @@ pub const FuncGen = struct {
4699 .mutability = .constant,4671 .mutability = .constant,
4700 .init = llvm_val,4672 .init = llvm_val,
4701 };4673 };
4702 try o.builder.llvm_globals.append(o.gpa, llvm_global);4674 try o.builder.llvm.globals.append(o.gpa, llvm_global);
4703 _ = try o.builder.addGlobal(.none, global);4675 _ = try o.builder.addGlobal(.none, global);
4704 try o.builder.variables.append(o.gpa, variable);4676 try o.builder.variables.append(o.gpa, variable);
47054677
...@@ -7855,7 +7827,7 @@ pub const FuncGen = struct {...@@ -7855,7 +7827,7 @@ pub const FuncGen = struct {
7855 .global = @enumFromInt(o.builder.globals.count()),7827 .global = @enumFromInt(o.builder.globals.count()),
7856 };7828 };
78577829
7858 try o.builder.llvm_globals.append(self.gpa, f);7830 try o.builder.llvm.globals.append(self.gpa, f);
7859 _ = try o.builder.addGlobal(fn_name, global);7831 _ = try o.builder.addGlobal(fn_name, global);
7860 try o.builder.functions.append(self.gpa, function);7832 try o.builder.functions.append(self.gpa, function);
7861 break :b f;7833 break :b f;
...@@ -9372,7 +9344,7 @@ pub const FuncGen = struct {...@@ -9372,7 +9344,7 @@ pub const FuncGen = struct {
9372 self.builder.positionBuilderAtEnd(unnamed_block);9344 self.builder.positionBuilderAtEnd(unnamed_block);
9373 _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));9345 _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));
93749346
9375 try o.builder.llvm_globals.append(self.gpa, fn_val);9347 try o.builder.llvm.globals.append(self.gpa, fn_val);
9376 _ = try o.builder.addGlobal(llvm_fn_name, global);9348 _ = try o.builder.addGlobal(llvm_fn_name, global);
9377 try o.builder.functions.append(self.gpa, function);9349 try o.builder.functions.append(self.gpa, function);
9378 gop.value_ptr.* = global.kind.function;9350 gop.value_ptr.* = global.kind.function;
...@@ -9484,7 +9456,7 @@ pub const FuncGen = struct {...@@ -9484,7 +9456,7 @@ pub const FuncGen = struct {
9484 self.builder.positionBuilderAtEnd(bad_value_block);9456 self.builder.positionBuilderAtEnd(bad_value_block);
9485 _ = self.builder.buildUnreachable();9457 _ = self.builder.buildUnreachable();
94869458
9487 try o.builder.llvm_globals.append(self.gpa, fn_val);9459 try o.builder.llvm.globals.append(self.gpa, fn_val);
9488 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);9460 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
9489 try o.builder.functions.append(self.gpa, function);9461 try o.builder.functions.append(self.gpa, function);
9490 return fn_val;9462 return fn_val;
...@@ -9515,7 +9487,7 @@ pub const FuncGen = struct {...@@ -9515,7 +9487,7 @@ pub const FuncGen = struct {
9515 .global = @enumFromInt(o.builder.globals.count()),9487 .global = @enumFromInt(o.builder.globals.count()),
9516 };9488 };
95179489
9518 try o.builder.llvm_globals.append(self.gpa, llvm_fn);9490 try o.builder.llvm.globals.append(self.gpa, llvm_fn);
9519 _ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global);9491 _ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global);
9520 try o.builder.functions.append(self.gpa, function);9492 try o.builder.functions.append(self.gpa, function);
9521 return llvm_fn;9493 return llvm_fn;
...@@ -10156,7 +10128,7 @@ pub const FuncGen = struct {...@@ -10156,7 +10128,7 @@ pub const FuncGen = struct {
10156 .mutability = .constant,10128 .mutability = .constant,
10157 .init = undef_init,10129 .init = undef_init,
10158 };10130 };
10159 try o.builder.llvm_globals.append(o.gpa, error_name_table_global);10131 try o.builder.llvm.globals.append(o.gpa, error_name_table_global);
10160 _ = try o.builder.addGlobal(name, global);10132 _ = try o.builder.addGlobal(name, global);
10161 try o.builder.variables.append(o.gpa, variable);10133 try o.builder.variables.append(o.gpa, variable);
1016210134
src/codegen/llvm/Builder.zig+130-66
...@@ -1,12 +1,16 @@...@@ -1,12 +1,16 @@
1gpa: Allocator,1gpa: Allocator,
2use_lib_llvm: bool,2use_lib_llvm: bool,
33
4llvm_context: *llvm.Context,4llvm: if (build_options.have_llvm) struct {
5llvm_module: *llvm.Module,5 context: *llvm.Context,
6di_builder: ?*llvm.DIBuilder = null,6 module: ?*llvm.Module = null,
7llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},7 target: ?*llvm.Target = null,
8llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},8 di_builder: ?*llvm.DIBuilder = null,
9llvm_constants: std.ArrayListUnmanaged(*llvm.Value) = .{},9 di_compile_unit: ?*llvm.DICompileUnit = null,
10 types: std.ArrayListUnmanaged(*llvm.Type) = .{},
11 globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
12 constants: std.ArrayListUnmanaged(*llvm.Value) = .{},
13} else void,
1014
11source_filename: String = .none,15source_filename: String = .none,
12data_layout: String = .none,16data_layout: String = .none,
...@@ -38,6 +42,14 @@ constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb) = .{},...@@ -38,6 +42,14 @@ constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb) = .{},
38pub const expected_fields_len = 32;42pub const expected_fields_len = 32;
39pub const expected_gep_indices_len = 8;43pub const expected_gep_indices_len = 8;
4044
45pub const Options = struct {
46 allocator: Allocator,
47 use_lib_llvm: bool = false,
48 name: []const u8 = &.{},
49 target: std.Target = builtin.target,
50 triple: []const u8 = &.{},
51};
52
41pub const String = enum(u32) {53pub const String = enum(u32) {
42 none = std.math.maxInt(u31),54 none = std.math.maxInt(u31),
43 empty,55 empty,
...@@ -481,7 +493,7 @@ pub const Type = enum(u32) {...@@ -481,7 +493,7 @@ pub const Type = enum(u32) {
481493
482 pub fn toLlvm(self: Type, builder: *const Builder) *llvm.Type {494 pub fn toLlvm(self: Type, builder: *const Builder) *llvm.Type {
483 assert(builder.useLibLlvm());495 assert(builder.useLibLlvm());
484 return builder.llvm_types.items[@intFromEnum(self)];496 return builder.llvm.types.items[@intFromEnum(self)];
485 }497 }
486};498};
487499
...@@ -751,7 +763,7 @@ pub const Global = struct {...@@ -751,7 +763,7 @@ pub const Global = struct {
751763
752 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {764 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
753 assert(builder.useLibLlvm());765 assert(builder.useLibLlvm());
754 return builder.llvm_globals.items[@intFromEnum(self)];766 return builder.llvm.globals.items[@intFromEnum(self)];
755 }767 }
756768
757 const FormatData = struct {769 const FormatData = struct {
...@@ -780,9 +792,9 @@ pub const Global = struct {...@@ -780,9 +792,9 @@ pub const Global = struct {
780 pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {792 pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {
781 const index = @intFromEnum(self);793 const index = @intFromEnum(self);
782 if (builder.globals.keys()[index] == name) return;794 if (builder.globals.keys()[index] == name) return;
783 if (builder.useLibLlvm()) builder.llvm_globals.appendAssumeCapacity(builder.llvm_globals.items[index]);795 if (builder.useLibLlvm()) builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
784 _ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);796 _ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);
785 if (builder.useLibLlvm()) _ = builder.llvm_globals.pop();797 if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
786 builder.globals.swapRemoveAt(index);798 builder.globals.swapRemoveAt(index);
787 self.updateName(builder);799 self.updateName(builder);
788 }800 }
...@@ -802,7 +814,7 @@ pub const Global = struct {...@@ -802,7 +814,7 @@ pub const Global = struct {
802 if (!builder.useLibLlvm()) return;814 if (!builder.useLibLlvm()) return;
803 const index = @intFromEnum(self);815 const index = @intFromEnum(self);
804 const slice = builder.globals.keys()[index].toSlice(builder) orelse "";816 const slice = builder.globals.keys()[index].toSlice(builder) orelse "";
805 builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);817 builder.llvm.globals.items[index].setValueName2(slice.ptr, slice.len);
806 }818 }
807 };819 };
808820
...@@ -1414,7 +1426,7 @@ pub const Constant = enum(u32) {...@@ -1414,7 +1426,7 @@ pub const Constant = enum(u32) {
1414 pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {1426 pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {
1415 assert(builder.useLibLlvm());1427 assert(builder.useLibLlvm());
1416 return switch (self.unwrap()) {1428 return switch (self.unwrap()) {
1417 .constant => |constant| builder.llvm_constants.items[constant],1429 .constant => |constant| builder.llvm.constants.items[constant],
1418 .global => |global| global.toLlvm(builder),1430 .global => |global| global.toLlvm(builder),
1419 };1431 };
1420 }1432 }
...@@ -1436,26 +1448,70 @@ pub const Value = enum(u32) {...@@ -1436,26 +1448,70 @@ pub const Value = enum(u32) {
1436 }1448 }
1437};1449};
14381450
1439pub fn init(self: *Builder) Allocator.Error!void {1451pub const InitError = error{
1452 InvalidLlvmTriple,
1453} || Allocator.Error;
1454
1455pub fn init(options: Options) InitError!Builder {
1456 var self = Builder{
1457 .gpa = options.allocator,
1458 .use_lib_llvm = options.use_lib_llvm,
1459 .llvm = undefined,
1460 };
1461 if (self.useLibLlvm()) self.llvm = .{ .context = llvm.Context.create() };
1462 errdefer self.deinit();
1463
1440 try self.string_indices.append(self.gpa, 0);1464 try self.string_indices.append(self.gpa, 0);
1441 assert(try self.string("") == .empty);1465 assert(try self.string("") == .empty);
14421466
1467 if (options.name.len > 0) self.source_filename = try self.string(options.name);
1468 self.initializeLLVMTarget(options.target.cpu.arch);
1469 if (self.useLibLlvm()) self.llvm.module = llvm.Module.createWithName(
1470 (self.source_filename.toSlice(&self) orelse "").ptr,
1471 self.llvm.context,
1472 );
1473
1474 if (options.triple.len > 0) {
1475 self.target_triple = try self.string(options.triple);
1476
1477 if (self.useLibLlvm()) {
1478 var error_message: [*:0]const u8 = undefined;
1479 var target: *llvm.Target = undefined;
1480 if (llvm.Target.getFromTriple(
1481 self.target_triple.toSlice(&self).?.ptr,
1482 &target,
1483 &error_message,
1484 ).toBool()) {
1485 defer llvm.disposeMessage(error_message);
1486
1487 log.err("LLVM failed to parse '{s}': {s}", .{
1488 self.target_triple.toSlice(&self).?,
1489 error_message,
1490 });
1491 return InitError.InvalidLlvmTriple;
1492 }
1493 self.llvm.target = target;
1494 self.llvm.module.?.setTarget(self.target_triple.toSlice(&self).?.ptr);
1495 }
1496 }
1497
1443 {1498 {
1444 const static_len = @typeInfo(Type).Enum.fields.len - 1;1499 const static_len = @typeInfo(Type).Enum.fields.len - 1;
1445 try self.type_map.ensureTotalCapacity(self.gpa, static_len);1500 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
1446 try self.type_items.ensureTotalCapacity(self.gpa, static_len);1501 try self.type_items.ensureTotalCapacity(self.gpa, static_len);
1447 if (self.useLibLlvm()) try self.llvm_types.ensureTotalCapacity(self.gpa, static_len);1502 if (self.useLibLlvm()) try self.llvm.types.ensureTotalCapacity(self.gpa, static_len);
1448 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {1503 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
1449 const result = self.getOrPutTypeNoExtraAssumeCapacity(1504 const result = self.getOrPutTypeNoExtraAssumeCapacity(
1450 .{ .tag = .simple, .data = simple_field.value },1505 .{ .tag = .simple, .data = simple_field.value },
1451 );1506 );
1452 assert(result.new and result.type == @field(Type, simple_field.name));1507 assert(result.new and result.type == @field(Type, simple_field.name));
1453 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(1508 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
1454 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm_context),1509 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm.context),
1455 );1510 );
1456 }1511 }
1457 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits| assert(self.intTypeAssumeCapacity(bits) ==1512 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
1458 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));1513 assert(self.intTypeAssumeCapacity(bits) ==
1514 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
1459 inline for (.{0}) |addr_space|1515 inline for (.{0}) |addr_space|
1460 assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);1516 assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
1461 }1517 }
...@@ -1463,13 +1519,11 @@ pub fn init(self: *Builder) Allocator.Error!void {...@@ -1463,13 +1519,11 @@ pub fn init(self: *Builder) Allocator.Error!void {
1463 assert(try self.intConst(.i1, 0) == .false);1519 assert(try self.intConst(.i1, 0) == .false);
1464 assert(try self.intConst(.i1, 1) == .true);1520 assert(try self.intConst(.i1, 1) == .true);
1465 assert(try self.noneConst(.token) == .none);1521 assert(try self.noneConst(.token) == .none);
1522
1523 return self;
1466}1524}
14671525
1468pub fn deinit(self: *Builder) void {1526pub fn deinit(self: *Builder) void {
1469 self.llvm_types.deinit(self.gpa);
1470 self.llvm_globals.deinit(self.gpa);
1471 self.llvm_constants.deinit(self.gpa);
1472
1473 self.string_map.deinit(self.gpa);1527 self.string_map.deinit(self.gpa);
1474 self.string_bytes.deinit(self.gpa);1528 self.string_bytes.deinit(self.gpa);
1475 self.string_indices.deinit(self.gpa);1529 self.string_indices.deinit(self.gpa);
...@@ -1492,6 +1546,14 @@ pub fn deinit(self: *Builder) void {...@@ -1492,6 +1546,14 @@ pub fn deinit(self: *Builder) void {
1492 self.constant_extra.deinit(self.gpa);1546 self.constant_extra.deinit(self.gpa);
1493 self.constant_limbs.deinit(self.gpa);1547 self.constant_limbs.deinit(self.gpa);
14941548
1549 if (self.useLibLlvm()) {
1550 self.llvm.constants.deinit(self.gpa);
1551 self.llvm.globals.deinit(self.gpa);
1552 self.llvm.types.deinit(self.gpa);
1553 if (self.llvm.di_builder) |di_builder| di_builder.dispose();
1554 if (self.llvm.module) |module| module.dispose();
1555 self.llvm.context.dispose();
1556 }
1495 self.* = undefined;1557 self.* = undefined;
1496}1558}
14971559
...@@ -1807,7 +1869,7 @@ pub fn namedTypeSetBody(...@@ -1807,7 +1869,7 @@ pub fn namedTypeSetBody(
1807 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);1869 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
1808 defer self.gpa.free(llvm_fields);1870 defer self.gpa.free(llvm_fields);
1809 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);1871 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);
1810 self.llvm_types.items[@intFromEnum(named_type)].structSetBody(1872 self.llvm.types.items[@intFromEnum(named_type)].structSetBody(
1811 llvm_fields.ptr,1873 llvm_fields.ptr,
1812 @intCast(llvm_fields.len),1874 @intCast(llvm_fields.len),
1813 switch (body_item.tag) {1875 switch (body_item.tag) {
...@@ -1869,7 +1931,7 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo...@@ -1869,7 +1931,7 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo
1869 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);1931 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);
1870 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);1932 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);
1871 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);1933 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);
1872 if (self.useLibLlvm()) try self.llvm_constants.ensureUnusedCapacity(self.gpa, 1);1934 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, 1);
1873 return self.bigIntConstAssumeCapacity(ty, value);1935 return self.bigIntConstAssumeCapacity(ty, value);
1874}1936}
18751937
...@@ -2166,7 +2228,7 @@ fn isValidIdentifier(id: []const u8) bool {...@@ -2166,7 +2228,7 @@ fn isValidIdentifier(id: []const u8) bool {
2166}2228}
21672229
2168fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {2230fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {
2169 if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);2231 if (self.useLibLlvm()) try self.llvm.globals.ensureUnusedCapacity(self.gpa, 1);
2170 try self.string_map.ensureUnusedCapacity(self.gpa, 1);2232 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
2171 if (name.toSlice(self)) |id| try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len +2233 if (name.toSlice(self)) |id| try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len +
2172 comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}));2234 comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}));
...@@ -2222,7 +2284,7 @@ fn fnTypeAssumeCapacity(...@@ -2222,7 +2284,7 @@ fn fnTypeAssumeCapacity(
2222 const llvm_params = try self.gpa.alloc(*llvm.Type, params.len);2284 const llvm_params = try self.gpa.alloc(*llvm.Type, params.len);
2223 defer self.gpa.free(llvm_params);2285 defer self.gpa.free(llvm_params);
2224 for (llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(self);2286 for (llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(self);
2225 self.llvm_types.appendAssumeCapacity(llvm.functionType(2287 self.llvm.types.appendAssumeCapacity(llvm.functionType(
2226 ret.toLlvm(self),2288 ret.toLlvm(self),
2227 llvm_params.ptr,2289 llvm_params.ptr,
2228 @intCast(llvm_params.len),2290 @intCast(llvm_params.len),
...@@ -2240,7 +2302,7 @@ fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {...@@ -2240,7 +2302,7 @@ fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
2240 assert(bits > 0);2302 assert(bits > 0);
2241 const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });2303 const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
2242 if (self.useLibLlvm() and result.new)2304 if (self.useLibLlvm() and result.new)
2243 self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));2305 self.llvm.types.appendAssumeCapacity(self.llvm.context.intType(bits));
2244 return result.type;2306 return result.type;
2245}2307}
22462308
...@@ -2249,7 +2311,7 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {...@@ -2249,7 +2311,7 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
2249 .{ .tag = .pointer, .data = @intFromEnum(addr_space) },2311 .{ .tag = .pointer, .data = @intFromEnum(addr_space) },
2250 );2312 );
2251 if (self.useLibLlvm() and result.new)2313 if (self.useLibLlvm() and result.new)
2252 self.llvm_types.appendAssumeCapacity(self.llvm_context.pointerType(@intFromEnum(addr_space)));2314 self.llvm.types.appendAssumeCapacity(self.llvm.context.pointerType(@intFromEnum(addr_space)));
2253 return result.type;2315 return result.type;
2254}2316}
22552317
...@@ -2286,7 +2348,7 @@ fn vectorTypeAssumeCapacity(...@@ -2286,7 +2348,7 @@ fn vectorTypeAssumeCapacity(
2286 .tag = tag,2348 .tag = tag,
2287 .data = self.addTypeExtraAssumeCapacity(data),2349 .data = self.addTypeExtraAssumeCapacity(data),
2288 });2350 });
2289 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(switch (kind) {2351 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(switch (kind) {
2290 .normal => &llvm.Type.vectorType,2352 .normal => &llvm.Type.vectorType,
2291 .scalable => &llvm.Type.scalableVectorType,2353 .scalable => &llvm.Type.scalableVectorType,
2292 }(child.toLlvm(self), @intCast(len)));2354 }(child.toLlvm(self), @intCast(len)));
...@@ -2319,7 +2381,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {...@@ -2319,7 +2381,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
2319 .tag = .small_array,2381 .tag = .small_array,
2320 .data = self.addTypeExtraAssumeCapacity(data),2382 .data = self.addTypeExtraAssumeCapacity(data),
2321 });2383 });
2322 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(2384 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
2323 child.toLlvm(self).arrayType(@intCast(len)),2385 child.toLlvm(self).arrayType(@intCast(len)),
2324 );2386 );
2325 }2387 }
...@@ -2352,7 +2414,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {...@@ -2352,7 +2414,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
2352 .tag = .array,2414 .tag = .array,
2353 .data = self.addTypeExtraAssumeCapacity(data),2415 .data = self.addTypeExtraAssumeCapacity(data),
2354 });2416 });
2355 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(2417 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
2356 child.toLlvm(self).arrayType(@intCast(len)),2418 child.toLlvm(self).arrayType(@intCast(len)),
2357 );2419 );
2358 }2420 }
...@@ -2406,7 +2468,7 @@ fn structTypeAssumeCapacity(...@@ -2406,7 +2468,7 @@ fn structTypeAssumeCapacity(
2406 defer allocator.free(llvm_fields);2468 defer allocator.free(llvm_fields);
2407 for (llvm_fields, fields) |*llvm_field, field| llvm_field.* = field.toLlvm(self);2469 for (llvm_fields, fields) |*llvm_field, field| llvm_field.* = field.toLlvm(self);
24082470
2409 self.llvm_types.appendAssumeCapacity(self.llvm_context.structType(2471 self.llvm.types.appendAssumeCapacity(self.llvm.context.structType(
2410 llvm_fields.ptr,2472 llvm_fields.ptr,
2411 @intCast(llvm_fields.len),2473 @intCast(llvm_fields.len),
2412 switch (kind) {2474 switch (kind) {
...@@ -2456,8 +2518,8 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {...@@ -2456,8 +2518,8 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
2456 });2518 });
2457 const result: Type = @enumFromInt(gop.index);2519 const result: Type = @enumFromInt(gop.index);
2458 type_gop.value_ptr.* = result;2520 type_gop.value_ptr.* = result;
2459 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(2521 if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
2460 self.llvm_context.structCreateNamed(id.toSlice(self) orelse ""),2522 self.llvm.context.structCreateNamed(id.toSlice(self) orelse ""),
2461 );2523 );
2462 return result;2524 return result;
2463 }2525 }
...@@ -2481,7 +2543,7 @@ fn ensureUnusedTypeCapacity(...@@ -2481,7 +2543,7 @@ fn ensureUnusedTypeCapacity(
2481 self.gpa,2543 self.gpa,
2482 count * (@typeInfo(E).Struct.fields.len + trail_len),2544 count * (@typeInfo(E).Struct.fields.len + trail_len),
2483 ) else assert(trail_len == 0);2545 ) else assert(trail_len == 0);
2484 if (self.useLibLlvm()) try self.llvm_types.ensureUnusedCapacity(self.gpa, count);2546 if (self.useLibLlvm()) try self.llvm.types.ensureUnusedCapacity(self.gpa, count);
2485}2547}
24862548
2487fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {2549fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {
...@@ -2613,9 +2675,9 @@ fn bigIntConstAssumeCapacity(...@@ -2613,9 +2675,9 @@ fn bigIntConstAssumeCapacity(
2613 if (self.useLibLlvm()) {2675 if (self.useLibLlvm()) {
2614 const llvm_type = ty.toLlvm(self);2676 const llvm_type = ty.toLlvm(self);
2615 if (canonical_value.to(c_longlong)) |small| {2677 if (canonical_value.to(c_longlong)) |small| {
2616 self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));2678 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
2617 } else |_| if (canonical_value.to(c_ulonglong)) |small| {2679 } else |_| if (canonical_value.to(c_ulonglong)) |small| {
2618 self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(small, .False));2680 self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
2619 } else |_| {2681 } else |_| {
2620 const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(2682 const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(
2621 usize,2683 usize,
...@@ -2643,7 +2705,7 @@ fn bigIntConstAssumeCapacity(...@@ -2643,7 +2705,7 @@ fn bigIntConstAssumeCapacity(
2643 }2705 }
2644 result_limb.* = llvm_limb;2706 result_limb.* = llvm_limb;
2645 }2707 }
2646 self.llvm_constants.appendAssumeCapacity(2708 self.llvm.constants.appendAssumeCapacity(
2647 llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),2709 llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),
2648 );2710 );
2649 }2711 }
...@@ -2656,7 +2718,7 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {...@@ -2656,7 +2718,7 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {
2656 const result = self.getOrPutConstantNoExtraAssumeCapacity(2718 const result = self.getOrPutConstantNoExtraAssumeCapacity(
2657 .{ .tag = .half, .data = @as(u16, @bitCast(val)) },2719 .{ .tag = .half, .data = @as(u16, @bitCast(val)) },
2658 );2720 );
2659 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(2721 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
2660 if (std.math.isSignalNan(val))2722 if (std.math.isSignalNan(val))
2661 Type.i16.toLlvm(self).constInt(@as(u16, @bitCast(val)), .False)2723 Type.i16.toLlvm(self).constInt(@as(u16, @bitCast(val)), .False)
2662 .constBitCast(Type.half.toLlvm(self))2724 .constBitCast(Type.half.toLlvm(self))
...@@ -2671,7 +2733,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {...@@ -2671,7 +2733,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
2671 const result = self.getOrPutConstantNoExtraAssumeCapacity(2733 const result = self.getOrPutConstantNoExtraAssumeCapacity(
2672 .{ .tag = .bfloat, .data = @bitCast(val) },2734 .{ .tag = .bfloat, .data = @bitCast(val) },
2673 );2735 );
2674 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(2736 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
2675 if (std.math.isSignalNan(val))2737 if (std.math.isSignalNan(val))
2676 Type.i16.toLlvm(self).constInt(@as(u32, @bitCast(val)) >> 16, .False)2738 Type.i16.toLlvm(self).constInt(@as(u32, @bitCast(val)) >> 16, .False)
2677 .constBitCast(Type.bfloat.toLlvm(self))2739 .constBitCast(Type.bfloat.toLlvm(self))
...@@ -2680,7 +2742,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {...@@ -2680,7 +2742,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
2680 );2742 );
26812743
2682 if (self.useLibLlvm() and result.new)2744 if (self.useLibLlvm() and result.new)
2683 self.llvm_constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));2745 self.llvm.constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));
2684 return result.constant;2746 return result.constant;
2685}2747}
26862748
...@@ -2688,7 +2750,7 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {...@@ -2688,7 +2750,7 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {
2688 const result = self.getOrPutConstantNoExtraAssumeCapacity(2750 const result = self.getOrPutConstantNoExtraAssumeCapacity(
2689 .{ .tag = .float, .data = @bitCast(val) },2751 .{ .tag = .float, .data = @bitCast(val) },
2690 );2752 );
2691 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(2753 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
2692 if (std.math.isSignalNan(val))2754 if (std.math.isSignalNan(val))
2693 Type.i32.toLlvm(self).constInt(@as(u32, @bitCast(val)), .False)2755 Type.i32.toLlvm(self).constInt(@as(u32, @bitCast(val)), .False)
2694 .constBitCast(Type.float.toLlvm(self))2756 .constBitCast(Type.float.toLlvm(self))
...@@ -2725,7 +2787,7 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {...@@ -2725,7 +2787,7 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {
2725 .hi = @truncate(@as(u64, @bitCast(val))),2787 .hi = @truncate(@as(u64, @bitCast(val))),
2726 }),2788 }),
2727 });2789 });
2728 if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(2790 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
2729 if (std.math.isSignalNan(val))2791 if (std.math.isSignalNan(val))
2730 Type.i64.toLlvm(self).constInt(@as(u64, @bitCast(val)), .False)2792 Type.i64.toLlvm(self).constInt(@as(u64, @bitCast(val)), .False)
2731 .constBitCast(Type.double.toLlvm(self))2793 .constBitCast(Type.double.toLlvm(self))
...@@ -2771,7 +2833,7 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {...@@ -2771,7 +2833,7 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {
2771 @truncate(@as(u128, @bitCast(val))),2833 @truncate(@as(u128, @bitCast(val))),
2772 @intCast(@as(u128, @bitCast(val)) >> 64),2834 @intCast(@as(u128, @bitCast(val)) >> 64),
2773 };2835 };
2774 self.llvm_constants.appendAssumeCapacity(2836 self.llvm.constants.appendAssumeCapacity(
2775 Type.i128.toLlvm(self)2837 Type.i128.toLlvm(self)
2776 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)2838 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
2777 .constBitCast(Type.fp128.toLlvm(self)),2839 .constBitCast(Type.fp128.toLlvm(self)),
...@@ -2815,7 +2877,7 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {...@@ -2815,7 +2877,7 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {
2815 @truncate(@as(u80, @bitCast(val))),2877 @truncate(@as(u80, @bitCast(val))),
2816 @intCast(@as(u80, @bitCast(val)) >> 64),2878 @intCast(@as(u80, @bitCast(val)) >> 64),
2817 };2879 };
2818 self.llvm_constants.appendAssumeCapacity(2880 self.llvm.constants.appendAssumeCapacity(
2819 Type.i80.toLlvm(self)2881 Type.i80.toLlvm(self)
2820 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)2882 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
2821 .constBitCast(Type.x86_fp80.toLlvm(self)),2883 .constBitCast(Type.x86_fp80.toLlvm(self)),
...@@ -2857,7 +2919,7 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {...@@ -2857,7 +2919,7 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {
2857 });2919 });
2858 if (self.useLibLlvm()) {2920 if (self.useLibLlvm()) {
2859 const llvm_limbs: *const [2]u64 = @ptrCast(&val);2921 const llvm_limbs: *const [2]u64 = @ptrCast(&val);
2860 self.llvm_constants.appendAssumeCapacity(2922 self.llvm.constants.appendAssumeCapacity(
2861 Type.i128.toLlvm(self)2923 Type.i128.toLlvm(self)
2862 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs)2924 .constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs)
2863 .constBitCast(Type.ppc_fp128.toLlvm(self)),2925 .constBitCast(Type.ppc_fp128.toLlvm(self)),
...@@ -2873,7 +2935,7 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -2873,7 +2935,7 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {
2873 .{ .tag = .null, .data = @intFromEnum(ty) },2935 .{ .tag = .null, .data = @intFromEnum(ty) },
2874 );2936 );
2875 if (self.useLibLlvm() and result.new)2937 if (self.useLibLlvm() and result.new)
2876 self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());2938 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
2877 return result.constant;2939 return result.constant;
2878}2940}
28792941
...@@ -2883,7 +2945,7 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -2883,7 +2945,7 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {
2883 .{ .tag = .none, .data = @intFromEnum(ty) },2945 .{ .tag = .none, .data = @intFromEnum(ty) },
2884 );2946 );
2885 if (self.useLibLlvm() and result.new)2947 if (self.useLibLlvm() and result.new)
2886 self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());2948 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
2887 return result.constant;2949 return result.constant;
2888}2950}
28892951
...@@ -2929,7 +2991,7 @@ fn structConstAssumeCapacity(...@@ -2929,7 +2991,7 @@ fn structConstAssumeCapacity(
2929 defer allocator.free(llvm_vals);2991 defer allocator.free(llvm_vals);
2930 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);2992 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
29312993
2932 self.llvm_constants.appendAssumeCapacity(2994 self.llvm.constants.appendAssumeCapacity(
2933 ty.toLlvm(self).constNamedStruct(llvm_vals.ptr, @intCast(llvm_vals.len)),2995 ty.toLlvm(self).constNamedStruct(llvm_vals.ptr, @intCast(llvm_vals.len)),
2934 );2996 );
2935 }2997 }
...@@ -2971,7 +3033,7 @@ fn arrayConstAssumeCapacity(...@@ -2971,7 +3033,7 @@ fn arrayConstAssumeCapacity(
2971 defer allocator.free(llvm_vals);3033 defer allocator.free(llvm_vals);
2972 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);3034 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
29733035
2974 self.llvm_constants.appendAssumeCapacity(3036 self.llvm.constants.appendAssumeCapacity(
2975 type_extra.child.toLlvm(self).constArray(llvm_vals.ptr, @intCast(llvm_vals.len)),3037 type_extra.child.toLlvm(self).constArray(llvm_vals.ptr, @intCast(llvm_vals.len)),
2976 );3038 );
2977 }3039 }
...@@ -2985,8 +3047,8 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {...@@ -2985,8 +3047,8 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {
2985 const result = self.getOrPutConstantNoExtraAssumeCapacity(3047 const result = self.getOrPutConstantNoExtraAssumeCapacity(
2986 .{ .tag = .string, .data = @intFromEnum(val) },3048 .{ .tag = .string, .data = @intFromEnum(val) },
2987 );3049 );
2988 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(3050 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
2989 self.llvm_context.constString(slice.ptr, @intCast(slice.len), .True),3051 self.llvm.context.constString(slice.ptr, @intCast(slice.len), .True),
2990 );3052 );
2991 return result.constant;3053 return result.constant;
2992}3054}
...@@ -2998,8 +3060,8 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {...@@ -2998,8 +3060,8 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {
2998 const result = self.getOrPutConstantNoExtraAssumeCapacity(3060 const result = self.getOrPutConstantNoExtraAssumeCapacity(
2999 .{ .tag = .string_null, .data = @intFromEnum(val) },3061 .{ .tag = .string_null, .data = @intFromEnum(val) },
3000 );3062 );
3001 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(3063 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
3002 self.llvm_context.constString(slice.ptr, @intCast(slice.len + 1), .True),3064 self.llvm.context.constString(slice.ptr, @intCast(slice.len + 1), .True),
3003 );3065 );
3004 return result.constant;3066 return result.constant;
3005}3067}
...@@ -3032,7 +3094,7 @@ fn vectorConstAssumeCapacity(...@@ -3032,7 +3094,7 @@ fn vectorConstAssumeCapacity(
3032 defer allocator.free(llvm_vals);3094 defer allocator.free(llvm_vals);
3033 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);3095 for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
30343096
3035 self.llvm_constants.appendAssumeCapacity(3097 self.llvm.constants.appendAssumeCapacity(
3036 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),3098 llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
3037 );3099 );
3038 }3100 }
...@@ -3061,7 +3123,7 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -3061,7 +3123,7 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {
3061 .{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },3123 .{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },
3062 );3124 );
3063 if (self.useLibLlvm() and result.new)3125 if (self.useLibLlvm() and result.new)
3064 self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());3126 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
3065 return result.constant;3127 return result.constant;
3066}3128}
30673129
...@@ -3078,7 +3140,7 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -3078,7 +3140,7 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {
3078 .{ .tag = .undef, .data = @intFromEnum(ty) },3140 .{ .tag = .undef, .data = @intFromEnum(ty) },
3079 );3141 );
3080 if (self.useLibLlvm() and result.new)3142 if (self.useLibLlvm() and result.new)
3081 self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());3143 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
3082 return result.constant;3144 return result.constant;
3083}3145}
30843146
...@@ -3095,7 +3157,7 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {...@@ -3095,7 +3157,7 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {
3095 .{ .tag = .poison, .data = @intFromEnum(ty) },3157 .{ .tag = .poison, .data = @intFromEnum(ty) },
3096 );3158 );
3097 if (self.useLibLlvm() and result.new)3159 if (self.useLibLlvm() and result.new)
3098 self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());3160 self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
3099 return result.constant;3161 return result.constant;
3100}3162}
31013163
...@@ -3128,7 +3190,7 @@ fn blockAddrConstAssumeCapacity(...@@ -3128,7 +3190,7 @@ fn blockAddrConstAssumeCapacity(
3128 .tag = .blockaddress,3190 .tag = .blockaddress,
3129 .data = self.addConstantExtraAssumeCapacity(data),3191 .data = self.addConstantExtraAssumeCapacity(data),
3130 });3192 });
3131 if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(3193 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3132 function.toLlvm(self).blockAddress(block.toValue(self, function).toLlvm(self, function)),3194 function.toLlvm(self).blockAddress(block.toValue(self, function).toLlvm(self, function)),
3133 );3195 );
3134 }3196 }
...@@ -3139,7 +3201,7 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde...@@ -3139,7 +3201,7 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde
3139 const result = self.getOrPutConstantNoExtraAssumeCapacity(3201 const result = self.getOrPutConstantNoExtraAssumeCapacity(
3140 .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },3202 .{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },
3141 );3203 );
3142 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(undefined);3204 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
3143 return result.constant;3205 return result.constant;
3144}3206}
31453207
...@@ -3147,7 +3209,7 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {...@@ -3147,7 +3209,7 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {
3147 const result = self.getOrPutConstantNoExtraAssumeCapacity(3209 const result = self.getOrPutConstantNoExtraAssumeCapacity(
3148 .{ .tag = .no_cfi, .data = @intFromEnum(function) },3210 .{ .tag = .no_cfi, .data = @intFromEnum(function) },
3149 );3211 );
3150 if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(undefined);3212 if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
3151 return result.constant;3213 return result.constant;
3152}3214}
31533215
...@@ -3226,7 +3288,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, arg: Constant, ty:...@@ -3226,7 +3288,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, arg: Constant, ty:
3226 .tag = tag,3288 .tag = tag,
3227 .data = self.addConstantExtraAssumeCapacity(data.cast),3289 .data = self.addConstantExtraAssumeCapacity(data.cast),
3228 });3290 });
3229 if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(switch (tag) {3291 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
3230 .trunc => &llvm.Value.constTrunc,3292 .trunc => &llvm.Value.constTrunc,
3231 .zext => &llvm.Value.constZExt,3293 .zext => &llvm.Value.constZExt,
3232 .sext => &llvm.Value.constSExt,3294 .sext => &llvm.Value.constSExt,
...@@ -3330,7 +3392,7 @@ fn gepConstAssumeCapacity(...@@ -3330,7 +3392,7 @@ fn gepConstAssumeCapacity(
3330 defer allocator.free(llvm_indices);3392 defer allocator.free(llvm_indices);
3331 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);3393 for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
33323394
3333 self.llvm_constants.appendAssumeCapacity(switch (kind) {3395 self.llvm.constants.appendAssumeCapacity(switch (kind) {
3334 .normal => &llvm.Type.constGEP,3396 .normal => &llvm.Type.constGEP,
3335 .inbounds => &llvm.Type.constInBoundsGEP,3397 .inbounds => &llvm.Type.constInBoundsGEP,
3336 }(ty.toLlvm(self), base.toLlvm(self), llvm_indices.ptr, @intCast(indices.len)));3398 }(ty.toLlvm(self), base.toLlvm(self), llvm_indices.ptr, @intCast(indices.len)));
...@@ -3374,7 +3436,7 @@ fn binConstAssumeCapacity(...@@ -3374,7 +3436,7 @@ fn binConstAssumeCapacity(
3374 .tag = tag,3436 .tag = tag,
3375 .data = self.addConstantExtraAssumeCapacity(data.bin),3437 .data = self.addConstantExtraAssumeCapacity(data.bin),
3376 });3438 });
3377 if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(switch (tag) {3439 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
3378 .add => &llvm.Value.constAdd,3440 .add => &llvm.Value.constAdd,
3379 .sub => &llvm.Value.constSub,3441 .sub => &llvm.Value.constSub,
3380 .mul => &llvm.Value.constMul,3442 .mul => &llvm.Value.constMul,
...@@ -3402,7 +3464,7 @@ fn ensureUnusedConstantCapacity(...@@ -3402,7 +3464,7 @@ fn ensureUnusedConstantCapacity(
3402 self.gpa,3464 self.gpa,
3403 count * (@typeInfo(E).Struct.fields.len + trail_len),3465 count * (@typeInfo(E).Struct.fields.len + trail_len),
3404 ) else assert(trail_len == 0);3466 ) else assert(trail_len == 0);
3405 if (self.useLibLlvm()) try self.llvm_constants.ensureUnusedCapacity(self.gpa, count);3467 if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, count);
3406}3468}
34073469
3408fn getOrPutConstantNoExtraAssumeCapacity(3470fn getOrPutConstantNoExtraAssumeCapacity(
...@@ -3516,13 +3578,15 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite...@@ -3516,13 +3578,15 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite
3516 return self.constantExtraDataTrail(T, index).data;3578 return self.constantExtraDataTrail(T, index).data;
3517}3579}
35183580
3519inline fn useLibLlvm(self: *const Builder) bool {3581pub inline fn useLibLlvm(self: *const Builder) bool {
3520 return build_options.have_llvm and self.use_lib_llvm;3582 return build_options.have_llvm and self.use_lib_llvm;
3521}3583}
35223584
3523const assert = std.debug.assert;3585const assert = std.debug.assert;
3524const build_options = @import("build_options");3586const build_options = @import("build_options");
3587const builtin = @import("builtin");
3525const llvm = @import("bindings.zig");3588const llvm = @import("bindings.zig");
3589const log = std.log.scoped(.llvm);
3526const std = @import("std");3590const std = @import("std");
35273591
3528const Allocator = std.mem.Allocator;3592const Allocator = std.mem.Allocator;