RemoveUnusedModuleElements: Optimize indirect calls when the table is immutable
To do this, refactor the table scanning code out of Directize into TableUtils. Then when we see a CallIndirect in RemoveUnusedModuleElements, we no longer automatically assume it could call anything whose reference was taken: if we see the table is not modified, then only the table's known contents might be called.
That is, before: CallIndirect implied we could call anything of that type, in that table. But also, we assumed other things might be written into the table at runtime, so anything whose reference was taken was callable. After: We know which tables do not have new entries written into them.
Measuring on Dart, I see a small benefit here. Probably it is small as other devirtualization etc. mechanisms already handle most things.
friendly nonurgent ping @tlively