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:
@@ -1865,22 +1865,22 @@
|
||||
(decl vec_label_get (VecMachLabel u8) MachLabel )
|
||||
(extern constructor vec_label_get vec_label_get)
|
||||
|
||||
(decl partial lower_branch (Inst VecMachLabel) InstOutput)
|
||||
(decl partial lower_branch (Inst VecMachLabel) Unit)
|
||||
(rule (lower_branch (jump _ _) targets )
|
||||
(side_effect (SideEffectNoResult.Inst (gen_jump (vec_label_get targets 0)))))
|
||||
(emit_side_effect (SideEffectNoResult.Inst (gen_jump (vec_label_get targets 0)))))
|
||||
|
||||
;;; cc a b targets Type
|
||||
(decl lower_br_icmp (IntCC ValueRegs ValueRegs VecMachLabel Type) InstOutput)
|
||||
(decl lower_br_icmp (IntCC ValueRegs ValueRegs VecMachLabel Type) Unit)
|
||||
(extern constructor lower_br_icmp lower_br_icmp)
|
||||
|
||||
(decl lower_br_fcmp (FloatCC Reg Reg VecMachLabel Type) InstOutput)
|
||||
(decl lower_br_fcmp (FloatCC Reg Reg VecMachLabel Type) Unit)
|
||||
(extern constructor lower_br_fcmp lower_br_fcmp)
|
||||
|
||||
;; int scalar zero regs.
|
||||
(decl int_zero_reg (Type) ValueRegs)
|
||||
(extern constructor int_zero_reg int_zero_reg)
|
||||
|
||||
(decl lower_brz_or_nz (IntCC ValueRegs VecMachLabel Type) InstOutput)
|
||||
(decl lower_brz_or_nz (IntCC ValueRegs VecMachLabel Type) Unit)
|
||||
(extern constructor lower_brz_or_nz lower_brz_or_nz)
|
||||
|
||||
;; Normalize a value for comparision.
|
||||
@@ -1940,7 +1940,7 @@
|
||||
(lower_br_fcmp cc a b targets ty))
|
||||
|
||||
;;;
|
||||
(decl lower_br_table (Reg VecMachLabel) InstOutput)
|
||||
(decl lower_br_table (Reg VecMachLabel) Unit)
|
||||
(extern constructor lower_br_table lower_br_table)
|
||||
|
||||
(rule
|
||||
|
||||
@@ -4,7 +4,6 @@ use crate::isa::riscv64::inst::*;
|
||||
use crate::isa::riscv64::Riscv64Backend;
|
||||
use crate::machinst::lower::*;
|
||||
use crate::machinst::*;
|
||||
use crate::CodegenResult;
|
||||
pub mod isle;
|
||||
|
||||
//=============================================================================
|
||||
@@ -13,53 +12,17 @@ pub mod isle;
|
||||
impl LowerBackend for Riscv64Backend {
|
||||
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)
|
||||
}
|
||||
|
||||
fn maybe_pinned_reg(&self) -> Option<Reg> {
|
||||
|
||||
@@ -68,7 +68,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
b: Reg,
|
||||
targets: &VecMachLabel,
|
||||
ty: Type,
|
||||
) -> InstOutput {
|
||||
) -> Unit {
|
||||
let tmp = self.temp_writable_reg(I64);
|
||||
MInst::lower_br_fcmp(
|
||||
*cc,
|
||||
@@ -81,7 +81,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
)
|
||||
.iter()
|
||||
.for_each(|i| self.emit(i));
|
||||
InstOutput::default()
|
||||
}
|
||||
|
||||
fn lower_brz_or_nz(
|
||||
@@ -90,7 +89,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
a: ValueRegs,
|
||||
targets: &VecMachLabel,
|
||||
ty: Type,
|
||||
) -> InstOutput {
|
||||
) -> Unit {
|
||||
MInst::lower_br_icmp(
|
||||
*cc,
|
||||
a,
|
||||
@@ -101,7 +100,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
)
|
||||
.iter()
|
||||
.for_each(|i| self.emit(i));
|
||||
InstOutput::default()
|
||||
}
|
||||
fn lower_br_icmp(
|
||||
&mut self,
|
||||
@@ -110,7 +108,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
b: ValueRegs,
|
||||
targets: &VecMachLabel,
|
||||
ty: Type,
|
||||
) -> InstOutput {
|
||||
) -> Unit {
|
||||
let test = generated_code::constructor_lower_icmp(self, cc, a, b, ty);
|
||||
self.emit(&MInst::CondBr {
|
||||
taken: BranchTarget::Label(targets[0]),
|
||||
@@ -121,7 +119,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
rs2: zero_reg(),
|
||||
},
|
||||
});
|
||||
InstOutput::default()
|
||||
}
|
||||
fn load_ra(&mut self) -> Reg {
|
||||
if self.backend.flags.preserve_frame_pointers() {
|
||||
@@ -397,7 +394,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
tmp.to_reg()
|
||||
}
|
||||
|
||||
fn lower_br_table(&mut self, index: Reg, targets: &VecMachLabel) -> InstOutput {
|
||||
fn lower_br_table(&mut self, index: Reg, targets: &VecMachLabel) -> Unit {
|
||||
let tmp1 = self.temp_writable_reg(I64);
|
||||
let targets: Vec<BranchTarget> = targets
|
||||
.into_iter()
|
||||
@@ -409,7 +406,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
|
||||
tmp1,
|
||||
targets,
|
||||
});
|
||||
InstOutput::default()
|
||||
}
|
||||
fn x_reg(&mut self, x: u8) -> Reg {
|
||||
x_reg(x as usize)
|
||||
@@ -446,7 +442,7 @@ pub(crate) fn lower_branch(
|
||||
backend: &Riscv64Backend,
|
||||
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