[llvm] [TableGen] Add a backend generating SDNode descriptions (PR #123002)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 17 14:46:14 PST 2025


================
@@ -0,0 +1,370 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Basic/SequenceToOffsetTable.h"
+#include "Common/CodeGenDAGPatterns.h" // For SDNodeInfo.
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/StringToOffsetTable.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+static cl::OptionCategory SDNodeInfoEmitterCat("Options for -gen-sdnode-info");
+
+static cl::opt<std::string> TargetSDNodeNamespace(
+    "sdnode-namespace", cl::cat(SDNodeInfoEmitterCat),
+    cl::desc("Specify target SDNode namespace (default=<Target>ISD)"));
+
+static cl::opt<bool> WarnOnSkippedNodes(
+    "warn-on-skipped-nodes", cl::cat(SDNodeInfoEmitterCat),
+    cl::desc("Explain why a node was skipped (default=true)"), cl::init(true));
+
+namespace {
+
+class SDNodeInfoEmitter {
+  const RecordKeeper &RK;
+  const CodeGenTarget Target;
+  std::vector<SDNodeInfo> AllNodes;
+  std::map<StringRef, SmallVector<const SDNodeInfo *, 2>> TargetNodesByName;
+
+public:
+  explicit SDNodeInfoEmitter(const RecordKeeper &RK);
+
+  void run(raw_ostream &OS) const;
+
+private:
+  void emitEnum(raw_ostream &OS) const;
+
+  std::vector<unsigned> emitNodeNames(raw_ostream &OS) const;
+
+  std::vector<std::pair<unsigned, unsigned>>
+  emitTypeConstraints(raw_ostream &OS) const;
+
+  void emitDescs(raw_ostream &OS) const;
+};
+
+} // namespace
+
+static bool haveCompatibleDescriptions(const SDNodeInfo *N1,
+                                       const SDNodeInfo *N2) {
+  // Number of results/operands must match.
+  if (N1->getNumResults() != N2->getNumResults() ||
+      N1->getNumOperands() != N2->getNumOperands())
+    return false;
+
+  // Flags must match.
+  if (N1->isStrictFP() != N2->isStrictFP() ||
+      N1->getTSFlags() != N2->getTSFlags())
+    return false;
+
+  // We're only interested in a subset of node properties. Properties like
+  // SDNPAssociative and SDNPCommutative do not impose constraints on nodes,
+  // and sometimes differ between nodes sharing the same enum name.
+  constexpr unsigned PropMask = (1 << SDNPHasChain) | (1 << SDNPOutGlue) |
+                                (1 << SDNPInGlue) | (1 << SDNPOptInGlue) |
+                                (1 << SDNPMemOperand) | (1 << SDNPVariadic);
+
+  return (N1->getProperties() & PropMask) == (N2->getProperties() & PropMask);
+}
+
+static bool haveCompatibleDescriptions(ArrayRef<const SDNodeInfo *> Nodes) {
+  const SDNodeInfo *N = Nodes.front();
+  return all_of(drop_begin(Nodes), [&](const SDNodeInfo *Other) {
+    return haveCompatibleDescriptions(Other, N);
+  });
+}
+
+static void warnOnSkippedNode(const SDNodeInfo *N, const Twine &Reason) {
+  PrintWarning(N->getRecord()->getLoc(), "skipped node: " + Reason);
+}
+
+SDNodeInfoEmitter::SDNodeInfoEmitter(const RecordKeeper &RK)
+    : RK(RK), Target(RK) {
+  const CodeGenHwModes &HwModes = Target.getHwModes();
+
+  // Figure out target SDNode namespace.
+  if (!TargetSDNodeNamespace.getNumOccurrences())
+    TargetSDNodeNamespace = Target.getName().str() + "ISD";
+
+  // Parse all SDNode records.
+  for (const Record *R : RK.getAllDerivedDefinitions("SDNode"))
+    AllNodes.emplace_back(R, HwModes);
+
+  // Filter nodes by the target SDNode namespace and create a mapping
+  // from an enum name to a list of nodes that have that name.
+  // The mapping is usually 1:1, but in rare cases it can be 1:N.
+  for (const SDNodeInfo &Node : AllNodes) {
----------------
topperc wrote:

Can this be merged with the RK.getAllDerivedDefinitions("SDNode") loop?

https://github.com/llvm/llvm-project/pull/123002


More information about the llvm-commits mailing list