-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[SelectionDAG] Wire up -gen-sdnode-info TableGen backend #125358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-llvm-selectiondag Author: Sergei Barannikov (s-barannikov) ChangesThis patch introduces SelectionDAGGenTargetInfo and SDNodeInfo classes, which provide methods for accessing the generated SDNode descriptions. RFC: https://discourse.llvm.org/t/rfc-tablegen-erating-sdnode-descriptions Patch is 24.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125358.diff 12 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/SDNodeInfo.h b/llvm/include/llvm/CodeGen/SDNodeInfo.h
new file mode 100644
index 00000000000000..4842401e612efc
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/SDNodeInfo.h
@@ -0,0 +1,115 @@
+//==------------------------------------------------------------------------==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
+#define LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
+
+#include "ISDOpcodes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringTable.h"
+#include "llvm/CodeGenTypes/MachineValueType.h"
+
+namespace llvm {
+
+class SDNode;
+class SelectionDAG;
+
+enum SDNP {
+ SDNPHasChain,
+ SDNPOutGlue,
+ SDNPInGlue,
+ SDNPOptInGlue,
+ SDNPMemOperand,
+ SDNPVariadic,
+};
+
+enum SDTC {
+ SDTCisVT,
+ SDTCisPtrTy,
+ SDTCisInt,
+ SDTCisFP,
+ SDTCisVec,
+ SDTCisSameAs,
+ SDTCisVTSmallerThanOp,
+ SDTCisOpSmallerThanOp,
+ SDTCisEltOfVec,
+ SDTCisSubVecOfVec,
+ SDTCVecEltisVT,
+ SDTCisSameNumEltsAs,
+ SDTCisSameSizeAs,
+};
+
+enum SDNF {
+ SDNFIsStrictFP,
+};
+
+struct SDTypeConstraint {
+ SDTC Kind;
+ uint8_t OpNo;
+ uint8_t OtherOpNo;
+ MVT::SimpleValueType VT;
+};
+
+struct SDNodeDesc {
+ unsigned NumResults;
+ int NumOperands;
+ uint32_t Properties;
+ uint32_t Flags;
+ uint32_t TSFlags;
+ unsigned NameOffset;
+ unsigned ConstraintOffset;
+ unsigned ConstraintCount;
+
+ bool hasProperty(SDNP Property) const { return Properties & (1 << Property); }
+
+ bool hasFlag(SDNF Flag) const { return Flags & (1 << Flag); }
+};
+
+class SDNodeInfo final {
+ unsigned NumOpcodes;
+ const SDNodeDesc *Descs;
+ StringTable Names;
+ const SDTypeConstraint *Constraints;
+
+public:
+ constexpr SDNodeInfo(unsigned NumOpcodes, const SDNodeDesc *Descs,
+ StringTable Names, const SDTypeConstraint *Constraints)
+ : NumOpcodes(NumOpcodes), Descs(Descs), Names(Names),
+ Constraints(Constraints) {}
+
+ /// Returns true if there is a generated description for a node with the given
+ /// target-specific opcode.
+ bool hasDesc(unsigned Opcode) const {
+ assert(Opcode >= ISD::BUILTIN_OP_END && "Expected target-specific opcode");
+ return Opcode < ISD::BUILTIN_OP_END + NumOpcodes;
+ }
+
+ /// Returns the description of a node with the given opcode.
+ const SDNodeDesc &getDesc(unsigned Opcode) const {
+ assert(hasDesc(Opcode));
+ return Descs[Opcode - ISD::BUILTIN_OP_END];
+ }
+
+ /// Returns operand constraints for a node with the given opcode.
+ ArrayRef<SDTypeConstraint> getConstraints(unsigned Opcode) const {
+ const SDNodeDesc &Desc = getDesc(Opcode);
+ return ArrayRef(&Constraints[Desc.ConstraintOffset], Desc.ConstraintCount);
+ }
+
+ /// Returns the name of the given target-specific opcode, suitable for
+ /// debug printing.
+ StringRef getName(unsigned Opcode) const {
+ return Names[getDesc(Opcode).NameOffset];
+ }
+
+ void verifyNode(const SelectionDAG &DAG, const SDNode *N) const;
+};
+
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_CODEGEN_SDNODEINFO_H
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index ef5ae5dba58de4..a3846541d31b11 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
#define LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
+#include "SDNodeInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/CodeGen.h"
@@ -35,6 +36,12 @@ class SelectionDAGTargetInfo {
SelectionDAGTargetInfo &operator=(const SelectionDAGTargetInfo &) = delete;
virtual ~SelectionDAGTargetInfo();
+ /// Returns the name of the given target-specific opcode, suitable for
+ /// debug printing.
+ virtual const char *getTargetNodeName(unsigned Opcode) const {
+ return nullptr;
+ }
+
/// Returns true if a node with the given target-specific opcode has
/// a memory operand. Nodes with such opcodes can only be created with
/// `SelectionDAG::getMemIntrinsicNode`.
@@ -48,6 +55,10 @@ class SelectionDAGTargetInfo {
/// may raise a floating-point exception.
virtual bool mayRaiseFPException(unsigned Opcode) const;
+ /// Checks that the given target-specific node is valid. Aborts if it is not.
+ virtual void verifyTargetNode(const SelectionDAG &DAG,
+ const SDNode *N) const {}
+
/// Emit target-specific code that performs a memcpy.
/// This can be used by targets to provide code sequences for cases
/// that don't fit the target's parameters for simple loads/stores and can be
@@ -176,6 +187,43 @@ class SelectionDAGTargetInfo {
}
};
+/// Proxy class that targets should inherit from if they wish to use
+/// the generated node descriptions.
+class SelectionDAGGenTargetInfo : public SelectionDAGTargetInfo {
+protected:
+ const SDNodeInfo &GenNodeInfo;
+
+ explicit SelectionDAGGenTargetInfo(const SDNodeInfo &GenNodeInfo)
+ : GenNodeInfo(GenNodeInfo) {}
+
+public:
+ ~SelectionDAGGenTargetInfo() override;
+
+ const char *getTargetNodeName(unsigned Opcode) const override {
+ assert(GenNodeInfo.hasDesc(Opcode) &&
+ "The name should be provided by the derived class");
+ return GenNodeInfo.getName(Opcode).data();
+ }
+
+ bool isTargetMemoryOpcode(unsigned Opcode) const override {
+ if (GenNodeInfo.hasDesc(Opcode))
+ return GenNodeInfo.getDesc(Opcode).hasProperty(SDNPMemOperand);
+ return false;
+ }
+
+ bool isTargetStrictFPOpcode(unsigned Opcode) const override {
+ if (GenNodeInfo.hasDesc(Opcode))
+ return GenNodeInfo.getDesc(Opcode).hasFlag(SDNFIsStrictFP);
+ return false;
+ }
+
+ void verifyTargetNode(const SelectionDAG &DAG,
+ const SDNode *N) const override {
+ if (GenNodeInfo.hasDesc(N->getOpcode()))
+ GenNodeInfo.verifyNode(DAG, N);
+ }
+};
+
} // end namespace llvm
#endif // LLVM_CODEGEN_SELECTIONDAGTARGETINFO_H
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 9fcd2ac9514e56..fea710b9b660c8 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4930,11 +4930,6 @@ class TargetLowering : public TargetLoweringBase {
bool verifyReturnAddressArgumentIsConstant(SDValue Op,
SelectionDAG &DAG) const;
-#ifndef NDEBUG
- /// Check the given SDNode. Aborts if it is invalid.
- virtual void verifyTargetSDNode(const SDNode *N) const {};
-#endif
-
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
//
diff --git a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
index cbfbfa3a321bcf..93a742a19aa793 100644
--- a/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
+++ b/llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_component_library(LLVMSelectionDAG
LegalizeVectorOps.cpp
LegalizeVectorTypes.cpp
ResourcePriorityQueue.cpp
+ SDNodeInfo.cpp
ScheduleDAGFast.cpp
ScheduleDAGRRList.cpp
ScheduleDAGSDNodes.cpp
diff --git a/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp
new file mode 100644
index 00000000000000..e3f6c98a9a90a0
--- /dev/null
+++ b/llvm/lib/CodeGen/SelectionDAG/SDNodeInfo.cpp
@@ -0,0 +1,128 @@
+//==------------------------------------------------------------------------==//
+//
+// 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 "llvm/CodeGen/SDNodeInfo.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+using namespace llvm;
+
+static void reportNodeError(const SelectionDAG &DAG, const SDNode *N,
+ const Twine &Msg) {
+ std::string S;
+ raw_string_ostream SS(S);
+ SS << "invalid node: " << Msg << '\n';
+ N->printrWithDepth(SS, &DAG, 2);
+ report_fatal_error(StringRef(S));
+}
+
+static void checkResultType(const SelectionDAG &DAG, const SDNode *N,
+ unsigned ResIdx, EVT ExpectedVT) {
+ EVT ActualVT = N->getValueType(ResIdx);
+ if (ActualVT != ExpectedVT)
+ reportNodeError(
+ DAG, N,
+ "result #" + Twine(ResIdx) + " has invalid type; expected " +
+ ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
+}
+
+static void checkOperandType(const SelectionDAG &DAG, const SDNode *N,
+ unsigned OpIdx, EVT ExpectedVT) {
+ EVT ActualVT = N->getOperand(OpIdx).getValueType();
+ if (ActualVT != ExpectedVT)
+ reportNodeError(
+ DAG, N,
+ "operand #" + Twine(OpIdx) + " has invalid type; expected " +
+ ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());
+}
+
+void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const {
+ const SDNodeDesc &Desc = getDesc(N->getOpcode());
+ bool HasChain = Desc.hasProperty(SDNPHasChain);
+ bool HasOutGlue = Desc.hasProperty(SDNPOutGlue);
+ bool HasInGlue = Desc.hasProperty(SDNPInGlue);
+ bool HasOptInGlue = Desc.hasProperty(SDNPOptInGlue);
+ bool IsVariadic = Desc.hasProperty(SDNPVariadic);
+
+ unsigned ActualNumResults = N->getNumValues();
+ unsigned ExpectedNumResults = Desc.NumResults + HasChain + HasOutGlue;
+
+ if (ActualNumResults != ExpectedNumResults)
+ reportNodeError(DAG, N,
+ "invalid number of results; expected " +
+ Twine(ExpectedNumResults) + ", got " +
+ Twine(ActualNumResults));
+
+ // Chain result comes after all normal results.
+ if (HasChain) {
+ unsigned ChainResIdx = Desc.NumResults;
+ checkResultType(DAG, N, ChainResIdx, MVT::Other);
+ }
+
+ // Glue result comes last.
+ if (HasOutGlue) {
+ unsigned GlueResIdx = Desc.NumResults + HasChain;
+ checkResultType(DAG, N, GlueResIdx, MVT::Glue);
+ }
+
+ // In the most general case, the operands of a node go in the following order:
+ // chain, fix#0, ..., fix#M-1, var#0, ... var#N-1, glue
+ // If the number of operands is < 0, M can be any;
+ // If the node has SDNPVariadic property, N can be any.
+ bool HasOptionalOperands = Desc.NumOperands < 0 || IsVariadic;
+
+ unsigned ActualNumOperands = N->getNumOperands();
+ unsigned ExpectedMinNumOperands =
+ (Desc.NumOperands >= 0 ? Desc.NumOperands : 0) + HasChain + HasInGlue;
+
+ // Check the lower bound.
+ if (ActualNumOperands < ExpectedMinNumOperands) {
+ StringRef How = HasOptionalOperands ? "at least " : "";
+ reportNodeError(DAG, N,
+ "invalid number of operands; expected " + How +
+ Twine(ExpectedMinNumOperands) + ", got " +
+ Twine(ActualNumOperands));
+ }
+
+ // Check the upper bound. We can only do this if the number of fixed operands
+ // is known and there are no variadic operands.
+ if (Desc.NumOperands >= 0 && !IsVariadic) {
+ // Account for optional input glue.
+ unsigned ExpectedMaxNumOperands = ExpectedMinNumOperands + HasOptInGlue;
+ if (ActualNumOperands > ExpectedMaxNumOperands) {
+ StringRef How = HasOptInGlue ? "at most " : "";
+ reportNodeError(DAG, N,
+ "invalid number of operands; expected " + How +
+ Twine(ExpectedMaxNumOperands) + ", got " +
+ Twine(ActualNumOperands));
+ }
+ }
+
+ // Chain operand comes first.
+ if (HasChain)
+ checkOperandType(DAG, N, 0, MVT::Other);
+
+ // Glue operand comes last.
+ if (HasInGlue)
+ checkOperandType(DAG, N, ActualNumOperands - 1, MVT::Glue);
+ if (HasOptInGlue && ActualNumOperands >= 1 &&
+ N->getOperand(ActualNumOperands - 1).getValueType() == MVT::Glue)
+ HasInGlue = true;
+
+ // Check variadic operands. These should be Register or RegisterMask.
+ if (IsVariadic && Desc.NumOperands >= 0) {
+ unsigned VarOpStart = HasChain + Desc.NumOperands;
+ unsigned VarOpEnd = ActualNumOperands - HasInGlue;
+ for (unsigned OpIdx = VarOpStart; OpIdx != VarOpEnd; ++OpIdx) {
+ unsigned OpOpcode = N->getOperand(OpIdx).getOpcode();
+ if (OpOpcode != ISD::Register && OpOpcode != ISD::RegisterMask)
+ reportNodeError(DAG, N,
+ "variadic operand #" + Twine(OpIdx) +
+ " must be Register or RegisterMask");
+ }
+ }
+}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b416c0efbbc4fc..b08d1e1d960bad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1155,11 +1155,11 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
#ifndef NDEBUG
/// VerifySDNode - Check the given SDNode. Aborts if it is invalid.
-static void VerifySDNode(SDNode *N, const TargetLowering *TLI) {
+static void VerifySDNode(const SelectionDAG &DAG, SDNode *N) {
switch (N->getOpcode()) {
default:
- if (N->getOpcode() > ISD::BUILTIN_OP_END)
- TLI->verifyTargetSDNode(N);
+ if (N->isTargetOpcode())
+ DAG.getSelectionDAGInfo().verifyTargetNode(DAG, N);
break;
case ISD::BUILD_PAIR: {
EVT VT = N->getValueType(0);
@@ -1203,7 +1203,7 @@ void SelectionDAG::InsertNode(SDNode *N) {
AllNodes.push_back(N);
#ifndef NDEBUG
N->PersistentId = NextPersistentId++;
- VerifySDNode(N, TLI);
+ VerifySDNode(*this, N);
#endif
for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
DUL->NodeInserted(N);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index f63c8dd3df1c83..8f5795253f37f9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -68,6 +69,9 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
return "<<Unknown Machine Node #" + utostr(getOpcode()) + ">>";
}
if (G) {
+ const SelectionDAGTargetInfo &TSI = G->getSelectionDAGInfo();
+ if (const char *Name = TSI.getTargetNodeName(getOpcode()))
+ return Name;
const TargetLowering &TLI = G->getTargetLoweringInfo();
const char *Name = TLI.getTargetNodeName(getOpcode());
if (Name) return Name;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
index 0f3b36658f10ad..f4422a15bf9dfe 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp
@@ -16,6 +16,8 @@ using namespace llvm;
SelectionDAGTargetInfo::~SelectionDAGTargetInfo() = default;
+SelectionDAGGenTargetInfo::~SelectionDAGGenTargetInfo() = default;
+
bool SelectionDAGTargetInfo::mayRaiseFPException(unsigned Opcode) const {
// FIXME: All target memory opcodes are currently automatically considered
// to possibly raise FP exceptions. See rev. 63336795.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 84f6d421b70f96..8276fcf8679d14 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -30076,83 +30076,3 @@ bool AArch64TargetLowering::isTypeDesirableForOp(unsigned Opc, EVT VT) const {
return TargetLowering::isTypeDesirableForOp(Opc, VT);
}
-
-#ifndef NDEBUG
-void AArch64TargetLowering::verifyTargetSDNode(const SDNode *N) const {
- switch (N->getOpcode()) {
- default:
- break;
- case AArch64ISD::SADDWT:
- case AArch64ISD::SADDWB:
- case AArch64ISD::UADDWT:
- case AArch64ISD::UADDWB: {
- assert(N->getNumValues() == 1 && "Expected one result!");
- assert(N->getNumOperands() == 2 && "Expected two operands!");
- EVT VT = N->getValueType(0);
- EVT Op0VT = N->getOperand(0).getValueType();
- EVT Op1VT = N->getOperand(1).getValueType();
- assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
- VT.isInteger() && Op0VT.isInteger() && Op1VT.isInteger() &&
- "Expected integer vectors!");
- assert(VT == Op0VT &&
- "Expected result and first input to have the same type!");
- assert(Op0VT.getSizeInBits() == Op1VT.getSizeInBits() &&
- "Expected vectors of equal size!");
- assert(Op0VT.getVectorElementCount() * 2 == Op1VT.getVectorElementCount() &&
- "Expected result vector and first input vector to have half the "
- "lanes of the second input vector!");
- break;
- }
- case AArch64ISD::SUNPKLO:
- case AArch64ISD::SUNPKHI:
- case AArch64ISD::UUNPKLO:
- case AArch64ISD::UUNPKHI: {
- assert(N->getNumValues() == 1 && "Expected one result!");
- assert(N->getNumOperands() == 1 && "Expected one operand!");
- EVT VT = N->getValueType(0);
- EVT OpVT = N->getOperand(0).getValueType();
- assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
- VT.isInteger() && "Expected integer vectors!");
- assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
- "Expected vectors of equal size!");
- assert(OpVT.getVectorElementCount() == VT.getVectorElementCount() * 2 &&
- "Expected result vector with half the lanes of its input!");
- break;
- }
- case AArch64ISD::TRN1:
- case AArch64ISD::TRN2:
- case AArch64ISD::UZP1:
- case AArch64ISD::UZP2:
- case AArch64ISD::ZIP1:
- case AArch64ISD::ZIP2: {
- assert(N->getNumValues() == 1 && "Expected one result!");
- assert(N->getNumOperands() == 2 && "Expected two operands!");
- EVT VT = N->getValueType(0);
- EVT Op0VT = N->getOperand(0).getValueType();
- EVT Op1VT = N->getOperand(1).getValueType();
- assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
- "Expected vectors!");
- assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
- break;
- }
- case AArch64ISD::RSHRNB_I: {
- assert(N->getNumValues() == 1 && "Expected one result!");
- assert(N->getNumOperands() == 2 && "Expected two operands!");
- EVT VT = N->getValueType(0);
- EVT Op0VT = N->getOperand(0).getValueType();
- EVT Op1VT = N->getOperand(1).getValueType();
- assert(VT.isVector() && VT.isInteger() &&
- "Expected integer vector result type!");
- assert(Op0VT.isVector() && Op0VT.isInteger() &&
- "Expected first operand to be an integer vector!");
- assert(VT.getSizeInBits() == Op0VT.getSizeInBits() &&
- "Expected vectors of equal size!");
- assert(VT.getVectorElementCount() == Op0VT.getVectorElementCount() * 2 &&
- "Expected input vector with half the lanes of its result!");
- assert(Op1VT == MVT::i32 && isa<ConstantSDNode>(N->getOperand(1)) &&
- "Expected second operand to be a constant i32!");
- break;
- }
- }
-}
-#endif
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index b26f28dc79f886..891940786edaf5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -1040,10 +1040,6 @@ class AArch64TargetLowering : public TargetLowering {
/// True if stack clash protection is enabled for this functions.
bool hasInlineStackProbe(const MachineFunction &MF) const override;
-#ifndef NDEBUG
- void verifyTargetSDNode(const SDNode *N) const override;
-#endif
-
private:
/// Keep a pointer to the AArch64Subtarget around so that we can
/// make the right decision when generating code for different targets.
diff --g...
[truncated]
|
ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString()); | ||
} | ||
|
||
void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently this only verifies basic SDNode "prototype" -- the number of operands/results and the types of chain/glue operands/results. I refrained from making use of the imported SDTypeProfile in this patch to keep it smaller (and I need to spend more time on implementing proper type profile checking anyway).
Please let me know if I should add anything to the description or comments to the code. |
This patch introduces SelectionDAGGenTargetInfo and SDNodeInfo classes, which provide methods for accessing the generated SDNode descriptions. RFC: https://discourse.llvm.org/t/rfc-tablegen-erating-sdnode-descriptions Draft PR: llvm#119709
1ea008e
to
4b2c60b
Compare
ping? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we ever verified normal (non-target) SDNodes using similar logics you put in SDNodeInfo::verifyNode?
This |
Right, but I'm curious whether we should call SDNodeInfo::verifyNode on non-target nodes too. Because I think there is no mechanism to prevent users from inserting chain / glue operands with the wrong order in non-target nodes. |
|
Oh yeah you're right
I vaguely remember we do some sort of check on chain / glue operands, maybe when we're linearizing the DAG, I can't recall the exact location. But in any case, I agree this can leave for future works. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
66c8c1c
to
477ae73
Compare
477ae73
to
1c2529d
Compare
…#125358) This patch introduces SelectionDAGGenTargetInfo and SDNodeInfo classes, which provide methods for accessing the generated SDNode descriptions. Pull Request: llvm/llvm-project#125358 Draft PR: llvm/llvm-project#119709 RFC: https://discourse.llvm.org/t/rfc-tablegen-erating-sdnode-descriptions
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/17/builds/7072 Here is the relevant piece of the build log for the reference
|
This patch introduces SelectionDAGGenTargetInfo and SDNodeInfo classes, which provide methods for accessing the generated SDNode descriptions.
RFC: https://discourse.llvm.org/t/rfc-tablegen-erating-sdnode-descriptions
Draft PR: #119709