Explicit 'hands-on' control of the routing sounds like a good idea, but it isn't.
Think back to the days when assembler programmers could squeeze a little bit more performance out of an algorithm by using manual assembly code instead of a compiler. There's only so much complexity you can think your way through. As the target becomes more complex, branch-prediction tables, multiple cores, deep execution pipelines, microthreading, that becomes impractical. I am writing here as somebody who wrote assembly code for a TI C6000 DSP, 8 execution units and a 5 deep pipeline for memory load/save, nightmare!
Only enthusiastic hobbyists write assembler these days, people who want to get the job done learn how to constrain, and to help, the compiler.
Anyhow, routing involves multiple resource types (long lines, half lines, straight through a mux, adjacent local lines, to mention but a few), multiple timing constraints (only a few of which are critical) and a lot of both.
The bottom line is that if you are laying out a single D latch, you can probably see your way round the routing. If you are doing anything of a worthwhile size, then you do not want to be, and cannot be, driving the routing directly. What you want to be doing is constraining, and helping, the routing optimiser. How?
Understand your timing constraints. Understand which are critical, and which are not. Don't over constrain for safety, the router is already taking account of worst case process with worst case voltage and temperature, that's why the timing tables are so humungeous. If you over-constrain, the router will struggle more. Only tightly constrain the critical lines.
Use floorplanning, this is where you can intervene with a bit of human 'I can see what I want' expertise. The placer doesn't always get it right. If the router fails, see what the placer has done, and if necessary, move some blocks from 'stupid' positions for a more sensible placing. Then let the router run again. Iterate that cycle, but let the router do its own thing.