diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2014-02-28 06:11:16 +0000 |
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2014-02-28 06:11:16 +0000 |
| commit | b998915ee117aea49397c4a825762f6c3b58e4d8 (patch) | |
| tree | 67b6efd6b3fb3e6479aa7c836a1c393c4e69c5f3 /llvm/lib/Target | |
| parent | 1e3f3bf950bab3b218e7331a92d06566fa132230 (diff) | |
| download | bcm5719-llvm-b998915ee117aea49397c4a825762f6c3b58e4d8.tar.gz bcm5719-llvm-b998915ee117aea49397c4a825762f6c3b58e4d8.zip | |
Swap PPC isel operands to allow for 0-folding
The PPC isel instruction can fold 0 into the first operand (thus eliminating
the need to materialize a zero-containing register when the 'true' result of
the isel is 0). When the isel is fed by a bit register operation that we can
invert, do so as part of the bit-register-operation peephole routine.
llvm-svn: 202469
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index b9eecbe16f3..44821d31b51 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -189,6 +189,9 @@ private: void PeepholePPC64(); void PeepholdCROps(); + + bool AllUsersSelectZero(SDNode *N); + void SwapAllSelectUsers(SDNode *N); }; } @@ -1504,6 +1507,74 @@ void PPCDAGToDAGISel::PostprocessISelDAG() { PeepholdCROps(); } +// Check if all users of this node will become isel where the second operand +// is the constant zero. If this is so, and if we can negate the condition, +// then we can flip the true and false operands. This will allow the zero to +// be folded with the isel so that we don't need to materialize a register +// containing zero. +bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *N) { + // If we're not using isel, then this does not matter. + if (!PPCSubTarget.hasISEL()) + return false; + + for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); + UI != UE; ++UI) { + SDNode *User = *UI; + if (!User->isMachineOpcode()) + return false; + if (User->getMachineOpcode() != PPC::SELECT_I4 && + User->getMachineOpcode() != PPC::SELECT_I8) + return false; + + SDNode *Op2 = User->getOperand(2).getNode(); + if (!Op2->isMachineOpcode()) + return false; + + if (Op2->getMachineOpcode() != PPC::LI && + Op2->getMachineOpcode() != PPC::LI8) + return false; + + ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op2->getOperand(0)); + if (!C) + return false; + + if (!C->isNullValue()) + return false; + } + + return true; +} + +void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *N) { + SmallVector<SDNode *, 4> ToReplace; + for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); + UI != UE; ++UI) { + SDNode *User = *UI; + assert((User->getMachineOpcode() == PPC::SELECT_I4 || + User->getMachineOpcode() == PPC::SELECT_I8) && + "Must have all select users"); + ToReplace.push_back(User); + } + + for (SmallVector<SDNode *, 4>::iterator UI = ToReplace.begin(), + UE = ToReplace.end(); UI != UE; ++UI) { + SDNode *User = *UI; + SDNode *ResNode = + CurDAG->getMachineNode(User->getMachineOpcode(), SDLoc(User), + User->getValueType(0), User->getOperand(0), + User->getOperand(2), + User->getOperand(1)); + + DEBUG(dbgs() << "CR Peephole replacing:\nOld: "); + DEBUG(User->dump(CurDAG)); + DEBUG(dbgs() << "\nNew: "); + DEBUG(ResNode->dump(CurDAG)); + DEBUG(dbgs() << "\n"); + + ReplaceUses(User, ResNode); + } +} + void PPCDAGToDAGISel::PeepholdCROps() { bool IsModified; do { @@ -1563,6 +1634,7 @@ void PPCDAGToDAGISel::PeepholdCROps() { break; } + bool SelectSwap = false; switch (Opcode) { default: break; case PPC::CRAND: @@ -1591,6 +1663,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRNAND, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CRNAND: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1624,6 +1701,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(1). getOperand(0), MachineNode->getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRAND, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CROR: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1651,6 +1733,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRNOR, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CRXOR: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1685,6 +1772,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CREQV, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CRNOR: if (Op1Set || Op2Set) @@ -1713,6 +1805,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(1). getOperand(0), MachineNode->getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CROR, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CREQV: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1747,6 +1844,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRXOR, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(0), + MachineNode->getOperand(1)), + SelectSwap = true; break; case PPC::CRANDC: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1777,6 +1879,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRORC, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(1), + MachineNode->getOperand(0)), + SelectSwap = true; break; case PPC::CRORC: if (MachineNode->getOperand(0) == MachineNode->getOperand(1)) @@ -1807,6 +1914,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { MVT::i1, MachineNode->getOperand(0), MachineNode->getOperand(1). getOperand(0)); + else if (AllUsersSelectZero(MachineNode)) + ResNode = CurDAG->getMachineNode(PPC::CRANDC, SDLoc(MachineNode), + MVT::i1, MachineNode->getOperand(1), + MachineNode->getOperand(0)), + SelectSwap = true; break; case PPC::SELECT_I4: case PPC::SELECT_I8: @@ -1841,6 +1953,11 @@ void PPCDAGToDAGISel::PeepholdCROps() { break; } + // If we're inverting this node because it is used only by selects that + // we'd like to swap, then swap the selects before the node replacement. + if (SelectSwap) + SwapAllSelectUsers(MachineNode); + if (ResNode != MachineNode) { DEBUG(dbgs() << "CR Peephole replacing:\nOld: "); DEBUG(MachineNode->dump(CurDAG)); |

