static public boolean equivalentFunctions(Function f1, Function f2, boolean ignoreName) {
		if (f1 == f2) {
			return true;
		}
		if (f1 == null || f2 == null) {
			return false;
		}
		boolean f1IsThunk = f1.isThunk();
		boolean f2IsThunk = f2.isThunk();
		if (f1IsThunk != f2IsThunk) {
			return false;
		}

		Program program1 = f1.getProgram();
		Program program2 = f2.getProgram();

		boolean f1IsExternal = f1.isExternal();
		boolean f2IsExternal = f2.isExternal();
		if (f1IsExternal != f2IsExternal) {
			return false;
		}
		if (!f1IsExternal) {
			Address entry1 = f1.getEntryPoint();
			Address entry2 = f2.getEntryPoint();
			Address entry2AsP1 = SimpleDiffUtility.getCompatibleAddress(program2, entry2, program1);
			if (!entry1.equals(entry2AsP1)) {
				return false;
			}
			AddressSetView body1 = f1.getBody();
			AddressSetView body2 = f2.getBody();
			AddressSet body2AsP1 = DiffUtility.getCompatibleAddressSet(body2, program1);
			if (!body1.equals(body2AsP1)) {
				return false;
			}
		}

		if (f1IsThunk) {
			return isEquivalentThunk(f1, f2);
		}

		StackFrame frame1 = f1.getStackFrame();
		StackFrame frame2 = f2.getStackFrame();

		if ((!ignoreName && !f1.getName().equals(f2.getName())) ||
			(f1.getStackPurgeSize() != f2.getStackPurgeSize()) ||
			(f1.getSignatureSource() != f2.getSignatureSource()) ||
			(f1.hasVarArgs() != f2.hasVarArgs()) || (f1.isInline() != f2.isInline()) ||
			(f1.hasNoReturn() != f2.hasNoReturn()) ||
			(!equivalentTagSets(f1.getTags(), f2.getTags())) ||
			!f1.getCallingConventionName().equals(f2.getCallingConventionName()) ||
			// Uses frame for some values since they may be adjusted
			// It is currently impossible to create a function with
			// identical attributes since some are hidden
			// For now, we are not allowing you to set the parameter offset or local size outright.
			//			(frame1.getLocalSize() != frame2.getLocalSize()) ||
			//			(frame1.getParameterOffset() != frame2.getParameterOffset()) ||
			(frame1.getReturnAddressOffset() != frame2.getReturnAddressOffset()) ||
			(f1.hasCustomVariableStorage() != f2.hasCustomVariableStorage())) {
			return false;
		}

		boolean hasCustomStorage = f1.hasCustomVariableStorage();
		if (!equivalentVariables(f1.getReturn(), f2.getReturn(), hasCustomStorage)) {
			return false;
		}
		if (!equivalentVariableArrays(f1.getParameters(), f2.getParameters(), hasCustomStorage)) {
			return false;
		}
		if (!f1IsExternal &&
			!equivalentVariableArrays(f1.getLocalVariables(), f2.getLocalVariables(), false)) {
			return false;
		}
		return true;
	}
Compares an array of bookmarks from program1 with an array of bookmarks from program2 to see if they are equivalent.
@param pgm1 program1
@param bookmarks1 program1 array of bookmarks
@param pgm2 program2
@param bookmarks2 program2 array of bookmarks
@return true if the arrays of bookmarks are equal.
Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java