aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorJohn Schmidt <3405586+schmee@users.noreply.github.com>2022-02-15 03:52:12 +0100
committerGitHub <noreply@github.com>2022-02-14 21:52:12 -0500
commit807edd2234b016cd5470c51ac2bac451554c614d (patch)
tree8ef308a0e0b082361acb82c075b3af16962364d6 /src/codegen/llvm.zig
parent7b938767bb18535a870d0460c9f4d9e3d93ab053 (diff)
downloadzig-807edd2234b016cd5470c51ac2bac451554c614d.tar.gz
zig-807edd2234b016cd5470c51ac2bac451554c614d.zip
LLVM backend: refactor LLVM bitcount ops (#10882)
Use `llvm.getIntrinsic` instead of `llvm.getNamedFunction`
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig56
1 files changed, 14 insertions, 42 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 493b895d5d..3d65829c1e 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2203,8 +2203,8 @@ pub const FuncGen = struct {
.memcpy => try self.airMemcpy(inst),
.set_union_tag => try self.airSetUnionTag(inst),
.get_union_tag => try self.airGetUnionTag(inst),
- .clz => try self.airClzCtz(inst, "ctlz"),
- .ctz => try self.airClzCtz(inst, "cttz"),
+ .clz => try self.airClzCtz(inst, "llvm.ctlz"),
+ .ctz => try self.airClzCtz(inst, "llvm.cttz"),
.popcount => try self.airPopCount(inst),
.tag_name => try self.airTagName(inst),
.error_name => try self.airErrorName(inst),
@@ -4320,40 +4320,24 @@ pub const FuncGen = struct {
return self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
}
- fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, prefix: [*:0]const u8) !?*const llvm.Value {
+ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_ty = self.air.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
- const target = self.dg.module.getTarget();
- const bits = operand_ty.intInfo(target).bits;
- const vec_len: ?u32 = switch (operand_ty.zigTypeTag()) {
- .Vector => operand_ty.vectorLen(),
- else => null,
- };
- var fn_name_buf: [100]u8 = undefined;
- const llvm_fn_name = if (vec_len) |len|
- std.fmt.bufPrintZ(&fn_name_buf, "llvm.{s}.v{d}i{d}", .{
- prefix, len, bits,
- }) catch unreachable
- else
- std.fmt.bufPrintZ(&fn_name_buf, "llvm.{s}.i{d}", .{
- prefix, bits,
- }) catch unreachable;
const llvm_i1 = self.context.intType(1);
- const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
- const operand_llvm_ty = try self.dg.llvmType(operand_ty);
- const param_types = [_]*const llvm.Type{ operand_llvm_ty, llvm_i1 };
- const fn_type = llvm.functionType(operand_llvm_ty, &param_types, param_types.len, .False);
- break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
- };
+ const operand_llvm_ty = try self.dg.llvmType(operand_ty);
+ const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
const params = [_]*const llvm.Value{ operand, llvm_i1.constNull() };
const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
const result_ty = self.air.typeOfIndex(inst);
const result_llvm_ty = try self.dg.llvmType(result_ty);
+
+ const target = self.dg.module.getTarget();
+ const bits = operand_ty.intInfo(target).bits;
const result_bits = result_ty.intInfo(target).bits;
if (bits > result_bits) {
return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
@@ -4370,29 +4354,17 @@ pub const FuncGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_ty = self.air.typeOf(ty_op.operand);
const operand = try self.resolveInst(ty_op.operand);
- const target = self.dg.module.getTarget();
- const bits = operand_ty.intInfo(target).bits;
- const vec_len: ?u32 = switch (operand_ty.zigTypeTag()) {
- .Vector => operand_ty.vectorLen(),
- else => null,
- };
-
- var fn_name_buf: [100]u8 = undefined;
- const llvm_fn_name = if (vec_len) |len|
- std.fmt.bufPrintZ(&fn_name_buf, "llvm.ctpop.v{d}i{d}", .{ len, bits }) catch unreachable
- else
- std.fmt.bufPrintZ(&fn_name_buf, "llvm.ctpop.i{d}", .{bits}) catch unreachable;
- const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
- const operand_llvm_ty = try self.dg.llvmType(operand_ty);
- const param_types = [_]*const llvm.Type{operand_llvm_ty};
- const fn_type = llvm.functionType(operand_llvm_ty, &param_types, param_types.len, .False);
- break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
- };
const params = [_]*const llvm.Value{operand};
+ const operand_llvm_ty = try self.dg.llvmType(operand_ty);
+ const fn_val = self.getIntrinsic("llvm.ctpop", &.{operand_llvm_ty});
+
const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
const result_ty = self.air.typeOfIndex(inst);
const result_llvm_ty = try self.dg.llvmType(result_ty);
+
+ const target = self.dg.module.getTarget();
+ const bits = operand_ty.intInfo(target).bits;
const result_bits = result_ty.intInfo(target).bits;
if (bits > result_bits) {
return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");