static boolean equivalentReferences(Program p1, Program p2, Reference ref1, Reference ref2) {
		if (ref1 == ref2) {
			return true;
		}
		if (ref1 == null || ref2 == null) {
			return false;
		}
		if (ref1.getOperandIndex() != ref2.getOperandIndex() ||
			ref1.getReferenceType() != ref2.getReferenceType() ||
			//        		ref1.getSource() != ref2.getSource() || // ignore source type since we can't change it anyway.
			ref1.isPrimary() != ref2.isPrimary()) {
			return false;
		}
		Address fromAddr1 = ref1.getFromAddress();
		Address fromAddr2 = ref2.getFromAddress();
		Address fromAddr2AsP1 = SimpleDiffUtility.getCompatibleAddress(p2, fromAddr2, p1);
		if (!fromAddr1.equals(fromAddr2AsP1)) {
			return false;
		}
		if (!ref1.isExternalReference()) {
			Address toAddr1 = ref1.getToAddress();
			Address toAddr2 = ref2.getToAddress();
			Address toAddr2AsP1 = SimpleDiffUtility.getCompatibleAddress(p2, toAddr2, p1);
			if (!toAddr1.equals(toAddr2AsP1)) {
				return false;
			}
		}
		Symbol p1Symbol = p1.getSymbolTable().getSymbol(ref1.getSymbolID());
		Symbol p2Symbol = p2.getSymbolTable().getSymbol(ref2.getSymbolID());
		if (!ProgramDiff.equivalentSymbols(p1, p2, p1Symbol, p2Symbol)) {
			return false;
		}

		// Entry Point Reference
		if (ref1.isEntryPointReference()) {
			return ref2.isEntryPointReference();
		}
		// External Reference
		if (ref1.isExternalReference()) {
			if (!ref2.isExternalReference()) {
				return false;
			}
			ExternalReference extRef1 = (ExternalReference) ref1;
			ExternalReference extRef2 = (ExternalReference) ref2;
			ExternalLocation extLoc1 = extRef1.getExternalLocation();
			ExternalLocation extLoc2 = extRef2.getExternalLocation();
			return isEquivalent(extLoc1, extLoc2);
		}
		// Offset Reference
		if (ref1.isOffsetReference()) {
			if (!ref2.isOffsetReference()) {
				return false;
			}
			OffsetReference offsetRef1 = (OffsetReference) ref1;
			OffsetReference offsetRef2 = (OffsetReference) ref2;
			return offsetRef1.getOffset() == offsetRef2.getOffset();
		}
		// Shifted Reference
		if (ref1.isShiftedReference()) {
			if (!ref2.isShiftedReference()) {
				return false;
			}
			ShiftedReference shiftedRef1 = (ShiftedReference) ref1;
			ShiftedReference shiftedRef2 = (ShiftedReference) ref2;
			return shiftedRef1.getShift() == shiftedRef2.getShift();
		}
		// Stack Reference
		if (ref1.isStackReference()) {
			if (!ref2.isStackReference()) {
				return false;
			}
			StackReference stackRef1 = (StackReference) ref1;
			StackReference stackRef2 = (StackReference) ref2;
			return stackRef1.getStackOffset() == stackRef2.getStackOffset();
		}
		// Register Reference
		if (ref1.isRegisterReference()) {
			if (!ref2.isRegisterReference()) {
				return false;
			}
		}
		// Memory Reference
		if (ref1.isMemoryReference()) {
			return ref2.isMemoryReference();
		}

		return true;
	}
Compares reference from program1 with reference from program2 to see if they are equivalent.
@param p1 program1
@param p2 program2
@param ref1 program1 reference
@param ref2 program2 reference
@return true if they are equivalent
Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java