Return the cost of an opcode.
(op: Opcode)
| 65 | |
| 66 | /// Return the cost of an opcode. |
| 67 | fn of_opcode(op: Opcode) -> Cost { |
| 68 | match op { |
| 69 | // Constants. |
| 70 | Opcode::Iconst | Opcode::F32const | Opcode::F64const => Cost::new(1), |
| 71 | |
| 72 | // Extends/reduces. |
| 73 | Opcode::Uextend |
| 74 | | Opcode::Sextend |
| 75 | | Opcode::Ireduce |
| 76 | | Opcode::Iconcat |
| 77 | | Opcode::Isplit => Cost::new(1), |
| 78 | |
| 79 | // "Simple" arithmetic. |
| 80 | Opcode::Iadd |
| 81 | | Opcode::Isub |
| 82 | | Opcode::Band |
| 83 | | Opcode::Bor |
| 84 | | Opcode::Bxor |
| 85 | | Opcode::Bnot |
| 86 | | Opcode::Ishl |
| 87 | | Opcode::Ushr |
| 88 | | Opcode::Sshr => Cost::new(3), |
| 89 | |
| 90 | // "Expensive" arithmetic. |
| 91 | Opcode::Imul => Cost::new(10), |
| 92 | |
| 93 | // Everything else. |
| 94 | _ => { |
| 95 | // By default, be slightly more expensive than "simple" |
| 96 | // arithmetic. |
| 97 | let mut c = Cost::new(4); |
| 98 | |
| 99 | // And then get more expensive as the opcode does more side |
| 100 | // effects. |
| 101 | if op.can_trap() || op.other_side_effects() { |
| 102 | c = c + Cost::new(10); |
| 103 | } |
| 104 | if op.can_load() { |
| 105 | c = c + Cost::new(20); |
| 106 | } |
| 107 | if op.can_store() { |
| 108 | c = c + Cost::new(50); |
| 109 | } |
| 110 | |
| 111 | c |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | /// Compute the cost of the operation and its given operands. |
| 117 | /// |
nothing calls this directly
no test coverage detected