Force an evaluation of the expression; this tries to prevent the compiler from optimizing the computation away even if the result eventually gets discarded.
pub fn doNotOptimizeAway(val: anytype) void
pub fn doNotOptimizeAway(val: anytype) void {
if (@inComptime()) return;
const max_gp_register_bits = @bitSizeOf(c_long);
const t = @typeInfo(@TypeOf(val));
switch (t) {
.void, .null, .comptime_int, .comptime_float => return,
.@"enum" => doNotOptimizeAway(@backingInt(val)),
.bool => doNotOptimizeAway(@intFromBool(val)),
.int => {
const bits = t.int.bits;
if (bits <= max_gp_register_bits and builtin.zig_backend != .stage2_c) {
const val2 = @as(
@Int(t.int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, bits))),
val,
);
asm volatile (""
:
: [_] "r" (val2),
);
} else doNotOptimizeAway(&val);
},
.float => {
if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c) {
asm volatile (""
:
: [_] "rm" (val),
);
} else doNotOptimizeAway(&val);
},
.pointer => {
if (builtin.zig_backend == .stage2_c) {
doNotOptimizeAwayC(val);
} else {
asm volatile (""
:
: [_] "m" (val),
: .{ .memory = true });
}
},
.array => {
if (t.array.len * @sizeOf(t.array.child) <= 64) {
for (val) |v| doNotOptimizeAway(v);
} else doNotOptimizeAway(&val);
},
else => doNotOptimizeAway(&val),
}
}