diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-09-05 10:36:45 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-09-05 10:36:45 +0000 |
commit | 16277c4698f36a756c540fae326874774156aaed (patch) | |
tree | 640d07133c8f2ab9f909e7b2c464f96e6c1a5496 /lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | |
parent | a83aeae350d822ec84ded34ff3fdf1e0917d3bfd (diff) | |
download | external_llvm-16277c4698f36a756c540fae326874774156aaed.zip external_llvm-16277c4698f36a756c540fae326874774156aaed.tar.gz external_llvm-16277c4698f36a756c540fae326874774156aaed.tar.bz2 |
[SystemZ] Add NC, OC and XC
For now these are just used to handle scalar ANDs, ORs and XORs in which
all operands are memory.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190041 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ/SystemZISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index e0d5437..9d71c39 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -290,8 +290,15 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { SDNode *splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0, uint64_t UpperVal, uint64_t LowerVal); + // N is a (store (load Y), X) pattern. Return true if it can use an MVC + // from Y to X. bool storeLoadCanUseMVC(SDNode *N) const; + // N is a (store (op (load A[0]), (load A[1])), X) pattern. Return true + // if A[1 - I] == X and if N can use a block operation like NC from A[I] + // to X. + bool storeLoadCanUseBlockBinary(SDNode *N, unsigned I) const; + public: SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) : SelectionDAGISel(TM, OptLevel), @@ -925,34 +932,27 @@ SDNode *SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node, return Or.getNode(); } -// N is a (store (load ...), ...) pattern. Return true if it can use MVC. -bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { - StoreSDNode *Store = cast<StoreSDNode>(N); - LoadSDNode *Load = cast<LoadSDNode>(Store->getValue().getNode()); +// Return true if Load and Store: +// - are loads and stores of the same size; +// - do not partially overlap; and +// - can be decomposed into what are logically individual character accesses +// without changing the semantics. +static bool canUseBlockOperation(StoreSDNode *Store, LoadSDNode *Load, + AliasAnalysis *AA) { + // Check that the two memory operands have the same size. + if (Load->getMemoryVT() != Store->getMemoryVT()) + return false; - // MVC is logically a bytewise copy, so can't be used for volatile accesses. + // Volatility stops an access from being decomposed. if (Load->isVolatile() || Store->isVolatile()) return false; - // Prefer not to use MVC if either address can use ... RELATIVE LONG - // instructions. - assert(Load->getMemoryVT() == Store->getMemoryVT() && - "Should already have checked that the types match"); - uint64_t Size = Load->getMemoryVT().getStoreSize(); - if (Size > 1 && Size <= 8) { - // Prefer LHRL, LRL and LGRL. - if (Load->getBasePtr().getOpcode() == SystemZISD::PCREL_WRAPPER) - return false; - // Prefer STHRL, STRL and STGRL. - if (Store->getBasePtr().getOpcode() == SystemZISD::PCREL_WRAPPER) - return false; - } - // There's no chance of overlap if the load is invariant. if (Load->isInvariant()) return true; // If both operands are aligned, they must be equal or not overlap. + uint64_t Size = Load->getMemoryVT().getStoreSize(); if (Load->getAlignment() >= Size && Store->getAlignment() >= Size) return true; @@ -968,6 +968,37 @@ bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { AliasAnalysis::Location(V2, End2, Store->getTBAAInfo())); } +bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { + StoreSDNode *Store = cast<StoreSDNode>(N); + LoadSDNode *Load = cast<LoadSDNode>(Store->getValue()); + + // Prefer not to use MVC if either address can use ... RELATIVE LONG + // instructions. + uint64_t Size = Load->getMemoryVT().getStoreSize(); + if (Size > 1 && Size <= 8) { + // Prefer LHRL, LRL and LGRL. + if (Load->getBasePtr().getOpcode() == SystemZISD::PCREL_WRAPPER) + return false; + // Prefer STHRL, STRL and STGRL. + if (Store->getBasePtr().getOpcode() == SystemZISD::PCREL_WRAPPER) + return false; + } + + return canUseBlockOperation(Store, Load, AA); +} + +bool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(SDNode *N, + unsigned I) const { + StoreSDNode *StoreA = cast<StoreSDNode>(N); + LoadSDNode *LoadA = cast<LoadSDNode>(StoreA->getValue().getOperand(1 - I)); + LoadSDNode *LoadB = cast<LoadSDNode>(StoreA->getValue().getOperand(I)); + if (LoadA->isVolatile() || + LoadA->getMemoryVT() != StoreA->getMemoryVT() || + LoadA->getBasePtr() != StoreA->getBasePtr()) + return false; + return canUseBlockOperation(StoreA, LoadB, AA); +} + SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { // Dump information about the Node being selected DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); |