So as Mehdi was saying, you can’t just look at all TF dependencies on anything in LLVM: it’s going to matter what in LLVM changes. A small change in LLVM is going to invalidate things that depend on the specific target in LLVM that changed. That said, TF’s monolithic structure is pretty likely to create unnecessary dependencies and cause unnecessary recompiles.
Your query also doesn’t work for me. Maybe because of recent changes to use the upstream LLVM Bazel build files? //third_party/llvm is empty. I think you want @llvm-project. Everything in the repo would be @llvm-project//.... Similarly, your query for //tensorflow:* is I believe only capturing rules directly in that package and you’d need //tensorflow/... to get everything. But for reasons that aren’t really clear to me doing an aquery with either of those wildcards fail in different ways. Fun. Anyway, so we’ll limit ourselves to individual packages for now.
If llvm:Support changes:
$ bazel aquery "rdeps(//tensorflow:*, @llvm-project//llvm:Support)" --include_aspects 2>/dev/null | grep Compiling | wc -l
4930

but if llvm:Symbolize changes, then nothing needs to be recompiled
$ bazel aquery "rdeps(//tensorflow:*, @llvm-project//llvm:Symbolize)" --include_aspects 2>/dev/null | grep Compiling | wc -l
0

for an in-between example:
$ bazel aquery "rdeps(//tensorflow:*, @llvm-project//llvm:ProfileData)" --include_aspects 2>/dev/null | grep Compiling | wc -l
2818

and don’t forget about MLIR:
$ bazel aquery "rdeps(//tensorflow:*, @llvm-project//mlir:Support)" --include_aspects 2>/dev/null | grep Compiling | wc -l
1924

Another important component is that if you’re using a cache like --disk_cache, Bazel will only rerun a compile command if the inputs actually change because it’s hashing the content. So if you have a change to llvm:Support that adds something hidden behind a preprocessor macro but that doesn’t actually result in a different compiled output, then Bazel will not recompile things that depend on it, instead using the cache hit.