Register allocation is usually on a far "lower" codegen level as is often DCE, they should be possible to compute/run on a SSA node level or similar long after destruction sequences are applied.
Now, there is far more "language level" flow analysis today apart from this as required by allowing auto type inference in more places (and things relaxed in relation to that). Reading up it seems to be suitably done in Clang on the ClangIR(MLIR extension) level, something that sits between AST and the LLVM IR.
Regardless of how it's implemented, I'm pretty sure that NRVO carried a fair bit more complexity requirements compared to RVO depending on how prepared the corebases for different compilers were to handle it.