Store hosts for a play as a play attribute

Operate on that play attribute to make things faster for larger
inventories. Instead of making a round trip through inventory.list_hosts
and working through some lengthy list comprehensions over and over
again, calculate the potenital hosts for a play once, then reduce from
it the unavailable hosts when necessary.

Also moves how the %fail is done. The host count is a play level count
of available hosts, which then is compared after each task to the
current number of available hosts for the play. This used to get a new
count every task which was also time expensive.
Store the list of hosts to run on in runner object

This reduces the number of times inventory.list_hosts is called, which
can be costly. When coming from a playbook that data is already known.
Fix merge conflicts from #5519