private JitVal trySimplifiedSubPiece(JitOutVar out, int offset, JitVal v) {
		if (!(v instanceof JitOutVar vOut)) {
			return null;
		}
		if (vOut.definition() instanceof JitSynthSubPieceOp subsub) {
			subsub.unlink();
			return dfm
					.notifyOp(new JitSynthSubPieceOp(out, offset + subsub.offset(), subsub.v()))
					.out();
		}
		if (vOut.definition() instanceof JitCatenateOp cat) {
			cat.unlink();
			List<JitVal> newParts = new ArrayList<>(cat.parts());
			removeOffsetFromRight(newParts, offset);
			removeFromLeftToSize(newParts, out.size());
			assert !newParts.isEmpty();
			if (newParts.size() == 1) {
				// Context should already be notified
				return newParts.get(0);
			}
			return dfm.notifyOp(new JitCatenateOp(out, newParts)).out();
		}
		return null;
	}
Try to produce a simplified {@link JitSynthSubPieceOp} or {@link JitCatenateOp}

<p>
This takes an input, subpiece offset, and output variable. If the input variable is the
result of another subpiece, the result can be a single simplified subpiece. Similarly, if the
input is the result of a catenation, then the result can be a simplified catenation, or
possibly subpiece.

If either of these situations applies, and simplification is possible, this returns a
non-null result, and that result is added to the use-def graph specifying the given output
variable as the simplified output. Otherwise, the result is null and the caller should create
a new subpiece op.

@param out the output variable
@param offset the subpiece offset (number of bytes shifted right)
@param v the input value
@return the output variable, as the result of the simplified sub-graph.
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/emu/jit/analysis/JitDataFlowArithmetic.java