Page MenuHomePhabricator

[AArch64] Only use writeback in the load/store optimizer when needed
Changes PlannedPublic

Authored by john.brawn on Dec 5 2017, 3:44 AM.

Details

Summary

Currently the load/store optimizer always uses writeback when merging an add with a load or store, even if it isn't necessary, which prevents optimization in cases where a load destination is the same register as the base. This patch makes it only use writeback when necessary, allowing us to optimise such cases.

Diff Detail

Repository
rL LLVM

Event Timeline

john.brawn created this revision.Dec 5 2017, 3:44 AM
junbuml added inline comments.Dec 5 2017, 7:14 AM
lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
1346

I'm not sure if it's safe enough to use the kill marker here? Is this information still valid for us to rely on?

john.brawn added inline comments.Dec 5 2017, 8:07 AM
lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
1346

The load/store optimizer in the ARM backend relies on it, so I would assume so. After some searching around I found TargetRegisterInfo::trackLivenessAfterRegAlloc which the AArch64 backend does return true for, and I couldn't find anything else that we would need to do to make sure it's valid.

gberry added a subscriber: gberry.Dec 5 2017, 10:59 AM
gberry added inline comments.
lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
1346

The kill markers are slowly being phased out. They should always be correct, but they are conservative (e.g. a lot of passes just delete them in regions of code they transform since that is the easiest way to keep them correct) and will become more so over time.

MatzeB edited edge metadata.Dec 5 2017, 1:13 PM

Yes please don't add new code that relies on kill flags, you will see them used less and less, your code will be less and less effective.

Post-RA you should perform all your liveness query needs with LiveRegUnits (or LivePhysRegs). They allow you to start from the end of a basic block where we have live-out information (it's actually live-in information of the successors) and simulating liveness while walking backwards to the point you are interested in. You have to be a bit careful about the performance implications (ideally you change your highlevel algorithms to work backwards through basic blocks as well so you only simulate once for all transformations you do in a basic block rather than simulating anew for every single transformation you perform).

mcrosier resigned from this revision.Mar 5 2018, 8:31 AM

I'm not sure what is gained by not performing this optimization, if I understood the gist of it from the new test case below. For even if the register is killed, the pointer adjustment is folded into the load or store and an instruction is eliminated. What other optimizations are expected to be happen should this patch be applied?

john.brawn planned changes to this revision.Mar 23 2018, 7:42 AM

I'm not sure what is gained by not performing this optimization, if I understood the gist of it from the new test case below. For even if the register is killed, the pointer adjustment is folded into the load or store and an instruction is eliminated. What other optimizations are expected to be happen should this patch be applied?

I'm not quite sure what you're asking here? If you mean "what is gained by not using writeback in cases where we currently don't use writeback", then the answer is that we don't gain anything, but by not using writeback we can optimise cases that can't currently be optimised because the use of writeback would be invalid. Though the title and summary don't really convey that very well, perhaps "Allow more load/store optimization by not using writeback" or something would be better.

I'm not currently planning on working on this patch further at the moment though (but I may get back to it some time in the future), as changing to not using kill flags looks like it would take some work and I currently have other priorities.