protected void findLocationsRemoveFunctionBodies(Program program, AddressSet set,
			Set<Address> locations, TaskMonitor monitor) throws CancelledException {

		monitor.setMessage("Finding function locations...");
		long total = set.getNumAddresses();
		monitor.initialize(total);

		// iterate over functions in program
		// add each defined function start to the list
		// return the address set that is minus the bodies of each function
		AddressSet inBodySet = new AddressSet();
		Iterator<Function> fiter = program.getFunctionManager().getFunctionsOverlapping(set);
		while (fiter.hasNext()) {
			monitor.checkCancelled();
			Function function = fiter.next();
			locations.add(function.getEntryPoint());
			inBodySet.add(function.getBody());
		}

		monitor.setProgress(total - inBodySet.getNumAddresses());
		set.delete(inBodySet);

		// set now has Stuff in it that isn't in a recorded function body
		ReferenceManager referenceManager = program.getReferenceManager();
		AddressIterator referenceDestinationIterator =
			referenceManager.getReferenceDestinationIterator(set, true);

		AddressSet outOfBodySet = new AddressSet();
		while (referenceDestinationIterator.hasNext()) {
			monitor.checkCancelled();
			Address address = referenceDestinationIterator.next();
			ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
			while (referencesTo.hasNext()) {
				Reference reference = referencesTo.next();
				if (reference.getReferenceType().isCall()) {
					locations.add(address);
					outOfBodySet.add(address);
					// could subtract all local non-call flows from the set, but
					// might be extra work...
					break;
				}
			}
		}

		monitor.incrementProgress(outOfBodySet.getNumAddresses());
		set.delete(outOfBodySet);

		// now iterate over individual address ranges, and use first address as a start
		outOfBodySet = new AddressSet();
		AddressRangeIterator addressRanges = set.getAddressRanges();
		while (addressRanges.hasNext()) {
			monitor.checkCancelled();
			AddressRange addressRange = addressRanges.next();
			locations.add(addressRange.getMinAddress());
			outOfBodySet.add(addressRange.getMinAddress());
		}

		monitor.incrementProgress(outOfBodySet.getNumAddresses());
		set.delete(outOfBodySet);
	}
Find function locations and leave only the function entry point in the address
set.  Anything not in a function is still in the address set.

@param program program
@param set remove known function bodies from the set, leave entry points
@param locations set of known function start addresses
@param monitor to cancel
@throws CancelledException if cancelled
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/ConstantPropagationAnalyzer.java