wrap rest of IR indexes
[bigint-presentation-code.git] / register_allocator / src / fuzzing.rs
index 235ed73ffd27c228db46f65c48ed2457b2c45bf1..25748ad87dd142481178f10094765c0d35001be6 100644 (file)
@@ -1,11 +1,11 @@
 #![cfg(feature = "fuzzing")]
 use crate::{
     function::{
-        Block, BlockTermInstKind, BranchSuccParamUse, Constraint, CopyInstKind, FnFields, Inst,
-        InstKind, InstStage, KindAndConstraint, Operand, OperandKind, OperandKindDefOnly,
-        OperandUse, SSAVal, SSAValDef,
+        Block, BlockTermInstKind, Constraint, CopyInstKind, Entries, EntriesMut, FnFields, Inst,
+        InstKind, InstStage, KindAndConstraint, Operand, OperandKind, OperandKindDefOnly, SSAVal,
+        SSAValDef,
     },
-    index::{BlockIdx, InstIdx, InstRange, SSAValIdx},
+    index::{BlockIdx, InstIdx, InstRange, OperandIdx, RangeIter, SSAValIdx},
     interned::{GlobalState, Intern},
     loc::Ty,
     loc_set::LocSet,
@@ -78,11 +78,11 @@ impl FnBuilder<'_, '_, '_> {
         let idom = self.func.blocks[block_idx].immediate_dominator;
         self.available_ssa_vals_at_end(idom)
     }
-    fn new_ssa_val(ssa_vals: &mut Vec<SSAVal>, ty: Ty, def: SSAValDef) -> SSAValIdx {
+    fn new_ssa_val(ssa_vals: &mut Vec<SSAVal>, ty: Ty) -> SSAValIdx {
         let retval = SSAValIdx::new(ssa_vals.len());
         ssa_vals.push(SSAVal {
             ty,
-            def,
+            def: SSAValDef::invalid(),
             operand_uses: Default::default(),
             branch_succ_param_uses: Default::default(),
         });
@@ -117,7 +117,7 @@ impl FnBuilder<'_, '_, '_> {
         }
         let mut possible_src_operand_idxs = vec![];
         let mut possible_dest_operand_idxs = vec![];
-        for (operand_idx, operand) in operands.iter().enumerate() {
+        for (operand_idx, operand) in operands.entries() {
             match operand.kind_and_constraint.kind() {
                 OperandKind::Use => possible_src_operand_idxs.push(operand_idx),
                 OperandKind::Def => possible_dest_operand_idxs.push(operand_idx),
@@ -129,7 +129,7 @@ impl FnBuilder<'_, '_, '_> {
         // src can have duplicates, so pick randomly
         let possible_src_operand_idxs = (0..u.int_in_range(1..=3)?)
             .map(|_| u.choose(&possible_src_operand_idxs).copied())
-            .collect::<Result<Vec<usize>, Error>>()?;
+            .collect::<Result<Vec<OperandIdx>, Error>>()?;
         // dest can't have duplicates, so shuffle
         let len = possible_dest_operand_idxs.len();
         for i in 0..len {
@@ -184,20 +184,12 @@ impl FnBuilder<'_, '_, '_> {
     }
     fn run(&mut self) -> Result<(), Error> {
         let block_count = self.u.int_in_range(1..=10u16)?;
-        for block_idx in 0..block_count as usize {
-            let block_idx = BlockIdx::new(block_idx);
+        for block_idx in RangeIter::<BlockIdx>::from_usize_range(0..block_count as usize) {
             let mut params = Vec::new();
             if block_idx != BlockIdx::ENTRY_BLOCK {
-                for param_idx in 0..self.u.int_in_range(0..=10)? {
+                for _param_idx in 0..self.u.int_in_range(0..=10)? {
                     let ty = self.u.arbitrary()?;
-                    params.push(Self::new_ssa_val(
-                        &mut self.func.ssa_vals,
-                        ty,
-                        SSAValDef::BlockParam {
-                            block: block_idx,
-                            param_idx,
-                        },
-                    ));
+                    params.push(Self::new_ssa_val(&mut self.func.ssa_vals, ty));
                 }
             }
             let end = InstIdx::new(self.func.insts.len());
@@ -216,11 +208,7 @@ impl FnBuilder<'_, '_, '_> {
                     let kind = self.u.arbitrary()?;
                     let ssa_val = if let OperandKind::Def = kind {
                         let ty = self.u.arbitrary()?;
-                        let def = SSAValDef::Operand {
-                            inst: InstIdx::new(self.func.insts.len()),
-                            operand_idx: operands.len(),
-                        };
-                        Self::new_ssa_val(&mut self.func.ssa_vals, ty, def)
+                        Self::new_ssa_val(&mut self.func.ssa_vals, ty)
                     } else {
                         SSAValIdx::new(!0)
                     };
@@ -254,8 +242,7 @@ impl FnBuilder<'_, '_, '_> {
                 self.new_inst_in_last_block(inst_kind, operands, clobbers);
             }
         }
-        for block_idx in 0..self.func.blocks.len() {
-            let block_idx = BlockIdx::new(block_idx);
+        for block_idx in self.func.blocks.keys() {
             let term_idx = self
                 .func
                 .try_get_block_term_inst_idx(block_idx)
@@ -271,8 +258,7 @@ impl FnBuilder<'_, '_, '_> {
                 self.func.blocks[succ].preds.insert(block_idx);
             }
         }
-        for block_idx in 0..self.func.blocks.len() {
-            let block_idx = BlockIdx::new(block_idx);
+        for block_idx in self.func.blocks.keys() {
             let term_idx = self
                 .func
                 .try_get_block_term_inst_idx(block_idx)
@@ -304,19 +290,17 @@ impl FnBuilder<'_, '_, '_> {
             });
         }
         let dominators = dominators::simple_fast(&self.func, BlockIdx::ENTRY_BLOCK);
-        for block_idx in 0..self.func.blocks.len() {
-            let block_idx = BlockIdx::new(block_idx);
+        for block_idx in self.func.blocks.keys() {
             self.func.blocks[block_idx].immediate_dominator =
                 dominators.immediate_dominator(block_idx);
         }
         // must have filled dominators first since available_ssa_vals_before_start() needs them
-        for block_idx in 0..self.func.blocks.len() {
-            let block_idx = BlockIdx::new(block_idx);
+        for block_idx in self.func.blocks.keys() {
             let mut available_ssa_vals = self.available_ssa_vals_before_start(block_idx);
             available_ssa_vals.extend(&self.func.ssa_vals, &self.func.blocks[block_idx].params);
             for inst_idx in self.func.blocks[block_idx].insts {
                 let inst = &mut self.func.insts[inst_idx];
-                for (operand_idx, operand) in inst.operands.iter_mut().enumerate() {
+                for (_operand_idx, operand) in inst.operands.entries_mut() {
                     if operand.kind_and_constraint.kind() != OperandKind::Use {
                         continue;
                     }
@@ -330,22 +314,12 @@ impl FnBuilder<'_, '_, '_> {
                             ssa_val: Self::new_ssa_val(
                                 &mut self.func.ssa_vals,
                                 self.u.arbitrary()?,
-                                SSAValDef::Operand {
-                                    inst: inst_idx,
-                                    operand_idx,
-                                },
                             ),
                             stage: self.u.arbitrary()?,
                         };
                     } else {
                         operand.ssa_val = *self.u.choose(&available_ssa_vals.all)?;
                     }
-                    self.func.ssa_vals[operand.ssa_val]
-                        .operand_uses
-                        .insert(OperandUse {
-                            inst: inst_idx,
-                            operand_idx,
-                        });
                 }
                 available_ssa_vals.extend(
                     &self.func.ssa_vals,
@@ -360,27 +334,15 @@ impl FnBuilder<'_, '_, '_> {
                     InstKind::BlockTerm(block_term_inst_kind) => {
                         for (&succ_idx, params) in &mut block_term_inst_kind.succs_and_params {
                             let succ = &self.func.blocks[succ_idx];
-                            for (param_idx, &succ_param) in succ.params.iter().enumerate() {
+                            for (_param_idx, &succ_param) in succ.params.entries() {
                                 let succ_param_ty = self.func.ssa_vals[succ_param].ty;
                                 let choices = available_ssa_vals.per_ty(succ_param_ty);
                                 let ssa_val_idx;
                                 if choices.is_empty() {
                                     // no available ssa vals with correct type, fix that by appending def operand with that type
-                                    ssa_val_idx = Self::new_ssa_val(
-                                        &mut self.func.ssa_vals,
-                                        succ_param_ty,
-                                        SSAValDef::Operand {
-                                            inst: inst_idx,
-                                            operand_idx: inst.operands.len(),
-                                        },
-                                    );
+                                    ssa_val_idx =
+                                        Self::new_ssa_val(&mut self.func.ssa_vals, succ_param_ty);
                                     available_ssa_vals.extend(&self.func.ssa_vals, [ssa_val_idx]);
-                                    self.func.ssa_vals[ssa_val_idx].operand_uses.insert(
-                                        OperandUse {
-                                            inst: inst_idx,
-                                            operand_idx: inst.operands.len(),
-                                        },
-                                    );
                                     inst.operands.push(Operand {
                                         kind_and_constraint: KindAndConstraint::Constraint {
                                             kind: OperandKind::Def,
@@ -393,23 +355,15 @@ impl FnBuilder<'_, '_, '_> {
                                     ssa_val_idx = *self.u.choose(choices)?
                                 };
                                 params.push(ssa_val_idx);
-                                self.func.ssa_vals[ssa_val_idx]
-                                    .branch_succ_param_uses
-                                    .insert(BranchSuccParamUse {
-                                        branch_inst: inst_idx,
-                                        succ: succ_idx,
-                                        param_idx,
-                                    });
                             }
                         }
                     }
                 }
             }
         }
-        for (inst_idx, inst) in self.func.insts.iter_mut().enumerate() {
-            let inst_idx = InstIdx::new(inst_idx);
-            let mut reusable_operand_idxs: HashMap<Ty, Vec<usize>> = HashMap::new();
-            for (operand_idx, operand) in inst.operands.iter().enumerate() {
+        for (inst_idx, inst) in self.func.insts.entries_mut() {
+            let mut reusable_operand_idxs: HashMap<Ty, Vec<OperandIdx>> = HashMap::new();
+            for (operand_idx, operand) in inst.operands.entries() {
                 if operand.kind_and_constraint.kind() == OperandKind::Use {
                     reusable_operand_idxs
                         .entry(self.func.ssa_vals[operand.ssa_val].ty)
@@ -418,21 +372,24 @@ impl FnBuilder<'_, '_, '_> {
                 }
             }
             let mut used_locs = EnumMap::<InstStage, LocSet>::default();
-            for operand_idx in 0..inst.operands.len() {
+            for operand_idx in inst.operands.keys() {
                 let operand = &inst.operands[operand_idx];
                 let operand_ty = self.func.ssa_vals[operand.ssa_val].ty;
                 if operand.kind_and_constraint.kind() == OperandKind::Def && self.u.arbitrary()? {
-                    let reuse_operand_idx = self.u.choose_index(inst.operands.len())?;
-                    let reuse_operand = &inst.operands[reuse_operand_idx];
-                    if reuse_operand_idx != operand_idx
-                        && reuse_operand.kind_and_constraint.kind() == OperandKind::Use
-                        && self.func.ssa_vals[reuse_operand.ssa_val].ty == operand_ty
-                    {
-                        inst.operands[operand_idx].kind_and_constraint = KindAndConstraint::Reuse {
-                            kind: OperandKindDefOnly,
-                            reuse_operand_idx,
-                        };
-                        continue;
+                    let reusable_operand_idxs = reusable_operand_idxs
+                        .get(&operand_ty)
+                        .map(Deref::deref)
+                        .unwrap_or_default();
+                    if !reusable_operand_idxs.is_empty() {
+                        let reuse_operand_idx = *self.u.choose(reusable_operand_idxs)?;
+                        if reuse_operand_idx != operand_idx {
+                            inst.operands[operand_idx].kind_and_constraint =
+                                KindAndConstraint::Reuse {
+                                    kind: OperandKindDefOnly,
+                                    reuse_operand_idx,
+                                };
+                            continue;
+                        }
                     }
                 }
                 let operand = &mut inst.operands[operand_idx];