Index: include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -59,8 +59,8 @@ MI.getOperand(1).getReg(), MRI)) { unsigned DstReg = MI.getOperand(0).getReg(); LLT DstTy = MRI.getType(DstReg); - if (isInstUnsupported(TargetOpcode::G_AND, DstTy) || - isInstUnsupported(TargetOpcode::G_CONSTANT, DstTy)) + if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) || + isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}})) return false; DEBUG(dbgs() << ".. Combine MI: " << MI;); Builder.setInstr(MI); @@ -87,9 +87,9 @@ MI.getOperand(1).getReg(), MRI)) { unsigned DstReg = MI.getOperand(0).getReg(); LLT DstTy = MRI.getType(DstReg); - if (isInstUnsupported(TargetOpcode::G_SHL, DstTy) || - isInstUnsupported(TargetOpcode::G_ASHR, DstTy) || - isInstUnsupported(TargetOpcode::G_CONSTANT, DstTy)) + if (isInstUnsupported({TargetOpcode::G_SHL, {DstTy}}) || + isInstUnsupported({TargetOpcode::G_ASHR, {DstTy}}) || + isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}})) return false; DEBUG(dbgs() << ".. Combine MI: " << MI;); Builder.setInstr(MI); @@ -121,7 +121,7 @@ MI.getOperand(1).getReg(), MRI)) { unsigned DstReg = MI.getOperand(0).getReg(); LLT DstTy = MRI.getType(DstReg); - if (isInstUnsupported(TargetOpcode::G_IMPLICIT_DEF, DstTy)) + if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) return false; DEBUG(dbgs() << ".. Combine EXT(IMPLICIT_DEF) " << MI;); Builder.setInstr(MI); @@ -277,10 +277,10 @@ /// Checks if the target legalizer info has specified anything about the /// instruction, or if unsupported. - bool isInstUnsupported(unsigned Opcode, const LLT &DstTy) const { - auto Action = LI.getAction({Opcode, 0, DstTy}); - return Action.first == LegalizerInfo::LegalizeAction::Unsupported || - Action.first == LegalizerInfo::LegalizeAction::NotFound; + bool isInstUnsupported(const LegalityQuery &Query) const { + auto Action = LI.getAction(Query); + return std::get<0>(Action) == LegalizerInfo::LegalizeAction::Unsupported || + std::get<0>(Action) == LegalizerInfo::LegalizeAction::NotFound; } }; Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -51,6 +51,14 @@ } }; +struct LegalityQuery { + unsigned Opcode; + ArrayRef Types; + + LegalityQuery(unsigned Opcode, ArrayRef Types) + : Opcode(Opcode), Types(Types) {} +}; + class LegalizerInfo { public: enum LegalizeAction : std::uint8_t { @@ -259,13 +267,13 @@ LegalizeAction DecreaseAction, LegalizeAction IncreaseAction); - /// Determine what action should be taken to legalize the given generic - /// instruction opcode, type-index and type. Requires computeTables to have - /// been called. + /// Determine what action should be taken to legalize the described + /// instruction. Requires computeTables to have been called. /// /// \returns a pair consisting of the kind of legalization that should be /// performed and the destination type. - std::pair getAction(const InstrAspect &Aspect) const; + std::tuple + getAction(const LegalityQuery &Query) const; /// Determine what action should be taken to legalize the given generic /// instruction. @@ -283,6 +291,15 @@ MachineIRBuilder &MIRBuilder) const; private: + /// Determine what action should be taken to legalize the given generic + /// instruction opcode, type-index and type. Requires computeTables to have + /// been called. + /// + /// \returns a pair consisting of the kind of legalization that should be + /// performed and the destination type. + std::pair + getAspectAction(const InstrAspect &Aspect) const; + /// The SizeAndActionsVec is a representation mapping between all natural /// numbers and an Action. The natural number represents the bit size of /// the InstrAspect. For example, for a target with native support for 32-bit Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -870,7 +870,7 @@ // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)). // First, check if G_FNEG is marked as Lower. If so, we may // end up with an infinite loop as G_FSUB is used to legalize G_FNEG. - if (LI.getAction({G_FNEG, Ty}).first == LegalizerInfo::Lower) + if (std::get<0>(LI.getAction({G_FNEG, {Ty}})) == LegalizerInfo::Lower) return UnableToLegalize; unsigned Res = MI.getOperand(0).getReg(); unsigned LHS = MI.getOperand(1).getReg(); Index: lib/CodeGen/GlobalISel/LegalizerInfo.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -163,7 +163,7 @@ // we have any hope of doing well with something like <13 x i3>. Even the common // cases should do better than what we have now. std::pair -LegalizerInfo::getAction(const InstrAspect &Aspect) const { +LegalizerInfo::getAspectAction(const InstrAspect &Aspect) const { assert(TablesInitialized && "backend forgot to call computeTables"); // These *have* to be implemented for now, they're the fundamental basis of // how everything else is transformed. @@ -186,9 +186,20 @@ return MRI.getType(MI.getOperand(OpIdx).getReg()); } +std::tuple +LegalizerInfo::getAction(const LegalityQuery &Query) const { + for (unsigned i = 0; i < Query.Types.size(); ++i) { + auto Action = getAspectAction({Query.Opcode, i, Query.Types[i]}); + if (Action.first != Legal) + return std::make_tuple(Action.first, i, Action.second); + } + return std::make_tuple(Legal, 0, LLT{}); +} + std::tuple LegalizerInfo::getAction(const MachineInstr &MI, const MachineRegisterInfo &MRI) const { + SmallVector Types; SmallBitVector SeenTypes(8); const MCOperandInfo *OpInfo = MI.getDesc().OpInfo; // FIXME: probably we'll need to cache the results here somehow? @@ -205,11 +216,9 @@ SeenTypes.set(TypeIdx); LLT Ty = getTypeFromTypeIdx(MI, MRI, i, TypeIdx); - auto Action = getAction({MI.getOpcode(), TypeIdx, Ty}); - if (Action.first != Legal) - return std::make_tuple(Action.first, TypeIdx, Action.second); + Types.push_back(Ty); } - return std::make_tuple(Legal, 0, LLT{}); + return getAction({MI.getOpcode(), Types}); } bool LegalizerInfo::isLegal(const MachineInstr &MI,