zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 43311e19f440a1b6294653f9fdf97c64f3bdd0ae (tree)
parent 6d691d3540b1979f0a8d604922c93209b9c0dba0
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue, 31 May 2022 15:16:38 -0700

LLVM: add readonly, nonnull, align attributes to pointer params

Diffstat:
Msrc/codegen/llvm.zig | 29+++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -2214,16 +2214,31 @@ pub const DeclGen = struct { } // Set parameter attributes. - // TODO: more attributes. see codegen.cpp `make_fn_llvm_value`. switch (fn_info.cc) { .Unspecified, .Inline => { var llvm_param_i: c_uint = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing); for (fn_info.param_types) |param_ty| { if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue; + // TODO: noalias attribute + if (isByRef(param_ty)) { dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull"); - // TODO readonly, noalias, align + dg.addArgAttr(llvm_fn, llvm_param_i, "readonly"); + dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", param_ty.abiAlignment(target)); + } else if (param_ty.isPtrAtRuntime()) { + const ptr_info = param_ty.ptrInfo().data; + if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") { + dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull"); + } + if (!ptr_info.mutable) { + dg.addArgAttr(llvm_fn, llvm_param_i, "readonly"); + } + if (ptr_info.@"align" != 0) { + dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.@"align"); + } else { + dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.pointee_type.abiAlignment(target)); + } } llvm_param_i += 1; } @@ -2237,6 +2252,12 @@ pub const DeclGen = struct { @panic("TODO: LLVM backend lower async function"); }, else => { + // TODO set attributes such as noalias, nonnull, readonly, and align + // Note that there is not a one to one correspondence between fn_info.param_types + // and llvm parameters due to C ABI lowering. This will need to involve + // iterateParamTypes which is currently happening over in updateFunc. + // Probably this whole "set parameter attributes" section of code should + // move there and integrate with this abstraction. llvm_fn.setFunctionCallConv(toLlvmCallConv(fn_info.cc, target)); }, } @@ -3705,6 +3726,10 @@ pub const DeclGen = struct { return dg.addAttr(fn_val, param_index + 1, attr_name); } + fn addArgAttrInt(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void { + return dg.addAttrInt(fn_val, param_index + 1, attr_name, int); + } + fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); assert(kind_id != 0);