[PATCH] D123394: [CodeGen] Late cleanup of redundant address/immediate definitions.

Jonas Paulsson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 15 08:14:01 PDT 2022


jonpa added a comment.

In D123394#3790449 <https://reviews.llvm.org/D123394#3790449>, @lattner wrote:

> Do you have a sense of what (in practice) is causing the dead operations to get emitted?  Can they practically be handled upstream?  Such a thing would be a win for all the upstream cost models and would reduce compile time.
>
> I wonder if a version of your pass working as an "assertion" could shake out some obvious missed optimizations or other bugs that cause extraneous instructions to get emitted.
>
> If there are well known things that are impractical to handle (for one reason or another) then something like this would make sense to me.

I did another round today of trying to understand the causes here while building SPEC on SystemZ. The patch applied as it is removes ~22k instructions. I could see that rematerialization was the cause in some cases so I rebuilt the comparison without it. In the next comparison I in addition also disabled the register coalescer. These disablings were done both on main and the patch when comparing in each step:

- main <> patch: ~22k instructions less

- main <> patch, while disabling all rematerialization in the backend  (returning false in isTriviallyReMaterializable()): ~15k instructions less

- main <> patch, while disabling all rematerialization in the backend, and also disabling register coalescing (-join-intervals=false): ~8k instructions less

The register coalescer seems to play a role here as it can take two unrelated but identical immediate loads and make them define the same virtual register. This causes them to end up in the same physreg, and in some cases then the second one can be removed. This looks kind of similar to the results of rematerialization (having two smaller live-ranges instead of one).

For the remaining 8k instruction it seems that many of these are instructions present after isel already. Prior to isel it is an operand of an instruction, e.g. a call operand, and then (in some contexts) target decides to load it into a register. Then there are also on SystemZ the already mentioned duplicated address offsets loads into registers, emitted post-RA, which is different.

It seems to me that these redundant instructions are the effect of the overall heuristic in the compiler of reducing register pressure at the cost of more immediate loads, in all of the above. It's the way it should be, but it wouldn't hurt to clean things up somewhere in the end as much as possible. I don't think that can be done until the final allocation of registers is done (how would one know if there is a clobbering of the reg in between two identical immediate loads?). That's what it looks like to me on SystemZ, at least.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D123394/new/

https://reviews.llvm.org/D123394



More information about the llvm-commits mailing list