first cut at supporting "nop synthesis" in the opt pass

Peter, could you check if this seems to be on the right track?

While building gzip using this + Raimondas's nop inference, I got an "Instruction does not dominate all uses!" so I know that there is something I've failed to take into account.

"nop inference" is what we have been calling the phenomenon when an LLVM value can be proven to be equal to some other value that was available earlier. It's a degenerate case of synthesis that I thought would be useful to handle in the opt pass before moving on to more interesting stuff.

Because of the way we unique `Inst`s, there will not necessarily be a unique `Origin` for each `Inst`. This also has implications for choosing an appropriate replacement. For example:

```
define void f(i32 %i, i32 %j) {
entry:
  %add1 = add i32 %i, %j
  br i1 ..., label %bb1, label %bb2

bb1:
  %add2 = add i32 %i, %j
  br label %exit

bb2:
  %add3 = add i32 %i, %j
  br label %exit

exit:
  %add_phi = phi %add2, %add3
  ...
}
```

If we wanted to replace the phi with `add i32 %i, %j`, we ought to use the one in `%entry`, as the others will fail the dominance test.

One other representation that comes to mind is to have a `std::multimap<souper::Inst *, llvm::Value *>` somewhere that stores all observed origins. Then when you want to replace a value with something else you look through the `multimap` for a replacement that satisfies the dominance relationship. That might also be a better solution for the issue we were discussing in private mail.