Skip to content

Commit d2c733b

Browse files
committed
[SelectionDAG] Add getTokenFactor, which splits nodes with > 64k operands.
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
1 parent f535694 commit d2c733b

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,11 @@ class SelectionDAG {
11541154
SDValue Op3, SDValue Op4, SDValue Op5);
11551155
SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
11561156

1157+
/// Creates a new TokenFactor containing \p Vals. If \p Vals contains 64k
1158+
/// values or more, move values into new TokenFactors in 64k-1 blocks, until
1159+
/// the final TokenFactor has less than 64k operands.
1160+
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl<SDValue> &Vals);
1161+
11571162
/// *Mutate* the specified machine node's memory references to the provided
11581163
/// list.
11591164
void setNodeMemRefs(MachineSDNode *N,

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9286,6 +9286,19 @@ void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
92869286
checkForCycles(Node);
92879287
}
92889288

9289+
SDValue SelectionDAG::getTokenFactor(const SDLoc &DL,
9290+
SmallVectorImpl<SDValue> &Vals) {
9291+
size_t Limit = SDNode::getMaxNumOperands();
9292+
while (Vals.size() > Limit) {
9293+
unsigned SliceIdx = Vals.size() - Limit;
9294+
auto ExtractedTFs = ArrayRef<SDValue>(Vals).slice(SliceIdx, Limit);
9295+
SDValue NewTF = getNode(ISD::TokenFactor, DL, MVT::Other, ExtractedTFs);
9296+
Vals.erase(Vals.begin() + SliceIdx, Vals.end());
9297+
Vals.emplace_back(NewTF);
9298+
}
9299+
return getNode(ISD::TokenFactor, DL, MVT::Other, Vals);
9300+
}
9301+
92899302
#ifndef NDEBUG
92909303
static void checkForCyclesHelper(const SDNode *N,
92919304
SmallPtrSetImpl<const SDNode*> &Visited,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,19 +1032,7 @@ SDValue SelectionDAGBuilder::getRoot() {
10321032
}
10331033

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

0 commit comments

Comments
 (0)