cranelift: Rework block instructions to use BlockCall (#5464)

Add a new type BlockCall that represents the pair of a block name with arguments to be passed to it. (The mnemonic here is that it looks a bit like a function call.) Rework the implementation of jump, brz, and brnz to use BlockCall instead of storing the block arguments as varargs in the instruction's ValueList.

To ensure that we're processing block arguments from BlockCall values in instructions, three new functions have been introduced on DataFlowGraph that both sets of arguments:

inst_values - returns an iterator that traverses values in the instruction and block arguments
map_inst_values - applies a function to each value in the instruction and block arguments
overwrite_inst_values - overwrite all values in an instruction and block arguments with values from the iterator

Co-authored-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
Trevor Elliott
2023-01-17 16:31:15 -08:00
committed by GitHub
parent 3a2ca67570
commit 1e6c13d83e
32 changed files with 475 additions and 422 deletions

View File

@@ -2464,7 +2464,7 @@
;;; Rules for `brz`/`brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; `brz` following `icmp`
(rule (lower_branch (brz (maybe_uextend (icmp cc x @ (value_type ty) y)) _ _) targets)
(rule (lower_branch (brz (maybe_uextend (icmp cc x @ (value_type ty) y)) _) targets)
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y ty))
;; Negate the condition for `brz`.
(cond Cond (invert_cond (cond_code (flags_and_cc_cc comparison))))
@@ -2476,7 +2476,7 @@
not_taken
(cond_br_cond cond))))))
;; `brnz` following `icmp`
(rule (lower_branch (brnz (maybe_uextend (icmp cc x @ (value_type ty) y)) _ _) targets)
(rule (lower_branch (brnz (maybe_uextend (icmp cc x @ (value_type ty) y)) _) targets)
(let ((comparison FlagsAndCC (lower_icmp_into_flags cc x y ty))
(cond Cond (cond_code (flags_and_cc_cc comparison)))
(taken BranchTarget (branch_target targets 0))
@@ -2487,7 +2487,7 @@
not_taken
(cond_br_cond cond))))))
;; `brz` following `fcmp`
(rule (lower_branch (brz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _ _) targets)
(rule (lower_branch (brz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _) targets)
(let ((cond Cond (fp_cond_code cc))
(cond Cond (invert_cond cond)) ;; negate for `brz`
(taken BranchTarget (branch_target targets 0))
@@ -2497,7 +2497,7 @@
(cond_br taken not_taken
(cond_br_cond cond))))))
;; `brnz` following `fcmp`
(rule (lower_branch (brnz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _ _) targets)
(rule (lower_branch (brnz (maybe_uextend (fcmp cc x @ (value_type (ty_scalar_float ty)) y)) _) targets)
(let ((cond Cond (fp_cond_code cc))
(taken BranchTarget (branch_target targets 0))
(not_taken BranchTarget (branch_target targets 1)))
@@ -2506,7 +2506,7 @@
(cond_br taken not_taken
(cond_br_cond cond))))))
;; standard `brz`
(rule -1 (lower_branch (brz c @ (value_type $I128) _ _) targets)
(rule -1 (lower_branch (brz c @ (value_type $I128) _) targets)
(let ((flags ProducesFlags (flags_to_producesflags c))
(c ValueRegs (put_in_regs c))
(c_lo Reg (value_regs_get c 0))
@@ -2517,7 +2517,7 @@
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_zero rt))))))
(rule -2 (lower_branch (brz c @ (value_type ty) _ _) targets)
(rule -2 (lower_branch (brz c @ (value_type ty) _) targets)
(if (ty_int_ref_scalar_64 ty))
(let ((flags ProducesFlags (flags_to_producesflags c))
(rt Reg (put_in_reg_zext64 c))
@@ -2527,7 +2527,7 @@
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_zero rt))))))
;; standard `brnz`
(rule -1 (lower_branch (brnz c @ (value_type $I128) _ _) targets)
(rule -1 (lower_branch (brnz c @ (value_type $I128) _) targets)
(let ((flags ProducesFlags (flags_to_producesflags c))
(c ValueRegs (put_in_regs c))
(c_lo Reg (value_regs_get c 0))
@@ -2538,7 +2538,7 @@
(emit_side_effect
(with_flags_side_effect flags
(cond_br taken not_taken (cond_br_not_zero rt))))))
(rule -2 (lower_branch (brnz c @ (value_type ty) _ _) targets)
(rule -2 (lower_branch (brnz c @ (value_type ty) _) targets)
(if (ty_int_ref_scalar_64 ty))
(let ((flags ProducesFlags (flags_to_producesflags c))
(rt Reg (put_in_reg_zext64 c))
@@ -2550,7 +2550,7 @@
;;; Rules for `jump` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower_branch (jump _ _) targets)
(rule (lower_branch (jump _) targets)
(emit_side_effect (aarch64_jump (branch_target targets 0))))
;;; Rules for `br_table` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@@ -1857,7 +1857,7 @@
(extern constructor vec_label_get vec_label_get)
(decl partial lower_branch (Inst VecMachLabel) Unit)
(rule (lower_branch (jump _ _) targets )
(rule (lower_branch (jump _) targets )
(emit_side_effect (SideEffectNoResult.Inst (gen_jump (vec_label_get targets 0)))))
;;; cc a b targets Type
@@ -1900,44 +1900,44 @@
;;;;;
(rule
(lower_branch (brz v @ (value_type ty) _ _) targets)
(lower_branch (brz v @ (value_type ty) _) targets)
(lower_brz_or_nz (IntCC.Equal) (normalize_cmp_value ty v) targets ty))
;; Special case for SI128 to reify the comparison value and branch on it.
(rule 2
(lower_branch (brz v @ (value_type $I128) _ _) targets)
(lower_branch (brz v @ (value_type $I128) _) targets)
(let ((zero ValueRegs (value_regs (zero_reg) (zero_reg)))
(cmp Reg (gen_icmp (IntCC.Equal) v zero $I128)))
(lower_brz_or_nz (IntCC.NotEqual) cmp targets $I64)))
(rule 1
(lower_branch (brz (icmp cc a @ (value_type ty) b) _ _) targets)
(lower_branch (brz (icmp cc a @ (value_type ty) b) _) targets)
(lower_br_icmp (intcc_inverse cc) a b targets ty))
(rule 1
(lower_branch (brz (fcmp cc a @ (value_type ty) b) _ _) targets)
(lower_branch (brz (fcmp cc a @ (value_type ty) b) _) targets)
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp (floatcc_inverse cc) ty a b) then else))))
;;;;
(rule
(lower_branch (brnz v @ (value_type ty) _ _) targets)
(lower_branch (brnz v @ (value_type ty) _) targets)
(lower_brz_or_nz (IntCC.NotEqual) (normalize_cmp_value ty v) targets ty))
;; Special case for SI128 to reify the comparison value and branch on it.
(rule 2
(lower_branch (brnz v @ (value_type $I128) _ _) targets)
(lower_branch (brnz v @ (value_type $I128) _) targets)
(let ((zero ValueRegs (value_regs (zero_reg) (zero_reg)))
(cmp Reg (gen_icmp (IntCC.NotEqual) v zero $I128)))
(lower_brz_or_nz (IntCC.NotEqual) cmp targets $I64)))
(rule 1
(lower_branch (brnz (icmp cc a @ (value_type ty) b) _ _) targets)
(lower_branch (brnz (icmp cc a @ (value_type ty) b) _) targets)
(lower_br_icmp cc a b targets ty))
(rule 1
(lower_branch (brnz (fcmp cc a @ (value_type ty) b) _ _) targets)
(lower_branch (brnz (fcmp cc a @ (value_type ty) b) _) targets)
(let ((then BranchTarget (label_to_br_target (vec_label_get targets 0)))
(else BranchTarget (label_to_br_target (vec_label_get targets 1))))
(emit_side_effect (cond_br (emit_fcmp cc ty a b) then else))))

View File

@@ -3714,7 +3714,7 @@
;; Unconditional branch. The target is found as first (and only) element in
;; the list of the current block's branch targets passed as `targets`.
(rule (lower_branch (jump _ _) targets)
(rule (lower_branch (jump _) targets)
(emit_side_effect (jump_impl (vec_element targets 0))))
@@ -3755,7 +3755,7 @@
;; Two-way conditional branch on zero. `targets` contains:
;; - element 0: target if the condition is true (i.e. value is zero)
;; - element 1: target if the condition is false (i.e. value is nonzero)
(rule (lower_branch (brz val_cond _ _) targets)
(rule (lower_branch (brz val_cond _) targets)
(emit_side_effect (cond_br_bool (invert_bool (value_nonzero val_cond))
(vec_element targets 0)
(vec_element targets 1))))
@@ -3766,7 +3766,7 @@
;; Two-way conditional branch on nonzero. `targets` contains:
;; - element 0: target if the condition is true (i.e. value is nonzero)
;; - element 1: target if the condition is false (i.e. value is zero)
(rule (lower_branch (brnz val_cond _ _) targets)
(rule (lower_branch (brnz val_cond _) targets)
(emit_side_effect (cond_br_bool (value_nonzero val_cond)
(vec_element targets 0)
(vec_element targets 1))))

View File

@@ -2882,46 +2882,46 @@
;; Rules for `jump` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower_branch (jump _ _) (single_target target))
(rule (lower_branch (jump _) (single_target target))
(emit_side_effect (jmp_known target)))
;; Rules for `brz` and `brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 2 (lower_branch (brz (maybe_uextend (icmp cc a b)) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brz (maybe_uextend (icmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp IcmpCondResult (invert_icmp_cond_result (emit_cmp cc a b))))
(emit_side_effect (jmp_cond_icmp cmp taken not_taken))))
(rule 2 (lower_branch (brz (maybe_uextend (fcmp cc a b)) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brz (maybe_uextend (fcmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp FcmpCondResult (emit_fcmp (floatcc_inverse cc) a b)))
(emit_side_effect (jmp_cond_fcmp cmp taken not_taken))))
(rule 1 (lower_branch (brz val @ (value_type $I128) _ _) (two_targets taken not_taken))
(rule 1 (lower_branch (brz val @ (value_type $I128) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (cmp_zero_i128 (CC.NZ) val) taken not_taken)))
(rule 0 (lower_branch (brz val @ (value_type (ty_int_bool_or_ref)) _ _) (two_targets taken not_taken))
(rule 0 (lower_branch (brz val @ (value_type (ty_int_bool_or_ref)) _) (two_targets taken not_taken))
(emit_side_effect
(with_flags_side_effect (cmp_zero_int_bool_ref val)
(jmp_cond (CC.Z) taken not_taken))))
(rule 2 (lower_branch (brnz (icmp cc a b) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brnz (icmp cc a b) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (emit_cmp cc a b) taken not_taken)))
(rule 2 (lower_branch (brnz (fcmp cc a b) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brnz (fcmp cc a b) _) (two_targets taken not_taken))
(let ((cmp FcmpCondResult (emit_fcmp cc a b)))
(emit_side_effect (jmp_cond_fcmp cmp taken not_taken))))
(rule 2 (lower_branch (brnz (uextend (icmp cc a b)) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brnz (uextend (icmp cc a b)) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (emit_cmp cc a b) taken not_taken)))
(rule 2 (lower_branch (brnz (uextend (fcmp cc a b)) _ _) (two_targets taken not_taken))
(rule 2 (lower_branch (brnz (uextend (fcmp cc a b)) _) (two_targets taken not_taken))
(let ((cmp FcmpCondResult (emit_fcmp cc a b)))
(emit_side_effect (jmp_cond_fcmp cmp taken not_taken))))
(rule 1 (lower_branch (brnz val @ (value_type $I128) _ _) (two_targets taken not_taken))
(rule 1 (lower_branch (brnz val @ (value_type $I128) _) (two_targets taken not_taken))
(emit_side_effect (jmp_cond_icmp (cmp_zero_i128 (CC.Z) val) taken not_taken)))
(rule 0 (lower_branch (brnz val @ (value_type (ty_int_bool_or_ref)) _ _) (two_targets taken not_taken))
(rule 0 (lower_branch (brnz val @ (value_type (ty_int_bool_or_ref)) _) (two_targets taken not_taken))
(emit_side_effect
(with_flags_side_effect (cmp_zero_int_bool_ref val)
(jmp_cond (CC.NZ) taken not_taken))))