public static LinkedList<BasicBlock> enumerateLeafFirst(Function F){
		Hashtable<BasicBlock, HashSet<BasicBlock>> targets = enumerateTargets(F);
		Hashtable<BasicBlock, HashSet<BasicBlock>> sources = enumerateSources(F);
		LinkedList<BasicBlock> ordering = new LinkedList<BasicBlock>();
		LinkedList<BasicBlock> queue = new LinkedList<BasicBlock>();
		
		// This is supposed to enumerate basic blocks in F in leaf-first order
		// This means that blocks with no targets are to be placed first, followed by their prececessors, etc.
		// The entry block is to be placed last.
		
		// Approach:
		// Enumerate the targets
		// Add all bbs with no targets to the end of the queue.
		
		// While the queue is not empty:
		//  pop a BB off the queue
		//  add BB to the ordering
		//  put all of BB's sources at the end of the queue
		//  Invariant: all of BB's targets have been visited!
		
		// IMPLEMENTATION:
		// Add all bbs with no targets to the end of the queue.
		for (BasicBlock bb : F.getBasicBlocks()){
			if (targets.get(bb).isEmpty()){
				queue.addLast(bb);
			}
		}
		
		while (!queue.isEmpty()){
			BasicBlock bb = queue.removeFirst();
			
			//  add BB to the ordering
			ordering.addLast(bb);
			
		//  put all of BB's sources at the end of the queue
			for (BasicBlock sbb : sources.get(bb)){
				if ((!ordering.contains(sbb)) && (!queue.contains(sbb))){
					queue.addLast(sbb);
				}
			}
			
			//  Invariant: all of BB's targets have been visited!
			//  The only exception is if the BB targets itself
			for (BasicBlock tbb : targets.get(bb)){
				if (tbb != bb){
					// This is not possible for loops:
					//assert ordering.contains(tbb);
				}
			}
		}
		
		// Make sure everything's been scheduled
		assert ordering.size() == F.getBasicBlocks().size();
		
		return ordering;
	}