(isa: &dyn TargetIsa, mut func: Function, verbose: bool)
| 805 | } |
| 806 | |
| 807 | fn reduce(isa: &dyn TargetIsa, mut func: Function, verbose: bool) -> Result<(Function, String)> { |
| 808 | let mut context = CrashCheckContext::new(isa); |
| 809 | |
| 810 | if let CheckResult::Succeed = context.check_for_crash(&func) { |
| 811 | anyhow::bail!("Given function compiled successfully or gave a verifier error."); |
| 812 | } |
| 813 | |
| 814 | try_resolve_aliases(&mut context, &mut func); |
| 815 | try_remove_srclocs(&mut context, &mut func); |
| 816 | |
| 817 | for pass_idx in 0..100 { |
| 818 | let mut should_keep_reducing = false; |
| 819 | let mut phase = 0; |
| 820 | |
| 821 | loop { |
| 822 | let mut mutator: Box<dyn Mutator> = match phase { |
| 823 | 0 => Box::new(RemoveInst::new(&func)), |
| 824 | 1 => Box::new(ReplaceInstWithConst::new(&func)), |
| 825 | 2 => Box::new(ReplaceInstWithTrap::new(&func)), |
| 826 | 3 => Box::new(MoveInstToEntryBlock::new(&func)), |
| 827 | 4 => Box::new(RemoveBlock::new(&func)), |
| 828 | 5 => Box::new(ReplaceBlockParamWithConst::new(&func)), |
| 829 | 6 => Box::new(RemoveUnusedEntities::new()), |
| 830 | 7 => Box::new(MergeBlocks::new(&func)), |
| 831 | _ => break, |
| 832 | }; |
| 833 | |
| 834 | println!("pass {} phase {}", pass_idx, mutator.name()); |
| 835 | |
| 836 | for _ in 0..10000 { |
| 837 | let (mutated_func, msg, mutation_kind) = match mutator.mutate(func.clone()) { |
| 838 | Some(res) => res, |
| 839 | None => { |
| 840 | break; |
| 841 | } |
| 842 | }; |
| 843 | |
| 844 | if let ProgressStatus::Skip = mutation_kind { |
| 845 | // The mutator didn't change anything, but we want to try more mutator |
| 846 | // iterations. |
| 847 | continue; |
| 848 | } |
| 849 | |
| 850 | match context.check_for_crash(&mutated_func) { |
| 851 | CheckResult::Succeed => { |
| 852 | // Mutating didn't hit the problem anymore, discard changes. |
| 853 | continue; |
| 854 | } |
| 855 | CheckResult::Crash(_) => { |
| 856 | // Panic remained while mutating, make changes definitive. |
| 857 | func = mutated_func; |
| 858 | |
| 859 | // Notify the mutator that the mutation was successful. |
| 860 | mutator.did_crash(); |
| 861 | |
| 862 | let verb = match mutation_kind { |
| 863 | ProgressStatus::ExpandedOrShrinked => { |
| 864 | should_keep_reducing = true; |
no test coverage detected