When created in RegStackify pass, tee has two destinations, where
operand 0 is stackified and operand 1 is not. But it is possible that
operand 0 is unstackified in fixUnwindMismatches function in CFGStackify
pass when a nested try-catch-end is introduced. In this case,
local.tee has lost its purpose, so we generate local.tee as planned
when op0 remains stackified, and generate local.set instead if op0 got
unstackified.
Related explanation in RegStackify: https://github.com/llvm/llvm-project/blob/339177d1da0c6f0cf181ba987836148acb526926/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L611-L630
For example,
- In RegStackify. (r0 is stackified and r1 is not)
r0, r1 = tee defreg ... use r0 ... ... use r1 ...
- In CFGStackify, r0 may get unstackified
- In ExplicitLocals,
3-a. If r0 remains stackified, use local.tee as planned:
r0 = local.tee N defreg ... ... use r0 ... (from stackified r0) ... local.get N ... use r1 ... (from local.get N)
3-b. If r0 got unstackified, use local.set instead:
local.set N defrag ... local.get N ... use r0 ... (from local.get N) local.get N ... use r1 ... (from local.get N)
does this mean that fixUnwindMismatches makes it unstackified or that it's already unstackified when fixUnwindMismatches runs?
edit:
I think it means the former, so maybe this could say "operand 0 becomes unstackified" instead. I guess this is all because "unstackified" could be a noun or a verb.... thanks English...