Simplify LowerBackend interface (#5432)
* Refactor lower_branch to have Unit result Branches cannot have any output, so it is more straightforward to have the ISLE term return Unit instead of InstOutput. Also provide a new `emit_side_effect` term to simplify implementation of `lower_branch` rules with Unit result. * Simplify LowerBackend interface Move all remaining asserts from the LowerBackend::lower and ::lower_branch_group into the common call site. Change return value of ::lower to Option<InstOutput>, and return value of ::lower_branch_group to Option<()> to match ISLE term signature. Only pass the first branch into ::lower_branch_group and rename it to ::lower_branch. As a result of all those changes, LowerBackend routines now consists solely to calls to the corresponding ISLE routines.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
;; A variant of the main lowering constructor term, used for branches.
|
||||
;; The only difference is that it gets an extra argument holding a vector
|
||||
;; of branch targets to be used.
|
||||
(decl partial lower_branch (Inst VecMachLabel) InstOutput)
|
||||
(decl partial lower_branch (Inst VecMachLabel) Unit)
|
||||
|
||||
|
||||
;;;; Rules for `iconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -3715,7 +3715,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)
|
||||
(side_effect (jump_impl (vec_element targets 0))))
|
||||
(emit_side_effect (jump_impl (vec_element targets 0))))
|
||||
|
||||
|
||||
;;;; Rules for `br_table` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -3731,8 +3731,8 @@
|
||||
(cond ProducesBool
|
||||
(bool (icmpu_uimm32 $I64 idx (vec_length_minus1 targets))
|
||||
(intcc_as_cond (IntCC.UnsignedGreaterThanOrEqual))))
|
||||
(_ InstOutput (side_effect (oneway_cond_br_bool cond
|
||||
(vec_element targets 0)))))
|
||||
(_ Unit (emit_side_effect (oneway_cond_br_bool cond
|
||||
(vec_element targets 0)))))
|
||||
;; Scale the index by the element size, and then emit the
|
||||
;; compound instruction that does:
|
||||
;;
|
||||
@@ -3747,7 +3747,7 @@
|
||||
;; PC-rel offset to the jumptable would be incorrect.
|
||||
;; (The alternative is to introduce a relocation pass
|
||||
;; for inlined jumptables, which is much worse, IMHO.)
|
||||
(side_effect (jt_sequence (lshl_imm $I64 idx 2) targets))))
|
||||
(emit_side_effect (jt_sequence (lshl_imm $I64 idx 2) targets))))
|
||||
|
||||
|
||||
;;;; Rules for `brz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -3756,9 +3756,9 @@
|
||||
;; - 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)
|
||||
(side_effect (cond_br_bool (invert_bool (value_nonzero val_cond))
|
||||
(vec_element targets 0)
|
||||
(vec_element targets 1))))
|
||||
(emit_side_effect (cond_br_bool (invert_bool (value_nonzero val_cond))
|
||||
(vec_element targets 0)
|
||||
(vec_element targets 1))))
|
||||
|
||||
|
||||
;;;; Rules for `brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -3767,9 +3767,9 @@
|
||||
;; - 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)
|
||||
(side_effect (cond_br_bool (value_nonzero val_cond)
|
||||
(vec_element targets 0)
|
||||
(vec_element targets 1))))
|
||||
(emit_side_effect (cond_br_bool (value_nonzero val_cond)
|
||||
(vec_element targets 0)
|
||||
(vec_element targets 1))))
|
||||
|
||||
|
||||
;;;; Rules for `trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
//! Lowering rules for S390x.
|
||||
|
||||
use crate::ir::Inst as IRInst;
|
||||
use crate::ir::Opcode;
|
||||
use crate::isa::s390x::inst::Inst;
|
||||
use crate::isa::s390x::S390xBackend;
|
||||
use crate::machinst::{InstOutput, Lower, LowerBackend, MachLabel};
|
||||
use crate::CodegenResult;
|
||||
|
||||
pub mod isle;
|
||||
|
||||
@@ -15,52 +13,16 @@ pub mod isle;
|
||||
impl LowerBackend for S390xBackend {
|
||||
type MInst = Inst;
|
||||
|
||||
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> CodegenResult<InstOutput> {
|
||||
if let Some(temp_regs) = super::lower::isle::lower(ctx, self, ir_inst) {
|
||||
return Ok(temp_regs);
|
||||
}
|
||||
|
||||
let ty = if ctx.num_outputs(ir_inst) > 0 {
|
||||
Some(ctx.output_ty(ir_inst, 0))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
unreachable!(
|
||||
"not implemented in ISLE: inst = `{}`, type = `{:?}`",
|
||||
ctx.dfg().display_inst(ir_inst),
|
||||
ty
|
||||
);
|
||||
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> Option<InstOutput> {
|
||||
isle::lower(ctx, self, ir_inst)
|
||||
}
|
||||
|
||||
fn lower_branch_group(
|
||||
fn lower_branch(
|
||||
&self,
|
||||
ctx: &mut Lower<Inst>,
|
||||
branches: &[IRInst],
|
||||
ir_inst: IRInst,
|
||||
targets: &[MachLabel],
|
||||
) -> CodegenResult<()> {
|
||||
// A block should end with at most two branches. The first may be a
|
||||
// conditional branch; a conditional branch can be followed only by an
|
||||
// unconditional branch or fallthrough. Otherwise, if only one branch,
|
||||
// it may be an unconditional branch, a fallthrough, a return, or a
|
||||
// trap. These conditions are verified by `is_ebb_basic()` during the
|
||||
// verifier pass.
|
||||
assert!(branches.len() <= 2);
|
||||
if branches.len() == 2 {
|
||||
let op1 = ctx.data(branches[1]).opcode();
|
||||
assert!(op1 == Opcode::Jump);
|
||||
}
|
||||
|
||||
// Lower the first branch in ISLE. This will automatically handle
|
||||
// the second branch (if any) by emitting a two-way conditional branch.
|
||||
if let Some(temp_regs) = super::lower::isle::lower_branch(ctx, self, branches[0], targets) {
|
||||
assert!(temp_regs.len() == 0);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
unreachable!(
|
||||
"not implemented in ISLE: branch = `{}`",
|
||||
ctx.dfg().display_inst(branches[0]),
|
||||
);
|
||||
) -> Option<()> {
|
||||
isle::lower_branch(ctx, self, ir_inst, targets)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ pub(crate) fn lower_branch(
|
||||
backend: &S390xBackend,
|
||||
branch: Inst,
|
||||
targets: &[MachLabel],
|
||||
) -> Option<InstOutput> {
|
||||
) -> Option<()> {
|
||||
// TODO: reuse the ISLE context across lowerings so we can reuse its
|
||||
// internal heap allocations.
|
||||
let mut isle_ctx = IsleContext { lower_ctx, backend };
|
||||
|
||||
Reference in New Issue
Block a user