authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-07 03:36:11-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 21:32:50-04:00
log5b79f08ee82a48d84146706faf2229e7c298340d
tree183317a107a16cb78c8dd5c15cbd31fbebb53f95
parentb63d9745b5d7413acea4f4723ac9f696e3fb8149

llvm: finish converting attributes to use Builder and the C LLVM API


5 files changed, 133 insertions(+), 288 deletions(-)

src/codegen/llvm.zig+30-209
...@@ -1314,28 +1314,21 @@ pub const Object = struct {...@@ -1314,28 +1314,21 @@ pub const Object = struct {
13141314
1315 if (func.analysis(ip).is_noinline) {1315 if (func.analysis(ip).is_noinline) {
1316 try attributes.addFnAttr(.@"noinline", &o.builder);1316 try attributes.addFnAttr(.@"noinline", &o.builder);
1317 o.addFnAttr(llvm_func, "noinline");
1318 } else {1317 } else {
1319 _ = try attributes.removeFnAttr(.@"noinline");1318 _ = try attributes.removeFnAttr(.@"noinline");
1320 Object.removeFnAttr(llvm_func, "noinline");
1321 }1319 }
13221320
1323 if (func.analysis(ip).stack_alignment.toByteUnitsOptional()) |alignment| {1321 if (func.analysis(ip).stack_alignment.toByteUnitsOptional()) |alignment| {
1324 try attributes.addFnAttr(.{ .alignstack = Builder.Alignment.fromByteUnits(alignment) }, &o.builder);1322 try attributes.addFnAttr(.{ .alignstack = Builder.Alignment.fromByteUnits(alignment) }, &o.builder);
1325 try attributes.addFnAttr(.@"noinline", &o.builder);1323 try attributes.addFnAttr(.@"noinline", &o.builder);
1326 o.addFnAttrInt(llvm_func, "alignstack", alignment);
1327 o.addFnAttr(llvm_func, "noinline");
1328 } else {1324 } else {
1329 _ = try attributes.removeFnAttr(.alignstack);1325 _ = try attributes.removeFnAttr(.alignstack);
1330 Object.removeFnAttr(llvm_func, "alignstack");
1331 }1326 }
13321327
1333 if (func.analysis(ip).is_cold) {1328 if (func.analysis(ip).is_cold) {
1334 try attributes.addFnAttr(.cold, &o.builder);1329 try attributes.addFnAttr(.cold, &o.builder);
1335 o.addFnAttr(llvm_func, "cold");
1336 } else {1330 } else {
1337 _ = try attributes.removeFnAttr(.cold);1331 _ = try attributes.removeFnAttr(.cold);
1338 Object.removeFnAttr(llvm_func, "cold");
1339 }1332 }
13401333
1341 // TODO: disable this if safety is off for the function scope1334 // TODO: disable this if safety is off for the function scope
...@@ -1346,10 +1339,6 @@ pub const Object = struct {...@@ -1346,10 +1339,6 @@ pub const Object = struct {
1346 .kind = try o.builder.string("stack-protector-buffer-size"),1339 .kind = try o.builder.string("stack-protector-buffer-size"),
1347 .value = try o.builder.fmt("{d}", .{ssp_buf_size}),1340 .value = try o.builder.fmt("{d}", .{ssp_buf_size}),
1348 } }, &o.builder);1341 } }, &o.builder);
1349 var buf: [12]u8 = undefined;
1350 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;
1351 o.addFnAttr(llvm_func, "sspstrong");
1352 o.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg);
1353 }1342 }
13541343
1355 // TODO: disable this if safety is off for the function scope1344 // TODO: disable this if safety is off for the function scope
...@@ -1358,13 +1347,11 @@ pub const Object = struct {...@@ -1358,13 +1347,11 @@ pub const Object = struct {
1358 .kind = try o.builder.string("probe-stack"),1347 .kind = try o.builder.string("probe-stack"),
1359 .value = try o.builder.string("__zig_probe_stack"),1348 .value = try o.builder.string("__zig_probe_stack"),
1360 } }, &o.builder);1349 } }, &o.builder);
1361 o.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
1362 } else if (target.os.tag == .uefi) {1350 } else if (target.os.tag == .uefi) {
1363 try attributes.addFnAttr(.{ .string = .{1351 try attributes.addFnAttr(.{ .string = .{
1364 .kind = try o.builder.string("no-stack-arg-probe"),1352 .kind = try o.builder.string("no-stack-arg-probe"),
1365 .value = .empty,1353 .value = .empty,
1366 } }, &o.builder);1354 } }, &o.builder);
1367 o.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
1368 }1355 }
13691356
1370 if (ip.stringToSliceUnwrap(decl.@"linksection")) |section| {1357 if (ip.stringToSliceUnwrap(decl.@"linksection")) |section| {
...@@ -1389,14 +1376,8 @@ pub const Object = struct {...@@ -1389,14 +1376,8 @@ pub const Object = struct {
1389 } else .none;1376 } else .none;
13901377
1391 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type.toType())) |s| switch (s) {1378 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type.toType())) |s| switch (s) {
1392 .signed => {1379 .signed => try attributes.addRetAttr(.signext, &o.builder),
1393 try attributes.addRetAttr(.signext, &o.builder);1380 .unsigned => try attributes.addRetAttr(.zeroext, &o.builder),
1394 o.addAttr(llvm_func, 0, "signext");
1395 },
1396 .unsigned => {
1397 try attributes.addRetAttr(.zeroext, &o.builder);
1398 o.addAttr(llvm_func, 0, "zeroext");
1399 },
1400 };1381 };
14011382
1402 const err_return_tracing = fn_info.return_type.toType().isError(mod) and1383 const err_return_tracing = fn_info.return_type.toType().isError(mod) and
...@@ -1437,7 +1418,7 @@ pub const Object = struct {...@@ -1437,7 +1418,7 @@ pub const Object = struct {
1437 } else {1418 } else {
1438 args.appendAssumeCapacity(param);1419 args.appendAssumeCapacity(param);
14391420
1440 try o.addByValParamAttrsOld(&attributes, llvm_func, param_ty, param_index, fn_info, llvm_arg_i);1421 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, llvm_arg_i);
1441 }1422 }
1442 llvm_arg_i += 1;1423 llvm_arg_i += 1;
1443 },1424 },
...@@ -1447,7 +1428,7 @@ pub const Object = struct {...@@ -1447,7 +1428,7 @@ pub const Object = struct {
1447 const param = wip.arg(llvm_arg_i);1428 const param = wip.arg(llvm_arg_i);
1448 const alignment = Builder.Alignment.fromByteUnits(param_ty.abiAlignment(mod));1429 const alignment = Builder.Alignment.fromByteUnits(param_ty.abiAlignment(mod));
14491430
1450 try o.addByRefParamAttrsOld(&attributes, llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);1431 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
1451 llvm_arg_i += 1;1432 llvm_arg_i += 1;
14521433
1453 if (isByRef(param_ty, mod)) {1434 if (isByRef(param_ty, mod)) {
...@@ -1463,7 +1444,6 @@ pub const Object = struct {...@@ -1463,7 +1444,6 @@ pub const Object = struct {
1463 const alignment = Builder.Alignment.fromByteUnits(param_ty.abiAlignment(mod));1444 const alignment = Builder.Alignment.fromByteUnits(param_ty.abiAlignment(mod));
14641445
1465 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);1446 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
1466 o.addArgAttr(llvm_func, llvm_arg_i, "noundef");
1467 llvm_arg_i += 1;1447 llvm_arg_i += 1;
14681448
1469 if (isByRef(param_ty, mod)) {1449 if (isByRef(param_ty, mod)) {
...@@ -1500,23 +1480,19 @@ pub const Object = struct {...@@ -1500,23 +1480,19 @@ pub const Object = struct {
1500 if (math.cast(u5, it.zig_index - 1)) |i| {1480 if (math.cast(u5, it.zig_index - 1)) |i| {
1501 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {1481 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {
1502 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);1482 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);
1503 o.addArgAttr(llvm_func, llvm_arg_i, "noalias");
1504 }1483 }
1505 }1484 }
1506 if (param_ty.zigTypeTag(mod) != .Optional) {1485 if (param_ty.zigTypeTag(mod) != .Optional) {
1507 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);1486 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
1508 o.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
1509 }1487 }
1510 if (ptr_info.flags.is_const) {1488 if (ptr_info.flags.is_const) {
1511 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);1489 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
1512 o.addArgAttr(llvm_func, llvm_arg_i, "readonly");
1513 }1490 }
1514 const elem_align = Builder.Alignment.fromByteUnits(1491 const elem_align = Builder.Alignment.fromByteUnits(
1515 ptr_info.flags.alignment.toByteUnitsOptional() orelse1492 ptr_info.flags.alignment.toByteUnitsOptional() orelse
1516 @max(ptr_info.child.toType().abiAlignment(mod), 1),1493 @max(ptr_info.child.toType().abiAlignment(mod), 1),
1517 );1494 );
1518 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);1495 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
1519 o.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align.toByteUnits() orelse 0);
1520 const ptr_param = wip.arg(llvm_arg_i);1496 const ptr_param = wip.arg(llvm_arg_i);
1521 llvm_arg_i += 1;1497 llvm_arg_i += 1;
1522 const len_param = wip.arg(llvm_arg_i);1498 const len_param = wip.arg(llvm_arg_i);
...@@ -1590,7 +1566,7 @@ pub const Object = struct {...@@ -1590,7 +1566,7 @@ pub const Object = struct {
1590 }1566 }
1591 }1567 }
15921568
1593 function.ptr(&o.builder).attributes = try attributes.finish(&o.builder);1569 function.setAttributes(try attributes.finish(&o.builder), &o.builder);
15941570
1595 var di_file: ?*llvm.DIFile = null;1571 var di_file: ?*llvm.DIFile = null;
1596 var di_scope: ?*llvm.DIScope = null;1572 var di_scope: ?*llvm.DIScope = null;
...@@ -2951,15 +2927,11 @@ pub const Object = struct {...@@ -2951,15 +2927,11 @@ pub const Object = struct {
2951 .kind = try o.builder.string("wasm-import-name"),2927 .kind = try o.builder.string("wasm-import-name"),
2952 .value = try o.builder.string(ip.stringToSlice(decl.name)),2928 .value = try o.builder.string(ip.stringToSlice(decl.name)),
2953 } }, &o.builder);2929 } }, &o.builder);
2954 o.addFnAttrString(llvm_fn, "wasm-import-name", ip.stringToSlice(decl.name));
2955 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {2930 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
2956 if (!std.mem.eql(u8, lib_name, "c")) {2931 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{
2957 try attributes.addFnAttr(.{ .string = .{2932 .kind = try o.builder.string("wasm-import-module"),
2958 .kind = try o.builder.string("wasm-import-module"),2933 .value = try o.builder.string(lib_name),
2959 .value = try o.builder.string(lib_name),2934 } }, &o.builder);
2960 } }, &o.builder);
2961 o.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
2962 }
2963 }2935 }
2964 }2936 }
2965 }2937 }
...@@ -2969,12 +2941,9 @@ pub const Object = struct {...@@ -2969,12 +2941,9 @@ pub const Object = struct {
2969 // Sret pointers must not be address 02941 // Sret pointers must not be address 0
2970 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);2942 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
2971 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);2943 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);
2972 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull"); // Sret pointers must not be address 0
2973 o.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
29742944
2975 const raw_llvm_ret_ty = try o.lowerType(fn_info.return_type.toType());2945 const raw_llvm_ret_ty = try o.lowerType(fn_info.return_type.toType());
2976 try attributes.addParamAttr(llvm_arg_i, .{ .sret = raw_llvm_ret_ty }, &o.builder);2946 try attributes.addParamAttr(llvm_arg_i, .{ .sret = raw_llvm_ret_ty }, &o.builder);
2977 llvm_fn.addSretAttr(raw_llvm_ret_ty.toLlvm(&o.builder));
29782947
2979 llvm_arg_i += 1;2948 llvm_arg_i += 1;
2980 }2949 }
...@@ -2984,7 +2953,6 @@ pub const Object = struct {...@@ -2984,7 +2953,6 @@ pub const Object = struct {
29842953
2985 if (err_return_tracing) {2954 if (err_return_tracing) {
2986 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);2955 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
2987 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
2988 llvm_arg_i += 1;2956 llvm_arg_i += 1;
2989 }2957 }
29902958
...@@ -2995,7 +2963,6 @@ pub const Object = struct {...@@ -2995,7 +2963,6 @@ pub const Object = struct {
2995 },2963 },
2996 .Naked => {2964 .Naked => {
2997 try attributes.addFnAttr(.naked, &o.builder);2965 try attributes.addFnAttr(.naked, &o.builder);
2998 o.addFnAttr(llvm_fn, "naked");
2999 },2966 },
3000 .Async => {2967 .Async => {
3001 function.call_conv = .fastcc;2968 function.call_conv = .fastcc;
...@@ -3014,11 +2981,10 @@ pub const Object = struct {...@@ -3014,11 +2981,10 @@ pub const Object = struct {
3014 }2981 }
30152982
3016 // Function attributes that are independent of analysis results of the function body.2983 // Function attributes that are independent of analysis results of the function body.
3017 try o.addCommonFnAttributes(&attributes, llvm_fn);2984 try o.addCommonFnAttributes(&attributes);
30182985
3019 if (fn_info.return_type == .noreturn_type) {2986 if (fn_info.return_type == .noreturn_type) {
3020 try attributes.addFnAttr(.noreturn, &o.builder);2987 try attributes.addFnAttr(.noreturn, &o.builder);
3021 o.addFnAttr(llvm_fn, "noreturn");
3022 }2988 }
30232989
3024 // Add parameter attributes. We handle only the case of extern functions (no body)2990 // Add parameter attributes. We handle only the case of extern functions (no body)
...@@ -3031,7 +2997,7 @@ pub const Object = struct {...@@ -3031,7 +2997,7 @@ pub const Object = struct {
3031 const param_index = it.zig_index - 1;2997 const param_index = it.zig_index - 1;
3032 const param_ty = fn_info.param_types.get(ip)[param_index].toType();2998 const param_ty = fn_info.param_types.get(ip)[param_index].toType();
3033 if (!isByRef(param_ty, mod)) {2999 if (!isByRef(param_ty, mod)) {
3034 try o.addByValParamAttrsOld(&attributes, llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);3000 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
3035 }3001 }
3036 },3002 },
3037 .byref => {3003 .byref => {
...@@ -3039,11 +3005,10 @@ pub const Object = struct {...@@ -3039,11 +3005,10 @@ pub const Object = struct {
3039 const param_llvm_ty = try o.lowerType(param_ty.toType());3005 const param_llvm_ty = try o.lowerType(param_ty.toType());
3040 const alignment =3006 const alignment =
3041 Builder.Alignment.fromByteUnits(param_ty.toType().abiAlignment(mod));3007 Builder.Alignment.fromByteUnits(param_ty.toType().abiAlignment(mod));
3042 try o.addByRefParamAttrsOld(&attributes, llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);3008 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
3043 },3009 },
3044 .byref_mut => {3010 .byref_mut => {
3045 try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder);3011 try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder);
3046 o.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");
3047 },3012 },
3048 // No attributes needed for these.3013 // No attributes needed for these.
3049 .no_bits,3014 .no_bits,
...@@ -3060,43 +3025,36 @@ pub const Object = struct {...@@ -3060,43 +3025,36 @@ pub const Object = struct {
3060 };3025 };
3061 }3026 }
30623027
3063 function.attributes = try attributes.finish(&o.builder);
3064
3065 try o.builder.llvm.globals.append(o.gpa, llvm_fn);3028 try o.builder.llvm.globals.append(o.gpa, llvm_fn);
3066 gop.value_ptr.* = try o.builder.addGlobal(fqn, global);3029 gop.value_ptr.* = try o.builder.addGlobal(fqn, global);
3067 try o.builder.functions.append(o.gpa, function);3030 try o.builder.functions.append(o.gpa, function);
3031 global.kind.function.setAttributes(try attributes.finish(&o.builder), &o.builder);
3068 return global.kind.function;3032 return global.kind.function;
3069 }3033 }
30703034
3071 fn addCommonFnAttributes(3035 fn addCommonFnAttributes(
3072 o: *Object,3036 o: *Object,
3073 attributes: *Builder.FunctionAttributes.Wip,3037 attributes: *Builder.FunctionAttributes.Wip,
3074 llvm_fn: *llvm.Value,
3075 ) Allocator.Error!void {3038 ) Allocator.Error!void {
3076 const comp = o.module.comp;3039 const comp = o.module.comp;
30773040
3078 if (!comp.bin_file.options.red_zone) {3041 if (!comp.bin_file.options.red_zone) {
3079 try attributes.addFnAttr(.noredzone, &o.builder);3042 try attributes.addFnAttr(.noredzone, &o.builder);
3080 o.addFnAttr(llvm_fn, "noredzone");
3081 }3043 }
3082 if (comp.bin_file.options.omit_frame_pointer) {3044 if (comp.bin_file.options.omit_frame_pointer) {
3083 try attributes.addFnAttr(.{ .string = .{3045 try attributes.addFnAttr(.{ .string = .{
3084 .kind = try o.builder.string("frame-pointer"),3046 .kind = try o.builder.string("frame-pointer"),
3085 .value = try o.builder.string("none"),3047 .value = try o.builder.string("none"),
3086 } }, &o.builder);3048 } }, &o.builder);
3087 o.addFnAttrString(llvm_fn, "frame-pointer", "none");
3088 } else {3049 } else {
3089 try attributes.addFnAttr(.{ .string = .{3050 try attributes.addFnAttr(.{ .string = .{
3090 .kind = try o.builder.string("frame-pointer"),3051 .kind = try o.builder.string("frame-pointer"),
3091 .value = try o.builder.string("all"),3052 .value = try o.builder.string("all"),
3092 } }, &o.builder);3053 } }, &o.builder);
3093 o.addFnAttrString(llvm_fn, "frame-pointer", "all");
3094 }3054 }
3095 try attributes.addFnAttr(.nounwind, &o.builder);3055 try attributes.addFnAttr(.nounwind, &o.builder);
3096 o.addFnAttr(llvm_fn, "nounwind");
3097 if (comp.unwind_tables) {3056 if (comp.unwind_tables) {
3098 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);3057 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
3099 o.addFnAttrInt(llvm_fn, "uwtable", 2);
3100 }3058 }
3101 if (comp.bin_file.options.skip_linker_dependencies or3059 if (comp.bin_file.options.skip_linker_dependencies or
3102 comp.bin_file.options.no_builtin)3060 comp.bin_file.options.no_builtin)
...@@ -3107,38 +3065,31 @@ pub const Object = struct {...@@ -3107,38 +3065,31 @@ pub const Object = struct {
3107 // body of memcpy with a call to memcpy, which would then cause a stack3065 // body of memcpy with a call to memcpy, which would then cause a stack
3108 // overflow instead of performing memcpy.3066 // overflow instead of performing memcpy.
3109 try attributes.addFnAttr(.nobuiltin, &o.builder);3067 try attributes.addFnAttr(.nobuiltin, &o.builder);
3110 o.addFnAttr(llvm_fn, "nobuiltin");
3111 }3068 }
3112 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {3069 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {
3113 try attributes.addFnAttr(.minsize, &o.builder);3070 try attributes.addFnAttr(.minsize, &o.builder);
3114 try attributes.addFnAttr(.optsize, &o.builder);3071 try attributes.addFnAttr(.optsize, &o.builder);
3115 o.addFnAttr(llvm_fn, "minsize");
3116 o.addFnAttr(llvm_fn, "optsize");
3117 }3072 }
3118 if (comp.bin_file.options.tsan) {3073 if (comp.bin_file.options.tsan) {
3119 try attributes.addFnAttr(.sanitize_thread, &o.builder);3074 try attributes.addFnAttr(.sanitize_thread, &o.builder);
3120 o.addFnAttr(llvm_fn, "sanitize_thread");
3121 }3075 }
3122 if (comp.getTarget().cpu.model.llvm_name) |s| {3076 if (comp.getTarget().cpu.model.llvm_name) |s| {
3123 try attributes.addFnAttr(.{ .string = .{3077 try attributes.addFnAttr(.{ .string = .{
3124 .kind = try o.builder.string("target-cpu"),3078 .kind = try o.builder.string("target-cpu"),
3125 .value = try o.builder.string(s),3079 .value = try o.builder.string(s),
3126 } }, &o.builder);3080 } }, &o.builder);
3127 llvm_fn.addFunctionAttr("target-cpu", s);
3128 }3081 }
3129 if (comp.bin_file.options.llvm_cpu_features) |s| {3082 if (comp.bin_file.options.llvm_cpu_features) |s| {
3130 try attributes.addFnAttr(.{ .string = .{3083 try attributes.addFnAttr(.{ .string = .{
3131 .kind = try o.builder.string("target-features"),3084 .kind = try o.builder.string("target-features"),
3132 .value = try o.builder.string(std.mem.span(s)),3085 .value = try o.builder.string(std.mem.span(s)),
3133 } }, &o.builder);3086 } }, &o.builder);
3134 llvm_fn.addFunctionAttr("target-features", s);
3135 }3087 }
3136 if (comp.getTarget().cpu.arch.isBpf()) {3088 if (comp.getTarget().cpu.arch.isBpf()) {
3137 try attributes.addFnAttr(.{ .string = .{3089 try attributes.addFnAttr(.{ .string = .{
3138 .kind = try o.builder.string("no-builtins"),3090 .kind = try o.builder.string("no-builtins"),
3139 .value = .empty,3091 .value = .empty,
3140 } }, &o.builder);3092 } }, &o.builder);
3141 llvm_fn.addFunctionAttr("no-builtins", "");
3142 }3093 }
3143 }3094 }
31443095
...@@ -4483,69 +4434,6 @@ pub const Object = struct {...@@ -4483,69 +4434,6 @@ pub const Object = struct {
4483 return o.builder.castConst(.inttoptr, try o.builder.intConst(llvm_usize, int), llvm_ptr_ty);4434 return o.builder.castConst(.inttoptr, try o.builder.intConst(llvm_usize, int), llvm_ptr_ty);
4484 }4435 }
44854436
4486 fn addAttr(o: *Object, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
4487 return o.addAttrInt(val, index, name, 0);
4488 }
4489
4490 fn addArgAttr(o: *Object, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void {
4491 return o.addAttr(fn_val, param_index + 1, attr_name);
4492 }
4493
4494 fn addArgAttrInt(o: *Object, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void {
4495 return o.addAttrInt(fn_val, param_index + 1, attr_name, int);
4496 }
4497
4498 fn removeAttr(val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
4499 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);
4500 assert(kind_id != 0);
4501 val.removeEnumAttributeAtIndex(index, kind_id);
4502 }
4503
4504 fn addAttrInt(
4505 o: *Object,
4506 val: *llvm.Value,
4507 index: llvm.AttributeIndex,
4508 name: []const u8,
4509 int: u64,
4510 ) void {
4511 const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len);
4512 assert(kind_id != 0);
4513 const llvm_attr = o.builder.llvm.context.createEnumAttribute(kind_id, int);
4514 val.addAttributeAtIndex(index, llvm_attr);
4515 }
4516
4517 fn addAttrString(
4518 o: *Object,
4519 val: *llvm.Value,
4520 index: llvm.AttributeIndex,
4521 name: []const u8,
4522 value: []const u8,
4523 ) void {
4524 const llvm_attr = o.builder.llvm.context.createStringAttribute(
4525 name.ptr,
4526 @intCast(name.len),
4527 value.ptr,
4528 @intCast(value.len),
4529 );
4530 val.addAttributeAtIndex(index, llvm_attr);
4531 }
4532
4533 fn addFnAttr(o: *Object, val: *llvm.Value, name: []const u8) void {
4534 o.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name);
4535 }
4536
4537 fn addFnAttrString(o: *Object, val: *llvm.Value, name: []const u8, value: []const u8) void {
4538 o.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value);
4539 }
4540
4541 fn removeFnAttr(fn_val: *llvm.Value, name: []const u8) void {
4542 removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name);
4543 }
4544
4545 fn addFnAttrInt(o: *Object, fn_val: *llvm.Value, name: []const u8, int: u64) void {
4546 return o.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int);
4547 }
4548
4549 /// If the operand type of an atomic operation is not byte sized we need to4437 /// If the operand type of an atomic operation is not byte sized we need to
4550 /// widen it before using it and then truncate the result.4438 /// widen it before using it and then truncate the result.
4551 /// RMW exchange of floating-point values is bitcasted to same-sized integer4439 /// RMW exchange of floating-point values is bitcasted to same-sized integer
...@@ -4608,80 +4496,13 @@ pub const Object = struct {...@@ -4608,80 +4496,13 @@ pub const Object = struct {
4608 attributes: *Builder.FunctionAttributes.Wip,4496 attributes: *Builder.FunctionAttributes.Wip,
4609 llvm_arg_i: u32,4497 llvm_arg_i: u32,
4610 alignment: Builder.Alignment,4498 alignment: Builder.Alignment,
4611 byval_attr: bool,4499 byval: bool,
4612 param_llvm_ty: Builder.Type,4500 param_llvm_ty: Builder.Type,
4613 ) Allocator.Error!void {4501 ) Allocator.Error!void {
4614 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);4502 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4615 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);4503 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4616 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = alignment }, &o.builder);4504 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = alignment }, &o.builder);
4617 if (byval_attr) {4505 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
4618 try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
4619 }
4620 }
4621
4622 fn addByValParamAttrsOld(
4623 o: *Object,
4624 attributes: *Builder.FunctionAttributes.Wip,
4625 llvm_fn: *llvm.Value,
4626 param_ty: Type,
4627 param_index: u32,
4628 fn_info: InternPool.Key.FuncType,
4629 llvm_arg_i: u32,
4630 ) Allocator.Error!void {
4631 const mod = o.module;
4632 if (param_ty.isPtrAtRuntime(mod)) {
4633 const ptr_info = param_ty.ptrInfo(mod);
4634 if (math.cast(u5, param_index)) |i| {
4635 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {
4636 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);
4637 o.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
4638 }
4639 }
4640 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.flags.is_allowzero) {
4641 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4642 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4643 }
4644 if (ptr_info.flags.is_const) {
4645 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4646 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4647 }
4648 const elem_align = Builder.Alignment.fromByteUnits(
4649 ptr_info.flags.alignment.toByteUnitsOptional() orelse
4650 @max(ptr_info.child.toType().abiAlignment(mod), 1),
4651 );
4652 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
4653 o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align.toByteUnits() orelse 0);
4654 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
4655 .signed => {
4656 try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder);
4657 o.addArgAttr(llvm_fn, llvm_arg_i, "signext");
4658 },
4659 .unsigned => {
4660 try attributes.addParamAttr(llvm_arg_i, .zeroext, &o.builder);
4661 o.addArgAttr(llvm_fn, llvm_arg_i, "zeroext");
4662 },
4663 };
4664 }
4665
4666 fn addByRefParamAttrsOld(
4667 o: *Object,
4668 attributes: *Builder.FunctionAttributes.Wip,
4669 llvm_fn: *llvm.Value,
4670 llvm_arg_i: u32,
4671 alignment: Builder.Alignment,
4672 byval_attr: bool,
4673 param_llvm_ty: Builder.Type,
4674 ) Allocator.Error!void {
4675 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4676 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4677 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = alignment }, &o.builder);
4678 o.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
4679 o.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
4680 o.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment.toByteUnits() orelse 0);
4681 if (byval_attr) {
4682 try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
4683 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty.toLlvm(&o.builder));
4684 }
4685 }4506 }
4686};4507};
46874508
...@@ -9503,16 +9324,16 @@ pub const FuncGen = struct {...@@ -9503,16 +9324,16 @@ pub const FuncGen = struct {
95039324
9504 var attributes: Builder.FunctionAttributes.Wip = .{};9325 var attributes: Builder.FunctionAttributes.Wip = .{};
9505 defer attributes.deinit(&o.builder);9326 defer attributes.deinit(&o.builder);
95069327 try o.addCommonFnAttributes(&attributes);
9507 function_index.toLlvm(&o.builder).setLinkage(.Internal);9328 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9508 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9509 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
95109329
9511 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;9330 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9512 function_index.ptr(&o.builder).call_conv = .fastcc;9331 function_index.ptr(&o.builder).call_conv = .fastcc;
9513 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);
9514 gop.value_ptr.* = function_index;9332 gop.value_ptr.* = function_index;
95159333
9334 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9335 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9336
9516 var wip = try Builder.WipFunction.init(&o.builder, function_index);9337 var wip = try Builder.WipFunction.init(&o.builder, function_index);
9517 defer wip.deinit();9338 defer wip.deinit();
9518 wip.cursor = .{ .block = try wip.block(0, "Entry") };9339 wip.cursor = .{ .block = try wip.block(0, "Entry") };
...@@ -9577,16 +9398,16 @@ pub const FuncGen = struct {...@@ -9577,16 +9398,16 @@ pub const FuncGen = struct {
95779398
9578 var attributes: Builder.FunctionAttributes.Wip = .{};9399 var attributes: Builder.FunctionAttributes.Wip = .{};
9579 defer attributes.deinit(&o.builder);9400 defer attributes.deinit(&o.builder);
95809401 try o.addCommonFnAttributes(&attributes);
9581 function_index.toLlvm(&o.builder).setLinkage(.Internal);9402 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9582 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9583 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
95849403
9585 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;9404 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9586 function_index.ptr(&o.builder).call_conv = .fastcc;9405 function_index.ptr(&o.builder).call_conv = .fastcc;
9587 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);
9588 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;9406 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
95899407
9408 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9409 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9410
9590 var wip = try Builder.WipFunction.init(&o.builder, function_index);9411 var wip = try Builder.WipFunction.init(&o.builder, function_index);
9591 defer wip.deinit();9412 defer wip.deinit();
9592 wip.cursor = .{ .block = try wip.block(0, "Entry") };9413 wip.cursor = .{ .block = try wip.block(0, "Entry") };
...@@ -9659,14 +9480,14 @@ pub const FuncGen = struct {...@@ -9659,14 +9480,14 @@ pub const FuncGen = struct {
96599480
9660 var attributes: Builder.FunctionAttributes.Wip = .{};9481 var attributes: Builder.FunctionAttributes.Wip = .{};
9661 defer attributes.deinit(&o.builder);9482 defer attributes.deinit(&o.builder);
96629483 try o.addCommonFnAttributes(&attributes);
9663 function_index.toLlvm(&o.builder).setLinkage(.Internal);9484 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9664 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9665 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
96669485
9667 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;9486 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9668 function_index.ptr(&o.builder).call_conv = .fastcc;9487 function_index.ptr(&o.builder).call_conv = .fastcc;
9669 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);9488
9489 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9490 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
96709491
9671 return function_index;9492 return function_index;
9672 }9493 }
src/codegen/llvm/Builder.zig+98-11
...@@ -1349,21 +1349,29 @@ pub const Attribute = union(Kind) {...@@ -1349,21 +1349,29 @@ pub const Attribute = union(Kind) {
1349 //sanitize_memtag,1349 //sanitize_memtag,
1350 sanitize_address_dyninit,1350 sanitize_address_dyninit,
13511351
1352 string = std.math.maxInt(u31) - 1,1352 string = std.math.maxInt(u31),
1353 none = std.math.maxInt(u31),1353 none = std.math.maxInt(u32),
1354 _,1354 _,
13551355
1356 pub const len = @typeInfo(Kind).Enum.fields.len - 2;1356 pub const len = @typeInfo(Kind).Enum.fields.len - 2;
13571357
1358 pub fn fromString(str: String) Kind {1358 pub fn fromString(str: String) Kind {
1359 assert(!str.isAnon());1359 assert(!str.isAnon());
1360 return @enumFromInt(@intFromEnum(str));1360 const kind: Kind = @enumFromInt(@intFromEnum(str));
1361 assert(kind != .none);
1362 return kind;
1361 }1363 }
13621364
1363 fn toString(self: Kind) ?String {1365 fn toString(self: Kind) ?String {
1366 assert(self != .none);
1364 const str: String = @enumFromInt(@intFromEnum(self));1367 const str: String = @enumFromInt(@intFromEnum(self));
1365 return if (str.isAnon()) null else str;1368 return if (str.isAnon()) null else str;
1366 }1369 }
1370
1371 fn toLlvm(self: Kind, builder: *const Builder) *c_uint {
1372 assert(builder.useLibLlvm());
1373 return &builder.llvm.attribute_kind_ids.?[@intFromEnum(self)];
1374 }
1367 };1375 };
13681376
1369 pub const FpClass = packed struct(u32) {1377 pub const FpClass = packed struct(u32) {
...@@ -3147,6 +3155,86 @@ pub const Function = struct {...@@ -3147,6 +3155,86 @@ pub const Function = struct {
3147 return self.toConst(builder).toValue();3155 return self.toConst(builder).toValue();
3148 }3156 }
31493157
3158 pub fn setAttributes(
3159 self: Index,
3160 new_function_attributes: FunctionAttributes,
3161 builder: *Builder,
3162 ) void {
3163 if (builder.useLibLlvm()) {
3164 const llvm_function = self.toLlvm(builder);
3165 const old_function_attributes = self.ptrConst(builder).attributes;
3166 for (0..@max(
3167 old_function_attributes.slice(builder).len,
3168 new_function_attributes.slice(builder).len,
3169 )) |function_attribute_index| {
3170 const llvm_attribute_index =
3171 @as(llvm.AttributeIndex, @intCast(function_attribute_index)) -% 1;
3172 const old_attributes_slice =
3173 old_function_attributes.get(function_attribute_index, builder).slice(builder);
3174 const new_attributes_slice =
3175 new_function_attributes.get(function_attribute_index, builder).slice(builder);
3176 var old_attribute_index: usize = 0;
3177 var new_attribute_index: usize = 0;
3178 while (true) {
3179 const old_attribute_kind = if (old_attribute_index < old_attributes_slice.len)
3180 old_attributes_slice[old_attribute_index].getKind(builder)
3181 else
3182 .none;
3183 const new_attribute_kind = if (new_attribute_index < new_attributes_slice.len)
3184 new_attributes_slice[new_attribute_index].getKind(builder)
3185 else
3186 .none;
3187 switch (std.math.order(
3188 @intFromEnum(old_attribute_kind),
3189 @intFromEnum(new_attribute_kind),
3190 )) {
3191 .lt => {
3192 // Removed
3193 if (old_attribute_kind.toString()) |name| {
3194 const slice = name.slice(builder).?;
3195 llvm_function.removeStringAttributeAtIndex(
3196 llvm_attribute_index,
3197 slice.ptr,
3198 @intCast(slice.len),
3199 );
3200 } else {
3201 const llvm_kind_id = old_attribute_kind.toLlvm(builder).*;
3202 assert(llvm_kind_id != 0);
3203 llvm_function.removeEnumAttributeAtIndex(
3204 llvm_attribute_index,
3205 llvm_kind_id,
3206 );
3207 }
3208 old_attribute_index += 1;
3209 continue;
3210 },
3211 .eq => {
3212 // Iteration finished
3213 if (old_attribute_kind == .none) break;
3214 // No change
3215 if (old_attributes_slice[old_attribute_index] ==
3216 new_attributes_slice[new_attribute_index])
3217 {
3218 old_attribute_index += 1;
3219 new_attribute_index += 1;
3220 continue;
3221 }
3222 old_attribute_index += 1;
3223 },
3224 .gt => {},
3225 }
3226 // New or changed
3227 llvm_function.addAttributeAtIndex(
3228 llvm_attribute_index,
3229 new_attributes_slice[new_attribute_index].toLlvm(builder),
3230 );
3231 new_attribute_index += 1;
3232 }
3233 }
3234 }
3235 self.ptr(builder).attributes = new_function_attributes;
3236 }
3237
3150 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {3238 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
3151 return self.ptrConst(builder).global.toLlvm(builder);3239 return self.ptrConst(builder).global.toLlvm(builder);
3152 }3240 }
...@@ -5048,9 +5136,8 @@ pub const WipFunction = struct {...@@ -5048,9 +5136,8 @@ pub const WipFunction = struct {
5048 .tail, .tail_fast => .Tail,5136 .tail, .tail_fast => .Tail,
5049 });5137 });
5050 for (0.., function_attributes.slice(self.builder)) |index, attributes| {5138 for (0.., function_attributes.slice(self.builder)) |index, attributes| {
5051 const attribute_index = @as(llvm.AttributeIndex, @intCast(index)) -% 1;
5052 for (attributes.slice(self.builder)) |attribute| llvm_instruction.addCallSiteAttribute(5139 for (attributes.slice(self.builder)) |attribute| llvm_instruction.addCallSiteAttribute(
5053 attribute_index,5140 @as(llvm.AttributeIndex, @intCast(index)) -% 1,
5054 attribute.toLlvm(self.builder),5141 attribute.toLlvm(self.builder),
5055 );5142 );
5056 }5143 }
...@@ -7368,16 +7455,16 @@ pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Inde...@@ -7368,16 +7455,16 @@ pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Inde
7368 gop.value_ptr.* = {};7455 gop.value_ptr.* = {};
7369 if (self.useLibLlvm()) self.llvm.attributes.appendAssumeCapacity(switch (attribute) {7456 if (self.useLibLlvm()) self.llvm.attributes.appendAssumeCapacity(switch (attribute) {
7370 else => llvm_attr: {7457 else => llvm_attr: {
7371 const kind_id = &self.llvm.attribute_kind_ids.?[@intFromEnum(attribute)];7458 const llvm_kind_id = attribute.getKind().toLlvm(self);
7372 if (kind_id.* == 0) {7459 if (llvm_kind_id.* == 0) {
7373 const name = @tagName(attribute);7460 const name = @tagName(attribute);
7374 kind_id.* = llvm.getEnumAttributeKindForName(name.ptr, name.len);7461 llvm_kind_id.* = llvm.getEnumAttributeKindForName(name.ptr, name.len);
7375 assert(kind_id.* != 0);7462 assert(llvm_kind_id.* != 0);
7376 }7463 }
7377 break :llvm_attr switch (attribute) {7464 break :llvm_attr switch (attribute) {
7378 else => switch (attribute) {7465 else => switch (attribute) {
7379 inline else => |value| self.llvm.context.createEnumAttribute(7466 inline else => |value| self.llvm.context.createEnumAttribute(
7380 kind_id.*,7467 llvm_kind_id.*,
7381 switch (@TypeOf(value)) {7468 switch (@TypeOf(value)) {
7382 void => 0,7469 void => 0,
7383 u32 => value,7470 u32 => value,
...@@ -7411,7 +7498,7 @@ pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Inde...@@ -7411,7 +7498,7 @@ pub fn attr(self: *Builder, attribute: Attribute) Allocator.Error!Attribute.Inde
7411 .inalloca,7498 .inalloca,
7412 .sret,7499 .sret,
7413 .elementtype,7500 .elementtype,
7414 => |ty| self.llvm.context.createTypeAttribute(kind_id.*, ty.toLlvm(self)),7501 => |ty| self.llvm.context.createTypeAttribute(llvm_kind_id.*, ty.toLlvm(self)),
7415 .string, .none => unreachable,7502 .string, .none => unreachable,
7416 };7503 };
7417 },7504 },
src/codegen/llvm/bindings.zig+5-8
...@@ -115,12 +115,15 @@ pub const Context = opaque {...@@ -115,12 +115,15 @@ pub const Context = opaque {
115};115};
116116
117pub const Value = opaque {117pub const Value = opaque {
118 pub const addAttributeAtIndex = ZigLLVMAddAttributeAtIndex;118 pub const addAttributeAtIndex = LLVMAddAttributeAtIndex;
119 extern fn ZigLLVMAddAttributeAtIndex(*Value, Idx: AttributeIndex, A: *Attribute) void;119 extern fn LLVMAddAttributeAtIndex(F: *Value, Idx: AttributeIndex, A: *Attribute) void;
120120
121 pub const removeEnumAttributeAtIndex = LLVMRemoveEnumAttributeAtIndex;121 pub const removeEnumAttributeAtIndex = LLVMRemoveEnumAttributeAtIndex;
122 extern fn LLVMRemoveEnumAttributeAtIndex(F: *Value, Idx: AttributeIndex, KindID: c_uint) void;122 extern fn LLVMRemoveEnumAttributeAtIndex(F: *Value, Idx: AttributeIndex, KindID: c_uint) void;
123123
124 pub const removeStringAttributeAtIndex = LLVMRemoveStringAttributeAtIndex;
125 extern fn LLVMRemoveStringAttributeAtIndex(F: *Value, Idx: AttributeIndex, K: [*]const u8, KLen: c_uint) void;
126
124 pub const getFirstBasicBlock = LLVMGetFirstBasicBlock;127 pub const getFirstBasicBlock = LLVMGetFirstBasicBlock;
125 extern fn LLVMGetFirstBasicBlock(Fn: *Value) ?*BasicBlock;128 extern fn LLVMGetFirstBasicBlock(Fn: *Value) ?*BasicBlock;
126129
...@@ -342,9 +345,6 @@ pub const Value = opaque {...@@ -342,9 +345,6 @@ pub const Value = opaque {
342 pub const deleteFunction = LLVMDeleteFunction;345 pub const deleteFunction = LLVMDeleteFunction;
343 extern fn LLVMDeleteFunction(Fn: *Value) void;346 extern fn LLVMDeleteFunction(Fn: *Value) void;
344347
345 pub const addSretAttr = ZigLLVMAddSretAttr;
346 extern fn ZigLLVMAddSretAttr(fn_ref: *Value, type_val: *Type) void;
347
348 pub const getParam = LLVMGetParam;348 pub const getParam = LLVMGetParam;
349 extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value;349 extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value;
350350
...@@ -369,9 +369,6 @@ pub const Value = opaque {...@@ -369,9 +369,6 @@ pub const Value = opaque {
369 pub const getAlignment = LLVMGetAlignment;369 pub const getAlignment = LLVMGetAlignment;
370 extern fn LLVMGetAlignment(V: *Value) c_uint;370 extern fn LLVMGetAlignment(V: *Value) c_uint;
371371
372 pub const addFunctionAttr = ZigLLVMAddFunctionAttr;
373 extern fn ZigLLVMAddFunctionAttr(Fn: *Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void;
374
375 pub const addByValAttr = ZigLLVMAddByValAttr;372 pub const addByValAttr = ZigLLVMAddByValAttr;
376 extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void;373 extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void;
377374
src/zig_llvm.cpp-46
...@@ -408,14 +408,6 @@ void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCall...@@ -408,14 +408,6 @@ void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCall
408 unwrap<CallInst>(Call)->setTailCallKind(TCK);408 unwrap<CallInst>(Call)->setTailCallKind(TCK);
409}409}
410410
411void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A) {
412 if (isa<Function>(unwrap(Val))) {
413 unwrap<Function>(Val)->addAttributeAtIndex(Idx, unwrap(A));
414 } else {
415 unwrap<CallInst>(Val)->addAttributeAtIndex(Idx, unwrap(A));
416 }
417}
418
419LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,411LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
420 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile)412 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile)
421{413{
...@@ -950,36 +942,6 @@ void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {...@@ -950,36 +942,6 @@ void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
950 }942 }
951}943}
952944
953void ZigLLVMAddByValAttr(LLVMValueRef Val, unsigned ArgNo, LLVMTypeRef type_val) {
954 if (isa<Function>(unwrap(Val))) {
955 Function *func = unwrap<Function>(Val);
956 AttrBuilder attr_builder(func->getContext());
957 Type *llvm_type = unwrap<Type>(type_val);
958 attr_builder.addByValAttr(llvm_type);
959 func->addParamAttrs(ArgNo, attr_builder);
960 } else {
961 CallInst *call = unwrap<CallInst>(Val);
962 AttrBuilder attr_builder(call->getContext());
963 Type *llvm_type = unwrap<Type>(type_val);
964 attr_builder.addByValAttr(llvm_type);
965 // NOTE: +1 here since index 0 refers to the return value
966 call->addAttributeAtIndex(ArgNo + 1, attr_builder.getAttribute(Attribute::ByVal));
967 }
968}
969
970void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) {
971 Function *func = unwrap<Function>(fn_ref);
972 AttrBuilder attr_builder(func->getContext());
973 Type *llvm_type = unwrap<Type>(type_val);
974 attr_builder.addStructRetAttr(llvm_type);
975 func->addParamAttrs(0, attr_builder);
976}
977
978void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) {
979 Function *func = unwrap<Function>(fn_ref);
980 func->addFnAttr(attr_name, attr_value);
981}
982
983void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {945void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
984 cl::ParseCommandLineOptions(argc, argv);946 cl::ParseCommandLineOptions(argc, argv);
985}947}
...@@ -1172,14 +1134,6 @@ bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disab...@@ -1172,14 +1134,6 @@ bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disab
1172 return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);1134 return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
1173}1135}
11741136
1175inline LLVMAttributeRef wrap(Attribute Attr) {
1176 return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
1177}
1178
1179inline Attribute unwrap(LLVMAttributeRef Attr) {
1180 return Attribute::fromRawPointer(Attr);
1181}
1182
1183LLVMValueRef ZigLLVMBuildAndReduce(LLVMBuilderRef B, LLVMValueRef Val) {1137LLVMValueRef ZigLLVMBuildAndReduce(LLVMBuilderRef B, LLVMValueRef Val) {
1184 return wrap(unwrap(B)->CreateAndReduce(unwrap(Val)));1138 return wrap(unwrap(B)->CreateAndReduce(unwrap(Val)));
1185}1139}
src/zig_llvm.h-14
...@@ -122,15 +122,6 @@ enum ZigLLVM_CallingConv {...@@ -122,15 +122,6 @@ enum ZigLLVM_CallingConv {
122 ZigLLVM_MaxID = 1023,122 ZigLLVM_MaxID = 1023,
123};123};
124124
125enum ZigLLVM_CallAttr {
126 ZigLLVM_CallAttrAuto,
127 ZigLLVM_CallAttrNeverTail,
128 ZigLLVM_CallAttrNeverInline,
129 ZigLLVM_CallAttrAlwaysTail,
130 ZigLLVM_CallAttrAlwaysInline,
131};
132ZIG_EXTERN_C void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A);
133
134ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,125ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
135 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile);126 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile);
136127
...@@ -301,11 +292,6 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBu...@@ -301,11 +292,6 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBu
301292
302ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);293ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
303294
304ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
305ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val);
306ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val);
307ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
308
309ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);295ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
310296
311ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression);297ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression);