[PATCH] D16463: [DAGCombiner] Check store node's value count before replaceStoreChain

Junmo Park via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 22 17:04:32 PST 2016


flyingforyou added a comment.

Thanks for comment Chad.

I respect your opinion. But I couldn't add testcase for this patch.
Because it's about assert.

So, I want to explain more about this.

  for (StoreSDNode *ChainedStore : ChainedStores) {
    // If ChainedStore has more than one value, we don't try replaceStoreChain.
    // replaceStoreChain uses CombineTo, which only consider Chain only.
    if (ChainedStore->getNumValues() != 1)
      continue;
  
    SDValue Chain = ChainedStore->getChain();
    SDValue BetterChain = FindBetterChain(ChainedStore, Chain);
  
    if (Chain != BetterChain) {
      MadeChange = true;
      BetterChains.push_back(std::make_pair(ChainedStore, BetterChain));
    }
  }
  
  // Do all replacements after finding the replacements to make to avoid making
  // the chains more complicated by introducing new TokenFactors.
  for (auto Replacement : BetterChains)
    replaceStoreChain(Replacement.first, Replacement.second);

When you see inside of for loop, `ChainedStore` is added to `BetterChains`.
After this, `replaceStoreChain` get `ChainedStore` for first parameter.

  SDValue DAGCombiner::replaceStoreChain(StoreSDNode *ST, SDValue BetterChain) {
    SDLoc SL(ST);
    SDValue ReplStore;
  
    // Replace the chain to avoid dependency.
    if (ST->isTruncatingStore()) {
      ReplStore = DAG.getTruncStore(BetterChain, SL, ST->getValue(),
                                    ST->getBasePtr(), ST->getMemoryVT(),
                                    ST->getMemOperand());
    } else {
      ReplStore = DAG.getStore(BetterChain, SL, ST->getValue(), ST->getBasePtr(),
                               ST->getMemOperand());
    }
  
    // Create token to keep both nodes around.
    SDValue Token = DAG.getNode(ISD::TokenFactor, SL,
                                MVT::Other, ST->getChain(), ReplStore);
  
    // Make sure the new and old chains are cleaned up.
    AddToWorklist(Token.getNode());
  
    // Don't add users to work list.
    return CombineTo(ST, Token, false);
  }

Inside of `replaceStoreChain`, `ChainedStore` will be passed to `CombineTo`'s first parameter.
And Token which is `CombineTo`'s second paratemter only can be combined with same type node.

  SDValue DAGCombiner::CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
                                 bool AddTo) {
    assert(N->getNumValues() == NumTo && "Broken CombineTo call!");
    ++NodesCombined;
    DEBUG(dbgs() << "\nReplacing.1 ";
          N->dump(&DAG);
          dbgs() << "\nWith: ";
          To[0].getNode()->dump(&DAG);
          dbgs() << " and " << NumTo-1 << " other values\n");
    for (unsigned i = 0, e = NumTo; i != e; ++i)
      assert((!To[i].getNode() ||
              N->getValueType(i) == To[i].getValueType()) &&
             "Cannot combine value to value of different type!");
  
    WorklistRemover DeadNodes(*this);
    DAG.ReplaceAllUsesWith(N, To);
    if (AddTo) {
      // Push the new nodes and any users onto the worklist
      for (unsigned i = 0, e = NumTo; i != e; ++i) {
        if (To[i].getNode()) {
          AddToWorklist(To[i].getNode());
          AddUsersToWorklist(To[i].getNode());
        }
      }
    }
  
    // Finally, if the node is now dead, remove it from the graph.  The node
    // may not be dead if the replacement process recursively simplified to
    // something else needing this node.
    if (N->use_empty())
      deleteAndRecombine(N);
    return SDValue(N, 0);
  }

There is a assert check  `assert(N->getNumValues() == NumTo && "Broken CombineTo call!");`.
When we call `CombineTo(ST, Token, false)`, this is changed likes below.

  /// Replaces all uses of the results of one DAG node with new values.
  SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true) {
    return CombineTo(N, &Res, 1, AddTo);
  }

That means `NumTo` is always `1`. This is why I added check code likes below.

  if (ChainedStore->getNumValues() != 1)
    continue;

Junmo.


http://reviews.llvm.org/D16463





More information about the llvm-commits mailing list