(&mut self, ctx: &mut IsleContext<'a, 'b, 'c>)
| 90 | type Output = (Type, InstructionData); |
| 91 | |
| 92 | fn next(&mut self, ctx: &mut IsleContext<'a, 'b, 'c>) -> Option<Self::Output> { |
| 93 | while let Some(value) = self.stack.pop() { |
| 94 | debug_assert!(ctx.ctx.func.dfg.value_is_real(value)); |
| 95 | trace!("iter: value {:?}", value); |
| 96 | match ctx.ctx.func.dfg.value_def(value) { |
| 97 | ValueDef::Union(x, y) => { |
| 98 | debug_assert_ne!(x, Value::reserved_value()); |
| 99 | debug_assert_ne!(y, Value::reserved_value()); |
| 100 | trace!(" -> {}, {}", x, y); |
| 101 | self.stack.push(x); |
| 102 | self.stack.push(y); |
| 103 | continue; |
| 104 | } |
| 105 | ValueDef::Result(inst, _) if ctx.ctx.func.dfg.inst_results(inst).len() == 1 => { |
| 106 | // Charge one unit of fuel per yielded match. When |
| 107 | // fuel is exhausted, terminate iteration early: |
| 108 | // returning no matches is always semantically valid |
| 109 | // (we just skip would-be rewrites) and bounds work |
| 110 | // per top-level ISLE invocation. |
| 111 | if ctx.ctx.extractor_fuel == 0 { |
| 112 | ctx.ctx.stats.rewrite_fuel_exhausted += 1; |
| 113 | trace!(" -> rewrite fuel exhausted"); |
| 114 | return None; |
| 115 | } |
| 116 | ctx.ctx.extractor_fuel -= 1; |
| 117 | let ty = ctx.ctx.func.dfg.value_type(value); |
| 118 | trace!(" -> value of type {}", ty); |
| 119 | return Some((ty, ctx.ctx.func.dfg.insts[inst])); |
| 120 | } |
| 121 | _ => {} |
| 122 | } |
| 123 | } |
| 124 | None |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | impl<'a, 'b, 'c> IntoContextIter for InstDataEtorIter<'a, 'b, 'c> |
no test coverage detected