aboutsummaryrefslogtreecommitdiff
path: root/src/Air.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-04-21 13:32:25 -0700
committerGitHub <noreply@github.com>2023-04-21 13:32:25 -0700
commit528b66f6ec9cfb140abff3dc0c4735c179520f42 (patch)
tree6fc4f164a93a6bd3c2c3467457aedce6fa7959b3 /src/Air.zig
parent391663e497f1871f6bddcf9cbc500710aa9aac4d (diff)
parentb3f9fe6d0439bcbb5c6baa77c0646c4da2e06dd7 (diff)
downloadzig-528b66f6ec9cfb140abff3dc0c4735c179520f42.tar.gz
zig-528b66f6ec9cfb140abff3dc0c4735c179520f42.zip
Merge pull request #15355 from mlugg/feat/liveness-control-flow
Liveness: control flow analysis and other goodies
Diffstat (limited to 'src/Air.zig')
-rw-r--r--src/Air.zig214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/Air.zig b/src/Air.zig
index b8771b2a61..19ba576a5f 100644
--- a/src/Air.zig
+++ b/src/Air.zig
@@ -1375,3 +1375,217 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
}
return bytes[0..end :0];
}
+
+/// Returns whether the given instruction must always be lowered, for instance because it can cause
+/// side effects. If an instruction does not need to be lowered, and Liveness determines its result
+/// is unused, backends should avoid lowering it.
+pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {
+ const data = air.instructions.items(.data)[inst];
+ return switch (air.instructions.items(.tag)[inst]) {
+ .arg,
+ .block,
+ .loop,
+ .br,
+ .trap,
+ .breakpoint,
+ .call,
+ .call_always_tail,
+ .call_never_tail,
+ .call_never_inline,
+ .cond_br,
+ .switch_br,
+ .@"try",
+ .try_ptr,
+ .dbg_stmt,
+ .dbg_block_begin,
+ .dbg_block_end,
+ .dbg_inline_begin,
+ .dbg_inline_end,
+ .dbg_var_ptr,
+ .dbg_var_val,
+ .ret,
+ .ret_load,
+ .store,
+ .unreach,
+ .optional_payload_ptr_set,
+ .errunion_payload_ptr_set,
+ .set_union_tag,
+ .memset,
+ .memcpy,
+ .cmpxchg_weak,
+ .cmpxchg_strong,
+ .fence,
+ .atomic_store_unordered,
+ .atomic_store_monotonic,
+ .atomic_store_release,
+ .atomic_store_seq_cst,
+ .atomic_rmw,
+ .prefetch,
+ .wasm_memory_grow,
+ .set_err_return_trace,
+ .vector_store_elem,
+ .c_va_arg,
+ .c_va_copy,
+ .c_va_end,
+ .c_va_start,
+ => true,
+
+ .add,
+ .add_optimized,
+ .addwrap,
+ .addwrap_optimized,
+ .add_sat,
+ .sub,
+ .sub_optimized,
+ .subwrap,
+ .subwrap_optimized,
+ .sub_sat,
+ .mul,
+ .mul_optimized,
+ .mulwrap,
+ .mulwrap_optimized,
+ .mul_sat,
+ .div_float,
+ .div_float_optimized,
+ .div_trunc,
+ .div_trunc_optimized,
+ .div_floor,
+ .div_floor_optimized,
+ .div_exact,
+ .div_exact_optimized,
+ .rem,
+ .rem_optimized,
+ .mod,
+ .mod_optimized,
+ .ptr_add,
+ .ptr_sub,
+ .max,
+ .min,
+ .add_with_overflow,
+ .sub_with_overflow,
+ .mul_with_overflow,
+ .shl_with_overflow,
+ .alloc,
+ .ret_ptr,
+ .bit_and,
+ .bit_or,
+ .shr,
+ .shr_exact,
+ .shl,
+ .shl_exact,
+ .shl_sat,
+ .xor,
+ .not,
+ .bitcast,
+ .ret_addr,
+ .frame_addr,
+ .clz,
+ .ctz,
+ .popcount,
+ .byte_swap,
+ .bit_reverse,
+ .sqrt,
+ .sin,
+ .cos,
+ .tan,
+ .exp,
+ .exp2,
+ .log,
+ .log2,
+ .log10,
+ .fabs,
+ .floor,
+ .ceil,
+ .round,
+ .trunc_float,
+ .neg,
+ .neg_optimized,
+ .cmp_lt,
+ .cmp_lt_optimized,
+ .cmp_lte,
+ .cmp_lte_optimized,
+ .cmp_eq,
+ .cmp_eq_optimized,
+ .cmp_gte,
+ .cmp_gte_optimized,
+ .cmp_gt,
+ .cmp_gt_optimized,
+ .cmp_neq,
+ .cmp_neq_optimized,
+ .cmp_vector,
+ .cmp_vector_optimized,
+ .constant,
+ .const_ty,
+ .is_null,
+ .is_non_null,
+ .is_null_ptr,
+ .is_non_null_ptr,
+ .is_err,
+ .is_non_err,
+ .is_err_ptr,
+ .is_non_err_ptr,
+ .bool_and,
+ .bool_or,
+ .ptrtoint,
+ .bool_to_int,
+ .fptrunc,
+ .fpext,
+ .intcast,
+ .trunc,
+ .optional_payload,
+ .optional_payload_ptr,
+ .wrap_optional,
+ .unwrap_errunion_payload,
+ .unwrap_errunion_err,
+ .unwrap_errunion_payload_ptr,
+ .unwrap_errunion_err_ptr,
+ .wrap_errunion_payload,
+ .wrap_errunion_err,
+ .struct_field_ptr,
+ .struct_field_ptr_index_0,
+ .struct_field_ptr_index_1,
+ .struct_field_ptr_index_2,
+ .struct_field_ptr_index_3,
+ .struct_field_val,
+ .get_union_tag,
+ .slice,
+ .slice_len,
+ .slice_ptr,
+ .ptr_slice_len_ptr,
+ .ptr_slice_ptr_ptr,
+ .array_elem_val,
+ .slice_elem_ptr,
+ .ptr_elem_ptr,
+ .array_to_slice,
+ .float_to_int,
+ .float_to_int_optimized,
+ .int_to_float,
+ .reduce,
+ .reduce_optimized,
+ .splat,
+ .shuffle,
+ .select,
+ .is_named_enum_value,
+ .tag_name,
+ .error_name,
+ .error_set_has_value,
+ .aggregate_init,
+ .union_init,
+ .mul_add,
+ .field_parent_ptr,
+ .wasm_memory_size,
+ .cmp_lt_errors_len,
+ .err_return_trace,
+ .addrspace_cast,
+ .save_err_return_trace_index,
+ .work_item_id,
+ .work_group_size,
+ .work_group_id,
+ => false,
+
+ .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,
+ .load => air.typeOf(data.ty_op.operand).isVolatilePtr(),
+ .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs).isVolatilePtr(),
+ .atomic_load => air.typeOf(data.atomic_load.ptr).isVolatilePtr(),
+ };
+}