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:
Ulrich Weigand
2022-12-14 01:48:25 +01:00
committed by GitHub
parent 299be327d5
commit f0af622208
16 changed files with 133 additions and 244 deletions

View File

@@ -299,51 +299,17 @@ fn lower_to_amode(ctx: &mut Lower<Inst>, spec: InsnInput, offset: i32) -> Amode
impl LowerBackend for X64Backend {
type MInst = Inst;
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> CodegenResult<InstOutput> {
if let Some(temp_regs) = 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);
}
if let Some(temp_regs) = 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> {