Why is vivado so wasteful with its D-flipflop placement?
Has the placer violated space constraints? No.

Has the router violated timings constraints? Probably not, if it finished successfully.

In which case you have a good design.

If you reduced the size of chip available to it, you'd find it would put more latches per slice.

If you tightened the timing constraints, you might find that if local routing resources were faster than inter-slice, that it would place latches on the same slice.

Lots of things have to be optimised by a placer/router. Amongst them is fast access to I/O pins, and heat generation, both of which would favour a spread such as you've shown.

Unless you've had several iterations around the constraints, you're not going to get the fastest possible, or the tightest area layout. When it's met constraints, the placer/router usually stops.

It's not obvious when we first write constraints for an automatic tool just how it's going to satisfy those. I frequently find myself thinking 'Oh, I didn't mean that, but I suppose that's exactly what I asked for' when doing this sort of thing.

There's a quite fun AI example where the system is given a bipedal walker, and asked to optimise its speed from start point to finish point across some difficult terrain. One solution it came up with was to give the walker very long legs, and have it fall over at the start. It was so tall it reached the finish.

Consider another optimisation problem. Manufacturer A wants to optimise his tools, so that me, the user, chooses them over manufacturer B. What makes a good placer/router, once meeting constraints has been achieved? A FAST placer router wins. If I use 90% of the resources, then I expect the tool to struggle, but if use 10%, I expect it to fly through. Why would the tool designers have it put all the latches in one slice, and then struggle to optimise the constrained local routing, when this initial placement is guarranteed to route easily?