private Set<Varnode> getCouldRetireVarnodes(JitBlock block) {
		if (!block.branchesOut().isEmpty()) {
			return vsm.getLiveVars(block);
		}
		if (block.flowsFrom().isEmpty()) {
			throw new AssertionError();
			// or just return Set.of()?
		}
		Set<Varnode> aliveAfterAnyFlow =
			new HashSet<>(vsm.getLiveVars(block.flowsFrom().values().iterator().next().to()));
		for (BlockFlow flow : block.flowsFrom().values()) {
			aliveAfterAnyFlow.retainAll(vsm.getLiveVars(flow.to()));
		}
		Set<Varnode> result = new HashSet<>(vsm.getLiveVars(block));
		result.removeAll(aliveAfterAnyFlow);
		return result;
	}
Get the varnodes that could be retired upon leaving this block

<p>
If the block has an {@link JitBlock#branchesOut() exit} branch, then all live varnodes could
be retired. The result is the union of retired varnodes among each flow
{@link JitBlock#flowsFrom() from} the block. Note that every block must have a means of
leaving, i.e., {@link JitBlock#branchesOut()} and {@link JitBlock#flowsFrom()} cannot both be
empty.

@implNote Because retired varnodes are the difference in live varnodes, we can optimize the
          set computation by taking the intersection of live varnodes among all flow
          destinations and subtracting it from the live varnodes of this block.

@param block the block to examine
@return the set of varnodes that could be retired
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/emu/jit/analysis/JitOpUseModel.java