ISLE: Lowering of multi-output instructions (#3783)

This changes the output of the `lower` constructor from a
`ValueRegs` to a new `InstOutput` type, which is a vector
of `ValueRegs`.

Code in `lower_common` is updated to use this new type to
handle instructions with multiple outputs.  All back-ends
are updated to use the new type.
This commit is contained in:
Ulrich Weigand
2022-02-24 23:03:06 +01:00
committed by GitHub
parent e8881b2cc0
commit 07d615d3f7
12 changed files with 1145 additions and 925 deletions

View File

@@ -2,7 +2,7 @@
;; The main lowering constructor term: takes a clif `Inst` and returns the
;; register(s) within which the lowered instruction's result values live.
(decl lower (Inst) ValueRegs)
(decl lower (Inst) InstOutput)
;;;; Rules for `iconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -148,48 +148,39 @@
;; replace this with a bool carry flag, and all consumers of `iflags`
;; remain in the handwritten pattern-matching code and explicitly
;; match on the flags producer. So we can get away with just
;; allocating a second temp so that the reg-renaming code does the
;; using an invalid second output, and the reg-renaming code does the
;; right thing, for now. For safety, we assert elsewhere that no one
;; actually uses the register assigned to the SSA `iflags`-typed
;; `Value`.
(decl unused_iflags () Gpr)
(rule (unused_iflags)
(temp_writable_gpr))
(decl output_ifcout (Reg) InstOutput)
(rule (output_ifcout reg)
(output_pair reg (value_regs_invalid)))
;; Add two registers.
(rule (lower (has_type (fits_in_64 ty)
(iadd_ifcout x y)))
(value_gprs (add ty x y)
(unused_iflags)))
(output_ifcout (add ty x y)))
;; Add a register and an immediate.
(rule (lower (has_type (fits_in_64 ty)
(iadd_ifcout x (simm32_from_value y))))
(value_gprs (add ty x y)
(unused_iflags)))
(output_ifcout (add ty x y)))
(rule (lower (has_type (fits_in_64 ty)
(iadd_ifcout (simm32_from_value x) y)))
(value_gprs (add ty y x)
(unused_iflags)))
(output_ifcout (add ty y x)))
;; Add a register and memory.
(rule (lower (has_type (fits_in_64 ty)
(iadd_ifcout x (sinkable_load y))))
(value_gprs (add ty
x
(sink_load_to_gpr_mem_imm y))
(unused_iflags)))
(output_ifcout (add ty x (sink_load_to_gpr_mem_imm y))))
(rule (lower (has_type (fits_in_64 ty)
(iadd_ifcout (sinkable_load x) y)))
(value_gprs (add ty
y
(sink_load_to_gpr_mem_imm x))
(unused_iflags)))
(output_ifcout (add ty y (sink_load_to_gpr_mem_imm x))))
;; (No `iadd_ifcout` for `i128`.)