@@ -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););
@@ -6157,23 +6161,46 @@ static SDValue foldCONCAT_VECTORS(const SDLoc &DL, EVT VT,
61576161}
61586162
61596163/// Gets or creates the specified node.
6160- SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
6164+ SDValue SelectionDAG::getNodeImpl(unsigned Opcode, const SDLoc &DL, EVT VT,
6165+ ArrayRef<SDValue> Ops,
6166+ const SDNodeFlags Flags) {
61616167 SDVTList VTs = getVTList(VT);
6162- FoldingSetNodeID ID;
6163- AddNodeIDNode(ID, Opcode, VTs, {});
6164- void *IP = nullptr;
6165- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
6166- return SDValue(E, 0);
6168+ return getNodeImpl(Opcode, DL, VTs, Ops, Flags);
6169+ }
61676170
6168- auto *N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6169- CSEMap.InsertNode(N, IP);
6171+ SDValue SelectionDAG::getNodeImpl(unsigned Opcode, const SDLoc &DL,
6172+ SDVTList VTs, ArrayRef<SDValue> Ops,
6173+ const SDNodeFlags Flags) {
6174+ SDNode *N;
6175+ // Don't CSE glue-producing nodes
6176+ if (VTs.VTs[VTs.NumVTs - 1] != MVT::Glue) {
6177+ FoldingSetNodeID ID;
6178+ AddNodeIDNode(ID, Opcode, VTs, Ops);
6179+ void *IP = nullptr;
6180+ if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
6181+ E->intersectFlagsWith(Flags);
6182+ return SDValue(E, 0);
6183+ }
6184+
6185+ N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6186+ createOperands(N, Ops);
6187+ CSEMap.InsertNode(N, IP);
6188+ } else {
6189+ N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6190+ createOperands(N, Ops);
6191+ }
61706192
6193+ N->setFlags(Flags);
61716194 InsertNode(N);
61726195 SDValue V = SDValue(N, 0);
61736196 NewSDValueDbgMsg(V, "Creating new node: ", this);
61746197 return V;
61756198}
61766199
6200+ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
6201+ return getNodeImpl(Opcode, DL, VT, {}, SDNodeFlags{});
6202+ }
6203+
61776204SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
61786205 SDValue N1) {
61796206 SDNodeFlags Flags;
@@ -6185,6 +6212,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
61856212SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
61866213 SDValue N1, const SDNodeFlags Flags) {
61876214 assert(N1.getOpcode() != ISD::DELETED_NODE && "Operand is DELETED_NODE!");
6215+ if (!EnableSimplifyNodes)
6216+ return getNodeImpl(Opcode, DL, VT, {N1}, Flags);
61886217
61896218 // Constant fold unary operations with a vector integer or float operand.
61906219 switch (Opcode) {
@@ -6501,31 +6530,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
65016530 break;
65026531 }
65036532
6504- SDNode *N;
6505- SDVTList VTs = getVTList(VT);
6506- SDValue Ops[] = {N1};
6507- if (VT != MVT::Glue) { // Don't CSE glue producing nodes
6508- FoldingSetNodeID ID;
6509- AddNodeIDNode(ID, Opcode, VTs, Ops);
6510- void *IP = nullptr;
6511- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
6512- E->intersectFlagsWith(Flags);
6513- return SDValue(E, 0);
6514- }
6515-
6516- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6517- N->setFlags(Flags);
6518- createOperands(N, Ops);
6519- CSEMap.InsertNode(N, IP);
6520- } else {
6521- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
6522- createOperands(N, Ops);
6523- }
6524-
6525- InsertNode(N);
6526- SDValue V = SDValue(N, 0);
6527- NewSDValueDbgMsg(V, "Creating new node: ", this);
6528- return V;
6533+ return getNodeImpl(Opcode, DL, VT, {N1}, Flags);
65296534}
65306535
65316536static std::optional<APInt> FoldValue(unsigned Opcode, const APInt &C1,
@@ -7219,6 +7224,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
72197224 assert(N1.getOpcode() != ISD::DELETED_NODE &&
72207225 N2.getOpcode() != ISD::DELETED_NODE &&
72217226 "Operand is DELETED_NODE!");
7227+ if (!EnableSimplifyNodes)
7228+ return getNodeImpl(Opcode, DL, VT, {N1, N2}, Flags);
72227229
72237230 canonicalizeCommutativeBinop(Opcode, N1, N2);
72247231
@@ -7665,32 +7672,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
76657672 }
76667673 }
76677674
7668- // Memoize this node if possible.
7669- SDNode *N;
7670- SDVTList VTs = getVTList(VT);
7671- SDValue Ops[] = {N1, N2};
7672- if (VT != MVT::Glue) {
7673- FoldingSetNodeID ID;
7674- AddNodeIDNode(ID, Opcode, VTs, Ops);
7675- void *IP = nullptr;
7676- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
7677- E->intersectFlagsWith(Flags);
7678- return SDValue(E, 0);
7679- }
7680-
7681- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7682- N->setFlags(Flags);
7683- createOperands(N, Ops);
7684- CSEMap.InsertNode(N, IP);
7685- } else {
7686- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7687- createOperands(N, Ops);
7688- }
7689-
7690- InsertNode(N);
7691- SDValue V = SDValue(N, 0);
7692- NewSDValueDbgMsg(V, "Creating new node: ", this);
7693- return V;
7675+ return getNodeImpl(Opcode, DL, VT, {N1, N2}, Flags);
76947676}
76957677
76967678SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
@@ -7708,6 +7690,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
77087690 N2.getOpcode() != ISD::DELETED_NODE &&
77097691 N3.getOpcode() != ISD::DELETED_NODE &&
77107692 "Operand is DELETED_NODE!");
7693+ if (!EnableSimplifyNodes)
7694+ return getNodeImpl(Opcode, DL, VT, {N1, N2, N3}, Flags);
7695+
77117696 // Perform various simplifications.
77127697 switch (Opcode) {
77137698 case ISD::FMA:
@@ -7862,33 +7847,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
78627847 break;
78637848 }
78647849 }
7865-
7866- // Memoize node if it doesn't produce a glue result.
7867- SDNode *N;
7868- SDVTList VTs = getVTList(VT);
7869- SDValue Ops[] = {N1, N2, N3};
7870- if (VT != MVT::Glue) {
7871- FoldingSetNodeID ID;
7872- AddNodeIDNode(ID, Opcode, VTs, Ops);
7873- void *IP = nullptr;
7874- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
7875- E->intersectFlagsWith(Flags);
7876- return SDValue(E, 0);
7877- }
7878-
7879- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7880- N->setFlags(Flags);
7881- createOperands(N, Ops);
7882- CSEMap.InsertNode(N, IP);
7883- } else {
7884- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
7885- createOperands(N, Ops);
7886- }
7887-
7888- InsertNode(N);
7889- SDValue V = SDValue(N, 0);
7890- NewSDValueDbgMsg(V, "Creating new node: ", this);
7891- return V;
7850+ return getNodeImpl(Opcode, DL, VT, {N1, N2, N3}, Flags);
78927851}
78937852
78947853SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
@@ -10343,6 +10302,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1034310302 assert(Op.getOpcode() != ISD::DELETED_NODE &&
1034410303 "Operand is DELETED_NODE!");
1034510304#endif
10305+ if (!EnableSimplifyNodes)
10306+ return getNodeImpl(Opcode, DL, VT, Ops, Flags);
1034610307
1034710308 switch (Opcode) {
1034810309 default: break;
@@ -10411,34 +10372,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1041110372 break;
1041210373 }
1041310374
10414- // Memoize nodes.
10415- SDNode *N;
10416- SDVTList VTs = getVTList(VT);
10417-
10418- if (VT != MVT::Glue) {
10419- FoldingSetNodeID ID;
10420- AddNodeIDNode(ID, Opcode, VTs, Ops);
10421- void *IP = nullptr;
10422-
10423- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
10424- E->intersectFlagsWith(Flags);
10425- return SDValue(E, 0);
10426- }
10427-
10428- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
10429- createOperands(N, Ops);
10430-
10431- CSEMap.InsertNode(N, IP);
10432- } else {
10433- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
10434- createOperands(N, Ops);
10435- }
10436-
10437- N->setFlags(Flags);
10438- InsertNode(N);
10439- SDValue V(N, 0);
10440- NewSDValueDbgMsg(V, "Creating new node: ", this);
10441- return V;
10375+ return getNodeImpl(Opcode, DL, VT, Ops, Flags);
1044210376}
1044310377
1044410378SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
@@ -10458,6 +10392,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1045810392 ArrayRef<SDValue> Ops, const SDNodeFlags Flags) {
1045910393 if (VTList.NumVTs == 1)
1046010394 return getNode(Opcode, DL, VTList.VTs[0], Ops, Flags);
10395+ if (!EnableSimplifyNodes)
10396+ return getNodeImpl(Opcode, DL, VTList, Ops, Flags);
1046110397
1046210398#ifndef NDEBUG
1046310399 for (const auto &Op : Ops)
@@ -10622,30 +10558,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1062210558#endif
1062310559 }
1062410560
10625- // Memoize the node unless it returns a glue result.
10626- SDNode *N;
10627- if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {
10628- FoldingSetNodeID ID;
10629- AddNodeIDNode(ID, Opcode, VTList, Ops);
10630- void *IP = nullptr;
10631- if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
10632- E->intersectFlagsWith(Flags);
10633- return SDValue(E, 0);
10634- }
10635-
10636- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
10637- createOperands(N, Ops);
10638- CSEMap.InsertNode(N, IP);
10639- } else {
10640- N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList);
10641- createOperands(N, Ops);
10642- }
10643-
10644- N->setFlags(Flags);
10645- InsertNode(N);
10646- SDValue V(N, 0);
10647- NewSDValueDbgMsg(V, "Creating new node: ", this);
10648- return V;
10561+ return getNodeImpl(Opcode, DL, VTList, Ops, Flags);
1064910562}
1065010563
1065110564SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL,
0 commit comments