Skip to content

Commit

Permalink
[SelectionDAG] Add getTokenFactor, which splits nodes with > 64k oper…
Browse files Browse the repository at this point in the history
…ands.

This functionality is required at multiple places which potentially
create large operand lists, like SelectionDAGBuilder or DAGCombiner.

Differential Revision: https://reviews.llvm.org/D56739

llvm-svn: 351552
  • Loading branch information
fhahn committed Jan 18, 2019
1 parent f535694 commit d2c733b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,11 @@ class SelectionDAG {
SDValue Op3, SDValue Op4, SDValue Op5);
SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);

/// Creates a new TokenFactor containing \p Vals. If \p Vals contains 64k
/// values or more, move values into new TokenFactors in 64k-1 blocks, until
/// the final TokenFactor has less than 64k operands.
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl<SDValue> &Vals);

/// *Mutate* the specified machine node's memory references to the provided
/// list.
void setNodeMemRefs(MachineSDNode *N,
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9286,6 +9286,19 @@ void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
checkForCycles(Node);
}

SDValue SelectionDAG::getTokenFactor(const SDLoc &DL,
SmallVectorImpl<SDValue> &Vals) {
size_t Limit = SDNode::getMaxNumOperands();
while (Vals.size() > Limit) {
unsigned SliceIdx = Vals.size() - Limit;
auto ExtractedTFs = ArrayRef<SDValue>(Vals).slice(SliceIdx, Limit);
SDValue NewTF = getNode(ISD::TokenFactor, DL, MVT::Other, ExtractedTFs);
Vals.erase(Vals.begin() + SliceIdx, Vals.end());
Vals.emplace_back(NewTF);
}
return getNode(ISD::TokenFactor, DL, MVT::Other, Vals);
}

#ifndef NDEBUG
static void checkForCyclesHelper(const SDNode *N,
SmallPtrSetImpl<const SDNode*> &Visited,
Expand Down
14 changes: 1 addition & 13 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,19 +1032,7 @@ SDValue SelectionDAGBuilder::getRoot() {
}

// Otherwise, we have to make a token factor node.
// If we have >= 2^16 loads then split across multiple token factors as
// there's a 64k limit on the number of SDNode operands.
SDValue Root;
size_t Limit = SDNode::getMaxNumOperands();
while (PendingLoads.size() > Limit) {
unsigned SliceIdx = PendingLoads.size() - Limit;
auto ExtractedTFs = ArrayRef<SDValue>(PendingLoads).slice(SliceIdx, Limit);
SDValue NewTF =
DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, ExtractedTFs);
PendingLoads.erase(PendingLoads.begin() + SliceIdx, PendingLoads.end());
PendingLoads.emplace_back(NewTF);
}
Root = DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, PendingLoads);
SDValue Root = DAG.getTokenFactor(getCurSDLoc(), PendingLoads);
PendingLoads.clear();
DAG.setRoot(Root);
return Root;
Expand Down

0 comments on commit d2c733b

Please sign in to comment.