diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-18 10:40:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-18 10:40:35 +0000 |
commit | 722a26d63e717f5cfbf924e042f4f300bfee1328 (patch) | |
tree | e3475aa52053a31f2f5f7dada1f87d71cfa5b517 /lib/Target | |
parent | 6a3d933e1645d34984f4c7c9e2e4e46d0d15e1b3 (diff) | |
download | external_llvm-722a26d63e717f5cfbf924e042f4f300bfee1328.zip external_llvm-722a26d63e717f5cfbf924e042f4f300bfee1328.tar.gz external_llvm-722a26d63e717f5cfbf924e042f4f300bfee1328.tar.bz2 |
[SystemZ] Use RNSBG
This should be the last of the R.SBG patches for now.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186573 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/SystemZ/README.txt | 5 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 83 |
2 files changed, 67 insertions, 21 deletions
diff --git a/lib/Target/SystemZ/README.txt b/lib/Target/SystemZ/README.txt index 55e9fc0..2782b63 100644 --- a/lib/Target/SystemZ/README.txt +++ b/lib/Target/SystemZ/README.txt @@ -118,11 +118,6 @@ such as ICM and STCM. -- -We could make more use of the ROTATE AND ... SELECTED BITS instructions. -At the moment we only use RISBG, and only then for subword atomic operations. - --- - DAGCombiner can detect integer absolute, but there's not yet an associated ISD opcode. We could add one and implement it using LOAD POSITIVE. Negated absolutes could use LOAD NEGATIVE. diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 0f9a37e..8866253 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -97,15 +97,24 @@ static uint64_t allOnes(unsigned int Count) { return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1; } -// Represents operands 2 to 5 of a ROTATE AND ... SELECTED BITS operation. -// The operands are: Input (R2), Start (I3), End (I4) and Rotate (I5). -// The operand value is effectively (and (rotl Input Rotate) Mask) and -// has BitSize bits. +// Represents operands 2 to 5 of the ROTATE AND ... SELECTED BITS operation +// given by Opcode. The operands are: Input (R2), Start (I3), End (I4) and +// Rotate (I5). The combined operand value is effectively: +// +// (or (rotl Input, Rotate), ~Mask) +// +// for RNSBG and: +// +// (and (rotl Input, Rotate), Mask) +// +// otherwise. The value has BitSize bits. struct RxSBGOperands { - RxSBGOperands(SDValue N) - : BitSize(N.getValueType().getSizeInBits()), Mask(allOnes(BitSize)), - Input(N), Start(64 - BitSize), End(63), Rotate(0) {} + RxSBGOperands(unsigned Op, SDValue N) + : Opcode(Op), BitSize(N.getValueType().getSizeInBits()), + Mask(allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63), + Rotate(0) {} + unsigned Opcode; unsigned BitSize; uint64_t Mask; SDValue Input; @@ -671,6 +680,9 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) { unsigned Opcode = N.getOpcode(); switch (Opcode) { case ISD::AND: { + if (RxSBG.Opcode == SystemZ::RNSBG) + return false; + ConstantSDNode *MaskNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); if (!MaskNode) @@ -692,6 +704,31 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) { return true; } + case ISD::OR: { + if (RxSBG.Opcode != SystemZ::RNSBG) + return false; + + ConstantSDNode *MaskNode = + dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); + if (!MaskNode) + return false; + + SDValue Input = N.getOperand(0); + uint64_t Mask = ~MaskNode->getZExtValue(); + if (!refineRxSBGMask(RxSBG, Mask)) { + // If some bits of Input are already known ones, those bits will have + // been removed from the mask. See if adding them back in makes the + // mask suitable. + APInt KnownZero, KnownOne; + CurDAG->ComputeMaskedBits(Input, KnownZero, KnownOne); + Mask &= ~KnownOne.getZExtValue(); + if (!refineRxSBGMask(RxSBG, Mask)) + return false; + } + RxSBG.Input = Input; + return true; + } + case ISD::ROTL: { // Any 64-bit rotate left can be merged into the RxSBG. if (RxSBG.BitSize != 64) @@ -707,18 +744,26 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) { } case ISD::SHL: { - // Treat (shl X, count) as (and (rotl X, count), ~0<<count). ConstantSDNode *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); if (!CountNode) return false; uint64_t Count = CountNode->getZExtValue(); - if (Count < 1 || - Count >= RxSBG.BitSize || - !refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count) << Count)) + if (Count < 1 || Count >= RxSBG.BitSize) return false; + if (RxSBG.Opcode == SystemZ::RNSBG) { + // Treat (shl X, count) as (rotl X, size-count) as long as the bottom + // count bits from RxSBG.Input are ignored. + if (shiftedInBitsMatter(RxSBG, Count, true)) + return false; + } else { + // Treat (shl X, count) as (and (rotl X, count), ~0<<count). + if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count) << Count)) + return false; + } + RxSBG.Rotate = (RxSBG.Rotate + Count) & 63; RxSBG.Input = N.getOperand(0); return true; @@ -735,9 +780,9 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) { if (Count < 1 || Count >= RxSBG.BitSize) return false; - if (Opcode == ISD::SRA) { - // Treat (sra X, count) as (rotl X, size-count) as long as the top - // Count bits from RxSBG.Input are ignored. + if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) { + // Treat (srl|sra X, count) as (rotl X, size-count) as long as the top + // count bits from RxSBG.Input are ignored. if (shiftedInBitsMatter(RxSBG, Count, false)) return false; } else { @@ -779,7 +824,7 @@ SDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) { } SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { - RxSBGOperands RISBG(SDValue(N, 0)); + RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0)); unsigned Count = 0; while (expandRxSBG(RISBG)) Count += 1; @@ -811,7 +856,10 @@ SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { SDNode *SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) { // Try treating each operand of N as the second operand of the RxSBG // and see which goes deepest. - RxSBGOperands RxSBG[] = { N->getOperand(0), N->getOperand(1) }; + RxSBGOperands RxSBG[] = { + RxSBGOperands(Opcode, N->getOperand(0)), + RxSBGOperands(Opcode, N->getOperand(1)) + }; unsigned Count[] = { 0, 0 }; for (unsigned I = 0; I < 2; ++I) while (expandRxSBG(RxSBG[I])) @@ -941,6 +989,9 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { break; case ISD::AND: + if (Node->getOperand(1).getOpcode() != ISD::Constant) + ResNode = tryRxSBG(Node, SystemZ::RNSBG); + // Fall through. case ISD::ROTL: case ISD::SHL: case ISD::SRL: |