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

@@ -38,6 +38,11 @@
(type ValueList (primitive ValueList))
(type ValueRegs (primitive ValueRegs))
;; Instruction lowering result: a vector of `ValueRegs`.
(type InstOutput (primitive InstOutput))
;; (Mutable) builder to incrementally construct an `InstOutput`.
(type InstOutputBuilder extern (enum))
(decl u32_add (u32 u32) u32)
(extern constructor u32_add u32_add)
@@ -64,6 +69,38 @@
(decl value_regs_invalid () ValueRegs)
(extern constructor value_regs_invalid value_regs_invalid)
;; Construct an empty `InstOutput`.
(decl output_none () InstOutput)
(extern constructor output_none output_none)
;; Construct a single-element `InstOutput`.
(decl output (ValueRegs) InstOutput)
(extern constructor output output)
;; Construct a two-element `InstOutput`.
(decl output_pair (ValueRegs ValueRegs) InstOutput)
(extern constructor output_pair output_pair)
;; Construct a single-element `InstOutput` from a single register.
(decl output_reg (Reg) InstOutput)
(rule (output_reg reg) (output (value_reg reg)))
;; Construct a single-element `InstOutput` from a value.
(decl output_value (Value) InstOutput)
(rule (output_value val) (output (put_in_regs val)))
;; Initially empty `InstOutput` builder.
(decl output_builder_new () InstOutputBuilder)
(extern constructor output_builder_new output_builder_new)
;; Append a `ValueRegs` to an `InstOutput` under construction.
(decl output_builder_push (InstOutputBuilder ValueRegs) Unit)
(extern constructor output_builder_push output_builder_push)
;; Finish building an `InstOutput` incrementally.
(decl output_builder_finish (InstOutputBuilder) InstOutput)
(extern constructor output_builder_finish output_builder_finish)
;; Get a temporary register for writing.
(decl temp_writable_reg (Type) WritableReg)
(extern constructor temp_writable_reg temp_writable_reg)
@@ -307,18 +344,18 @@
(type SideEffectNoResult (enum (Inst (inst MInst))))
;; Create an empty `ValueRegs`, but do emit the given side-effectful
;; Create an empty `InstOutput`, but do emit the given side-effectful
;; instruction.
(decl value_regs_none (SideEffectNoResult) ValueRegs)
(rule (value_regs_none (SideEffectNoResult.Inst inst))
(decl side_effect (SideEffectNoResult) InstOutput)
(rule (side_effect (SideEffectNoResult.Inst inst))
(let ((_ Unit (emit inst)))
(value_regs_invalid)))
(output_none)))
;; Similarly, but emit the side-effectful instruction as a safepoint.
(decl safepoint (SideEffectNoResult) ValueRegs)
(decl safepoint (SideEffectNoResult) InstOutput)
(rule (safepoint (SideEffectNoResult.Inst inst))
(let ((_ Unit (emit_safepoint inst)))
(value_regs_invalid)))
(output_none)))
;;;; Helpers for Working with Flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -438,3 +475,6 @@
(convert Value Reg put_in_reg)
(convert Value ValueRegs put_in_regs)
(convert WritableReg Reg writable_reg_to_reg)
(convert ValueRegs InstOutput output)
(convert Reg InstOutput output_reg)
(convert Value InstOutput output_value)