mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
llvm: cleanup init
This commit is contained in:
parent
ff8a49448c
commit
7ec7fe5359
2 changed files with 268 additions and 232 deletions
|
|
@ -35,7 +35,7 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
|
|||
|
||||
const Error = error{ OutOfMemory, CodegenFail };
|
||||
|
||||
pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
|
||||
pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
|
||||
var llvm_triple = std.ArrayList(u8).init(allocator);
|
||||
defer llvm_triple.deinit();
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
|
|||
};
|
||||
try llvm_triple.appendSlice(llvm_abi);
|
||||
|
||||
return llvm_triple.toOwnedSliceSentinel(0);
|
||||
return llvm_triple.toOwnedSlice();
|
||||
}
|
||||
|
||||
pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
|
||||
|
|
@ -602,160 +602,137 @@ pub const Object = struct {
|
|||
}
|
||||
|
||||
pub fn init(gpa: Allocator, options: link.Options) !Object {
|
||||
var builder = Builder{
|
||||
.gpa = gpa,
|
||||
.use_lib_llvm = options.use_lib_llvm,
|
||||
|
||||
.llvm_context = llvm.Context.create(),
|
||||
.llvm_module = undefined,
|
||||
};
|
||||
errdefer builder.llvm_context.dispose();
|
||||
|
||||
builder.initializeLLVMTarget(options.target.cpu.arch);
|
||||
|
||||
builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context);
|
||||
errdefer builder.llvm_module.dispose();
|
||||
|
||||
const llvm_target_triple = try targetTriple(gpa, options.target);
|
||||
defer gpa.free(llvm_target_triple);
|
||||
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
var target: *llvm.Target = undefined;
|
||||
if (llvm.Target.getFromTriple(llvm_target_triple.ptr, &target, &error_message).toBool()) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
log.err("LLVM failed to parse '{s}': {s}", .{ llvm_target_triple, error_message });
|
||||
return error.InvalidLlvmTriple;
|
||||
}
|
||||
|
||||
builder.llvm_module.setTarget(llvm_target_triple.ptr);
|
||||
var opt_di_builder: ?*llvm.DIBuilder = null;
|
||||
errdefer if (opt_di_builder) |di_builder| di_builder.dispose();
|
||||
|
||||
var di_compile_unit: ?*llvm.DICompileUnit = null;
|
||||
|
||||
if (!options.strip) {
|
||||
switch (options.target.ofmt) {
|
||||
.coff => builder.llvm_module.addModuleCodeViewFlag(),
|
||||
else => builder.llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
|
||||
}
|
||||
const di_builder = builder.llvm_module.createDIBuilder(true);
|
||||
opt_di_builder = di_builder;
|
||||
|
||||
// Don't use the version string here; LLVM misparses it when it
|
||||
// includes the git revision.
|
||||
const producer = try std.fmt.allocPrintZ(gpa, "zig {d}.{d}.{d}", .{
|
||||
build_options.semver.major,
|
||||
build_options.semver.minor,
|
||||
build_options.semver.patch,
|
||||
});
|
||||
defer gpa.free(producer);
|
||||
|
||||
// We fully resolve all paths at this point to avoid lack of source line info in stack
|
||||
// traces or lack of debugging information which, if relative paths were used, would
|
||||
// be very location dependent.
|
||||
// TODO: the only concern I have with this is WASI as either host or target, should
|
||||
// we leave the paths as relative then?
|
||||
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const compile_unit_dir = blk: {
|
||||
const path = d: {
|
||||
const mod = options.module orelse break :d ".";
|
||||
break :d mod.root_pkg.root_src_directory.path orelse ".";
|
||||
};
|
||||
if (std.fs.path.isAbsolute(path)) break :blk path;
|
||||
break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was
|
||||
};
|
||||
const compile_unit_dir_z = try gpa.dupeZ(u8, compile_unit_dir);
|
||||
defer gpa.free(compile_unit_dir_z);
|
||||
|
||||
di_compile_unit = di_builder.createCompileUnit(
|
||||
DW.LANG.C99,
|
||||
di_builder.createFile(options.root_name, compile_unit_dir_z),
|
||||
producer,
|
||||
options.optimize_mode != .Debug,
|
||||
"", // flags
|
||||
0, // runtime version
|
||||
"", // split name
|
||||
0, // dwo id
|
||||
true, // emit debug info
|
||||
);
|
||||
}
|
||||
|
||||
const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug)
|
||||
.None
|
||||
else
|
||||
.Aggressive;
|
||||
|
||||
const reloc_mode: llvm.RelocMode = if (options.pic)
|
||||
.PIC
|
||||
else if (options.link_mode == .Dynamic)
|
||||
llvm.RelocMode.DynamicNoPIC
|
||||
else
|
||||
.Static;
|
||||
|
||||
const code_model: llvm.CodeModel = switch (options.machine_code_model) {
|
||||
.default => .Default,
|
||||
.tiny => .Tiny,
|
||||
.small => .Small,
|
||||
.kernel => .Kernel,
|
||||
.medium => .Medium,
|
||||
.large => .Large,
|
||||
};
|
||||
|
||||
// TODO handle float ABI better- it should depend on the ABI portion of std.Target
|
||||
const float_abi: llvm.ABIType = .Default;
|
||||
|
||||
const target_machine = llvm.TargetMachine.create(
|
||||
target,
|
||||
llvm_target_triple.ptr,
|
||||
if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
|
||||
options.llvm_cpu_features,
|
||||
opt_level,
|
||||
reloc_mode,
|
||||
code_model,
|
||||
options.function_sections,
|
||||
float_abi,
|
||||
if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,
|
||||
);
|
||||
errdefer target_machine.dispose();
|
||||
|
||||
const target_data = target_machine.createTargetDataLayout();
|
||||
errdefer target_data.dispose();
|
||||
|
||||
builder.llvm_module.setModuleDataLayout(target_data);
|
||||
|
||||
if (options.pic) builder.llvm_module.setModulePICLevel();
|
||||
if (options.pie) builder.llvm_module.setModulePIELevel();
|
||||
if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model);
|
||||
|
||||
if (options.opt_bisect_limit >= 0) {
|
||||
builder.llvm_context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
|
||||
}
|
||||
|
||||
try builder.init();
|
||||
var builder = try Builder.init(.{
|
||||
.allocator = gpa,
|
||||
.use_lib_llvm = options.use_lib_llvm,
|
||||
.name = options.root_name,
|
||||
.target = options.target,
|
||||
.triple = llvm_target_triple,
|
||||
});
|
||||
errdefer builder.deinit();
|
||||
builder.source_filename = try builder.string(options.root_name);
|
||||
builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }});
|
||||
builder.target_triple = try builder.string(llvm_target_triple);
|
||||
|
||||
if (std.debug.runtime_safety) {
|
||||
const rep = target_data.stringRep();
|
||||
defer llvm.disposeMessage(rep);
|
||||
std.testing.expectEqualStrings(
|
||||
std.mem.span(rep),
|
||||
builder.data_layout.toSlice(&builder).?,
|
||||
) catch unreachable;
|
||||
var target_machine: *llvm.TargetMachine = undefined;
|
||||
var target_data: *llvm.TargetData = undefined;
|
||||
if (builder.useLibLlvm()) {
|
||||
if (!options.strip) {
|
||||
switch (options.target.ofmt) {
|
||||
.coff => builder.llvm.module.?.addModuleCodeViewFlag(),
|
||||
else => builder.llvm.module.?.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
|
||||
}
|
||||
builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true);
|
||||
|
||||
// Don't use the version string here; LLVM misparses it when it
|
||||
// includes the git revision.
|
||||
const producer = try builder.fmt("zig {d}.{d}.{d}", .{
|
||||
build_options.semver.major,
|
||||
build_options.semver.minor,
|
||||
build_options.semver.patch,
|
||||
});
|
||||
|
||||
// We fully resolve all paths at this point to avoid lack of source line info in stack
|
||||
// traces or lack of debugging information which, if relative paths were used, would
|
||||
// be very location dependent.
|
||||
// TODO: the only concern I have with this is WASI as either host or target, should
|
||||
// we leave the paths as relative then?
|
||||
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const compile_unit_dir = blk: {
|
||||
const path = d: {
|
||||
const mod = options.module orelse break :d ".";
|
||||
break :d mod.root_pkg.root_src_directory.path orelse ".";
|
||||
};
|
||||
if (std.fs.path.isAbsolute(path)) break :blk path;
|
||||
break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was
|
||||
};
|
||||
const compile_unit_dir_z = try builder.gpa.dupeZ(u8, compile_unit_dir);
|
||||
defer builder.gpa.free(compile_unit_dir_z);
|
||||
|
||||
builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit(
|
||||
DW.LANG.C99,
|
||||
builder.llvm.di_builder.?.createFile(options.root_name, compile_unit_dir_z),
|
||||
producer.toSlice(&builder).?,
|
||||
options.optimize_mode != .Debug,
|
||||
"", // flags
|
||||
0, // runtime version
|
||||
"", // split name
|
||||
0, // dwo id
|
||||
true, // emit debug info
|
||||
);
|
||||
}
|
||||
|
||||
const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug)
|
||||
.None
|
||||
else
|
||||
.Aggressive;
|
||||
|
||||
const reloc_mode: llvm.RelocMode = if (options.pic)
|
||||
.PIC
|
||||
else if (options.link_mode == .Dynamic)
|
||||
llvm.RelocMode.DynamicNoPIC
|
||||
else
|
||||
.Static;
|
||||
|
||||
const code_model: llvm.CodeModel = switch (options.machine_code_model) {
|
||||
.default => .Default,
|
||||
.tiny => .Tiny,
|
||||
.small => .Small,
|
||||
.kernel => .Kernel,
|
||||
.medium => .Medium,
|
||||
.large => .Large,
|
||||
};
|
||||
|
||||
// TODO handle float ABI better- it should depend on the ABI portion of std.Target
|
||||
const float_abi: llvm.ABIType = .Default;
|
||||
|
||||
target_machine = llvm.TargetMachine.create(
|
||||
builder.llvm.target.?,
|
||||
builder.target_triple.toSlice(&builder).?.ptr,
|
||||
if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
|
||||
options.llvm_cpu_features,
|
||||
opt_level,
|
||||
reloc_mode,
|
||||
code_model,
|
||||
options.function_sections,
|
||||
float_abi,
|
||||
if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,
|
||||
);
|
||||
errdefer target_machine.dispose();
|
||||
|
||||
target_data = target_machine.createTargetDataLayout();
|
||||
errdefer target_data.dispose();
|
||||
|
||||
builder.llvm.module.?.setModuleDataLayout(target_data);
|
||||
|
||||
if (options.pic) builder.llvm.module.?.setModulePICLevel();
|
||||
if (options.pie) builder.llvm.module.?.setModulePIELevel();
|
||||
if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model);
|
||||
|
||||
if (options.opt_bisect_limit >= 0) {
|
||||
builder.llvm.context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
|
||||
}
|
||||
|
||||
builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }});
|
||||
if (std.debug.runtime_safety) {
|
||||
const rep = target_data.stringRep();
|
||||
defer llvm.disposeMessage(rep);
|
||||
std.testing.expectEqualStrings(
|
||||
std.mem.span(rep),
|
||||
builder.data_layout.toSlice(&builder).?,
|
||||
) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
return Object{
|
||||
return .{
|
||||
.gpa = gpa,
|
||||
.builder = builder,
|
||||
.module = options.module.?,
|
||||
.llvm_module = builder.llvm_module,
|
||||
.llvm_module = builder.llvm.module.?,
|
||||
.di_map = .{},
|
||||
.di_builder = opt_di_builder,
|
||||
.di_compile_unit = di_compile_unit,
|
||||
.context = builder.llvm_context,
|
||||
.di_builder = builder.llvm.di_builder,
|
||||
.di_compile_unit = builder.llvm.di_compile_unit,
|
||||
.context = builder.llvm.context,
|
||||
.target_machine = target_machine,
|
||||
.target_data = target_data,
|
||||
.target = options.target,
|
||||
|
|
@ -770,15 +747,10 @@ pub const Object = struct {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *Object, gpa: Allocator) void {
|
||||
if (self.di_builder) |dib| {
|
||||
dib.dispose();
|
||||
self.di_map.deinit(gpa);
|
||||
self.di_type_map.deinit(gpa);
|
||||
}
|
||||
self.di_map.deinit(gpa);
|
||||
self.di_type_map.deinit(gpa);
|
||||
self.target_data.dispose();
|
||||
self.target_machine.dispose();
|
||||
self.llvm_module.dispose();
|
||||
self.context.dispose();
|
||||
self.decl_map.deinit(gpa);
|
||||
self.named_enum_map.deinit(gpa);
|
||||
self.type_map.deinit(gpa);
|
||||
|
|
@ -845,7 +817,7 @@ pub const Object = struct {
|
|||
.mutability = .constant,
|
||||
.init = str_init,
|
||||
};
|
||||
try o.builder.llvm_globals.append(o.gpa, str_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, str_global);
|
||||
const str_global_index = try o.builder.addGlobal(.none, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
|
||||
|
|
@ -875,7 +847,7 @@ pub const Object = struct {
|
|||
.mutability = .constant,
|
||||
.init = error_name_table_init,
|
||||
};
|
||||
try o.builder.llvm_globals.append(o.gpa, error_name_table_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, error_name_table_global);
|
||||
_ = try o.builder.addGlobal(.none, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
|
||||
|
|
@ -941,7 +913,7 @@ pub const Object = struct {
|
|||
|
||||
llvm_global.replaceAllUsesWith(other_llvm_global);
|
||||
deleteLlvmGlobal(llvm_global);
|
||||
object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global;
|
||||
object.builder.llvm.globals.items[@intFromEnum(global)] = other_llvm_global;
|
||||
}
|
||||
object.extern_collisions.clearRetainingCapacity();
|
||||
|
||||
|
|
@ -960,7 +932,7 @@ pub const Object = struct {
|
|||
other_llvm_global.replaceAllUsesWith(llvm_global);
|
||||
try global.takeName(&object.builder, other_global);
|
||||
deleteLlvmGlobal(other_llvm_global);
|
||||
object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global;
|
||||
object.builder.llvm.globals.items[@intFromEnum(other_global)] = llvm_global;
|
||||
// Problem: now we need to replace in the decl_map that
|
||||
// the extern decl index points to this new global. However we don't
|
||||
// know the decl index.
|
||||
|
|
@ -2765,7 +2737,7 @@ pub const Object = struct {
|
|||
.global = @enumFromInt(o.builder.globals.count()),
|
||||
.init = llvm_init,
|
||||
};
|
||||
try o.builder.llvm_globals.append(o.gpa, llvm_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, llvm_global);
|
||||
_ = try o.builder.addGlobal(.none, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
|
||||
|
|
@ -2908,7 +2880,7 @@ pub const Object = struct {
|
|||
};
|
||||
}
|
||||
|
||||
try o.builder.llvm_globals.append(o.gpa, llvm_fn);
|
||||
try o.builder.llvm.globals.append(o.gpa, llvm_fn);
|
||||
gop.value_ptr.* = try o.builder.addGlobal(fqn, global);
|
||||
try o.builder.functions.append(o.gpa, function);
|
||||
return global.kind.function;
|
||||
|
|
@ -3017,7 +2989,7 @@ pub const Object = struct {
|
|||
llvm_global.setUnnamedAddr(.True);
|
||||
}
|
||||
|
||||
try o.builder.llvm_globals.append(o.gpa, llvm_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, llvm_global);
|
||||
gop.value_ptr.* = try o.builder.addGlobal(name, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
return global.kind.variable;
|
||||
|
|
@ -4553,7 +4525,7 @@ pub const DeclGen = struct {
|
|||
// TODO: How should this work then the address space of a global changed?
|
||||
llvm_global.replaceAllUsesWith(new_global);
|
||||
new_global.takeName(llvm_global);
|
||||
o.builder.llvm_globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] =
|
||||
o.builder.llvm.globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] =
|
||||
new_global;
|
||||
llvm_global.deleteGlobal();
|
||||
llvm_global = new_global;
|
||||
|
|
@ -4699,7 +4671,7 @@ pub const FuncGen = struct {
|
|||
.mutability = .constant,
|
||||
.init = llvm_val,
|
||||
};
|
||||
try o.builder.llvm_globals.append(o.gpa, llvm_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, llvm_global);
|
||||
_ = try o.builder.addGlobal(.none, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
|
||||
|
|
@ -7855,7 +7827,7 @@ pub const FuncGen = struct {
|
|||
.global = @enumFromInt(o.builder.globals.count()),
|
||||
};
|
||||
|
||||
try o.builder.llvm_globals.append(self.gpa, f);
|
||||
try o.builder.llvm.globals.append(self.gpa, f);
|
||||
_ = try o.builder.addGlobal(fn_name, global);
|
||||
try o.builder.functions.append(self.gpa, function);
|
||||
break :b f;
|
||||
|
|
@ -9372,7 +9344,7 @@ pub const FuncGen = struct {
|
|||
self.builder.positionBuilderAtEnd(unnamed_block);
|
||||
_ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));
|
||||
|
||||
try o.builder.llvm_globals.append(self.gpa, fn_val);
|
||||
try o.builder.llvm.globals.append(self.gpa, fn_val);
|
||||
_ = try o.builder.addGlobal(llvm_fn_name, global);
|
||||
try o.builder.functions.append(self.gpa, function);
|
||||
gop.value_ptr.* = global.kind.function;
|
||||
|
|
@ -9484,7 +9456,7 @@ pub const FuncGen = struct {
|
|||
self.builder.positionBuilderAtEnd(bad_value_block);
|
||||
_ = self.builder.buildUnreachable();
|
||||
|
||||
try o.builder.llvm_globals.append(self.gpa, fn_val);
|
||||
try o.builder.llvm.globals.append(self.gpa, fn_val);
|
||||
gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
|
||||
try o.builder.functions.append(self.gpa, function);
|
||||
return fn_val;
|
||||
|
|
@ -9515,7 +9487,7 @@ pub const FuncGen = struct {
|
|||
.global = @enumFromInt(o.builder.globals.count()),
|
||||
};
|
||||
|
||||
try o.builder.llvm_globals.append(self.gpa, llvm_fn);
|
||||
try o.builder.llvm.globals.append(self.gpa, llvm_fn);
|
||||
_ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global);
|
||||
try o.builder.functions.append(self.gpa, function);
|
||||
return llvm_fn;
|
||||
|
|
@ -10156,7 +10128,7 @@ pub const FuncGen = struct {
|
|||
.mutability = .constant,
|
||||
.init = undef_init,
|
||||
};
|
||||
try o.builder.llvm_globals.append(o.gpa, error_name_table_global);
|
||||
try o.builder.llvm.globals.append(o.gpa, error_name_table_global);
|
||||
_ = try o.builder.addGlobal(name, global);
|
||||
try o.builder.variables.append(o.gpa, variable);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
gpa: Allocator,
|
||||
use_lib_llvm: bool,
|
||||
|
||||
llvm_context: *llvm.Context,
|
||||
llvm_module: *llvm.Module,
|
||||
di_builder: ?*llvm.DIBuilder = null,
|
||||
llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},
|
||||
llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
|
||||
llvm_constants: std.ArrayListUnmanaged(*llvm.Value) = .{},
|
||||
llvm: if (build_options.have_llvm) struct {
|
||||
context: *llvm.Context,
|
||||
module: ?*llvm.Module = null,
|
||||
target: ?*llvm.Target = null,
|
||||
di_builder: ?*llvm.DIBuilder = null,
|
||||
di_compile_unit: ?*llvm.DICompileUnit = null,
|
||||
types: std.ArrayListUnmanaged(*llvm.Type) = .{},
|
||||
globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
|
||||
constants: std.ArrayListUnmanaged(*llvm.Value) = .{},
|
||||
} else void,
|
||||
|
||||
source_filename: String = .none,
|
||||
data_layout: String = .none,
|
||||
|
|
@ -38,6 +42,14 @@ constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb) = .{},
|
|||
pub const expected_fields_len = 32;
|
||||
pub const expected_gep_indices_len = 8;
|
||||
|
||||
pub const Options = struct {
|
||||
allocator: Allocator,
|
||||
use_lib_llvm: bool = false,
|
||||
name: []const u8 = &.{},
|
||||
target: std.Target = builtin.target,
|
||||
triple: []const u8 = &.{},
|
||||
};
|
||||
|
||||
pub const String = enum(u32) {
|
||||
none = std.math.maxInt(u31),
|
||||
empty,
|
||||
|
|
@ -481,7 +493,7 @@ pub const Type = enum(u32) {
|
|||
|
||||
pub fn toLlvm(self: Type, builder: *const Builder) *llvm.Type {
|
||||
assert(builder.useLibLlvm());
|
||||
return builder.llvm_types.items[@intFromEnum(self)];
|
||||
return builder.llvm.types.items[@intFromEnum(self)];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -751,7 +763,7 @@ pub const Global = struct {
|
|||
|
||||
pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
|
||||
assert(builder.useLibLlvm());
|
||||
return builder.llvm_globals.items[@intFromEnum(self)];
|
||||
return builder.llvm.globals.items[@intFromEnum(self)];
|
||||
}
|
||||
|
||||
const FormatData = struct {
|
||||
|
|
@ -780,9 +792,9 @@ pub const Global = struct {
|
|||
pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {
|
||||
const index = @intFromEnum(self);
|
||||
if (builder.globals.keys()[index] == name) return;
|
||||
if (builder.useLibLlvm()) builder.llvm_globals.appendAssumeCapacity(builder.llvm_globals.items[index]);
|
||||
if (builder.useLibLlvm()) builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
|
||||
_ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);
|
||||
if (builder.useLibLlvm()) _ = builder.llvm_globals.pop();
|
||||
if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
|
||||
builder.globals.swapRemoveAt(index);
|
||||
self.updateName(builder);
|
||||
}
|
||||
|
|
@ -802,7 +814,7 @@ pub const Global = struct {
|
|||
if (!builder.useLibLlvm()) return;
|
||||
const index = @intFromEnum(self);
|
||||
const slice = builder.globals.keys()[index].toSlice(builder) orelse "";
|
||||
builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);
|
||||
builder.llvm.globals.items[index].setValueName2(slice.ptr, slice.len);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1414,7 +1426,7 @@ pub const Constant = enum(u32) {
|
|||
pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {
|
||||
assert(builder.useLibLlvm());
|
||||
return switch (self.unwrap()) {
|
||||
.constant => |constant| builder.llvm_constants.items[constant],
|
||||
.constant => |constant| builder.llvm.constants.items[constant],
|
||||
.global => |global| global.toLlvm(builder),
|
||||
};
|
||||
}
|
||||
|
|
@ -1436,26 +1448,70 @@ pub const Value = enum(u32) {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn init(self: *Builder) Allocator.Error!void {
|
||||
pub const InitError = error{
|
||||
InvalidLlvmTriple,
|
||||
} || Allocator.Error;
|
||||
|
||||
pub fn init(options: Options) InitError!Builder {
|
||||
var self = Builder{
|
||||
.gpa = options.allocator,
|
||||
.use_lib_llvm = options.use_lib_llvm,
|
||||
.llvm = undefined,
|
||||
};
|
||||
if (self.useLibLlvm()) self.llvm = .{ .context = llvm.Context.create() };
|
||||
errdefer self.deinit();
|
||||
|
||||
try self.string_indices.append(self.gpa, 0);
|
||||
assert(try self.string("") == .empty);
|
||||
|
||||
if (options.name.len > 0) self.source_filename = try self.string(options.name);
|
||||
self.initializeLLVMTarget(options.target.cpu.arch);
|
||||
if (self.useLibLlvm()) self.llvm.module = llvm.Module.createWithName(
|
||||
(self.source_filename.toSlice(&self) orelse "").ptr,
|
||||
self.llvm.context,
|
||||
);
|
||||
|
||||
if (options.triple.len > 0) {
|
||||
self.target_triple = try self.string(options.triple);
|
||||
|
||||
if (self.useLibLlvm()) {
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
var target: *llvm.Target = undefined;
|
||||
if (llvm.Target.getFromTriple(
|
||||
self.target_triple.toSlice(&self).?.ptr,
|
||||
&target,
|
||||
&error_message,
|
||||
).toBool()) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
log.err("LLVM failed to parse '{s}': {s}", .{
|
||||
self.target_triple.toSlice(&self).?,
|
||||
error_message,
|
||||
});
|
||||
return InitError.InvalidLlvmTriple;
|
||||
}
|
||||
self.llvm.target = target;
|
||||
self.llvm.module.?.setTarget(self.target_triple.toSlice(&self).?.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const static_len = @typeInfo(Type).Enum.fields.len - 1;
|
||||
try self.type_map.ensureTotalCapacity(self.gpa, static_len);
|
||||
try self.type_items.ensureTotalCapacity(self.gpa, static_len);
|
||||
if (self.useLibLlvm()) try self.llvm_types.ensureTotalCapacity(self.gpa, static_len);
|
||||
if (self.useLibLlvm()) try self.llvm.types.ensureTotalCapacity(self.gpa, static_len);
|
||||
inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
|
||||
const result = self.getOrPutTypeNoExtraAssumeCapacity(
|
||||
.{ .tag = .simple, .data = simple_field.value },
|
||||
);
|
||||
assert(result.new and result.type == @field(Type, simple_field.name));
|
||||
if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
|
||||
@field(llvm.Context, simple_field.name ++ "Type")(self.llvm_context),
|
||||
if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
|
||||
@field(llvm.Context, simple_field.name ++ "Type")(self.llvm.context),
|
||||
);
|
||||
}
|
||||
inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits| assert(self.intTypeAssumeCapacity(bits) ==
|
||||
@field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
|
||||
inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
|
||||
assert(self.intTypeAssumeCapacity(bits) ==
|
||||
@field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
|
||||
inline for (.{0}) |addr_space|
|
||||
assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
|
||||
}
|
||||
|
|
@ -1463,13 +1519,11 @@ pub fn init(self: *Builder) Allocator.Error!void {
|
|||
assert(try self.intConst(.i1, 0) == .false);
|
||||
assert(try self.intConst(.i1, 1) == .true);
|
||||
assert(try self.noneConst(.token) == .none);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Builder) void {
|
||||
self.llvm_types.deinit(self.gpa);
|
||||
self.llvm_globals.deinit(self.gpa);
|
||||
self.llvm_constants.deinit(self.gpa);
|
||||
|
||||
self.string_map.deinit(self.gpa);
|
||||
self.string_bytes.deinit(self.gpa);
|
||||
self.string_indices.deinit(self.gpa);
|
||||
|
|
@ -1492,6 +1546,14 @@ pub fn deinit(self: *Builder) void {
|
|||
self.constant_extra.deinit(self.gpa);
|
||||
self.constant_limbs.deinit(self.gpa);
|
||||
|
||||
if (self.useLibLlvm()) {
|
||||
self.llvm.constants.deinit(self.gpa);
|
||||
self.llvm.globals.deinit(self.gpa);
|
||||
self.llvm.types.deinit(self.gpa);
|
||||
if (self.llvm.di_builder) |di_builder| di_builder.dispose();
|
||||
if (self.llvm.module) |module| module.dispose();
|
||||
self.llvm.context.dispose();
|
||||
}
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
|
|
@ -1807,7 +1869,7 @@ pub fn namedTypeSetBody(
|
|||
const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
|
||||
defer self.gpa.free(llvm_fields);
|
||||
for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);
|
||||
self.llvm_types.items[@intFromEnum(named_type)].structSetBody(
|
||||
self.llvm.types.items[@intFromEnum(named_type)].structSetBody(
|
||||
llvm_fields.ptr,
|
||||
@intCast(llvm_fields.len),
|
||||
switch (body_item.tag) {
|
||||
|
|
@ -1869,7 +1931,7 @@ pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allo
|
|||
try self.constant_map.ensureUnusedCapacity(self.gpa, 1);
|
||||
try self.constant_items.ensureUnusedCapacity(self.gpa, 1);
|
||||
try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);
|
||||
if (self.useLibLlvm()) try self.llvm_constants.ensureUnusedCapacity(self.gpa, 1);
|
||||
if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, 1);
|
||||
return self.bigIntConstAssumeCapacity(ty, value);
|
||||
}
|
||||
|
||||
|
|
@ -2166,7 +2228,7 @@ fn isValidIdentifier(id: []const u8) bool {
|
|||
}
|
||||
|
||||
fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {
|
||||
if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);
|
||||
if (self.useLibLlvm()) try self.llvm.globals.ensureUnusedCapacity(self.gpa, 1);
|
||||
try self.string_map.ensureUnusedCapacity(self.gpa, 1);
|
||||
if (name.toSlice(self)) |id| try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len +
|
||||
comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}));
|
||||
|
|
@ -2222,7 +2284,7 @@ fn fnTypeAssumeCapacity(
|
|||
const llvm_params = try self.gpa.alloc(*llvm.Type, params.len);
|
||||
defer self.gpa.free(llvm_params);
|
||||
for (llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(self);
|
||||
self.llvm_types.appendAssumeCapacity(llvm.functionType(
|
||||
self.llvm.types.appendAssumeCapacity(llvm.functionType(
|
||||
ret.toLlvm(self),
|
||||
llvm_params.ptr,
|
||||
@intCast(llvm_params.len),
|
||||
|
|
@ -2240,7 +2302,7 @@ fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
|
|||
assert(bits > 0);
|
||||
const result = self.getOrPutTypeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));
|
||||
self.llvm.types.appendAssumeCapacity(self.llvm.context.intType(bits));
|
||||
return result.type;
|
||||
}
|
||||
|
||||
|
|
@ -2249,7 +2311,7 @@ fn ptrTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
|
|||
.{ .tag = .pointer, .data = @intFromEnum(addr_space) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_types.appendAssumeCapacity(self.llvm_context.pointerType(@intFromEnum(addr_space)));
|
||||
self.llvm.types.appendAssumeCapacity(self.llvm.context.pointerType(@intFromEnum(addr_space)));
|
||||
return result.type;
|
||||
}
|
||||
|
||||
|
|
@ -2286,7 +2348,7 @@ fn vectorTypeAssumeCapacity(
|
|||
.tag = tag,
|
||||
.data = self.addTypeExtraAssumeCapacity(data),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(switch (kind) {
|
||||
if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(switch (kind) {
|
||||
.normal => &llvm.Type.vectorType,
|
||||
.scalable => &llvm.Type.scalableVectorType,
|
||||
}(child.toLlvm(self), @intCast(len)));
|
||||
|
|
@ -2319,7 +2381,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
|
|||
.tag = .small_array,
|
||||
.data = self.addTypeExtraAssumeCapacity(data),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
|
||||
if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
|
||||
child.toLlvm(self).arrayType(@intCast(len)),
|
||||
);
|
||||
}
|
||||
|
|
@ -2352,7 +2414,7 @@ fn arrayTypeAssumeCapacity(self: *Builder, len: u64, child: Type) Type {
|
|||
.tag = .array,
|
||||
.data = self.addTypeExtraAssumeCapacity(data),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
|
||||
if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
|
||||
child.toLlvm(self).arrayType(@intCast(len)),
|
||||
);
|
||||
}
|
||||
|
|
@ -2406,7 +2468,7 @@ fn structTypeAssumeCapacity(
|
|||
defer allocator.free(llvm_fields);
|
||||
for (llvm_fields, fields) |*llvm_field, field| llvm_field.* = field.toLlvm(self);
|
||||
|
||||
self.llvm_types.appendAssumeCapacity(self.llvm_context.structType(
|
||||
self.llvm.types.appendAssumeCapacity(self.llvm.context.structType(
|
||||
llvm_fields.ptr,
|
||||
@intCast(llvm_fields.len),
|
||||
switch (kind) {
|
||||
|
|
@ -2456,8 +2518,8 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
|
|||
});
|
||||
const result: Type = @enumFromInt(gop.index);
|
||||
type_gop.value_ptr.* = result;
|
||||
if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
|
||||
self.llvm_context.structCreateNamed(id.toSlice(self) orelse ""),
|
||||
if (self.useLibLlvm()) self.llvm.types.appendAssumeCapacity(
|
||||
self.llvm.context.structCreateNamed(id.toSlice(self) orelse ""),
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2481,7 +2543,7 @@ fn ensureUnusedTypeCapacity(
|
|||
self.gpa,
|
||||
count * (@typeInfo(E).Struct.fields.len + trail_len),
|
||||
) else assert(trail_len == 0);
|
||||
if (self.useLibLlvm()) try self.llvm_types.ensureUnusedCapacity(self.gpa, count);
|
||||
if (self.useLibLlvm()) try self.llvm.types.ensureUnusedCapacity(self.gpa, count);
|
||||
}
|
||||
|
||||
fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { new: bool, type: Type } {
|
||||
|
|
@ -2613,9 +2675,9 @@ fn bigIntConstAssumeCapacity(
|
|||
if (self.useLibLlvm()) {
|
||||
const llvm_type = ty.toLlvm(self);
|
||||
if (canonical_value.to(c_longlong)) |small| {
|
||||
self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
|
||||
self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
|
||||
} else |_| if (canonical_value.to(c_ulonglong)) |small| {
|
||||
self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
|
||||
self.llvm.constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
|
||||
} else |_| {
|
||||
const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(
|
||||
usize,
|
||||
|
|
@ -2643,7 +2705,7 @@ fn bigIntConstAssumeCapacity(
|
|||
}
|
||||
result_limb.* = llvm_limb;
|
||||
}
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),
|
||||
);
|
||||
}
|
||||
|
|
@ -2656,7 +2718,7 @@ fn halfConstAssumeCapacity(self: *Builder, val: f16) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .half, .data = @as(u16, @bitCast(val)) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
|
||||
if (std.math.isSignalNan(val))
|
||||
Type.i16.toLlvm(self).constInt(@as(u16, @bitCast(val)), .False)
|
||||
.constBitCast(Type.half.toLlvm(self))
|
||||
|
|
@ -2671,7 +2733,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .bfloat, .data = @bitCast(val) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
|
||||
if (std.math.isSignalNan(val))
|
||||
Type.i16.toLlvm(self).constInt(@as(u32, @bitCast(val)) >> 16, .False)
|
||||
.constBitCast(Type.bfloat.toLlvm(self))
|
||||
|
|
@ -2680,7 +2742,7 @@ fn bfloatConstAssumeCapacity(self: *Builder, val: f32) Constant {
|
|||
);
|
||||
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));
|
||||
self.llvm.constants.appendAssumeCapacity(Type.bfloat.toLlvm(self).constReal(val));
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -2688,7 +2750,7 @@ fn floatConstAssumeCapacity(self: *Builder, val: f32) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .float, .data = @bitCast(val) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
|
||||
if (std.math.isSignalNan(val))
|
||||
Type.i32.toLlvm(self).constInt(@as(u32, @bitCast(val)), .False)
|
||||
.constBitCast(Type.float.toLlvm(self))
|
||||
|
|
@ -2725,7 +2787,7 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {
|
|||
.hi = @truncate(@as(u64, @bitCast(val))),
|
||||
}),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(
|
||||
if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
|
||||
if (std.math.isSignalNan(val))
|
||||
Type.i64.toLlvm(self).constInt(@as(u64, @bitCast(val)), .False)
|
||||
.constBitCast(Type.double.toLlvm(self))
|
||||
|
|
@ -2771,7 +2833,7 @@ fn fp128ConstAssumeCapacity(self: *Builder, val: f128) Constant {
|
|||
@truncate(@as(u128, @bitCast(val))),
|
||||
@intCast(@as(u128, @bitCast(val)) >> 64),
|
||||
};
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
Type.i128.toLlvm(self)
|
||||
.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
|
||||
.constBitCast(Type.fp128.toLlvm(self)),
|
||||
|
|
@ -2815,7 +2877,7 @@ fn x86_fp80ConstAssumeCapacity(self: *Builder, val: f80) Constant {
|
|||
@truncate(@as(u80, @bitCast(val))),
|
||||
@intCast(@as(u80, @bitCast(val)) >> 64),
|
||||
};
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
Type.i80.toLlvm(self)
|
||||
.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), &llvm_limbs)
|
||||
.constBitCast(Type.x86_fp80.toLlvm(self)),
|
||||
|
|
@ -2857,7 +2919,7 @@ fn ppc_fp128ConstAssumeCapacity(self: *Builder, val: [2]f64) Constant {
|
|||
});
|
||||
if (self.useLibLlvm()) {
|
||||
const llvm_limbs: *const [2]u64 = @ptrCast(&val);
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
Type.i128.toLlvm(self)
|
||||
.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs)
|
||||
.constBitCast(Type.ppc_fp128.toLlvm(self)),
|
||||
|
|
@ -2873,7 +2935,7 @@ fn nullConstAssumeCapacity(self: *Builder, ty: Type) Constant {
|
|||
.{ .tag = .null, .data = @intFromEnum(ty) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -2883,7 +2945,7 @@ fn noneConstAssumeCapacity(self: *Builder, ty: Type) Constant {
|
|||
.{ .tag = .none, .data = @intFromEnum(ty) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -2929,7 +2991,7 @@ fn structConstAssumeCapacity(
|
|||
defer allocator.free(llvm_vals);
|
||||
for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
|
||||
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
ty.toLlvm(self).constNamedStruct(llvm_vals.ptr, @intCast(llvm_vals.len)),
|
||||
);
|
||||
}
|
||||
|
|
@ -2971,7 +3033,7 @@ fn arrayConstAssumeCapacity(
|
|||
defer allocator.free(llvm_vals);
|
||||
for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
|
||||
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
type_extra.child.toLlvm(self).constArray(llvm_vals.ptr, @intCast(llvm_vals.len)),
|
||||
);
|
||||
}
|
||||
|
|
@ -2985,8 +3047,8 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .string, .data = @intFromEnum(val) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm_context.constString(slice.ptr, @intCast(slice.len), .True),
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
|
||||
self.llvm.context.constString(slice.ptr, @intCast(slice.len), .True),
|
||||
);
|
||||
return result.constant;
|
||||
}
|
||||
|
|
@ -2998,8 +3060,8 @@ fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .string_null, .data = @intFromEnum(val) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm_context.constString(slice.ptr, @intCast(slice.len + 1), .True),
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(
|
||||
self.llvm.context.constString(slice.ptr, @intCast(slice.len + 1), .True),
|
||||
);
|
||||
return result.constant;
|
||||
}
|
||||
|
|
@ -3032,7 +3094,7 @@ fn vectorConstAssumeCapacity(
|
|||
defer allocator.free(llvm_vals);
|
||||
for (llvm_vals, vals) |*llvm_val, val| llvm_val.* = val.toLlvm(self);
|
||||
|
||||
self.llvm_constants.appendAssumeCapacity(
|
||||
self.llvm.constants.appendAssumeCapacity(
|
||||
llvm.constVector(llvm_vals.ptr, @intCast(llvm_vals.len)),
|
||||
);
|
||||
}
|
||||
|
|
@ -3061,7 +3123,7 @@ fn zeroInitConstAssumeCapacity(self: *Builder, ty: Type) Constant {
|
|||
.{ .tag = .zeroinitializer, .data = @intFromEnum(ty) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).constNull());
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -3078,7 +3140,7 @@ fn undefConstAssumeCapacity(self: *Builder, ty: Type) Constant {
|
|||
.{ .tag = .undef, .data = @intFromEnum(ty) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
|
||||
self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -3095,7 +3157,7 @@ fn poisonConstAssumeCapacity(self: *Builder, ty: Type) Constant {
|
|||
.{ .tag = .poison, .data = @intFromEnum(ty) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new)
|
||||
self.llvm_constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
|
||||
self.llvm.constants.appendAssumeCapacity(ty.toLlvm(self).getUndef());
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -3128,7 +3190,7 @@ fn blockAddrConstAssumeCapacity(
|
|||
.tag = .blockaddress,
|
||||
.data = self.addConstantExtraAssumeCapacity(data),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(
|
||||
if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
|
||||
function.toLlvm(self).blockAddress(block.toValue(self, function).toLlvm(self, function)),
|
||||
);
|
||||
}
|
||||
|
|
@ -3139,7 +3201,7 @@ fn dsoLocalEquivalentConstAssumeCapacity(self: *Builder, function: Function.Inde
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .dso_local_equivalent, .data = @intFromEnum(function) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(undefined);
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -3147,7 +3209,7 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {
|
|||
const result = self.getOrPutConstantNoExtraAssumeCapacity(
|
||||
.{ .tag = .no_cfi, .data = @intFromEnum(function) },
|
||||
);
|
||||
if (self.useLibLlvm() and result.new) self.llvm_constants.appendAssumeCapacity(undefined);
|
||||
if (self.useLibLlvm() and result.new) self.llvm.constants.appendAssumeCapacity(undefined);
|
||||
return result.constant;
|
||||
}
|
||||
|
||||
|
|
@ -3226,7 +3288,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, arg: Constant, ty:
|
|||
.tag = tag,
|
||||
.data = self.addConstantExtraAssumeCapacity(data.cast),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(switch (tag) {
|
||||
if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
|
||||
.trunc => &llvm.Value.constTrunc,
|
||||
.zext => &llvm.Value.constZExt,
|
||||
.sext => &llvm.Value.constSExt,
|
||||
|
|
@ -3330,7 +3392,7 @@ fn gepConstAssumeCapacity(
|
|||
defer allocator.free(llvm_indices);
|
||||
for (llvm_indices, indices) |*llvm_index, index| llvm_index.* = index.toLlvm(self);
|
||||
|
||||
self.llvm_constants.appendAssumeCapacity(switch (kind) {
|
||||
self.llvm.constants.appendAssumeCapacity(switch (kind) {
|
||||
.normal => &llvm.Type.constGEP,
|
||||
.inbounds => &llvm.Type.constInBoundsGEP,
|
||||
}(ty.toLlvm(self), base.toLlvm(self), llvm_indices.ptr, @intCast(indices.len)));
|
||||
|
|
@ -3374,7 +3436,7 @@ fn binConstAssumeCapacity(
|
|||
.tag = tag,
|
||||
.data = self.addConstantExtraAssumeCapacity(data.bin),
|
||||
});
|
||||
if (self.useLibLlvm()) self.llvm_constants.appendAssumeCapacity(switch (tag) {
|
||||
if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(switch (tag) {
|
||||
.add => &llvm.Value.constAdd,
|
||||
.sub => &llvm.Value.constSub,
|
||||
.mul => &llvm.Value.constMul,
|
||||
|
|
@ -3402,7 +3464,7 @@ fn ensureUnusedConstantCapacity(
|
|||
self.gpa,
|
||||
count * (@typeInfo(E).Struct.fields.len + trail_len),
|
||||
) else assert(trail_len == 0);
|
||||
if (self.useLibLlvm()) try self.llvm_constants.ensureUnusedCapacity(self.gpa, count);
|
||||
if (self.useLibLlvm()) try self.llvm.constants.ensureUnusedCapacity(self.gpa, count);
|
||||
}
|
||||
|
||||
fn getOrPutConstantNoExtraAssumeCapacity(
|
||||
|
|
@ -3516,13 +3578,15 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite
|
|||
return self.constantExtraDataTrail(T, index).data;
|
||||
}
|
||||
|
||||
inline fn useLibLlvm(self: *const Builder) bool {
|
||||
pub inline fn useLibLlvm(self: *const Builder) bool {
|
||||
return build_options.have_llvm and self.use_lib_llvm;
|
||||
}
|
||||
|
||||
const assert = std.debug.assert;
|
||||
const build_options = @import("build_options");
|
||||
const builtin = @import("builtin");
|
||||
const llvm = @import("bindings.zig");
|
||||
const log = std.log.scoped(.llvm);
|
||||
const std = @import("std");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue