llvm: enable even without libllvm linked
This commit is contained in:
@@ -8,7 +8,7 @@ const native_endian = builtin.cpu.arch.endian();
|
||||
const DW = std.dwarf;
|
||||
|
||||
const Builder = @import("llvm/Builder.zig");
|
||||
const llvm = if (build_options.have_llvm or true)
|
||||
const llvm = if (build_options.have_llvm)
|
||||
@import("llvm/bindings.zig")
|
||||
else
|
||||
@compileError("LLVM unavailable");
|
||||
@@ -764,15 +764,37 @@ pub const Object = struct {
|
||||
builder: Builder,
|
||||
|
||||
module: *Module,
|
||||
di_builder: ?*llvm.DIBuilder,
|
||||
di_builder: ?if (build_options.have_llvm) *llvm.DIBuilder else noreturn,
|
||||
/// One of these mappings:
|
||||
/// - *Module.File => *DIFile
|
||||
/// - *Module.Decl (Fn) => *DISubprogram
|
||||
/// - *Module.Decl (Non-Fn) => *DIGlobalVariable
|
||||
di_map: std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode),
|
||||
di_compile_unit: ?*llvm.DICompileUnit,
|
||||
target_machine: *llvm.TargetMachine,
|
||||
target_data: *llvm.TargetData,
|
||||
di_map: if (build_options.have_llvm) std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode) else struct {
|
||||
const K = *const anyopaque;
|
||||
const V = noreturn;
|
||||
|
||||
const Self = @This();
|
||||
|
||||
metadata: ?noreturn = null,
|
||||
size: Size = 0,
|
||||
available: Size = 0,
|
||||
|
||||
pub const Size = u0;
|
||||
|
||||
pub fn deinit(self: *Self, allocator: Allocator) void {
|
||||
_ = allocator;
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn get(self: Self, key: K) ?V {
|
||||
_ = self;
|
||||
_ = key;
|
||||
return null;
|
||||
}
|
||||
},
|
||||
di_compile_unit: ?if (build_options.have_llvm) *llvm.DICompileUnit else noreturn,
|
||||
target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void,
|
||||
target_data: if (build_options.have_llvm) *llvm.TargetData else void,
|
||||
target: std.Target,
|
||||
/// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
|
||||
/// but that has some downsides:
|
||||
@@ -830,8 +852,8 @@ pub const Object = struct {
|
||||
});
|
||||
errdefer builder.deinit();
|
||||
|
||||
var target_machine: *llvm.TargetMachine = undefined;
|
||||
var target_data: *llvm.TargetData = undefined;
|
||||
var target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void = undefined;
|
||||
var target_data: if (build_options.have_llvm) *llvm.TargetData else void = undefined;
|
||||
if (builder.useLibLlvm()) {
|
||||
if (!options.strip) {
|
||||
switch (options.target.ofmt) {
|
||||
@@ -946,7 +968,7 @@ pub const Object = struct {
|
||||
.module = options.module.?,
|
||||
.di_map = .{},
|
||||
.di_builder = if (builder.useLibLlvm()) builder.llvm.di_builder else null, // TODO
|
||||
.di_compile_unit = builder.llvm.di_compile_unit,
|
||||
.di_compile_unit = if (builder.useLibLlvm()) builder.llvm.di_compile_unit else null,
|
||||
.target_machine = target_machine,
|
||||
.target_data = target_data,
|
||||
.target = options.target,
|
||||
@@ -961,9 +983,9 @@ pub const Object = struct {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Object, gpa: Allocator) void {
|
||||
self.di_map.deinit(gpa);
|
||||
self.di_type_map.deinit(gpa);
|
||||
if (self.builder.useLibLlvm()) {
|
||||
self.di_map.deinit(gpa);
|
||||
self.di_type_map.deinit(gpa);
|
||||
self.target_data.dispose();
|
||||
self.target_machine.dispose();
|
||||
}
|
||||
@@ -1519,8 +1541,8 @@ pub const Object = struct {
|
||||
|
||||
function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
|
||||
|
||||
var di_file: ?*llvm.DIFile = null;
|
||||
var di_scope: ?*llvm.DIScope = null;
|
||||
var di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn = null;
|
||||
var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null;
|
||||
|
||||
if (o.di_builder) |dib| {
|
||||
di_file = try o.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
@@ -4425,7 +4447,8 @@ pub const DeclGen = struct {
|
||||
}, &o.builder);
|
||||
|
||||
if (o.di_builder) |dib| {
|
||||
const di_file = try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
const di_file =
|
||||
try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
const is_internal_linkage = !o.module.decl_exports.contains(decl_index);
|
||||
@@ -4453,18 +4476,18 @@ pub const FuncGen = struct {
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
wip: Builder.WipFunction,
|
||||
di_scope: ?*llvm.DIScope,
|
||||
di_file: ?*llvm.DIFile,
|
||||
di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn,
|
||||
di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn,
|
||||
base_line: u32,
|
||||
prev_dbg_line: c_uint,
|
||||
prev_dbg_column: c_uint,
|
||||
|
||||
/// Stack of locations where a call was inlined.
|
||||
dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{},
|
||||
dbg_inlined: std.ArrayListUnmanaged(if (build_options.have_llvm) DbgState else void) = .{},
|
||||
|
||||
/// Stack of `DILexicalBlock`s. dbg_block instructions cannot happend accross
|
||||
/// dbg_inline instructions so no special handling there is required.
|
||||
dbg_block_stack: std.ArrayListUnmanaged(*llvm.DIScope) = .{},
|
||||
dbg_block_stack: std.ArrayListUnmanaged(if (build_options.have_llvm) *llvm.DIScope else void) = .{},
|
||||
|
||||
/// This stores the LLVM values used in a function, such that they can be referred to
|
||||
/// in other instructions. This table is cleared before every function is generated.
|
||||
@@ -4495,7 +4518,7 @@ pub const FuncGen = struct {
|
||||
|
||||
sync_scope: Builder.SyncScope,
|
||||
|
||||
const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 };
|
||||
const DbgState = if (build_options.have_llvm) struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 } else struct {};
|
||||
const BreakList = union {
|
||||
list: std.MultiArrayList(struct {
|
||||
bb: Builder.Function.Block.Index,
|
||||
@@ -6230,8 +6253,6 @@ pub const FuncGen = struct {
|
||||
}
|
||||
|
||||
fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
if (!self.dg.object.builder.useLibLlvm()) return .none;
|
||||
|
||||
const di_scope = self.di_scope orelse return .none;
|
||||
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
|
||||
self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
|
||||
@@ -6251,8 +6272,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
const dib = o.di_builder orelse return .none;
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
|
||||
@@ -6311,8 +6330,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
if (o.di_builder == null) return .none;
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
|
||||
@@ -6328,8 +6345,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgBlockBegin(self: *FuncGen) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
const dib = o.di_builder orelse return .none;
|
||||
const old_scope = self.di_scope.?;
|
||||
try self.dbg_block_stack.append(self.gpa, old_scope);
|
||||
@@ -6340,8 +6355,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgBlockEnd(self: *FuncGen) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
if (o.di_builder == null) return .none;
|
||||
self.di_scope = self.dbg_block_stack.pop();
|
||||
return .none;
|
||||
@@ -6349,8 +6362,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
const mod = o.module;
|
||||
const dib = o.di_builder orelse return .none;
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
@@ -6379,8 +6390,6 @@ pub const FuncGen = struct {
|
||||
|
||||
fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const o = self.dg.object;
|
||||
if (!o.builder.useLibLlvm()) return .none;
|
||||
|
||||
const dib = o.di_builder orelse return .none;
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const operand = try self.resolveInst(pl_op.operand);
|
||||
|
||||
@@ -5868,7 +5868,7 @@ pub const WipFunction = struct {
|
||||
vals: []const Value,
|
||||
blocks: []const Block.Index,
|
||||
wip: *WipFunction,
|
||||
) if (build_options.have_llvm) Allocator.Error!void else void {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!void {
|
||||
const incoming_len = self.block.ptrConst(wip).incoming;
|
||||
assert(vals.len == incoming_len and blocks.len == incoming_len);
|
||||
const instruction = wip.instructions.get(@intFromEnum(self.instruction));
|
||||
@@ -8389,9 +8389,9 @@ pub fn fnType(
|
||||
kind: Type.Function.Kind,
|
||||
) Allocator.Error!Type {
|
||||
try self.ensureUnusedTypeCapacity(1, Type.Function, params.len);
|
||||
return switch (kind) {
|
||||
inline else => |comptime_kind| self.fnTypeAssumeCapacity(ret, params, comptime_kind),
|
||||
};
|
||||
switch (kind) {
|
||||
inline else => |comptime_kind| return self.fnTypeAssumeCapacity(ret, params, comptime_kind),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intType(self: *Builder, bits: u24) Allocator.Error!Type {
|
||||
@@ -8411,9 +8411,9 @@ pub fn vectorType(
|
||||
child: Type,
|
||||
) Allocator.Error!Type {
|
||||
try self.ensureUnusedTypeCapacity(1, Type.Vector, 0);
|
||||
return switch (kind) {
|
||||
inline else => |comptime_kind| self.vectorTypeAssumeCapacity(comptime_kind, len, child),
|
||||
};
|
||||
switch (kind) {
|
||||
inline else => |comptime_kind| return self.vectorTypeAssumeCapacity(comptime_kind, len, child),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arrayType(self: *Builder, len: u64, child: Type) Allocator.Error!Type {
|
||||
@@ -8428,9 +8428,9 @@ pub fn structType(
|
||||
fields: []const Type,
|
||||
) Allocator.Error!Type {
|
||||
try self.ensureUnusedTypeCapacity(1, Type.Structure, fields.len);
|
||||
return switch (kind) {
|
||||
inline else => |comptime_kind| self.structTypeAssumeCapacity(comptime_kind, fields),
|
||||
};
|
||||
switch (kind) {
|
||||
inline else => |comptime_kind| return self.structTypeAssumeCapacity(comptime_kind, fields),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
|
||||
@@ -8450,7 +8450,7 @@ pub fn namedTypeSetBody(
|
||||
self: *Builder,
|
||||
named_type: Type,
|
||||
body_type: Type,
|
||||
) if (build_options.have_llvm) Allocator.Error!void else void {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!void {
|
||||
const named_item = self.type_items.items[@intFromEnum(named_type)];
|
||||
self.type_extra.items[named_item.data + std.meta.fieldIndex(Type.NamedStructure, "body").?] =
|
||||
@intFromEnum(body_type);
|
||||
@@ -9985,7 +9985,7 @@ fn fnTypeAssumeCapacity(
|
||||
ret: Type,
|
||||
params: []const Type,
|
||||
comptime kind: Type.Function.Kind,
|
||||
) if (build_options.have_llvm) Allocator.Error!Type else Type {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Type {
|
||||
const tag: Type.Tag = switch (kind) {
|
||||
.normal => .function,
|
||||
.vararg => .vararg_function,
|
||||
@@ -10169,7 +10169,7 @@ fn structTypeAssumeCapacity(
|
||||
self: *Builder,
|
||||
comptime kind: Type.Structure.Kind,
|
||||
fields: []const Type,
|
||||
) if (build_options.have_llvm) Allocator.Error!Type else Type {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Type {
|
||||
const tag: Type.Tag = switch (kind) {
|
||||
.normal => .structure,
|
||||
.@"packed" => .packed_structure,
|
||||
@@ -10397,7 +10397,7 @@ fn bigIntConstAssumeCapacity(
|
||||
self: *Builder,
|
||||
ty: Type,
|
||||
value: std.math.big.int.Const,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) Allocator.Error!Constant {
|
||||
const type_item = self.type_items.items[@intFromEnum(ty)];
|
||||
assert(type_item.tag == .integer);
|
||||
const bits = type_item.data;
|
||||
@@ -10743,7 +10743,7 @@ fn structConstAssumeCapacity(
|
||||
self: *Builder,
|
||||
ty: Type,
|
||||
vals: []const Constant,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
|
||||
const type_item = self.type_items.items[@intFromEnum(ty)];
|
||||
var extra = self.typeExtraDataTrail(Type.Structure, switch (type_item.tag) {
|
||||
.structure, .packed_structure => type_item.data,
|
||||
@@ -10791,7 +10791,7 @@ fn arrayConstAssumeCapacity(
|
||||
self: *Builder,
|
||||
ty: Type,
|
||||
vals: []const Constant,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
|
||||
const type_item = self.type_items.items[@intFromEnum(ty)];
|
||||
const type_extra: struct { len: u64, child: Type } = switch (type_item.tag) {
|
||||
inline .small_array, .array => |kind| extra: {
|
||||
@@ -10859,7 +10859,7 @@ fn vectorConstAssumeCapacity(
|
||||
self: *Builder,
|
||||
ty: Type,
|
||||
vals: []const Constant,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
|
||||
assert(ty.isVector(self));
|
||||
assert(ty.vectorLen(self) == vals.len);
|
||||
for (vals) |val| assert(ty.childType(self) == val.typeOf(self));
|
||||
@@ -10893,7 +10893,7 @@ fn splatConstAssumeCapacity(
|
||||
self: *Builder,
|
||||
ty: Type,
|
||||
val: Constant,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
|
||||
assert(ty.scalarType(self) == val.typeOf(self));
|
||||
|
||||
if (!ty.isVector(self)) return val;
|
||||
@@ -11182,7 +11182,7 @@ fn gepConstAssumeCapacity(
|
||||
base: Constant,
|
||||
inrange: ?u16,
|
||||
indices: []const Constant,
|
||||
) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
|
||||
) (if (build_options.have_llvm) Allocator.Error else error{})!Constant {
|
||||
const tag: Constant.Tag = switch (kind) {
|
||||
.normal => .getelementptr,
|
||||
.inbounds => .@"getelementptr inbounds",
|
||||
|
||||
Reference in New Issue
Block a user