From 978464915780fe1df2b68503bbc05e40c97ccab2 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 9 Jul 2013 09:46:39 +0000 Subject: [SystemZ] Use MVC for simple load/store pairs Look for patterns of the form (store (load ...), ...) in which the two locations are known not to partially overlap. (Identical locations are OK.) These sequences are better implemented by MVC unless either the load or the store could use RELATIVE LONG instructions. The testcase showed that we weren't using LHRL and LGHRL for extload16, only sextloadi16. The patch fixes that too. llvm-svn: 185919 --- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp') diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index f10ba23b6f7..0891adc0e30 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "SystemZTargetMachine.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -209,6 +210,8 @@ class SystemZDAGToDAGISel : public SelectionDAGISel { SDNode *splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0, uint64_t UpperVal, uint64_t LowerVal); + bool storeLoadCanUseMVC(SDNode *N) const; + public: SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) : SelectionDAGISel(TM, OptLevel), @@ -533,6 +536,49 @@ 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(N); + LoadSDNode *Load = cast(Store->getValue().getNode()); + + // MVC is logically a bytewise copy, so can't be used for volatile accesses. + 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. + if (Load->getAlignment() >= Size && Store->getAlignment() >= Size) + return true; + + // Otherwise we need to check whether there's an alias. + const Value *V1 = Load->getSrcValue(); + const Value *V2 = Store->getSrcValue(); + if (!V1 || !V2) + return false; + + int64_t End1 = Load->getSrcValueOffset() + Size; + int64_t End2 = Store->getSrcValueOffset() + Size; + return !AA->alias(AliasAnalysis::Location(V1, End1, Load->getTBAAInfo()), + AliasAnalysis::Location(V2, End2, Store->getTBAAInfo())); +} + SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { // Dump information about the Node being selected DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); -- cgit v1.2.3