diff --git a/src/cfg.rs b/src/cfg.rs index 7769556..a882f97 100644 --- a/src/cfg.rs +++ b/src/cfg.rs @@ -5,7 +5,7 @@ //! Lightweight CFG analyses. -use crate::{domtree, postorder, Block, Function, Inst, OperandKind, ProgPoint, RegAllocError}; +use crate::{domtree, postorder, Block, Function, Inst, ProgPoint, RegAllocError}; use smallvec::{smallvec, SmallVec}; #[derive(Clone, Debug)] @@ -16,12 +16,6 @@ pub struct CFGInfo { pub domtree: Vec, /// For each instruction, the block it belongs to. pub insn_block: Vec, - /// For each vreg, the instruction that defines it, if any. - pub vreg_def_inst: Vec, - /// For each vreg, the block that defines it as a blockparam, if - /// any. (Every vreg must have a valid entry in either - /// `vreg_def_inst` or `vreg_def_blockparam`.) - pub vreg_def_blockparam: Vec<(Block, u32)>, /// For each block, the first instruction. pub block_entry: Vec, /// For each block, the last instruction. @@ -48,8 +42,6 @@ impl CFGInfo { f.entry_block(), ); let mut insn_block = vec![Block::invalid(); f.num_insts()]; - let mut vreg_def_inst = vec![Inst::invalid(); f.num_vregs()]; - let mut vreg_def_blockparam = vec![(Block::invalid(), 0); f.num_vregs()]; let mut block_entry = vec![ProgPoint::before(Inst::invalid()); f.num_blocks()]; let mut block_exit = vec![ProgPoint::before(Inst::invalid()); f.num_blocks()]; let mut backedge_in = vec![0; f.num_blocks()]; @@ -57,19 +49,8 @@ impl CFGInfo { for block in 0..f.num_blocks() { let block = Block::new(block); - for (i, param) in f.block_params(block).iter().enumerate() { - vreg_def_blockparam[param.vreg()] = (block, i as u32); - } for inst in f.block_insns(block).iter() { insn_block[inst.index()] = block; - for operand in f.inst_operands(inst) { - match operand.kind() { - OperandKind::Def => { - vreg_def_inst[operand.vreg().vreg()] = inst; - } - _ => {} - } - } } block_entry[block.index()] = ProgPoint::before(f.block_insns(block).first()); block_exit[block.index()] = ProgPoint::after(f.block_insns(block).last()); @@ -139,8 +120,6 @@ impl CFGInfo { postorder, domtree, insn_block, - vreg_def_inst, - vreg_def_blockparam, block_entry, block_exit, approx_loop_depth, diff --git a/src/fuzzing/mod.rs b/src/fuzzing/mod.rs index e6a225e..1ab9d6d 100644 --- a/src/fuzzing/mod.rs +++ b/src/fuzzing/mod.rs @@ -6,6 +6,7 @@ //! Utilities for fuzzing. pub mod func; +pub mod ssa; // Re-exports for fuzz targets. @@ -21,9 +22,6 @@ pub mod moves { pub mod cfg { pub use crate::cfg::*; } -pub mod ssa { - pub use crate::ssa::*; -} pub mod ion { pub use crate::ion::*; } diff --git a/src/ssa.rs b/src/fuzzing/ssa.rs similarity index 75% rename from src/ssa.rs rename to src/fuzzing/ssa.rs index 44ef681..21852dc 100644 --- a/src/ssa.rs +++ b/src/fuzzing/ssa.rs @@ -10,6 +10,30 @@ use crate::cfg::CFGInfo; use crate::{Block, Function, Inst, OperandKind, RegAllocError}; pub fn validate_ssa(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllocError> { + // For each vreg, the instruction that defines it, if any. + let mut vreg_def_inst = vec![Inst::invalid(); f.num_vregs()]; + // For each vreg, the block that defines it as a blockparam, if + // any. (Every vreg must have a valid entry in either + // `vreg_def_inst` or `vreg_def_blockparam`.) + let mut vreg_def_blockparam = vec![(Block::invalid(), 0); f.num_vregs()]; + + for block in 0..f.num_blocks() { + let block = Block::new(block); + for (i, param) in f.block_params(block).iter().enumerate() { + vreg_def_blockparam[param.vreg()] = (block, i as u32); + } + for inst in f.block_insns(block).iter() { + for operand in f.inst_operands(inst) { + match operand.kind() { + OperandKind::Def => { + vreg_def_inst[operand.vreg().vreg()] = inst; + } + _ => {} + } + } + } + } + // Walk the blocks in arbitrary order. Check, for every use, that // the def is either in the same block in an earlier inst, or is // defined (by inst or blockparam) in some other block that @@ -29,10 +53,10 @@ pub fn validate_ssa(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo for operand in operands { match operand.kind() { OperandKind::Use => { - let def_block = if cfginfo.vreg_def_inst[operand.vreg().vreg()].is_valid() { - cfginfo.insn_block[cfginfo.vreg_def_inst[operand.vreg().vreg()].index()] + let def_block = if vreg_def_inst[operand.vreg().vreg()].is_valid() { + cfginfo.insn_block[vreg_def_inst[operand.vreg().vreg()].index()] } else { - cfginfo.vreg_def_blockparam[operand.vreg().vreg()].0 + vreg_def_blockparam[operand.vreg().vreg()].0 }; if def_block.is_invalid() { return Err(RegAllocError::SSA(operand.vreg(), iix)); diff --git a/src/lib.rs b/src/lib.rs index 2243f08..113eca9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,6 @@ pub mod indexset; pub(crate) mod ion; pub(crate) mod moves; pub(crate) mod postorder; -pub(crate) mod ssa; #[macro_use] mod index;