Remove analyze_branch and BranchInfo (#5730)
We don't have overlap in behavior for branch instructions anymore, so we can remove analyze_branch and instead match on the InstructionData directly. Co-authored-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::entity::{self, PrimaryMap, SecondaryMap};
|
||||
use crate::ir;
|
||||
use crate::ir::builder::ReplaceBuilder;
|
||||
use crate::ir::dynamic_type::{DynamicTypeData, DynamicTypes};
|
||||
use crate::ir::instructions::{BranchInfo, CallInfo, InstructionData};
|
||||
use crate::ir::instructions::{CallInfo, InstructionData};
|
||||
use crate::ir::{types, ConstantData, ConstantPool, Immediate};
|
||||
use crate::ir::{
|
||||
Block, BlockCall, DynamicType, FuncRef, Inst, SigRef, Signature, Type, Value,
|
||||
@@ -1035,11 +1035,6 @@ impl DataFlowGraph {
|
||||
impl ExactSizeIterator for InstResultTypes<'_> {}
|
||||
}
|
||||
|
||||
/// Check if `inst` is a branch.
|
||||
pub fn analyze_branch(&self, inst: Inst) -> BranchInfo {
|
||||
self.insts[inst].analyze_branch()
|
||||
}
|
||||
|
||||
/// Compute the type of an instruction result from opcode constraints and call signatures.
|
||||
///
|
||||
/// This computes the same sequence of result types that `make_inst_results()` above would
|
||||
|
||||
@@ -92,11 +92,6 @@ impl Value {
|
||||
/// the `Value` of such instructions, use [`inst_results`](super::DataFlowGraph::inst_results) or
|
||||
/// its analogue in `cranelift_frontend::FuncBuilder`.
|
||||
///
|
||||
/// If you look around the API, you can find many inventive uses for `Inst`,
|
||||
/// such as [annotating specific instructions with a comment][inst_comment]
|
||||
/// or [performing reflection at compile time](super::DataFlowGraph::analyze_branch)
|
||||
/// on the type of instruction.
|
||||
///
|
||||
/// [inst_comment]: https://github.com/bjorn3/rustc_codegen_cranelift/blob/0f8814fd6da3d436a90549d4bb19b94034f2b19c/src/pretty_clif.rs
|
||||
///
|
||||
/// While the order is stable, it is arbitrary and does not necessarily resemble the layout order.
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
//! instructions.
|
||||
|
||||
use crate::entity::{PrimaryMap, SecondaryMap};
|
||||
use crate::ir;
|
||||
use crate::ir::JumpTables;
|
||||
use crate::ir::{
|
||||
instructions::BranchInfo, Block, DynamicStackSlot, DynamicStackSlotData, DynamicType,
|
||||
ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Inst, InstructionData, JumpTable,
|
||||
JumpTableData, Opcode, SigRef, StackSlot, StackSlotData, Table, TableData, Type,
|
||||
self, Block, DataFlowGraph, DynamicStackSlot, DynamicStackSlotData, DynamicStackSlots,
|
||||
DynamicType, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Inst, InstructionData,
|
||||
JumpTable, JumpTableData, JumpTables, Layout, Opcode, SigRef, Signature, SourceLocs, StackSlot,
|
||||
StackSlotData, StackSlots, Table, TableData, Type,
|
||||
};
|
||||
use crate::ir::{DataFlowGraph, Layout, Signature};
|
||||
use crate::ir::{DynamicStackSlots, SourceLocs, StackSlots};
|
||||
use crate::isa::CallConv;
|
||||
use crate::value_label::ValueLabelsRanges;
|
||||
use crate::write::write_function;
|
||||
@@ -280,8 +277,10 @@ impl FunctionStencil {
|
||||
/// Rewrite the branch destination to `new_dest` if the destination matches `old_dest`.
|
||||
/// Does nothing if called with a non-jump or non-branch instruction.
|
||||
pub fn rewrite_branch_destination(&mut self, inst: Inst, old_dest: Block, new_dest: Block) {
|
||||
match self.dfg.analyze_branch(inst) {
|
||||
BranchInfo::SingleDest(dest) => {
|
||||
match self.dfg.insts[inst] {
|
||||
InstructionData::Jump {
|
||||
destination: dest, ..
|
||||
} => {
|
||||
if dest.block(&self.dfg.value_lists) == old_dest {
|
||||
for block in self.dfg.insts[inst].branch_destination_mut() {
|
||||
block.set_block(new_dest, &mut self.dfg.value_lists)
|
||||
@@ -289,7 +288,10 @@ impl FunctionStencil {
|
||||
}
|
||||
}
|
||||
|
||||
BranchInfo::Conditional(block_then, block_else) => {
|
||||
InstructionData::Brif {
|
||||
blocks: [block_then, block_else],
|
||||
..
|
||||
} => {
|
||||
if block_then.block(&self.dfg.value_lists) == old_dest {
|
||||
if let InstructionData::Brif {
|
||||
blocks: [block_then, _],
|
||||
@@ -315,7 +317,11 @@ impl FunctionStencil {
|
||||
}
|
||||
}
|
||||
|
||||
BranchInfo::Table(table, default_dest) => {
|
||||
InstructionData::BranchTable {
|
||||
table,
|
||||
destination: default_dest,
|
||||
..
|
||||
} => {
|
||||
self.jump_tables[table].iter_mut().for_each(|entry| {
|
||||
if *entry == old_dest {
|
||||
*entry = new_dest;
|
||||
@@ -335,7 +341,7 @@ impl FunctionStencil {
|
||||
}
|
||||
}
|
||||
|
||||
BranchInfo::NotABranch => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::ir::{
|
||||
self,
|
||||
condcodes::{FloatCC, IntCC},
|
||||
trapcode::TrapCode,
|
||||
types, Block, FuncRef, JumpTable, MemFlags, SigRef, StackSlot, Type, Value,
|
||||
types, Block, FuncRef, MemFlags, SigRef, StackSlot, Type, Value,
|
||||
};
|
||||
|
||||
/// Some instructions use an external list of argument values because there is not enough space in
|
||||
@@ -292,27 +292,6 @@ impl Default for VariableArgs {
|
||||
/// Avoid large matches on instruction formats by using the methods defined here to examine
|
||||
/// instructions.
|
||||
impl InstructionData {
|
||||
/// Return information about the destination of a branch or jump instruction.
|
||||
///
|
||||
/// Any instruction that can transfer control to another block reveals its possible destinations
|
||||
/// here.
|
||||
pub fn analyze_branch(&self) -> BranchInfo {
|
||||
match *self {
|
||||
Self::Jump { destination, .. } => BranchInfo::SingleDest(destination),
|
||||
Self::Brif {
|
||||
blocks: [block_then, block_else],
|
||||
..
|
||||
} => BranchInfo::Conditional(block_then, block_else),
|
||||
Self::BranchTable {
|
||||
table, destination, ..
|
||||
} => BranchInfo::Table(table, destination),
|
||||
_ => {
|
||||
debug_assert!(!self.opcode().is_branch());
|
||||
BranchInfo::NotABranch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the destinations of this instruction, if it's a branch.
|
||||
///
|
||||
/// `br_table` returns the empty slice.
|
||||
@@ -476,23 +455,6 @@ impl InstructionData {
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about branch and jump instructions.
|
||||
pub enum BranchInfo {
|
||||
/// This is not a branch or jump instruction.
|
||||
/// This instruction will not transfer control to another block in the function, but it may still
|
||||
/// affect control flow by returning or trapping.
|
||||
NotABranch,
|
||||
|
||||
/// This is a branch or jump to a single destination block, possibly taking value arguments.
|
||||
SingleDest(BlockCall),
|
||||
|
||||
/// This is a conditional branch
|
||||
Conditional(BlockCall, BlockCall),
|
||||
|
||||
/// This is a jump table branch which can have many destination blocks and one default block.
|
||||
Table(JumpTable, Block),
|
||||
}
|
||||
|
||||
/// Information about call instructions.
|
||||
pub enum CallInfo<'a> {
|
||||
/// This is not a call instruction.
|
||||
|
||||
Reference in New Issue
Block a user