Speculatively revert commit 164885 (nadav) in the hope of ressurecting a pile of
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index 4b815a8e4b72637fa870854ef0bd412f236852a5..da3293bc8c21ec140fa66de8eea7c81a4b95b82b 100644 (file)
@@ -301,10 +301,6 @@ namespace {
     /// looking for a better chain (aliasing node.)
     SDValue FindBetterChain(SDNode *N, SDValue Chain);
 
-    /// Merge consecutive store operations into a wide store.
-    /// \return True if some memory operations were changed.
-    bool MergeConsecutiveStores(StoreSDNode *N);
-
   public:
     DAGCombiner(SelectionDAG &D, AliasAnalysis &A, CodeGenOpt::Level OL)
       : DAG(D), TLI(D.getTargetLoweringInfo()), Level(BeforeLegalizeTypes),
@@ -7427,248 +7423,6 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) {
   return SDValue();
 }
 
-/// Returns the base pointer and an integer offset from that object.
-static std::pair<SDValue, int64_t> GetPointerBaseAndOffset(SDValue Ptr) {
-  if (Ptr->getOpcode() == ISD::ADD && isa<ConstantSDNode>(Ptr->getOperand(1))) {
-    int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
-    SDValue Base = Ptr->getOperand(0);
-    return std::make_pair(Base, Offset);
-  }
-
-  return std::make_pair(Ptr, 0);
-}
-
-struct ConsecutiveMemoryChainSorter {
-  typedef std::pair<LSBaseSDNode*, int64_t> MemLink;
-  bool operator()(MemLink LHS, MemLink RHS) {
-    return LHS.second < RHS.second;
-  }
-};
-
-bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
-  EVT MemVT = St->getMemoryVT();
-  int64_t ElementSizeBytes = MemVT.getSizeInBits()/8;
-
-  // Don't handle vectors.
-  if (MemVT.isVector() || !MemVT.isSimple())
-    return false;
-
-  // Perform an early exit check. Do not bother looking at stored values that
-  // are not constants or loads.
-  SDValue StoredVal = St->getValue();
-  if (!isa<ConstantSDNode>(StoredVal) && !isa<ConstantFPSDNode>(StoredVal) &&
-      !isa<LoadSDNode>(StoredVal))
-    return false;
-
-  // Is this a load-to-store or a const-store.
-  bool IsLoadSrc = isa<LoadSDNode>(StoredVal);
-
-  // Only look at ends of store chains.
-  SDValue Chain = SDValue(St, 1);
-  if (Chain->hasOneUse() && Chain->use_begin()->getOpcode() == ISD::STORE)
-    return false;
-
-  // This holds the base pointer and the offset in bytes from the base pointer.
-  std::pair<SDValue, int64_t> BasePtr =
-      GetPointerBaseAndOffset(St->getBasePtr());
-
-  // We must have a base and an offset.
-  if (!BasePtr.first.getNode())
-    return false;
-
-  // Do not handle stores to undef base pointers.
-  if (BasePtr.first.getOpcode() == ISD::UNDEF)
-    return false;
-
-  SmallVector<std::pair<StoreSDNode*, int64_t>, 8> StoreNodes;
-  // Walk up the chain and look for nodes with offsets from the same
-  // base pointer. Stop when reaching an instruction with a different kind
-  // or instruction which has a different base pointer.
-  StoreSDNode *Index = St;
-  while (Index) {
-    // If the chain has more than one use, then we can't reorder the mem ops.
-    if (Index != St && !SDValue(Index, 1)->hasOneUse())
-      break;
-
-    // Find the base pointer and offset for this memory node.
-    std::pair<SDValue, int64_t> Ptr =
-      GetPointerBaseAndOffset(Index->getBasePtr());
-
-    // Check that the base pointer is the same as the original one.
-    if (Ptr.first.getNode() != BasePtr.first.getNode())
-      break;
-
-    // Check that the alignment is the same.
-    if (Index->getAlignment() != St->getAlignment())
-      break;
-
-    // The memory operands must not be volatile.
-    if (Index->isVolatile() || Index->isIndexed())
-      break;
-
-    // No truncation.
-    if (StoreSDNode *St = dyn_cast<StoreSDNode>(Index))
-      if (St->isTruncatingStore())
-        break;
-
-    // The stored memory type must be the same.
-    if (Index->getMemoryVT() != MemVT)
-      break;
-
-    // We found a potential memory operand to merge.
-    StoreNodes.push_back(std::make_pair(Index,Ptr.second));
-
-   // Move up the chain to the next memory operation.
-    Index = dyn_cast<StoreSDNode>(Index->getChain().getNode());
-  }
-
-  // Check if there is anything to merge.
-  if (StoreNodes.size() < 2)
-    return false;
-
-  // Remember which node is the earliest node in the chain.
-  LSBaseSDNode *EarliestOp = StoreNodes.back().first;
-
-  // Sort the memory operands according to their distance from the base pointer.
-  std::sort(StoreNodes.begin(), StoreNodes.end(),
-            ConsecutiveMemoryChainSorter());
-
-  // Scan the memory operations on the chain and find the first non-consecutive
-  // store memory address.
-  unsigned LastConsecutiveStore = 0;
-  int64_t StartAddress = StoreNodes[0].second;
-  for (unsigned i=1; i<StoreNodes.size(); ++i) {
-    int64_t CurrAddress = StoreNodes[i].second;
-    if (CurrAddress - StartAddress != (ElementSizeBytes * i))
-      break;
-    LastConsecutiveStore = i;
-  }
-
-  // Store the constants into memory as one consecutive store.
-  if (!IsLoadSrc) {
-    unsigned LastConst = 0;
-    for (unsigned i=0; i<LastConsecutiveStore+1; ++i) {
-      SDValue StoredVal = StoreNodes[i].first->getValue();
-      bool IsConst = (isa<ConstantSDNode>(StoredVal) || isa<ConstantFPSDNode>(StoredVal));
-      if (!IsConst)
-        break;
-      LastConst = i;
-    }
-    unsigned NumElem = std::min(LastConsecutiveStore + 1, LastConst + 1);
-    if (NumElem < 2)
-      return false;
-
-    EVT JointMemOpVT = EVT::getVectorVT(*DAG.getContext(), MemVT, NumElem);
-    DebugLoc DL = StoreNodes[0].first->getDebugLoc();
-    SmallVector<SDValue, 8> Ops;
-
-    for (unsigned i = 0; i < NumElem ; ++i) {
-      StoreSDNode *St  = cast<StoreSDNode>(StoreNodes[i].first);
-      Ops.push_back(St->getValue());
-    }
-
-    SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, DL,
-                             JointMemOpVT, &Ops[0], Ops.size());
-
-    SDValue NewStore = DAG.getStore(EarliestOp->getChain(), DL, BV,
-                                    EarliestOp->getBasePtr(),
-                                    EarliestOp->getPointerInfo(), false, false,
-                                    EarliestOp->getAlignment());
-
-    for (unsigned i = 0; i < NumElem ; ++i) {
-      StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].first);
-      CombineTo(St, NewStore);
-    }
-    return true;
-  }
-
-  // Look for load nodes wich are used by the stored values.
-  SmallVector<std::pair<LoadSDNode*, int64_t>, 8> LoadNodes;
-
-  // Find acceptible loads. Loads need to have the same chain (token factor),
-  // must not be zext, volatile, indexed, and they must be consecutive.
-  SDValue LdBasePtr;
-  for (unsigned i=0; i<LastConsecutiveStore+1; ++i) {
-    LoadSDNode *Ld = dyn_cast<LoadSDNode>(StoreNodes[i].first->getValue());
-    if (!Ld) break;
-
-    // Loads must only have one use.
-    if (!Ld->hasNUsesOfValue(1, 0))
-      break;
-
-    // Check that the alignment is the same as the stores.
-    if (Ld->getAlignment() != St->getAlignment())
-      break;
-
-    // The memory operands must not be volatile.
-    if (Ld->isVolatile() || Ld->isIndexed())
-      break;
-
-    if (Ld->getExtensionType() != ISD::NON_EXTLOAD)
-      break;
-
-    // The stored memory type must be the same.
-    if (Ld->getMemoryVT() != MemVT)
-      break;
-
-    std::pair<SDValue, int64_t> LdPtr =
-    GetPointerBaseAndOffset(Ld->getBasePtr());
-
-    // If this is not the first ptr that we check.
-    if (LdBasePtr.getNode()) {
-      // The base ptr must be the same,
-      if (LdPtr.first != LdBasePtr)
-        break;
-    } else {
-      LdBasePtr = LdPtr.first;
-    }
-
-    // We found a potential memory operand to merge.
-    LoadNodes.push_back(std::make_pair(Ld, LdPtr.second));
-  }
-
-  if (LoadNodes.size() < 2)
-    return false;
-
-  // Scan the memory operations on the chain and find the first non-consecutive
-  // load memory address.
-  unsigned LastConsecutiveLoad = 0;
-  StartAddress = LoadNodes[0].second;
-  for (unsigned i=1; i<LoadNodes.size(); ++i) {
-    int64_t CurrAddress = LoadNodes[i].second;
-    if (CurrAddress - StartAddress != (ElementSizeBytes * i))
-      break;
-    LastConsecutiveLoad = i;
-  }
-
-  unsigned NumElem =
-    std::min(LastConsecutiveStore + 1, LastConsecutiveLoad + 1);
-
-  EVT JointMemOpVT = EVT::getVectorVT(*DAG.getContext(), MemVT, NumElem);
-  DebugLoc LoadDL = LoadNodes[0].first->getDebugLoc();
-  DebugLoc StoreDL = StoreNodes[0].first->getDebugLoc();
-
-  LoadSDNode *FirstLoad = LoadNodes[0].first;
-  SDValue NewLoad = DAG.getLoad(JointMemOpVT, LoadDL,
-                                FirstLoad->getChain(),
-                                FirstLoad->getBasePtr(),
-                                FirstLoad->getPointerInfo(),
-                                false, false, false,
-                                FirstLoad->getAlignment());
-
-  SDValue NewStore = DAG.getStore(EarliestOp->getChain(), StoreDL, NewLoad,
-                                  EarliestOp->getBasePtr(),
-                                  EarliestOp->getPointerInfo(), false, false,
-                                  EarliestOp->getAlignment());
-
-  for (unsigned i = 0; i < NumElem ; ++i) {
-    StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].first);
-    CombineTo(St, NewStore);
-  }
-
-  return true;
-}
-
 SDValue DAGCombiner::visitSTORE(SDNode *N) {
   StoreSDNode *ST  = cast<StoreSDNode>(N);
   SDValue Chain = ST->getChain();
@@ -7870,12 +7624,6 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
                              ST->getAlignment());
   }
 
-
-  // Only perform this optimization before the types are legal, because we
-  // don't want to generate illegal types in this optimization.
-  if (!LegalTypes && MergeConsecutiveStores(ST))
-    return SDValue(N, 0);
-
   return ReduceLoadOpStoreWidth(N);
 }