diff --git a/llvm/include/llvm/CodeGen/SDNodeProperties.td b/llvm/include/llvm/CodeGen/SDNodeProperties.td index 3cb304f47f4b9..d32904283a11a 100644 --- a/llvm/include/llvm/CodeGen/SDNodeProperties.td +++ b/llvm/include/llvm/CodeGen/SDNodeProperties.td @@ -29,5 +29,3 @@ def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand def SDNPVariadic : SDNodeProperty; // Node has variable arguments. -def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match -def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index 7bb6c3156c43e..2c58eedce1de0 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -2086,4 +2086,12 @@ class ComplexPattern RootNodes = roots; list Properties = props; int Complexity = complexity; + + // Set this to true if SelectFunc wants an additional argument + // that is the root of the matched pattern. + bit WantsRoot = false; + + // Set this to true if SelectFunc wants an additional argument + // that is the parent of the matched node. + bit WantsParent = false; } diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td index 27995ca5bb701..a67093b1a58c3 100644 --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -32,7 +32,8 @@ def tileslicerange2s4 : ComplexPattern", []>; def tileslicerange1s4 : ComplexPattern", []>; def tileslicerange0s4 : ComplexPattern", []>; -def am_sme_indexed_b4 :ComplexPattern", [], [SDNPWantRoot]>; +let WantsRoot = true in +def am_sme_indexed_b4 : ComplexPattern">; def SDTZALoadStore : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisInt<2>]>; def AArch64SMELdr : SDNode<"AArch64ISD::SME_ZA_LDR", SDTZALoadStore, diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 9ae66518dfb4e..34792f86521e5 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -9567,8 +9567,10 @@ multiclass sve_int_perm_bin_perm_128_zz opc, bit P, string asm, SDPatter } /// Addressing modes -def am_sve_indexed_s4 :ComplexPattern", [], [SDNPWantRoot]>; -def am_sve_indexed_s6 :ComplexPattern", [], [SDNPWantRoot]>; +let WantsRoot = true in { + def am_sve_indexed_s4 : ComplexPattern">; + def am_sve_indexed_s6 : ComplexPattern">; +} def am_sve_regreg_lsl0 : ComplexPattern", []>; def am_sve_regreg_lsl1 : ComplexPattern", []>; diff --git a/llvm/lib/Target/AMDGPU/BUFInstructions.td b/llvm/lib/Target/AMDGPU/BUFInstructions.td index a288c58def5cb..a351f451584f9 100644 --- a/llvm/lib/Target/AMDGPU/BUFInstructions.td +++ b/llvm/lib/Target/AMDGPU/BUFInstructions.td @@ -9,8 +9,10 @@ def MUBUFAddr64 : ComplexPattern; def MUBUFOffset : ComplexPattern; -def MUBUFScratchOffen : ComplexPattern; -def MUBUFScratchOffset : ComplexPattern; +let WantsParent = true in { + def MUBUFScratchOffen : ComplexPattern; + def MUBUFScratchOffset : ComplexPattern; +} def BUFSOffset : ComplexPattern; diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td index 9244b4a664986..8fa708b74dde3 100644 --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -6,13 +6,15 @@ // //===----------------------------------------------------------------------===// -def FlatOffset : ComplexPattern; -def GlobalOffset : ComplexPattern; -def ScratchOffset : ComplexPattern; +let WantsRoot = true in { + def FlatOffset : ComplexPattern; + def GlobalOffset : ComplexPattern; + def ScratchOffset : ComplexPattern; -def GlobalSAddr : ComplexPattern; -def ScratchSAddr : ComplexPattern; -def ScratchSVAddr : ComplexPattern; + def GlobalSAddr : ComplexPattern; + def ScratchSAddr : ComplexPattern; + def ScratchSVAddr : ComplexPattern; +} //===----------------------------------------------------------------------===// // FLAT classes diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 718cb964ab7c3..1cb6589184b60 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1225,25 +1225,25 @@ def PostIdxRegShiftedAsmOperand : AsmOperandClass { let ParserMethod = "parsePostIdxReg"; } def am2offset_reg : MemOperand, - ComplexPattern { + ComplexPattern { let EncoderMethod = "getAddrMode2OffsetOpValue"; let PrintMethod = "printAddrMode2OffsetOperand"; // When using this for assembly, it's always as a post-index offset. let ParserMatchClass = PostIdxRegShiftedAsmOperand; let MIOperandInfo = (ops GPRnopc, i32imm); + let WantsRoot = true; } // FIXME: am2offset_imm should only need the immediate, not the GPR. Having // the GPR is purely vestigal at this point. def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } def am2offset_imm : MemOperand, - ComplexPattern { + ComplexPattern { let EncoderMethod = "getAddrMode2OffsetOpValue"; let PrintMethod = "printAddrMode2OffsetOperand"; let ParserMatchClass = AM2OffsetImmAsmOperand; let MIOperandInfo = (ops GPRnopc, i32imm); + let WantsRoot = true; } @@ -1275,13 +1275,12 @@ def AM3OffsetAsmOperand : AsmOperandClass { let Name = "AM3Offset"; let ParserMethod = "parseAM3Offset"; } -def am3offset : MemOperand, - ComplexPattern { +def am3offset : MemOperand, ComplexPattern { let EncoderMethod = "getAddrMode3OffsetOpValue"; let PrintMethod = "printAddrMode3OffsetOperand"; let ParserMatchClass = AM3OffsetAsmOperand; let MIOperandInfo = (ops GPR, i32imm); + let WantsRoot = true; } // ldstm_mode := {ia, ib, da, db} @@ -1328,40 +1327,39 @@ def addrmode5fp16 : AddrMode5FP16 { // addrmode6 := reg with optional alignment // def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } -def addrmode6 : MemOperand, - ComplexPattern{ +def addrmode6 : MemOperand, ComplexPattern { let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm:$align); let EncoderMethod = "getAddrMode6AddressOpValue"; let DecoderMethod = "DecodeAddrMode6Operand"; let ParserMatchClass = AddrMode6AsmOperand; + let WantsParent = true; } -def am6offset : MemOperand, - ComplexPattern { +def am6offset : MemOperand, ComplexPattern { let PrintMethod = "printAddrMode6OffsetOperand"; let MIOperandInfo = (ops GPR); let EncoderMethod = "getAddrMode6OffsetOpValue"; let DecoderMethod = "DecodeGPRRegisterClass"; + let WantsRoot = true; } // Special version of addrmode6 to handle alignment encoding for VST1/VLD1 // (single element from one lane) for size 32. -def addrmode6oneL32 : MemOperand, - ComplexPattern{ +def addrmode6oneL32 : MemOperand, ComplexPattern { let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; + let WantsParent = true; } // Base class for addrmode6 with specific alignment restrictions. -class AddrMode6Align : MemOperand, - ComplexPattern{ +class AddrMode6Align : MemOperand, ComplexPattern { let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm:$align); let EncoderMethod = "getAddrMode6AddressOpValue"; let DecoderMethod = "DecodeAddrMode6Operand"; + let WantsParent = true; } // Special version of addrmode6 to handle no allowed alignment encoding for @@ -1432,22 +1430,23 @@ def addrmode6align64or128or256 : AddrMode6Align { // Special version of addrmode6 to handle alignment encoding for VLD-dup // instructions, specifically VLD4-dup. -def addrmode6dup : MemOperand, - ComplexPattern{ +def addrmode6dup : MemOperand, ComplexPattern { let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); let EncoderMethod = "getAddrMode6DupAddressOpValue"; // FIXME: This is close, but not quite right. The alignment specifier is // different. let ParserMatchClass = AddrMode6AsmOperand; + let WantsParent = true; } // Base class for addrmode6dup with specific alignment restrictions. class AddrMode6DupAlign : MemOperand, - ComplexPattern{ + ComplexPattern { let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); let EncoderMethod = "getAddrMode6DupAddressOpValue"; + let WantsParent = true; } // Special version of addrmode6 to handle no allowed alignment encoding for diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td index bdd0d739a0568..6dd8a374a92af 100644 --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -184,15 +184,16 @@ def t2am_imm7shift0OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<0>; def t2am_imm7shift1OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<1>; def t2am_imm7shift2OffsetAsmOperand : t2am_imm7shiftOffsetAsmOperand<2>; -class t2am_imm7_offset : MemOperand, - ComplexPattern", - [], [SDNPWantRoot]> { +class t2am_imm7_offset + : MemOperand, + ComplexPattern"> { // They are printed the same way as the imm8 version let PrintMethod = "printT2AddrModeImm8OffsetOperand"; let ParserMatchClass = !cast("t2am_imm7shift"#shift#"OffsetAsmOperand"); let EncoderMethod = "getT2ScaledImmOpValue<7,"#shift#">"; let DecoderMethod = "DecodeT2Imm7<"#shift#">"; + let WantsRoot = true; } // Operands for gather/scatter loads of the form [Rbase, Qoffsets] diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index cc7fc743fe4f9..b69bc601a0cdc 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -287,8 +287,8 @@ def t_addrmode_sp : MemOperand, // Inspects parent to determine whether an or instruction can be implemented as // an add (i.e. whether we know overflow won't occur in the add). -def AddLikeOrOp : ComplexPattern; +let WantsParent = true in +def AddLikeOrOp : ComplexPattern; // Pattern to exclude immediates from matching def non_imm32 : PatLeaf<(i32 GPR), [{ return !isa(N); }]>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 99617e53d657a..9ff056f9c06a1 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -267,11 +267,11 @@ def t2addrmode_imm8_pre : T2AddrMode_Imm8 { } def t2am_imm8_offset : MemOperand, - ComplexPattern { + ComplexPattern { let PrintMethod = "printT2AddrModeImm8OffsetOperand"; let EncoderMethod = "getT2AddrModeImm8OffsetOpValue"; let DecoderMethod = "DecodeT2Imm8"; + let WantsRoot = true; } // t2addrmode_imm8s4 := reg +/- (imm8 << 2) diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td index 61c17090e3fbe..5474a42e58848 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -232,7 +232,8 @@ def imm_port6 : Operand { } // Addressing mode pattern reg+imm6 -def addr : ComplexPattern; +let WantsRoot = true in +def addr : ComplexPattern; //===----------------------------------------------------------------------===// // AVR predicates for subtarget features diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.td b/llvm/lib/Target/M68k/M68kInstrInfo.td index 3a9e4fe77f1cc..dca774e94b9b5 100644 --- a/llvm/lib/Target/M68k/M68kInstrInfo.td +++ b/llvm/lib/Target/M68k/M68kInstrInfo.td @@ -466,34 +466,28 @@ def MxCONDle : PatLeaf<(i8 15)>; // Less or Equal // NOTE Though this CP is not strictly necessarily it will simplify instruciton // definitions -def MxCP_ARI : ComplexPattern; +let WantsParent = true in { + def MxCP_ARI : ComplexPattern; -def MxCP_ARIPI : ComplexPattern; + def MxCP_ARIPI : ComplexPattern; -def MxCP_ARIPD : ComplexPattern; + def MxCP_ARIPD : ComplexPattern; -def MxCP_ARID : ComplexPattern; + def MxCP_ARID : ComplexPattern; -def MxCP_ARII : ComplexPattern; + def MxCP_ARII : ComplexPattern; -def MxCP_AL : ComplexPattern; + def MxCP_AL : ComplexPattern; -def MxCP_PCD : ComplexPattern; - -def MxCP_PCI : ComplexPattern; + def MxCP_PCD : ComplexPattern; + def MxCP_PCI : ComplexPattern; +} //===----------------------------------------------------------------------===// // Pattern Fragments diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td index 66684dbff6b33..a7836ccc45f47 100644 --- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td +++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td @@ -1907,10 +1907,10 @@ defm SET_f64 : SET<"f64", Float64Regs, f64imm>; // Data Movement (Load / Store, Move) //----------------------------------- -def ADDRri : ComplexPattern; -def ADDRri64 : ComplexPattern; +let WantsRoot = true in { + def ADDRri : ComplexPattern; + def ADDRri64 : ComplexPattern; +} def ADDRvar : ComplexPattern; def MEMri : Operand { diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 0d3c07aa87ff2..be90a5c562c57 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -686,13 +686,15 @@ def addr : ComplexPattern; def iaddroff : ComplexPattern; // Load and Store Instruction Selection addressing modes. -def DForm : ComplexPattern; -def DSForm : ComplexPattern; -def DQForm : ComplexPattern; -def XForm : ComplexPattern; -def ForceXForm : ComplexPattern; -def PCRelForm : ComplexPattern; -def PDForm : ComplexPattern; +let WantsParent = true in { + def DForm : ComplexPattern; + def DSForm : ComplexPattern; + def DQForm : ComplexPattern; + def XForm : ComplexPattern; + def ForceXForm : ComplexPattern; + def PCRelForm : ComplexPattern; + def PDForm : ComplexPattern; +} //===----------------------------------------------------------------------===// // PowerPC Instruction Predicate Definitions. diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td index ba9779cdc335d..ea7af893ce103 100644 --- a/llvm/lib/Target/X86/X86InstrFragments.td +++ b/llvm/lib/Target/X86/X86InstrFragments.td @@ -352,7 +352,8 @@ def X86cmpccxadd : SDNode<"X86ISD::CMPCCXADD", SDTX86Cmpccxadd, SDNPMemOperand]>; // Define X86-specific addressing mode. -def addr : ComplexPattern; +let WantsParent = true in +def addr : ComplexPattern; def lea32addr : ComplexPattern; @@ -378,7 +379,8 @@ def tls64addr : ComplexPattern; -def vectoraddr : ComplexPattern; +let WantsParent = true in +def vectoraddr : ComplexPattern; // A relocatable immediate is an operand that can be relocated by the linker to // an immediate, such as a regular symbol in non-PIC code. diff --git a/llvm/utils/TableGen/Basic/SDNodeProperties.h b/llvm/utils/TableGen/Basic/SDNodeProperties.h index 1fe4044edcea2..97813067341fc 100644 --- a/llvm/utils/TableGen/Basic/SDNodeProperties.h +++ b/llvm/utils/TableGen/Basic/SDNodeProperties.h @@ -28,8 +28,6 @@ enum SDNP { SDNPSideEffect, SDNPMemOperand, SDNPVariadic, - SDNPWantRoot, - SDNPWantParent }; unsigned parseSDPatternOperatorProperties(const Record *R); diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp index 4e75db689a0b5..f01b8a962bfbb 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp @@ -424,14 +424,13 @@ ComplexPattern::ComplexPattern(const Record *R) { Properties |= 1 << SDNPMemOperand; } else if (Prop->getName() == "SDNPVariadic") { Properties |= 1 << SDNPVariadic; - } else if (Prop->getName() == "SDNPWantRoot") { - Properties |= 1 << SDNPWantRoot; - } else if (Prop->getName() == "SDNPWantParent") { - Properties |= 1 << SDNPWantParent; } else { PrintFatalError(R->getLoc(), "Unsupported SD Node property '" + Prop->getName() + "' on ComplexPattern '" + R->getName() + "'!"); } } + + WantsRoot = R->getValueAsBit("WantsRoot"); + WantsParent = R->getValueAsBit("WantsParent"); } diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.h b/llvm/utils/TableGen/Common/CodeGenTarget.h index 8bcb2f677a00b..c3c7f7e362dbf 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.h +++ b/llvm/utils/TableGen/Common/CodeGenTarget.h @@ -243,6 +243,8 @@ class ComplexPattern { std::vector RootNodes; unsigned Properties; // Node properties unsigned Complexity; + bool WantsRoot; + bool WantsParent; public: ComplexPattern(const Record *R); @@ -253,6 +255,8 @@ class ComplexPattern { const ArrayRef getRootNodes() const { return RootNodes; } bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } unsigned getComplexity() const { return Complexity; } + bool wantsRoot() const { return WantsRoot; } + bool wantsParent() const { return WantsParent; } }; } // namespace llvm diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index f2385bdf1dde4..f056306b2f857 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -1189,12 +1189,12 @@ void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) { OS << "("; // If the complex pattern wants the root of the match, pass it in as the // first argument. - if (P.hasProperty(SDNPWantRoot)) + if (P.wantsRoot()) OS << "Root, "; // If the complex pattern wants the parent of the operand being matched, // pass it in as the next argument. - if (P.hasProperty(SDNPWantParent)) + if (P.wantsParent()) OS << "Parent, "; OS << "N";