Home | History | Annotate | Download | only in GlobalISel
      1 //===- llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 /// \file This file declares the API for the instruction selector.
     11 /// This class is responsible for selecting machine instructions.
     12 /// It's implemented by the target. It's used by the InstructionSelect pass.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
     17 #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
     18 
     19 #include "llvm/ADT/SmallVector.h"
     20 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
     21 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
     22 #include "llvm/CodeGen/MachineInstrBuilder.h"
     23 #include "llvm/CodeGen/MachineOperand.h"
     24 #include "llvm/CodeGen/MachineRegisterInfo.h"
     25 #include "llvm/Support/Debug.h"
     26 #include "llvm/Support/ErrorHandling.h"
     27 #include "llvm/Support/raw_ostream.h"
     28 #include "llvm/Target/TargetInstrInfo.h"
     29 #include "llvm/Target/TargetOpcodes.h"
     30 #include "llvm/Target/TargetRegisterInfo.h"
     31 #include <cassert>
     32 #include <cstddef>
     33 #include <cstdint>
     34 
     35 namespace llvm {
     36 
     37 /// GlobalISel PatFrag Predicates
     38 enum {
     39   GIPFP_I64_Invalid = 0,
     40   GIPFP_APInt_Invalid = 0,
     41   GIPFP_APFloat_Invalid = 0,
     42 };
     43 
     44 template <class TgtInstructionSelector, class PredicateBitset,
     45           class ComplexMatcherMemFn>
     46 bool InstructionSelector::executeMatchTable(
     47     TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State,
     48     const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> &MatcherInfo,
     49     const int64_t *MatchTable, const TargetInstrInfo &TII,
     50     MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
     51     const RegisterBankInfo &RBI,
     52     const PredicateBitset &AvailableFeatures) const {
     53   uint64_t CurrentIdx = 0;
     54   SmallVector<uint64_t, 8> OnFailResumeAt;
     55 
     56   enum RejectAction { RejectAndGiveUp, RejectAndResume };
     57   auto handleReject = [&]() -> RejectAction {
     58     DEBUG(dbgs() << CurrentIdx << ": Rejected\n");
     59     if (OnFailResumeAt.empty())
     60       return RejectAndGiveUp;
     61     CurrentIdx = OnFailResumeAt.back();
     62     OnFailResumeAt.pop_back();
     63     DEBUG(dbgs() << CurrentIdx << ": Resume at " << CurrentIdx << " ("
     64                  << OnFailResumeAt.size() << " try-blocks remain)\n");
     65     return RejectAndResume;
     66   };
     67 
     68   while (true) {
     69     assert(CurrentIdx != ~0u && "Invalid MatchTable index");
     70     switch (MatchTable[CurrentIdx++]) {
     71     case GIM_Try: {
     72       DEBUG(dbgs() << CurrentIdx << ": Begin try-block\n");
     73       OnFailResumeAt.push_back(MatchTable[CurrentIdx++]);
     74       break;
     75     }
     76 
     77     case GIM_RecordInsn: {
     78       int64_t NewInsnID = MatchTable[CurrentIdx++];
     79       int64_t InsnID = MatchTable[CurrentIdx++];
     80       int64_t OpIdx = MatchTable[CurrentIdx++];
     81 
     82       // As an optimisation we require that MIs[0] is always the root. Refuse
     83       // any attempt to modify it.
     84       assert(NewInsnID != 0 && "Refusing to modify MIs[0]");
     85 
     86       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
     87       if (!MO.isReg()) {
     88         DEBUG(dbgs() << CurrentIdx << ": Not a register\n");
     89         if (handleReject() == RejectAndGiveUp)
     90           return false;
     91         break;
     92       }
     93       if (TRI.isPhysicalRegister(MO.getReg())) {
     94         DEBUG(dbgs() << CurrentIdx << ": Is a physical register\n");
     95         if (handleReject() == RejectAndGiveUp)
     96           return false;
     97         break;
     98       }
     99 
    100       MachineInstr *NewMI = MRI.getVRegDef(MO.getReg());
    101       if ((size_t)NewInsnID < State.MIs.size())
    102         State.MIs[NewInsnID] = NewMI;
    103       else {
    104         assert((size_t)NewInsnID == State.MIs.size() &&
    105                "Expected to store MIs in order");
    106         State.MIs.push_back(NewMI);
    107       }
    108       DEBUG(dbgs() << CurrentIdx << ": MIs[" << NewInsnID
    109                    << "] = GIM_RecordInsn(" << InsnID << ", " << OpIdx
    110                    << ")\n");
    111       break;
    112     }
    113 
    114     case GIM_CheckFeatures: {
    115       int64_t ExpectedBitsetID = MatchTable[CurrentIdx++];
    116       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckFeatures(ExpectedBitsetID="
    117                    << ExpectedBitsetID << ")\n");
    118       if ((AvailableFeatures & MatcherInfo.FeatureBitsets[ExpectedBitsetID]) !=
    119           MatcherInfo.FeatureBitsets[ExpectedBitsetID]) {
    120         if (handleReject() == RejectAndGiveUp)
    121           return false;
    122       }
    123       break;
    124     }
    125 
    126     case GIM_CheckOpcode: {
    127       int64_t InsnID = MatchTable[CurrentIdx++];
    128       int64_t Expected = MatchTable[CurrentIdx++];
    129 
    130       unsigned Opcode = State.MIs[InsnID]->getOpcode();
    131       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckOpcode(MIs[" << InsnID
    132                    << "], ExpectedOpcode=" << Expected << ") // Got=" << Opcode
    133                    << "\n");
    134       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    135       if (Opcode != Expected) {
    136         if (handleReject() == RejectAndGiveUp)
    137           return false;
    138       }
    139       break;
    140     }
    141 
    142     case GIM_CheckNumOperands: {
    143       int64_t InsnID = MatchTable[CurrentIdx++];
    144       int64_t Expected = MatchTable[CurrentIdx++];
    145       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckNumOperands(MIs[" << InsnID
    146                    << "], Expected=" << Expected << ")\n");
    147       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    148       if (State.MIs[InsnID]->getNumOperands() != Expected) {
    149         if (handleReject() == RejectAndGiveUp)
    150           return false;
    151       }
    152       break;
    153     }
    154     case GIM_CheckI64ImmPredicate: {
    155       int64_t InsnID = MatchTable[CurrentIdx++];
    156       int64_t Predicate = MatchTable[CurrentIdx++];
    157       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs[" << InsnID
    158                    << "], Predicate=" << Predicate << ")\n");
    159       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    160       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
    161              "Expected G_CONSTANT");
    162       assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
    163       int64_t Value = 0;
    164       if (State.MIs[InsnID]->getOperand(1).isCImm())
    165         Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
    166       else if (State.MIs[InsnID]->getOperand(1).isImm())
    167         Value = State.MIs[InsnID]->getOperand(1).getImm();
    168       else
    169         llvm_unreachable("Expected Imm or CImm operand");
    170 
    171       if (!MatcherInfo.I64ImmPredicateFns[Predicate](Value))
    172         if (handleReject() == RejectAndGiveUp)
    173           return false;
    174       break;
    175     }
    176     case GIM_CheckAPIntImmPredicate: {
    177       int64_t InsnID = MatchTable[CurrentIdx++];
    178       int64_t Predicate = MatchTable[CurrentIdx++];
    179       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
    180                    << InsnID << "], Predicate=" << Predicate << ")\n");
    181       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    182       assert(State.MIs[InsnID]->getOpcode() && "Expected G_CONSTANT");
    183       assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
    184       APInt Value;
    185       if (State.MIs[InsnID]->getOperand(1).isCImm())
    186         Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
    187       else
    188         llvm_unreachable("Expected Imm or CImm operand");
    189 
    190       if (!MatcherInfo.APIntImmPredicateFns[Predicate](Value))
    191         if (handleReject() == RejectAndGiveUp)
    192           return false;
    193       break;
    194     }
    195     case GIM_CheckAPFloatImmPredicate: {
    196       int64_t InsnID = MatchTable[CurrentIdx++];
    197       int64_t Predicate = MatchTable[CurrentIdx++];
    198       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs[" << InsnID
    199                    << "], Predicate=" << Predicate << ")\n");
    200       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    201       assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
    202              "Expected G_FCONSTANT");
    203       assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
    204       assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
    205       APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
    206 
    207       if (!MatcherInfo.APFloatImmPredicateFns[Predicate](Value))
    208         if (handleReject() == RejectAndGiveUp)
    209           return false;
    210       break;
    211     }
    212     case GIM_CheckNonAtomic: {
    213       int64_t InsnID = MatchTable[CurrentIdx++];
    214       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckNonAtomic(MIs[" << InsnID
    215                    << "])\n");
    216       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    217       assert((State.MIs[InsnID]->getOpcode() == TargetOpcode::G_LOAD ||
    218               State.MIs[InsnID]->getOpcode() == TargetOpcode::G_STORE) &&
    219              "Expected G_LOAD/G_STORE");
    220 
    221       if (!State.MIs[InsnID]->hasOneMemOperand())
    222         if (handleReject() == RejectAndGiveUp)
    223           return false;
    224 
    225       for (const auto &MMO : State.MIs[InsnID]->memoperands())
    226         if (MMO->getOrdering() != AtomicOrdering::NotAtomic)
    227           if (handleReject() == RejectAndGiveUp)
    228             return false;
    229       break;
    230     }
    231 
    232     case GIM_CheckType: {
    233       int64_t InsnID = MatchTable[CurrentIdx++];
    234       int64_t OpIdx = MatchTable[CurrentIdx++];
    235       int64_t TypeID = MatchTable[CurrentIdx++];
    236       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckType(MIs[" << InsnID
    237                    << "]->getOperand(" << OpIdx << "), TypeID=" << TypeID
    238                    << ")\n");
    239       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    240       if (MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg()) !=
    241           MatcherInfo.TypeObjects[TypeID]) {
    242         if (handleReject() == RejectAndGiveUp)
    243           return false;
    244       }
    245       break;
    246     }
    247     case GIM_CheckPointerToAny: {
    248       int64_t InsnID = MatchTable[CurrentIdx++];
    249       int64_t OpIdx = MatchTable[CurrentIdx++];
    250       int64_t SizeInBits = MatchTable[CurrentIdx++];
    251 
    252       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckPointerToAny(MIs[" << InsnID
    253                    << "]->getOperand(" << OpIdx
    254                    << "), SizeInBits=" << SizeInBits << ")\n");
    255       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    256 
    257       // iPTR must be looked up in the target.
    258       if (SizeInBits == 0) {
    259         MachineFunction *MF = State.MIs[InsnID]->getParent()->getParent();
    260         SizeInBits = MF->getDataLayout().getPointerSizeInBits(0);
    261       }
    262 
    263       assert(SizeInBits != 0 && "Pointer size must be known");
    264 
    265       const LLT &Ty = MRI.getType(State.MIs[InsnID]->getOperand(OpIdx).getReg());
    266       if (!Ty.isPointer() || Ty.getSizeInBits() != SizeInBits) {
    267         if (handleReject() == RejectAndGiveUp)
    268           return false;
    269       }
    270       break;
    271     }
    272     case GIM_CheckRegBankForClass: {
    273       int64_t InsnID = MatchTable[CurrentIdx++];
    274       int64_t OpIdx = MatchTable[CurrentIdx++];
    275       int64_t RCEnum = MatchTable[CurrentIdx++];
    276       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckRegBankForClass(MIs[" << InsnID
    277                    << "]->getOperand(" << OpIdx << "), RCEnum=" << RCEnum
    278                    << ")\n");
    279       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    280       if (&RBI.getRegBankFromRegClass(*TRI.getRegClass(RCEnum)) !=
    281           RBI.getRegBank(State.MIs[InsnID]->getOperand(OpIdx).getReg(), MRI,
    282                          TRI)) {
    283         if (handleReject() == RejectAndGiveUp)
    284           return false;
    285       }
    286       break;
    287     }
    288 
    289     case GIM_CheckComplexPattern: {
    290       int64_t InsnID = MatchTable[CurrentIdx++];
    291       int64_t OpIdx = MatchTable[CurrentIdx++];
    292       int64_t RendererID = MatchTable[CurrentIdx++];
    293       int64_t ComplexPredicateID = MatchTable[CurrentIdx++];
    294       DEBUG(dbgs() << CurrentIdx << ": State.Renderers[" << RendererID
    295                    << "] = GIM_CheckComplexPattern(MIs[" << InsnID
    296                    << "]->getOperand(" << OpIdx
    297                    << "), ComplexPredicateID=" << ComplexPredicateID << ")\n");
    298       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    299       // FIXME: Use std::invoke() when it's available.
    300       ComplexRendererFn Renderer =
    301           (ISel.*MatcherInfo.ComplexPredicates[ComplexPredicateID])(
    302               State.MIs[InsnID]->getOperand(OpIdx));
    303       if (Renderer.hasValue())
    304         State.Renderers[RendererID] = Renderer.getValue();
    305       else
    306         if (handleReject() == RejectAndGiveUp)
    307           return false;
    308       break;
    309     }
    310 
    311     case GIM_CheckConstantInt: {
    312       int64_t InsnID = MatchTable[CurrentIdx++];
    313       int64_t OpIdx = MatchTable[CurrentIdx++];
    314       int64_t Value = MatchTable[CurrentIdx++];
    315       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckConstantInt(MIs[" << InsnID
    316                    << "]->getOperand(" << OpIdx << "), Value=" << Value
    317                    << ")\n");
    318       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    319       if (!isOperandImmEqual(State.MIs[InsnID]->getOperand(OpIdx), Value,
    320                              MRI)) {
    321         if (handleReject() == RejectAndGiveUp)
    322           return false;
    323       }
    324       break;
    325     }
    326 
    327     case GIM_CheckLiteralInt: {
    328       int64_t InsnID = MatchTable[CurrentIdx++];
    329       int64_t OpIdx = MatchTable[CurrentIdx++];
    330       int64_t Value = MatchTable[CurrentIdx++];
    331       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckLiteralInt(MIs[" << InsnID
    332                    << "]->getOperand(" << OpIdx << "), Value=" << Value
    333                    << ")\n");
    334       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    335       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
    336       if (!MO.isCImm() || !MO.getCImm()->equalsInt(Value)) {
    337         if (handleReject() == RejectAndGiveUp)
    338           return false;
    339       }
    340       break;
    341     }
    342 
    343     case GIM_CheckIntrinsicID: {
    344       int64_t InsnID = MatchTable[CurrentIdx++];
    345       int64_t OpIdx = MatchTable[CurrentIdx++];
    346       int64_t Value = MatchTable[CurrentIdx++];
    347       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs[" << InsnID
    348                    << "]->getOperand(" << OpIdx << "), Value=" << Value
    349                    << ")\n");
    350       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    351       MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
    352       if (!MO.isIntrinsicID() || MO.getIntrinsicID() != Value)
    353         if (handleReject() == RejectAndGiveUp)
    354           return false;
    355       break;
    356     }
    357 
    358     case GIM_CheckIsMBB: {
    359       int64_t InsnID = MatchTable[CurrentIdx++];
    360       int64_t OpIdx = MatchTable[CurrentIdx++];
    361       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckIsMBB(MIs[" << InsnID
    362                    << "]->getOperand(" << OpIdx << "))\n");
    363       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    364       if (!State.MIs[InsnID]->getOperand(OpIdx).isMBB()) {
    365         if (handleReject() == RejectAndGiveUp)
    366           return false;
    367       }
    368       break;
    369     }
    370 
    371     case GIM_CheckIsSafeToFold: {
    372       int64_t InsnID = MatchTable[CurrentIdx++];
    373       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckIsSafeToFold(MIs[" << InsnID
    374                    << "])\n");
    375       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    376       if (!isObviouslySafeToFold(*State.MIs[InsnID])) {
    377         if (handleReject() == RejectAndGiveUp)
    378           return false;
    379       }
    380       break;
    381     }
    382     case GIM_CheckIsSameOperand: {
    383       int64_t InsnID = MatchTable[CurrentIdx++];
    384       int64_t OpIdx = MatchTable[CurrentIdx++];
    385       int64_t OtherInsnID = MatchTable[CurrentIdx++];
    386       int64_t OtherOpIdx = MatchTable[CurrentIdx++];
    387       DEBUG(dbgs() << CurrentIdx << ": GIM_CheckIsSameOperand(MIs[" << InsnID
    388                    << "][" << OpIdx << "], MIs[" << OtherInsnID << "]["
    389                    << OtherOpIdx << "])\n");
    390       assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
    391       assert(State.MIs[OtherInsnID] != nullptr && "Used insn before defined");
    392       if (!State.MIs[InsnID]->getOperand(OpIdx).isIdenticalTo(
    393               State.MIs[OtherInsnID]->getOperand(OtherOpIdx))) {
    394         if (handleReject() == RejectAndGiveUp)
    395           return false;
    396       }
    397       break;
    398     }
    399     case GIM_Reject:
    400       DEBUG(dbgs() << CurrentIdx << ": GIM_Reject");
    401       if (handleReject() == RejectAndGiveUp)
    402         return false;
    403       break;
    404 
    405     case GIR_MutateOpcode: {
    406       int64_t OldInsnID = MatchTable[CurrentIdx++];
    407       int64_t NewInsnID = MatchTable[CurrentIdx++];
    408       int64_t NewOpcode = MatchTable[CurrentIdx++];
    409       assert((size_t)NewInsnID == OutMIs.size() &&
    410              "Expected to store MIs in order");
    411       OutMIs.push_back(MachineInstrBuilder(*State.MIs[OldInsnID]->getMF(),
    412                                            State.MIs[OldInsnID]));
    413       OutMIs[NewInsnID]->setDesc(TII.get(NewOpcode));
    414       DEBUG(dbgs() << CurrentIdx << ": GIR_MutateOpcode(OutMIs[" << NewInsnID
    415                    << "], MIs[" << OldInsnID << "], " << NewOpcode << ")\n");
    416       break;
    417     }
    418 
    419     case GIR_BuildMI: {
    420       int64_t InsnID = MatchTable[CurrentIdx++];
    421       int64_t Opcode = MatchTable[CurrentIdx++];
    422       assert((size_t)InsnID == OutMIs.size() &&
    423              "Expected to store MIs in order");
    424       (void)InsnID;
    425       OutMIs.push_back(BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
    426                                State.MIs[0]->getDebugLoc(), TII.get(Opcode)));
    427       DEBUG(dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs[" << InsnID << "], "
    428                    << Opcode << ")\n");
    429       break;
    430     }
    431 
    432     case GIR_Copy: {
    433       int64_t NewInsnID = MatchTable[CurrentIdx++];
    434       int64_t OldInsnID = MatchTable[CurrentIdx++];
    435       int64_t OpIdx = MatchTable[CurrentIdx++];
    436       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
    437       OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(OpIdx));
    438       DEBUG(dbgs() << CurrentIdx << ": GIR_Copy(OutMIs[" << NewInsnID
    439                    << "], MIs[" << OldInsnID << "], " << OpIdx << ")\n");
    440       break;
    441     }
    442 
    443     case GIR_CopySubReg: {
    444       int64_t NewInsnID = MatchTable[CurrentIdx++];
    445       int64_t OldInsnID = MatchTable[CurrentIdx++];
    446       int64_t OpIdx = MatchTable[CurrentIdx++];
    447       int64_t SubRegIdx = MatchTable[CurrentIdx++];
    448       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
    449       OutMIs[NewInsnID].addReg(State.MIs[OldInsnID]->getOperand(OpIdx).getReg(),
    450                                0, SubRegIdx);
    451       DEBUG(dbgs() << CurrentIdx << ": GIR_CopySubReg(OutMIs[" << NewInsnID
    452                    << "], MIs[" << OldInsnID << "], " << OpIdx << ", "
    453                    << SubRegIdx << ")\n");
    454       break;
    455     }
    456 
    457     case GIR_AddImplicitDef: {
    458       int64_t InsnID = MatchTable[CurrentIdx++];
    459       int64_t RegNum = MatchTable[CurrentIdx++];
    460       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    461       OutMIs[InsnID].addDef(RegNum, RegState::Implicit);
    462       DEBUG(dbgs() << CurrentIdx << ": GIR_AddImplicitDef(OutMIs[" << InsnID
    463                    << "], " << RegNum << ")\n");
    464       break;
    465     }
    466 
    467     case GIR_AddImplicitUse: {
    468       int64_t InsnID = MatchTable[CurrentIdx++];
    469       int64_t RegNum = MatchTable[CurrentIdx++];
    470       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    471       OutMIs[InsnID].addUse(RegNum, RegState::Implicit);
    472       DEBUG(dbgs() << CurrentIdx << ": GIR_AddImplicitUse(OutMIs[" << InsnID
    473                    << "], " << RegNum << ")\n");
    474       break;
    475     }
    476 
    477     case GIR_AddRegister: {
    478       int64_t InsnID = MatchTable[CurrentIdx++];
    479       int64_t RegNum = MatchTable[CurrentIdx++];
    480       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    481       OutMIs[InsnID].addReg(RegNum);
    482       DEBUG(dbgs() << CurrentIdx << ": GIR_AddRegister(OutMIs[" << InsnID
    483                    << "], " << RegNum << ")\n");
    484       break;
    485     }
    486 
    487     case GIR_AddImm: {
    488       int64_t InsnID = MatchTable[CurrentIdx++];
    489       int64_t Imm = MatchTable[CurrentIdx++];
    490       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    491       OutMIs[InsnID].addImm(Imm);
    492       DEBUG(dbgs() << CurrentIdx << ": GIR_AddImm(OutMIs[" << InsnID << "], "
    493                    << Imm << ")\n");
    494       break;
    495     }
    496 
    497     case GIR_ComplexRenderer: {
    498       int64_t InsnID = MatchTable[CurrentIdx++];
    499       int64_t RendererID = MatchTable[CurrentIdx++];
    500       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    501       for (const auto &RenderOpFn : State.Renderers[RendererID])
    502         RenderOpFn(OutMIs[InsnID]);
    503       DEBUG(dbgs() << CurrentIdx << ": GIR_ComplexRenderer(OutMIs[" << InsnID
    504                    << "], " << RendererID << ")\n");
    505       break;
    506     }
    507     case GIR_ComplexSubOperandRenderer: {
    508       int64_t InsnID = MatchTable[CurrentIdx++];
    509       int64_t RendererID = MatchTable[CurrentIdx++];
    510       int64_t RenderOpID = MatchTable[CurrentIdx++];
    511       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    512       State.Renderers[RendererID][RenderOpID](OutMIs[InsnID]);
    513       DEBUG(dbgs() << CurrentIdx << ": GIR_ComplexSubOperandRenderer(OutMIs["
    514                    << InsnID << "], " << RendererID << ", " << RenderOpID
    515                    << ")\n");
    516       break;
    517     }
    518 
    519     case GIR_CopyConstantAsSImm: {
    520       int64_t NewInsnID = MatchTable[CurrentIdx++];
    521       int64_t OldInsnID = MatchTable[CurrentIdx++];
    522       assert(OutMIs[NewInsnID] && "Attempted to add to undefined instruction");
    523       assert(State.MIs[OldInsnID]->getOpcode() == TargetOpcode::G_CONSTANT && "Expected G_CONSTANT");
    524       if (State.MIs[OldInsnID]->getOperand(1).isCImm()) {
    525         OutMIs[NewInsnID].addImm(
    526             State.MIs[OldInsnID]->getOperand(1).getCImm()->getSExtValue());
    527       } else if (State.MIs[OldInsnID]->getOperand(1).isImm())
    528         OutMIs[NewInsnID].add(State.MIs[OldInsnID]->getOperand(1));
    529       else
    530         llvm_unreachable("Expected Imm or CImm operand");
    531       DEBUG(dbgs() << CurrentIdx << ": GIR_CopyConstantAsSImm(OutMIs[" << NewInsnID
    532                    << "], MIs[" << OldInsnID << "])\n");
    533       break;
    534     }
    535 
    536     case GIR_ConstrainOperandRC: {
    537       int64_t InsnID = MatchTable[CurrentIdx++];
    538       int64_t OpIdx = MatchTable[CurrentIdx++];
    539       int64_t RCEnum = MatchTable[CurrentIdx++];
    540       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    541       constrainOperandRegToRegClass(*OutMIs[InsnID].getInstr(), OpIdx,
    542                                     *TRI.getRegClass(RCEnum), TII, TRI, RBI);
    543       DEBUG(dbgs() << CurrentIdx << ": GIR_ConstrainOperandRC(OutMIs[" << InsnID
    544                    << "], " << OpIdx << ", " << RCEnum << ")\n");
    545       break;
    546     }
    547 
    548     case GIR_ConstrainSelectedInstOperands: {
    549       int64_t InsnID = MatchTable[CurrentIdx++];
    550       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    551       constrainSelectedInstRegOperands(*OutMIs[InsnID].getInstr(), TII, TRI,
    552                                        RBI);
    553       DEBUG(dbgs() << CurrentIdx
    554                    << ": GIR_ConstrainSelectedInstOperands(OutMIs[" << InsnID
    555                    << "])\n");
    556       break;
    557     }
    558 
    559     case GIR_MergeMemOperands: {
    560       int64_t InsnID = MatchTable[CurrentIdx++];
    561       assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
    562 
    563       DEBUG(dbgs() << CurrentIdx << ": GIR_MergeMemOperands(OutMIs[" << InsnID
    564                    << "]");
    565       int64_t MergeInsnID = GIU_MergeMemOperands_EndOfList;
    566       while ((MergeInsnID = MatchTable[CurrentIdx++]) !=
    567              GIU_MergeMemOperands_EndOfList) {
    568         DEBUG(dbgs() << ", MIs[" << MergeInsnID << "]");
    569         for (const auto &MMO : State.MIs[MergeInsnID]->memoperands())
    570           OutMIs[InsnID].addMemOperand(MMO);
    571       }
    572       DEBUG(dbgs() << ")\n");
    573       break;
    574     }
    575 
    576     case GIR_EraseFromParent: {
    577       int64_t InsnID = MatchTable[CurrentIdx++];
    578       assert(State.MIs[InsnID] &&
    579              "Attempted to erase an undefined instruction");
    580       State.MIs[InsnID]->eraseFromParent();
    581       DEBUG(dbgs() << CurrentIdx << ": GIR_EraseFromParent(MIs[" << InsnID
    582                    << "])\n");
    583       break;
    584     }
    585 
    586     case GIR_Done:
    587       DEBUG(dbgs() << CurrentIdx << ": GIR_Done");
    588       return true;
    589 
    590     default:
    591       llvm_unreachable("Unexpected command");
    592     }
    593   }
    594 }
    595 
    596 } // end namespace llvm
    597 
    598 #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
    599