@@ -115,6 +115,10 @@ static cl::opt<unsigned>
115115 MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192),
116116 cl::desc("DAG combiner limit number of steps when searching DAG "
117117 "for predecessor nodes"));
118+ static cl::opt<bool> EnableSimplifyNodes(
119+ "selectiondag-simplify-nodes", cl::Hidden, cl::init(true),
120+ cl::desc("Enable SelectionDAG::getNode simplifications. Useful for testing "
121+ "DAG combines."));
118122
119123static void NewSDValueDbgMsg(SDValue V, StringRef Msg, SelectionDAG *G) {
120124 LLVM_DEBUG(dbgs() << Msg; V.getNode()->dump(G););
@@ -6172,23 +6176,46 @@ static SDValue foldCONCAT_VECTORS(const SDLoc &DL, EVT VT,
61726176}
61736177
61746178/// Gets or creates the specified node.
6175- SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
6179+ SDValue SelectionDAG::getNodeImpl(unsigned Opcode, const SDLoc &DL, EVT VT,
6180+ ArrayRef<SDValue> Ops,
6181+ const SDNodeFlags Flags) {
61766182 SDVTList VTs = getVTList(VT);
6177- FoldingSetNodeID ID;
6178- AddNodeIDNode(ID, Opcode, VTs, {});
6179- void *IP = nullptr;
6180- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
6181- return SDValue(E, 0);
6183+ return getNodeImpl(Opcode, DL, VTs, Ops, Flags);
6184+ }
61826185
6183- auto *N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6184- CSEMap.InsertNode(N, IP);
6186+ SDValue SelectionDAG::getNodeImpl(unsigned Opcode, const SDLoc &DL,
6187+ SDVTList VTs, ArrayRef<SDValue> Ops,
6188+ const SDNodeFlags Flags) {
6189+ SDNode *N;
6190+ // Don't CSE glue-producing nodes
6191+ if (VTs.VTs[VTs.NumVTs - 1] != MVT::Glue) {
6192+ FoldingSetNodeID ID;
6193+ AddNodeIDNode(ID, Opcode, VTs, Ops);
6194+ void *IP = nullptr;
6195+ if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
6196+ E->intersectFlagsWith(Flags);
6197+ return SDValue(E, 0);
6198+ }
6199+
6200+ N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6201+ createOperands(N, Ops);
6202+ CSEMap.InsertNode(N, IP);
6203+ } else {
6204+ N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6205+ createOperands(N, Ops);
6206+ }
61856207
6208+ N->setFlags(Flags);
61866209 InsertNode(N);
61876210 SDValue V = SDValue(N, 0);
61886211 NewSDValueDbgMsg(V, "Creating new node: ", this);
61896212 return V;
61906213}
61916214
6215+ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
6216+ return getNodeImpl(Opcode, DL, VT, {}, SDNodeFlags{});
6217+ }
6218+
61926219SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
61936220 SDValue N1) {
61946221 SDNodeFlags Flags;
@@ -6200,6 +6227,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
62006227SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
62016228 SDValue N1, const SDNodeFlags Flags) {
62026229 assert(N1.getOpcode() != ISD::DELETED_NODE && "Operand is DELETED_NODE!");
6230+ if (!EnableSimplifyNodes)
6231+ return getNodeImpl(Opcode, DL, VT, {N1}, Flags);
62036232
62046233 // Constant fold unary operations with a vector integer or float operand.
62056234 switch (Opcode) {
@@ -6516,31 +6545,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
65166545 break;
65176546 }
65186547
6519- SDNode *N;
6520- SDVTList VTs = getVTList(VT);
6521- SDValue Ops[] = {N1};
6522- if (VT != MVT::Glue) { // Don't CSE glue producing nodes
6523- FoldingSetNodeID ID;
6524- AddNodeIDNode(ID, Opcode, VTs, Ops);
6525- void *IP = nullptr;
6526- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
6527- E->intersectFlagsWith(Flags);
6528- return SDValue(E, 0);
6529- }
6530-
6531- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6532- N->setFlags(Flags);
6533- createOperands(N, Ops);
6534- CSEMap.InsertNode(N, IP);
6535- } else {
6536- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6537- createOperands(N, Ops);
6538- }
6539-
6540- InsertNode(N);
6541- SDValue V = SDValue(N, 0);
6542- NewSDValueDbgMsg(V, "Creating new node: ", this);
6543- return V;
6548+ return getNodeImpl(Opcode, DL, VT, {N1}, Flags);
65446549}
65456550
65466551static std::optional<APInt> FoldValue(unsigned Opcode, const APInt &C1,
@@ -7234,6 +7239,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
72347239 assert(N1.getOpcode() != ISD::DELETED_NODE &&
72357240 N2.getOpcode() != ISD::DELETED_NODE &&
72367241 "Operand is DELETED_NODE!");
7242+ if (!EnableSimplifyNodes)
7243+ return getNodeImpl(Opcode, DL, VT, {N1, N2}, Flags);
72377244
72387245 canonicalizeCommutativeBinop(Opcode, N1, N2);
72397246
@@ -7680,32 +7687,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
76807687 }
76817688 }
76827689
7683- // Memoize this node if possible.
7684- SDNode *N;
7685- SDVTList VTs = getVTList(VT);
7686- SDValue Ops[] = {N1, N2};
7687- if (VT != MVT::Glue) {
7688- FoldingSetNodeID ID;
7689- AddNodeIDNode(ID, Opcode, VTs, Ops);
7690- void *IP = nullptr;
7691- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
7692- E->intersectFlagsWith(Flags);
7693- return SDValue(E, 0);
7694- }
7695-
7696- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7697- N->setFlags(Flags);
7698- createOperands(N, Ops);
7699- CSEMap.InsertNode(N, IP);
7700- } else {
7701- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7702- createOperands(N, Ops);
7703- }
7704-
7705- InsertNode(N);
7706- SDValue V = SDValue(N, 0);
7707- NewSDValueDbgMsg(V, "Creating new node: ", this);
7708- return V;
7690+ return getNodeImpl(Opcode, DL, VT, {N1, N2}, Flags);
77097691}
77107692
77117693SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
@@ -7723,6 +7705,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
77237705 N2.getOpcode() != ISD::DELETED_NODE &&
77247706 N3.getOpcode() != ISD::DELETED_NODE &&
77257707 "Operand is DELETED_NODE!");
7708+ if (!EnableSimplifyNodes)
7709+ return getNodeImpl(Opcode, DL, VT, {N1, N2, N3}, Flags);
7710+
77267711 // Perform various simplifications.
77277712 switch (Opcode) {
77287713 case ISD::FMA:
@@ -7877,33 +7862,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
78777862 break;
78787863 }
78797864 }
7880-
7881- // Memoize node if it doesn't produce a glue result.
7882- SDNode *N;
7883- SDVTList VTs = getVTList(VT);
7884- SDValue Ops[] = {N1, N2, N3};
7885- if (VT != MVT::Glue) {
7886- FoldingSetNodeID ID;
7887- AddNodeIDNode(ID, Opcode, VTs, Ops);
7888- void *IP = nullptr;
7889- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
7890- E->intersectFlagsWith(Flags);
7891- return SDValue(E, 0);
7892- }
7893-
7894- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7895- N->setFlags(Flags);
7896- createOperands(N, Ops);
7897- CSEMap.InsertNode(N, IP);
7898- } else {
7899- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7900- createOperands(N, Ops);
7901- }
7902-
7903- InsertNode(N);
7904- SDValue V = SDValue(N, 0);
7905- NewSDValueDbgMsg(V, "Creating new node: ", this);
7906- return V;
7865+ return getNodeImpl(Opcode, DL, VT, {N1, N2, N3}, Flags);
79077866}
79087867
79097868SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
@@ -10358,6 +10317,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1035810317 assert(Op.getOpcode() != ISD::DELETED_NODE &&
1035910318 "Operand is DELETED_NODE!");
1036010319#endif
10320+ if (!EnableSimplifyNodes)
10321+ return getNodeImpl(Opcode, DL, VT, Ops, Flags);
1036110322
1036210323 switch (Opcode) {
1036310324 default: break;
@@ -10426,34 +10387,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1042610387 break;
1042710388 }
1042810389
10429- // Memoize nodes.
10430- SDNode *N;
10431- SDVTList VTs = getVTList(VT);
10432-
10433- if (VT != MVT::Glue) {
10434- FoldingSetNodeID ID;
10435- AddNodeIDNode(ID, Opcode, VTs, Ops);
10436- void *IP = nullptr;
10437-
10438- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
10439- E->intersectFlagsWith(Flags);
10440- return SDValue(E, 0);
10441- }
10442-
10443- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
10444- createOperands(N, Ops);
10445-
10446- CSEMap.InsertNode(N, IP);
10447- } else {
10448- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
10449- createOperands(N, Ops);
10450- }
10451-
10452- N->setFlags(Flags);
10453- InsertNode(N);
10454- SDValue V(N, 0);
10455- NewSDValueDbgMsg(V, "Creating new node: ", this);
10456- return V;
10390+ return getNodeImpl(Opcode, DL, VT, Ops, Flags);
1045710391}
1045810392
1045910393SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
@@ -10473,6 +10407,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1047310407 ArrayRef<SDValue> Ops, const SDNodeFlags Flags) {
1047410408 if (VTList.NumVTs == 1)
1047510409 return getNode(Opcode, DL, VTList.VTs[0], Ops, Flags);
10410+ if (!EnableSimplifyNodes)
10411+ return getNodeImpl(Opcode, DL, VTList, Ops, Flags);
1047610412
1047710413#ifndef NDEBUG
1047810414 for (const auto &Op : Ops)
@@ -10637,30 +10573,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1063710573#endif
1063810574 }
1063910575
10640- // Memoize the node unless it returns a glue result.
10641- SDNode *N;
10642- if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {
10643- FoldingSetNodeID ID;
10644- AddNodeIDNode(ID, Opcode, VTList, Ops);
10645- void *IP = nullptr;
10646- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
10647- E->intersectFlagsWith(Flags);
10648- return SDValue(E, 0);
10649- }
10650-
10651- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
10652- createOperands(N, Ops);
10653- CSEMap.InsertNode(N, IP);
10654- } else {
10655- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
10656- createOperands(N, Ops);
10657- }
10658-
10659- N->setFlags(Flags);
10660- InsertNode(N);
10661- SDValue V(N, 0);
10662- NewSDValueDbgMsg(V, "Creating new node: ", this);
10663- return V;
10576+ return getNodeImpl(Opcode, DL, VTList, Ops, Flags);
1066410577}
1066510578
1066610579SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
0 commit comments