diff --git a/.gitignore b/.gitignore index dfeba61ddba1f0..a875dd888b3532 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ autoconf/autom4te.cache .vs # clangd index .clangd +.history/ diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index 1af96cb4a9ee31..39ce0cf91ac3d7 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -376,6 +376,7 @@ enum { /// Keeping track of the number of the GI opcodes. Must be the last entry. GIU_NumOpcodes, + GIM_CheckvtAny32, }; enum { diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h index 9e9e1806bc6fe4..1be548590d87fa 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -175,7 +175,7 @@ bool InstructionSelector::executeMatchTable( CurrentIdx = MatchTable[CurrentIdx + (Opcode - LowerBound)]; if (!CurrentIdx) { CurrentIdx = Default; - break; + break; } OnFailResumeAt.push_back(Default); break; @@ -396,7 +396,8 @@ bool InstructionSelector::executeMatchTable( unsigned AddrSpace = MatchTable[CurrentIdx++]; DEBUG_WITH_TYPE( TgtInstructionSelector::getName(), - dbgs() << "addrspace(" << MMOAddrSpace << ") vs " + dbgs() << CurrentIdx << ": GIM_CheckMemoryAddressSpace " + << "addrspace(" << MMOAddrSpace << ") vs " << AddrSpace << '\n'); if (AddrSpace == MMOAddrSpace) { @@ -532,6 +533,32 @@ bool InstructionSelector::executeMatchTable( } break; } + case GIM_CheckvtAny32: { + dbgs() << "YOOOOOOOO\n"; + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t OpIdx = MatchTable[CurrentIdx++]; + int64_t SizeInBits = MatchTable[CurrentIdx++]; + + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << CurrentIdx << ": GIM_CheckvtAny32MIs[" + << InsnID << "]->getOperand(" << OpIdx + << "), SizeInBits=" << SizeInBits << ")\n"); + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); + const LLT Ty = MRI.getType(MO.getReg()); + dbgs() << "Ty size " << Ty.getSizeInBits() << "\n"; + dbgs() << "SizeInBits" << SizeInBits << "\n"; + + if (Ty.getSizeInBits() != SizeInBits) { + if (handleReject() == RejectAndGiveUp) + return false; + } + /*else if (handleReject() == RejectAndGiveUp) + return false;*/ + + break; + } + case GIM_CheckPointerToAny: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; @@ -770,6 +797,9 @@ bool InstructionSelector::executeMatchTable( if (NewInsnID >= OutMIs.size()) OutMIs.resize(NewInsnID + 1); + auto T = State.MIs[0]; + dbgs() << "Dumping MI in GIR_BuildMI"; + T->dump(); OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0], State.MIs[0]->getDebugLoc(), TII.get(Opcode)); DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td index 16df565bc8b8d4..fdad0648784bd0 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -166,6 +166,9 @@ def FlagVT : ValueType<0 , 131>; // Pre-RA sched glue def isVoid : ValueType<0 , 132>; // Produces no value def untyped: ValueType<8 , 133>; // Produces an untyped value def exnref: ValueType<0, 134>; // WebAssembly's exnref type + +def vtAny32: ValueType<32, 247>; // Match any 32-bit type. + def token : ValueType<0 , 248>; // TokenTy def MetadataVT: ValueType<0, 249>; // Metadata diff --git a/llvm/include/llvm/Support/MachineValueType.h b/llvm/include/llvm/Support/MachineValueType.h index 26b45a602763ad..c32e314317ef4e 100644 --- a/llvm/include/llvm/Support/MachineValueType.h +++ b/llvm/include/llvm/Support/MachineValueType.h @@ -227,6 +227,9 @@ namespace llvm { // This value must be a multiple of 32. MAX_ALLOWED_VALUETYPE = 160, + // Match any 32-bit type. + vtAny32 = 247, + // A value of type llvm::TokenTy token = 248, @@ -306,6 +309,10 @@ namespace llvm { SimpleTy <= MVT::LAST_INTEGER_VALUETYPE); } + bool isvtAny32() const { + return (SimpleTy == MVT::vtAny32); + } + /// Return true if this is a vector value type. bool isVector() const { return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE && @@ -695,6 +702,7 @@ namespace llvm { "in codegen and has no size"); case Metadata: llvm_unreachable("Value type is metadata."); + case vtAny32: return TypeSize::Fixed(32); case i1: case v1i1: return TypeSize::Fixed(1); case nxv1i1: return TypeSize::Scalable(1); diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index dec8797b7d33c7..898fdf0ff09e7c 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -154,8 +154,13 @@ def : GINodeEquiv { let CheckMMOIsNonAtomic = 0; let CheckMMOIsAtomic = 1; } - def : GINodeEquiv; + +def : GINodeEquiv { + let CheckMMOIsNonAtomic = 0; + let CheckMMOIsAtomic = 1; +} + def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index 1f5cfba41a36c4..97be50affa437b 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -282,6 +282,11 @@ def SDTAtomicLoad : SDTypeProfile<1, 1, [ SDTCisInt<0>, SDTCisPtrTy<1> ]>; +// TODO: Put restriction on 0th operand too. +def SDTNewAtomicLoad : SDTypeProfile<1, 1, [ + SDTCisPtrTy<1> +]>; + def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> ]>; @@ -615,6 +620,9 @@ def atomic_load_fsub : SDNode<"ISD::ATOMIC_LOAD_FSUB" , SDTFPAtomic2, def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def new_atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTNewAtomicLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; + def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; @@ -1565,6 +1573,21 @@ def atomic_load_32 : let IsAtomic = 1; let MemoryVT = i32; } + +def atomic_load_iptr : + PatFrag<(ops node:$ptr), + (new_atomic_load node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = i32; +} + +def atomic_load_vtany32 : + PatFrag<(ops node:$ptr), + (new_atomic_load node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = vtAny32; +} + def atomic_load_64 : PatFrag<(ops node:$ptr), (atomic_load node:$ptr)> { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 279e53877dc8e0..342f3d3a4fda05 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1,3 +1,4 @@ +; //===- SelectionDAGISel.cpp - Implement the SelectionDAGISel class --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -2529,6 +2530,7 @@ CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, LLVM_ATTRIBUTE_ALWAYS_INLINE static inline bool CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, const SelectionDAGISel &SDISel, SDNode *N) { + //dbgs() << "passing to check pred " << (unsigned) MatcherTable[MatcherIndex] << "\n"; return SDISel.CheckNodePredicate(N, MatcherTable[MatcherIndex++]); } @@ -2540,14 +2542,28 @@ CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex, return N->getOpcode() == Opc; } +/* +LLVM_ATTRIBUTE_ALWAYS_INLINE static inline bool +isvtAny32Compatible (MVT::SimpleValueType T) { + return T == MVT::i32 || T == MVT::f32; +} +*/ + LLVM_ATTRIBUTE_ALWAYS_INLINE static inline bool CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const TargetLowering *TLI, const DataLayout &DL) { + dbgs() << "In check type\n"; MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; if (N.getValueType() == VT) return true; + if (VT == MVT::vtAny32) { //dbgs() << "Matching *****\n"; return isvtAny32Compatible(N.getValueType()); + dbgs() << "Matching ***\n"; + return true; + } + // Handle the case when VT is iPTR. return VT == MVT::iPTR && N.getValueType() == TLI->getPointerTy(DL); + } LLVM_ATTRIBUTE_ALWAYS_INLINE static inline bool @@ -2659,9 +2675,10 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table, case SelectionDAGISel::OPC_CheckPatternPredicate: Result = !::CheckPatternPredicate(Table, Index, SDISel); return Index; - case SelectionDAGISel::OPC_CheckPredicate: + case SelectionDAGISel::OPC_CheckPredicate: { Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode()); return Index; + } case SelectionDAGISel::OPC_CheckOpcode: Result = !::CheckOpcode(Table, Index, N.getNode()); return Index; @@ -3056,6 +3073,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this)) break; continue; case OPC_CheckPredicate: + dbgs() << "Check pred\n"; if (!::CheckNodePredicate(MatcherTable, MatcherIndex, *this, N.getNode())) break; @@ -3407,6 +3425,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, case OPC_EmitNode: case OPC_MorphNodeTo: case OPC_EmitNode0: case OPC_EmitNode1: case OPC_EmitNode2: case OPC_MorphNodeTo0: case OPC_MorphNodeTo1: case OPC_MorphNodeTo2: { + dbgs() << "Enter in interpreter\n"; uint16_t TargetOpc = MatcherTable[MatcherIndex++]; TargetOpc |= (unsigned short)MatcherTable[MatcherIndex++] << 8; unsigned EmitNodeInfo = MatcherTable[MatcherIndex++]; @@ -3426,6 +3445,8 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; if (VT == MVT::iPTR) VT = TLI->getPointerTy(CurDAG->getDataLayout()).SimpleTy; + if (VT == MVT::vtAny32) + VT = MVT::i32; VTs.push_back(VT); } diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp index 55dfabfaf6fef6..ce18dd2a4eb504 100644 --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -155,6 +155,7 @@ std::string EVT::getEVTString() const { case MVT::Metadata:return "Metadata"; case MVT::Untyped: return "Untyped"; case MVT::exnref : return "exnref"; + case MVT::vtAny32 : return "vtAny32"; } } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUGISel.td b/llvm/lib/Target/AMDGPU/AMDGPUGISel.td index 3f12addbcc79b3..6bdae210b0a07f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUGISel.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUGISel.td @@ -133,6 +133,9 @@ def : GINodeEquiv { bit CheckMMOIsAtomic = 1; } +def : GINodeEquiv { + bit CheckMMOIsAtomic = 1; +} def : GINodeEquiv; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp index 95795f87faaf2b..c3bdd749a30a4e 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -2096,6 +2096,9 @@ void AMDGPUInstructionSelector::initM0(MachineInstr &I) const { bool AMDGPUInstructionSelector::selectG_LOAD_ATOMICRMW(MachineInstr &I) const { initM0(I); + if (I.getOpcode() == 62) + dbgs() << "begin atomic load\n"; + return selectImpl(I, *CoverageInfo); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td index 706053a4e3157e..73db438c5e435f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td @@ -407,6 +407,16 @@ def atomic_load_32_#as : PatFrag<(ops node:$ptr), (atomic_load_32 node:$ptr)> { let MemoryVT = i32; } +def atomic_load_iptr_#as : PatFrag<(ops node:$ptr), (atomic_load_iptr node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = i32; +} + +def atomic_load_vtany32_#as : PatFrag<(ops node:$ptr), (atomic_load_vtany32 node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = vtAny32; +} + def atomic_load_64_#as : PatFrag<(ops node:$ptr), (atomic_load_64 node:$ptr)> { let IsAtomic = 1; let MemoryVT = i64; diff --git a/llvm/lib/Target/AMDGPU/DSInstructions.td b/llvm/lib/Target/AMDGPU/DSInstructions.td index 7c216254193483..54a6c50fb9433a 100644 --- a/llvm/lib/Target/AMDGPU/DSInstructions.td +++ b/llvm/lib/Target/AMDGPU/DSInstructions.td @@ -245,6 +245,14 @@ multiclass DS_1A_RET_mc { + def "" : DS_1A_RET; + + let has_m0_read = 0 in { + def _gfx9 : DS_1A_RET; + } +} + class DS_1A_RET_Tied : DS_1A_RET; @@ -539,7 +547,7 @@ defm DS_READ_I8 : DS_1A_RET_mc<"ds_read_i8">; defm DS_READ_U8 : DS_1A_RET_mc<"ds_read_u8">; defm DS_READ_I16 : DS_1A_RET_mc<"ds_read_i16">; defm DS_READ_U16 : DS_1A_RET_mc<"ds_read_u16">; -defm DS_READ_B32 : DS_1A_RET_mc<"ds_read_b32">; +defm DS_READ_B32 : DS_1A_RET_mc_new<"ds_read_b32">; defm DS_READ_B64 : DS_1A_RET_mc<"ds_read_b64", VReg_64>; defm DS_READ2_B32 : DS_1A_Off8_RET_mc<"ds_read2_b32", VReg_64>; @@ -622,8 +630,9 @@ def : GCNPat < (DS_SWIZZLE_B32 VGPR_32:$src, (as_i16timm $offset16), (i1 0)) >; -class DSReadPat : GCNPat < - (vt (frag (DS1Addr1Offset i32:$ptr, i16:$offset))), +// frag is acting as predicate. +class DSReadPat : GCNPat < + (vt1 (frag (DS1Addr1Offset i32:$ptr, i16:$offset))), (inst $ptr, offset:$offset, (i1 gds)) >; @@ -656,10 +665,16 @@ defm : DSReadPat_mc ; defm : DSReadPat_mc ; foreach vt = Reg32Types.types in { -defm : DSReadPat_mc ; +//defm : DSReadPat_mc ; } -defm : DSReadPat_mc ; +//defm : DSReadPat_mc ; +defm : DSReadPat_mc ; +//defm : DSReadPat_mc ; +//defm : DSReadPat_mc ; +//defm : DSReadPat_mc ; + +//defm : DSReadPat_mc ; defm : DSReadPat_mc ; let AddedComplexity = 100 in { diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 397791677eda74..d77f78aa116ee7 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -354,6 +354,10 @@ def AMDGPUatomic_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTAtomicLoad, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] >; +def AMDGPUatomic_new_ld_glue : SDNode <"ISD::ATOMIC_LOAD", SDTNewAtomicLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue] +>; + def unindexedload_glue : PatFrag <(ops node:$ptr), (AMDGPUld_glue node:$ptr)> { let IsLoad = 1; let IsUnindexed = 1; @@ -376,6 +380,18 @@ def atomic_load_64_glue : PatFrag<(ops node:$ptr), let MemoryVT = i64; } +def atomic_load_iptr_glue : PatFrag<(ops node:$ptr), + (AMDGPUatomic_new_ld_glue node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = i32; +} + +def atomic_load_vtany32_glue : PatFrag<(ops node:$ptr), + (AMDGPUatomic_new_ld_glue node:$ptr)> { + let IsAtomic = 1; + let MemoryVT = vtAny32; +} + def extload_glue : PatFrag<(ops node:$ptr), (unindexedload_glue node:$ptr)> { let IsLoad = 1; let IsAnyExtLoad = 1; @@ -455,6 +471,18 @@ def load_align16_local_m0 : PatFrag<(ops node:$ptr), } // End IsLoad = 1 let IsAtomic = 1, AddressSpaces = LoadAddress_local.AddrSpaces in { + +def atomic_load_iptr_local_m0 : PatFrag<(ops node:$ptr), + (atomic_load_iptr_glue node:$ptr)> { + let MemoryVT = i32; +} + +def atomic_load_vtany32_local_m0 : PatFrag<(ops node:$ptr), + (atomic_load_vtany32_glue node:$ptr)> { + let MemoryVT = vtAny32; + //let isCompatible = isIntType>.ret; +} + def atomic_load_32_local_m0 : PatFrag<(ops node:$ptr), (atomic_load_32_glue node:$ptr)> { let MemoryVT = i32; diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td index 5728a4df29958b..fd3cbf02677a64 100644 --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td @@ -468,6 +468,7 @@ class RegisterTypes reg_types> { def Reg16Types : RegisterTypes<[i16, f16]>; def Reg32Types : RegisterTypes<[i32, f32, v2i16, v2f16, p2, p3, p5, p6]>; +def Reg32AllTypes : RegisterTypes<[vtAny32]>; def VGPR_LO16 : RegisterClass<"AMDGPU", Reg16Types.types, 16, (add (sequence "VGPR%u_LO16", 0, 255))> { @@ -492,6 +493,13 @@ def VGPR_32 : RegisterClass<"AMDGPU", !listconcat(Reg32Types.types, Reg16Types.t let Weight = 1; } +def VGPR_32_all : RegisterClass<"AMDGPU", [vtAny32], 32, + (add (sequence "VGPR%u", 0, 255))> { + let AllocationPriority = 1; + let Size = 32; + let Weight = 1; +} + // VGPR 64-bit registers def VGPR_64 : SIRegisterTuples.ret, VGPR_32, 255, 1, 2, "v">; diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 6fdc116721f333..781baf8aa68092 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -70,6 +70,8 @@ static bool berase_if(MachineValueTypeSet &S, Predicate P) { TypeSetByHwMode::TypeSetByHwMode(ArrayRef VTList) { for (const ValueTypeByHwMode &VVT : VTList) { insert(VVT); + //dbgs() << "dumping in loop in constructor\n"; + //dump(); AddrSpaces.push_back(VVT.PtrAddrSpace); } } @@ -114,7 +116,9 @@ bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) { SmallDenseSet Modes; for (const auto &P : VVT) { unsigned M = P.first; + //dbgs() << "M = " << M << "\n"; Modes.insert(M); + //dbgs() << "P.second" << llvm::getEnumName(P.second.SimpleTy); // Make sure there exists a set for each specific mode from VVT. Changed |= getOrCreate(M).insert(P.second).second; // Cache VVT's default mode. @@ -126,11 +130,15 @@ bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) { // If VVT has a default mode, add the corresponding type to all // modes in "this" that do not exist in VVT. - if (ContainsDefault) - for (auto &I : *this) - if (!Modes.count(I.first)) + if (ContainsDefault) { + for (auto &I : *this) { + if (!Modes.count(I.first)) { + //dbgs() << "inside if\n";; Changed |= I.second.insert(DT).second; - + } + } + } + //if (!Changed) dbgs() << "failed to insert in TypeSetByHwMode::insert\n"; return Changed; } @@ -152,6 +160,7 @@ bool TypeSetByHwMode::constrain(const TypeSetByHwMode &VTS) { SetType &S = I.second; if (VTS.hasMode(M) || VTS.hasDefault()) { Changed |= intersect(I.second, VTS.get(M)); + //if (!Changed) dbgs() << "Changed is false in contrain intersect returned false\n"; } else if (!S.empty()) { S.clear(); Changed = true; @@ -272,9 +281,48 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { bool OutP = Out.count(MVT::iPTR), InP = In.count(MVT::iPTR); auto Int = [&In](MVT T) -> bool { return !In.count(T); }; - if (OutP == InP) - return berase_if(Out, Int); + //dbgs() << "dumping Out in intersect\n"; + //for (MVT T : Out) { dbgs() << getEnumName(T.SimpleTy); } + //dbgs() << "dumping In in intersect\n"; + //for (MVT T : In) { dbgs() << getEnumName(T.SimpleTy); } + + if (In.count(MVT::vtAny32) || Out.count(MVT::vtAny32)) { + if (Out.count(MVT::vtAny32) && Out.size() == 1) { + return false; + } + Out.clear(); + Out.insert(MVT::vtAny32); + return true; + } + /* + if (Out.count(MVT::vtAny32)) { + SetType In32Candidates = In; + for (MVT T : In32Candidates) { + if (T.getSizeInBits() != TypeSize::Fixed(32)) { + In32Candidates.erase(T); + } + } + return In32Candidates.size() > 0 ? true : false; + } + else if (In.count(MVT::vtAny32)) { + return false; + SetType Out32Candidates = Out; + for (MVT T : Out32Candidates) { + if (T.getSizeInBits() != TypeSize::Fixed(32)) { + Out32Candidates.erase(T); + } + } + Out = Out32Candidates; + return Out32Candidates.size() > 0 ? true : false; + }*/ + + if (OutP == InP) { + auto b = berase_if(Out, Int); + //if (!b) dbgs() << "failed in first case \n"; + //else dbgs() << "returning true under OutP==InP\n"; + return b; + } // Compute the intersection of scalars separately to account for only // one set containing iPTR. // The intersection of iPTR with a set of integer scalar types that does not @@ -299,9 +347,13 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { if (InP) { Diff = Out; berase_if(Diff, [&In](MVT T) { return In.count(T); }); + //dbgs() << "dumping Diff in intersect\n"; + //for (MVT T : Diff) { dbgs() << getEnumName(T.SimpleTy); } // Pre-remove these elements and rely only on InP/OutP to determine // whether a change has been made. berase_if(Out, [&Diff](MVT T) { return Diff.count(T); }); + //dbgs() << "dumping Out in intersect\n"; + //for (MVT T : Out) { dbgs() << getEnumName(T.SimpleTy); } } else { Diff = In; berase_if(Diff, [&Out](MVT T) { return Out.count(T); }); @@ -311,19 +363,25 @@ bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { // The actual intersection. bool Changed = berase_if(Out, Int); unsigned NumD = Diff.size(); - if (NumD == 0) + if (NumD == 0) { + //if (!Changed) dbgs() << "returning false because numD is 0\n"; return Changed; + } if (NumD == 1) { Out.insert(*Diff.begin()); // This is a change only if Out was the one with iPTR (which is now // being replaced). Changed |= OutP; + //if (!Changed) dbgs() << "returning false because NumD is 1\n"; } else { // Multiple elements from Out are now replaced with iPTR. Out.insert(MVT::iPTR); Changed |= !OutP; + //if (!Changed) dbgs() << "returning false because NumD is NOT 1\n"; } + + //if (!Changed) dbgs() << "finally returning false\n"; return Changed; } @@ -345,14 +403,26 @@ bool TypeInfer::MergeInTypeInfo(TypeSetByHwMode &Out, const TypeSetByHwMode &In) { ValidateOnExit _1(Out, *this); In.validate(); - if (In.empty() || Out == In || TP.hasError()) + //dbgs() << "in mergeintyeinfo dumping Out\n"; + //Out.dump(); + //dbgs() << "in mergeintyeinfo dumping In\n"; + //In.dump(); + + if (In.empty() || Out == In || TP.hasError()) { + //dbgs() << "returning false from merge in type info because one of three cond failed\n"; + //if (In.empty()) dbgs() << "In.empty is true\n"; + //if (Out == In) dbgs() << "Out == In\n"; + //if (TP.hasError()) dbgs() << "Tp has error\n"; return false; + } if (Out.empty()) { Out = In; + //dbgs() << "returning true from mergeintypeinfo because Out.empty()=true\n"; return true; } bool Changed = Out.constrain(In); + //if (!Changed) dbgs() << "Out.constrain did not change anything \n"; if (Changed && Out.empty()) TP.error("Type contradiction"); @@ -751,6 +821,8 @@ bool TypeInfer::EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B) { void TypeInfer::expandOverloads(TypeSetByHwMode &VTS) { ValidateOnExit _1(VTS, *this); + //dbgs() << "in expand overloads\n"; + //VTS.dump(); const TypeSetByHwMode &Legal = getLegalTypes(); assert(Legal.isDefaultOnly() && "Default-mode only expected"); const TypeSetByHwMode::SetType &LegalTypes = Legal.get(DefaultMode); @@ -829,6 +901,7 @@ const TypeSetByHwMode &TypeInfer::getLegalTypes() { #ifndef NDEBUG TypeInfer::ValidateOnExit::~ValidateOnExit() { + //dbgs() << "dumping in destructor \n"; VTS.dump(); if (Infer.Validate && !VTS.validate()) { dbgs() << "Type set is empty for each HW mode:\n" "possible type contradiction in the pattern below " @@ -1006,10 +1079,27 @@ std::string TreePredicateFn::getPredCode() const { Record *MemoryVT = getMemoryVT(); - if (MemoryVT) + if (MemoryVT) { + if (MemoryVT->getName().str() == "vtAny32") { + dbgs() << "MADDDDHUUUU\n"; + Code += "if (cast(N)->getMemoryVT() != MVT::i32) return false;\n"; + } else { + Code += ("if (cast(N)->getMemoryVT() != MVT::" + + MemoryVT->getName() + ") return false;\n") + .str(); + } + } + /* + if (MemoryVT) { Code += ("if (cast(N)->getMemoryVT() != MVT::" + MemoryVT->getName() + ") return false;\n") .str(); + if (MemoryVT->getName().str() == "vtAny32") { + dbgs() << "MADDDDHUUUU\n"; + Code += "if (cast(N)->getMemoryVT() != MVT::i32) return false;\n"; + } + } + */ } if (isAtomic() && isAtomicOrderingMonotonic()) @@ -1673,6 +1763,7 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo, assert(RC && "Unknown operand type"); CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo(); + //dbgs() << "Register class name " << Tgt.getRegisterClass(RC).getName() << "\n"; return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP); } @@ -1843,21 +1934,21 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { void TreePatternNode::print(raw_ostream &OS) const { if (isLeaf()) - OS << *getLeafValue(); + OS << "leaf value ={ " << *getLeafValue() << "leaf_end} "; else - OS << '(' << getOperator()->getName(); + OS << "(operator=" << getOperator()->getName(); for (unsigned i = 0, e = Types.size(); i != e; ++i) { - OS << ':'; + OS << " ext_type:"; getExtType(i).writeToStream(OS); } if (!isLeaf()) { if (getNumChildren() != 0) { - OS << " "; + OS << " child0"; getChild(0)->print(OS); for (unsigned i = 1, e = getNumChildren(); i != e; ++i) { - OS << ", "; + OS << ",child " << i; getChild(i)->print(OS); } } @@ -2129,7 +2220,7 @@ static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo, bool Unnamed, TreePattern &TP) { CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); - + //dbgs() << "Entered in getImplicitType\n"; // Check to see if this is a register operand. if (R->isSubClassOf("RegisterOperand")) { assert(ResNo == 0 && "Regoperand ref only has one result!"); @@ -2188,10 +2279,13 @@ static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo, // // (sext_inreg i32:$src, i16) // ~~~~~~~~ + //dbgs() << "in value type in getImplicitType\n"; if (NotRegisters) return TypeSetByHwMode(); // Unknown. const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes(); - return TypeSetByHwMode(getValueTypeByHwMode(R, CGH)); + auto B = TypeSetByHwMode(getValueTypeByHwMode(R, CGH)); + //B.dump(); + return B; } if (R->isSubClassOf("CondCode")) { @@ -2207,9 +2301,13 @@ static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo, return TypeSetByHwMode(CDP.getComplexPattern(R).getValueType()); } if (R->isSubClassOf("PointerLikeRegClass")) { + //dbgs() << "in pointer like reg class\n"; assert(ResNo == 0 && "Regclass can only have one result!"); TypeSetByHwMode VTS(MVT::iPTR); TP.getInfer().expandOverloads(VTS); + + //dbgs() << "In getImpliciType\n"; + //VTS.dump(); return VTS; } @@ -2359,18 +2457,24 @@ static void emitTooFewOperandsError(TreePattern &TP, /// this node and its children in the tree. This returns true if it makes a /// change, false otherwise. If a type contradiction is found, flag an error. bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { + //dbgs() << "InApplyTypeConstraints\n"; if (TP.hasError()) return false; CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); if (isLeaf()) { + //dbgs() << "In leaf\n"; if (DefInit *DI = dyn_cast(getLeafValue())) { // If it's a regclass or something else known, include the type. bool MadeChange = false; - for (unsigned i = 0, e = Types.size(); i != e; ++i) + for (unsigned i = 0, e = Types.size(); i != e; ++i) { + //dbgs() << "in ApplyTypeConstraints while iterating\n"; + //Types[i].dump(); MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i, NotRegisters, !hasName(), TP), TP); + } + //if (!MadeChange) dbgs() << "returning false from apply type constraints\n"; return MadeChange; } @@ -2439,6 +2543,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { } if (getOperator()->isSubClassOf("SDNode")) { + //dbgs() << "Inside SDNode\n"; + //dump(); + //dbgs() << "\n"; const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator()); // Check that the number of operands is sane. Negative operands -> varargs. @@ -2608,7 +2715,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (getOperator()->isSubClassOf("ComplexPattern")) { bool MadeChange = false; - + //dbgs() << "In ApplyTypeConstraints Complexpattern\n"; for (unsigned i = 0; i < getNumChildren(); ++i) MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); @@ -2801,9 +2908,13 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit, // Apply the type cast. assert(New->getNumTypes() == 1 && "FIXME: Unhandled"); + //if (Operator->getName() != "vtAny32") { const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes(); + auto TP = getValueTypeByHwMode(Operator, CGH); + //dbgs() << "before passing to updatenodetype, result of getvaluetype\n"; + //TP.dump(); New->UpdateNodeType(0, getValueTypeByHwMode(Operator, CGH), *this); - + //} if (!OpName.empty()) error("ValueType cast should not have a name!"); return New; @@ -2960,6 +3071,7 @@ InferAllTypes(const StringMap > *InNamedTypes) { bool MadeChange = true; while (MadeChange) { + //dbgs() << "in MadeChange loop\n"; MadeChange = false; for (TreePatternNodePtr &Tree : Trees) { MadeChange |= Tree->ApplyTypeConstraints(*this, false); @@ -2968,6 +3080,7 @@ InferAllTypes(const StringMap > *InNamedTypes) { // If there are constraints on our named nodes, apply them. for (auto &Entry : NamedNodes) { + //dbgs() << "key data " << Entry.getKeyData() << "\n"; SmallVectorImpl &Nodes = Entry.second; // If we have input named node types, propagate their types to the named @@ -2984,6 +3097,7 @@ InferAllTypes(const StringMap > *InNamedTypes) { // The input types should be fully resolved by now. for (TreePatternNode *Node : Nodes) { + //dbgs() << "in inferAllTypes after resolving input types In loop for register class\n"; // If this node is a register class, and it is the root of the pattern // then we're mapping something onto an input register. We allow // changing the type of the input register in this case. This allows @@ -3001,8 +3115,8 @@ InferAllTypes(const StringMap > *InNamedTypes) { "FIXME: cannot name multiple result nodes yet"); MadeChange |= Node->UpdateNodeType(0, InNodes[0]->getExtType(0), *this); - } - } + } // End for + } // End if // If there are multiple nodes with the same name, they must all have the // same type. @@ -3116,7 +3230,7 @@ void CodeGenDAGPatterns::ParseNodeInfo() { void CodeGenDAGPatterns::ParseNodeTransforms() { std::vector Xforms = Records.getAllDerivedDefinitions("SDNodeXForm"); while (!Xforms.empty()) { - Record *XFormNode = Xforms.back(); + Record *XFormNode = Xforms.back(); Record *SDNode = XFormNode->getValueAsDef("Opcode"); StringRef Code = XFormNode->getValueAsString("XFormFunction"); SDNodeXForms.insert( @@ -4142,7 +4256,13 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, // Inline pattern fragments and expand multiple alternatives. Pattern.InlinePatternFragments(); Result.InlinePatternFragments(); + //dbgs() << "In ParseOnePattern\n"; + //dbgs() << "Input pattern num tress " << Pattern.getNumTrees() << "\n"; + //Pattern.dump(); + //dbgs() << "Result Pattern Num trees****" << Result.getNumTrees() << "\n"; + //Result.dump(); + auto S = TheDef->getName().str(); if (Result.getNumTrees() != 1) Result.error("Cannot use multi-alternative fragments in result pattern!"); @@ -4150,6 +4270,10 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, bool IterateInference; bool InferredAllPatternTypes, InferredAllResultTypes; do { +/* if (S == "anonymous_10005") { + dbgs() << "anonymous_10005"; + dbgs() << "inferring for the pattern\n"; + } */ // Infer as many types as possible. If we cannot infer all of them, we // can never do anything with this pattern: report it to the user. InferredAllPatternTypes = @@ -4157,9 +4281,15 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, // Infer as many types as possible. If we cannot infer all of them, we // can never do anything with this pattern: report it to the user. + //dbgs() << "going for result *******************************\n"; InferredAllResultTypes = Result.InferAllTypes(&Pattern.getNamedNodesMap()); + //dbgs() << "\nAfter InferringAllTypes: InputPattern\n"; + //Pattern.dump(); + //dbgs() << "\nAfter InferringAllTypes: Result\n"; + //Result.dump(); + IterateInference = false; // Apply the type of the result to the source pattern. This helps us @@ -4170,6 +4300,7 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(), T->getNumTypes()); i != e; ++i) { + //if (S == "anonymous_10005") dbgs() << "e=" << e << "\n"; IterateInference |= T->UpdateNodeType( i, Result.getOnlyTree()->getExtType(i), Result); IterateInference |= Result.getOnlyTree()->UpdateNodeType( @@ -4185,12 +4316,16 @@ void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, // // In any case, to handle this, we just go through and disambiguate some // arbitrary types to the result pattern's nodes. + //auto TPN = Result.getTree(0).get(); + //dbgs() << "Parse one pattern Name: " << TPN->getName(); + if (!IterateInference && InferredAllPatternTypes && !InferredAllResultTypes) IterateInference = ForceArbitraryInstResultType(Result.getTree(0).get(), Result); + //dbgs() << "exit\n"; } while (IterateInference); - + //dbgs() << "out from loop in ParseOne Pattern\n"; // Verify that we inferred enough types that we can do something with the // pattern and result. If these fire the user has to add type casts. if (!InferredAllPatternTypes) @@ -4233,6 +4368,9 @@ void CodeGenDAGPatterns::ParsePatterns() { std::vector Patterns = Records.getAllDerivedDefinitions("Pattern"); for (Record *CurPattern : Patterns) { + //dbgs() << "In parse patterns " << CurPattern->getName().str() << "\n"; + //dbgs() << "Cur pattern in ParseAllPaterns \n"; + //CurPattern->dump(); DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch"); // If the pattern references the null_frag, there's nothing to do. @@ -4259,9 +4397,15 @@ void CodeGenDAGPatterns::ParsePatterns() { for (unsigned j = 0, ee = Pattern.getNumTrees(); j != ee; ++j) FindPatternInputsAndOutputs(Pattern, Pattern.getTree(j), InstInputs, InstResults, InstImpResults); - + //dbgs() <<"going to parseOnePattern\n"; ParseOnePattern(CurPattern, Pattern, Result, InstImpResults); + //dbgs() << "After parsing the patterns, types should be correct\n"; + //dbgs() << "Input pattern ****\n"; + //Pattern.dump(); + //dbgs() << "Result pattern ****\n"; + //Result.dump(); } + //dbgs() << "Done all patterns\n"; } static void collectModes(std::set &Modes, const TreePatternNode *N) { diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.h b/llvm/utils/TableGen/CodeGenDAGPatterns.h index a3b84d76fde9e2..517ed290dcc662 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.h @@ -91,9 +91,10 @@ struct MachineValueTypeSet { return (Words[T.SimpleTy / WordWidth] >> (T.SimpleTy % WordWidth)) & 1; } std::pair insert(MVT T) { - bool V = count(T.SimpleTy); + //bool V = count(T.SimpleTy); Words[T.SimpleTy / WordWidth] |= WordType(1) << (T.SimpleTy % WordWidth); - return {*this, V}; + bool P = count(T.SimpleTy); + return {*this, P}; } MachineValueTypeSet &insert(const MachineValueTypeSet &S) { for (unsigned i = 0; i != NumWords; ++i) @@ -202,6 +203,7 @@ struct TypeSetByHwMode : public InfoByHwMode { TypeSetByHwMode(ArrayRef VTList); SetType &getOrCreate(unsigned Mode) { + //dbgs() << "hasMode() " << hasMode(Mode) << "\n"; if (hasMode(Mode)) return get(Mode); return Map.insert({Mode,SetType()}).first->second; @@ -212,6 +214,12 @@ struct TypeSetByHwMode : public InfoByHwMode { LLVM_ATTRIBUTE_ALWAYS_INLINE bool isMachineValueType() const { + // dbgs() << "isDefaultOnly " << isDefaultOnly(); + //if (!isDefaultOnly()) dbgs() << "Defauly only false\n"; + if (Map.begin()->second.size() != 1) { + //dbgs() << "size not 1\n"; + //dump(); + } return isDefaultOnly() && Map.begin()->second.size() == 1; } @@ -225,6 +233,7 @@ struct TypeSetByHwMode : public InfoByHwMode { LLVM_ATTRIBUTE_ALWAYS_INLINE bool isDefaultOnly() const { + ///dbgs() << "Map size " << Map.size() << "*\n"; return Map.size() == 1 && Map.begin()->first == DefaultMode; } @@ -985,24 +994,41 @@ class TreePattern { inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, const TypeSetByHwMode &InTy, TreePattern &TP) { + //dbgs() << "in const updatetypenode inty.dump \n"; + //InTy.dump(); + TypeSetByHwMode VTS(InTy); + //dbgs() << "inside UpdateNodeType \n"; + //VTS.dump(); TP.getInfer().expandOverloads(VTS); + //dbgs() << "after expand overloads\n"; + //VTS.dump(); return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS); } inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy, TreePattern &TP) { + //dbgs() << "in MVT UpdateNodeType\n"; TypeSetByHwMode VTS(InTy); + //dbgs() << "before expand overload\n"; + //VTS.dump(); TP.getInfer().expandOverloads(VTS); + //dbgs() << "after expand overloads\n"; + //VTS.dump(); return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS); } inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, ValueTypeByHwMode InTy, TreePattern &TP) { + //dbgs() << "in non-const UpdateNodeType\n"; TypeSetByHwMode VTS(InTy); + //dbgs() << "before expand overload\n"; + //VTS.dump(); TP.getInfer().expandOverloads(VTS); + //dbgs() << "after expand overloads\n"; + //VTS.dump(); return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS); } diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp index 4584bc7cfae324..0bcfac912f89d8 100644 --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -745,6 +745,11 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) std::vector TypeList = R->getValueAsListOfDefs("RegTypes"); for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { Record *Type = TypeList[i]; + if (R->getName() == "VGPR_32") { + dbgs() << "Analyzing for VGPR_32\n"; + dbgs() << Type->getName() << "\n"; + dbgs() << llvm::getEnumName(llvm::getValueType(Type)) << "\n"; + } if (!Type->isSubClassOf("ValueType")) PrintFatalError(R->getLoc(), "RegTypes list member '" + Type->getName() + diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index 921d20e7af7659..290aa4c073c704 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -196,6 +196,7 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) { case MVT::iPTRAny: return "MVT::iPTRAny"; case MVT::Untyped: return "MVT::Untyped"; case MVT::exnref: return "MVT::exnref"; + case MVT::vtAny32: return "MVT::vtAny32"; default: llvm_unreachable("ILLEGAL VALUE TYPE!"); } } diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 026f9ad349444e..1148a318103af5 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -191,7 +191,7 @@ static Optional MVTToLLT(MVT::SimpleValueType SVT) { return LLTCodeGen( LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits())); - if (VT.isInteger() || VT.isFloatingPoint()) + if (VT.isInteger() || VT.isFloatingPoint() || VT.isvtAny32()) return LLTCodeGen(LLT::scalar(VT.getSizeInBits())); return None; } @@ -386,6 +386,7 @@ getNameForFeatureBitset(const std::vector &FeatureBitset) { std::string Name = "GIFBS"; for (const auto &Feature : FeatureBitset) Name += ("_" + Feature->getName()).str(); + dbgs() << Name << "\n"; return Name; } @@ -1079,6 +1080,7 @@ class PredicateMatcher { OPM_PointerToAny, OPM_RegBank, OPM_MBB, + OPM_vtAny32, }; protected: @@ -1255,6 +1257,30 @@ class PointerToAnyOperandMatcher : public OperandPredicateMatcher { } }; +class vtAny32OperandMatcher : public OperandPredicateMatcher { +protected: + unsigned SizeInBits; + +public: + vtAny32OperandMatcher(unsigned InsnVarID, unsigned OpIdx, + unsigned SizeInBits) + : OperandPredicateMatcher(OPM_vtAny32, InsnVarID, OpIdx), + SizeInBits(SizeInBits) {} + + static bool classof(const OperandPredicateMatcher *P) { + return P->getKind() == OPM_vtAny32; + } + + void emitPredicateOpcodes(MatchTable &Table, + RuleMatcher &Rule) const override { + Table << MatchTable::Opcode("GIM_CheckvtAny32") + << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) + << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx) + << MatchTable::Comment("SizeInBits") + << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak; + } +}; + /// Generates code to check that an operand is a particular target constant. class ComplexPatternOperandMatcher : public OperandPredicateMatcher { protected: @@ -1589,6 +1615,12 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy, if (!VTy.isMachineValueType()) return failedImport("unsupported typeset"); + if (VTy.getMachineValueType() == MVT::vtAny32) { + dbgs() << "found vtAny32\n"; + addPredicate(32); + return Error::success(); + } + if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) { addPredicate(0); return Error::success(); @@ -5232,7 +5264,9 @@ void GlobalISelEmitter::run(raw_ostream &OS) { } Rules.push_back(std::move(MatcherOrErr.get())); } - + for (const auto& R : Rules) { + dbgs() << "Rules opcodes " << R.getOpcode().str() << "\n"; + } // Comparison function to order records by name. auto orderByName = [](const Record *A, const Record *B) { return A->getName() < B->getName();