authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-31 15:16:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-31 15:16:38-07:00
log43311e19f440a1b6294653f9fdf97c64f3bdd0ae
tree02a3c174a43da39074d6130ed92c8a8a20773a7b
parent6d691d3540b1979f0a8d604922c93209b9c0dba0

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


1 files changed, 27 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+27-2
...@@ -2214,16 +2214,31 @@ pub const DeclGen = struct {...@@ -2214,16 +2214,31 @@ pub const DeclGen = struct {
2214 }2214 }
22152215
2216 // Set parameter attributes.2216 // Set parameter attributes.
2217 // TODO: more attributes. see codegen.cpp `make_fn_llvm_value`.
2218 switch (fn_info.cc) {2217 switch (fn_info.cc) {
2219 .Unspecified, .Inline => {2218 .Unspecified, .Inline => {
2220 var llvm_param_i: c_uint = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing);2219 var llvm_param_i: c_uint = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing);
2221 for (fn_info.param_types) |param_ty| {2220 for (fn_info.param_types) |param_ty| {
2222 if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;2221 if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;
22232222
2223 // TODO: noalias attribute
2224
2224 if (isByRef(param_ty)) {2225 if (isByRef(param_ty)) {
2225 dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull");2226 dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull");
2226 // TODO readonly, noalias, align2227 dg.addArgAttr(llvm_fn, llvm_param_i, "readonly");
2228 dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", param_ty.abiAlignment(target));
2229 } else if (param_ty.isPtrAtRuntime()) {
2230 const ptr_info = param_ty.ptrInfo().data;
2231 if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") {
2232 dg.addArgAttr(llvm_fn, llvm_param_i, "nonnull");
2233 }
2234 if (!ptr_info.mutable) {
2235 dg.addArgAttr(llvm_fn, llvm_param_i, "readonly");
2236 }
2237 if (ptr_info.@"align" != 0) {
2238 dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.@"align");
2239 } else {
2240 dg.addArgAttrInt(llvm_fn, llvm_param_i, "align", ptr_info.pointee_type.abiAlignment(target));
2241 }
2227 }2242 }
2228 llvm_param_i += 1;2243 llvm_param_i += 1;
2229 }2244 }
...@@ -2237,6 +2252,12 @@ pub const DeclGen = struct {...@@ -2237,6 +2252,12 @@ pub const DeclGen = struct {
2237 @panic("TODO: LLVM backend lower async function");2252 @panic("TODO: LLVM backend lower async function");
2238 },2253 },
2239 else => {2254 else => {
2255 // TODO set attributes such as noalias, nonnull, readonly, and align
2256 // Note that there is not a one to one correspondence between fn_info.param_types
2257 // and llvm parameters due to C ABI lowering. This will need to involve
2258 // iterateParamTypes which is currently happening over in updateFunc.
2259 // Probably this whole "set parameter attributes" section of code should
2260 // move there and integrate with this abstraction.
2240 llvm_fn.setFunctionCallConv(toLlvmCallConv(fn_info.cc, target));2261 llvm_fn.setFunctionCallConv(toLlvmCallConv(fn_info.cc, target));
2241 },2262 },
2242 }2263 }
...@@ -3705,6 +3726,10 @@ pub const DeclGen = struct {...@@ -3705,6 +3726,10 @@ pub const DeclGen = struct {
3705 return dg.addAttr(fn_val, param_index + 1, attr_name);3726 return dg.addAttr(fn_val, param_index + 1, attr_name);
3706 }3727 }
37073728
3729 fn addArgAttrInt(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void {
3730 return dg.addAttrInt(fn_val, param_index + 1, attr_name, int);
3731 }
3732
3708 fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {3733 fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
3709 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);3734 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);
3710 assert(kind_id != 0);3735 assert(kind_id != 0);