This is an archive of the discontinued LLVM Phabricator instance.

[PowerPC] Reduce register pressure by not materializing a constant just for use as an index register for X-Form loads/stores
ClosedPublic

Authored by lei on Jul 5 2017, 11:41 AM.

Details

Summary

Reduce register pressure by not materializing a constant just for use as an index register for X-Form loads/stores.

For this example:

float test (int *arr) {
  return arr[2];
}

We currently generate the following code:

li r4, 8
lxsiwax f0, r3, r4
xscvsxdsp f1, f0

With this patch, we will now generate:

addi r3, r3, 8
lxsiwax f0, 0, r3
xscvsxdsp f1, f0

Originally reported in: https://bugs.llvm.org/show_bug.cgi?id=27204

Diff Detail

Event Timeline

lei created this revision.Jul 5 2017, 11:41 AM
stefanp added inline comments.Jul 5 2017, 1:10 PM
lib/Target/PowerPC/PPCISelLowering.cpp
2247

Do we need N.getOperand(1) to have only one use?
For example:

r10 = (generate r10 somehow)
ADD r4 = r3 + r10  (Is ADD, is not immed S16, r3 has one use, BUT r10 has two uses)
LD r5 = (0, r4)
ADD r7 = r6 + r10 
LD r8 = (0, r7)

Ideally I think we can get rid of those ADDs from above.
There may be a case I'm not thinking of here.

echristo added inline comments.Jul 5 2017, 1:28 PM
lib/Target/PowerPC/PPCISelLowering.cpp
2239–2248

Between this and the comment underneath the if conditional it's a little hard to understand the tradeoffs involved. Also Stefan's comment.

2244

uint16_t Imm

stefanp added inline comments.Jul 6 2017, 9:28 AM
lib/Target/PowerPC/PPCISelLowering.cpp
2247

Sorry... I made a mistake with that last comment.
Ok, so I mixed up the location of the NOT in that if statement.

It may be clearer if instead of ! ( COND && COND && COND) it's !COND || !COND || !COND.
At least it may be clearer in my head...

Either way, I'll have to go back and look at this again.

lei added inline comments.Jul 6 2017, 9:53 AM
lib/Target/PowerPC/PPCISelLowering.cpp
2239–2248

change:

However we don't want to materialize a constant just for use as the index register.

to:

However, we can reduce register pressure if we do not materialize a constant just for use as the index register.
2247

Will update the if condition accordingly

lei added inline comments.Jul 6 2017, 10:11 AM
lib/Target/PowerPC/PPCISelLowering.cpp
2244

The static function isIntS16Immediate() takes a short&

echristo added inline comments.Jul 6 2017, 10:13 AM
lib/Target/PowerPC/PPCISelLowering.cpp
2244

Could fix that too :)

lei updated this revision to Diff 105474.Jul 6 2017, 10:39 AM

Simplify if statement and update comment to be more clear on the tradeoffs.

jtony added inline comments.Jul 6 2017, 11:10 AM
lib/Target/PowerPC/PPCISelLowering.cpp
2246

It would be nice to break the complex condition into several parts and give an meaningful name for each. It increase the code readability maintainability. Maybe something like this:
bool AAAA = N.getOpcode() == ISD::ADD;
bool BBBB = isIntS16Immediate(N.getOperand(1), imm) && N.getOperand(1).hasOneUse() && N.getOperand(0).hasOneUse(), then we can use
if (AAAA && !BBBB ) {...} instead. As an example name for AAAA, we can use IsADD, and for BBBB: CanGetRidOfAdd. I am not good at naming, you can figure out some better name than I. :-)

lei added inline comments.Jul 6 2017, 12:03 PM
lib/Target/PowerPC/PPCISelLowering.cpp
2244

fair enough

lei updated this revision to Diff 105504.Jul 6 2017, 12:08 PM

update static function isIntS16Immediate() to take a int16_t param rather then short.

lei marked an inline comment as done.Jul 6 2017, 12:29 PM
lei added inline comments.
lib/Target/PowerPC/PPCISelLowering.cpp
2246

Can't break this up. N.getOperand(1) isn’t guaranteed to succeed, we have to rely on checking whether it’s an ISD::ADD first. Sometimes the address is going to be something like ISD::TargetConstant/ISD::TargetGlobalAddress, etc. which actually doesn’t have operand 1.

sfertile edited edge metadata.Jul 6 2017, 1:34 PM

Regarding the isIntS16Immediate change, the function is duplicated in PPCISelDAGToDAG.cpp as well. I suggest we leave it as is in this patch, and then in a separate patch common up the definitions and change it to use an int16_t argument. That keeps this patch focused on only doing a single thing, and puts the code cleanup in its own NFC patch.

echristo edited edge metadata.Jul 6 2017, 1:44 PM

Regarding the isIntS16Immediate change, the function is duplicated in PPCISelDAGToDAG.cpp as well. I suggest we leave it as is in this patch, and then in a separate patch common up the definitions and change it to use an int16_t argument. That keeps this patch focused on only doing a single thing, and puts the code cleanup in its own NFC patch.

Feel free to do that first. :)

hfinkel accepted this revision.Jul 6 2017, 6:07 PM

Regarding the isIntS16Immediate change, the function is duplicated in PPCISelDAGToDAG.cpp as well. I suggest we leave it as is in this patch, and then in a separate patch common up the definitions and change it to use an int16_t argument. That keeps this patch focused on only doing a single thing, and puts the code cleanup in its own NFC patch.

Feel free to do that first. :)

Yes, please split this into two patches. Change the int16_t first, and then commit the functional change. LGTM.

This revision is now accepted and ready to land.Jul 6 2017, 6:07 PM
lei added a comment.Jul 10 2017, 8:04 AM

Regarding the isIntS16Immediate change, the function is duplicated in PPCISelDAGToDAG.cpp as well. I suggest we leave it as is in this patch, and then in a separate patch common up the definitions and change it to use an int16_t argument. That keeps this patch focused on only doing a single thing, and puts the code cleanup in its own NFC patch.

Feel free to do that first. :)

Yes, please split this into two patches. Change the int16_t first, and then commit the functional change. LGTM.

NFC patch committed: SVN-307442

This revision was automatically updated to reflect the committed changes.