diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 50 | 
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d5d3f7a61a9f..432c86dd6f1e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1118,22 +1118,30 @@ SDValue DAGCombiner::PromoteIntBinOp(SDValue Op) {      SDValue RV =          DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1)); -    // New replace instances of N0 and N1 -    if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 && -        NN0.getOpcode() != ISD::DELETED_NODE) { +    // We are always replacing N0/N1's use in N and only need +    // additional replacements if there are additional uses. +    Replace0 &= !N0->hasOneUse(); +    Replace1 &= (N0 != N1) && !N1->hasOneUse(); + +    // Combine Op here so it is presreved past replacements. +    CombineTo(Op.getNode(), RV); + +    // If operands have a use ordering, make sur we deal with +    // predecessor first. +    if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) { +      std::swap(N0, N1); +      std::swap(NN0, NN1); +    } + +    if (Replace0) {        AddToWorklist(NN0.getNode());        ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());      } - -    if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 && -        NN1.getOpcode() != ISD::DELETED_NODE) { +    if (Replace1) {        AddToWorklist(NN1.getNode());        ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());      } - -    // Deal with Op being deleted. -    if (Op && Op.getOpcode() != ISD::DELETED_NODE) -      return RV; +    return Op;    }    return SDValue();  } @@ -12599,25 +12607,37 @@ void DAGCombiner::getStoreMergeCandidates(          }  } -// We need to check that merging these stores does not cause a loop -// in the DAG. Any store candidate may depend on another candidate +// We need to check that merging these stores does not cause a loop in +// the DAG. Any store candidate may depend on another candidate  // indirectly through its operand (we already consider dependencies  // through the chain). Check in parallel by searching up from  // non-chain operands of candidates. +  bool DAGCombiner::checkMergeStoreCandidatesForDependencies(      SmallVectorImpl<MemOpLink> &StoreNodes, unsigned NumStores) { + +  // FIXME: We should be able to truncate a full search of +  // predecessors by doing a BFS and keeping tabs the originating +  // stores from which worklist nodes come from in a similar way to +  // TokenFactor simplfication. +    SmallPtrSet<const SDNode *, 16> Visited;    SmallVector<const SDNode *, 8> Worklist; -  // search ops of store candidates +  unsigned int Max = 8192; +  // Search Ops of store candidates.    for (unsigned i = 0; i < NumStores; ++i) {      SDNode *n = StoreNodes[i].MemNode;      // Potential loops may happen only through non-chain operands      for (unsigned j = 1; j < n->getNumOperands(); ++j)        Worklist.push_back(n->getOperand(j).getNode());    } -  // search through DAG. We can stop early if we find a storenode +  // Search through DAG. We can stop early if we find a store node.    for (unsigned i = 0; i < NumStores; ++i) { -    if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist)) +    if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist, +                                     Max)) +      return false; +    // Check if we ended early, failing conservatively if so. +    if (Visited.size() >= Max)        return false;    }    return true;  | 
