diff options
author | Hal Finkel <hfinkel@anl.gov> | 2015-01-04 12:35:03 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2015-01-04 12:35:03 +0000 |
commit | ca6375fb75979ac6098543613e2ac82d48afde5c (patch) | |
tree | bc146eb8bc683790cbe066a202e5be62c5a0edc2 /llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | |
parent | 66b3130cdae3b3631f094b4a556e7fde454eb030 (diff) | |
download | bcm5719-llvm-ca6375fb75979ac6098543613e2ac82d48afde5c.tar.gz bcm5719-llvm-ca6375fb75979ac6098543613e2ac82d48afde5c.zip |
[PowerPC] Materialize i64 constants using bit inversion
Materializing full 64-bit constants on PPC64 can be expensive, requiring up to
5 instructions depending on the locations of the non-zero bits. Sometimes
materializing the bit-reversed constant, and then flipping the bits, requires
fewer instructions than the direct method. If so, do that instead.
llvm-svn: 225132
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index c6dc50143c0..2e1c1abf5b6 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -544,7 +544,7 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { // Predict the number of instructions that would be generated by calling // SelectInt64(N). -static unsigned SelectInt64Count(int64_t Imm) { +static unsigned SelectInt64CountDirect(int64_t Imm) { // Assume no remaining bits. unsigned Remainder = 0; // Assume no shift required. @@ -602,9 +602,21 @@ static unsigned SelectInt64Count(int64_t Imm) { return Result; } +static unsigned SelectInt64Count(int64_t Imm) { + unsigned DirectCount = SelectInt64CountDirect(Imm); + + // If might be cheaper to materialize the bit-inverted constant, and then + // flip the bits (which takes one nor instruction). + unsigned NotDirectCount = SelectInt64CountDirect(~(uint64_t) Imm) + 1; + if (NotDirectCount < DirectCount) + return NotDirectCount; + + return DirectCount; +} + // Select a 64-bit constant. For cost-modeling purposes, SelectInt64Count // (above) needs to be kept in sync with this function. -static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { +static SDNode *SelectInt64Direct(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { // Assume no remaining bits. unsigned Remainder = 0; // Assume no shift required. @@ -678,6 +690,22 @@ static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { return Result; } +static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { + unsigned DirectCount = SelectInt64CountDirect(Imm); + + // If might be cheaper to materialize the bit-inverted constant, and then + // flip the bits (which takes one nor instruction). + unsigned NotDirectCount = SelectInt64CountDirect(~(uint64_t) Imm) + 1; + if (NotDirectCount < DirectCount) { + SDValue NotDirectVal = + SDValue(SelectInt64Direct(CurDAG, dl, ~(uint64_t) Imm), 0); + return CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, NotDirectVal, + NotDirectVal); + } + + return SelectInt64Direct(CurDAG, dl, Imm); +} + // Select a 64-bit constant. static SDNode *SelectInt64(SelectionDAG *CurDAG, SDNode *N) { SDLoc dl(N); |