Index: lib/CodeGen/MIRParser/MIParser.h =================================================================== --- lib/CodeGen/MIRParser/MIParser.h +++ lib/CodeGen/MIRParser/MIParser.h @@ -15,6 +15,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/Support/Allocator.h" namespace llvm { @@ -28,6 +29,7 @@ class SourceMgr; class StringRef; class TargetRegisterClass; +class TargetSubtargetInfo; struct VRegInfo { enum uint8_t { @@ -45,13 +47,121 @@ using Name2RegClassMap = StringMap; using Name2RegBankMap = StringMap; +struct PerTargetMIParsingState { +private: + const TargetSubtargetInfo &Subtarget; + + /// Maps from instruction names to op codes. + StringMap Names2InstrOpCodes; + + /// Maps from register names to registers. + StringMap Names2Regs; + + /// Maps from register mask names to register masks. + StringMap Names2RegMasks; + + /// Maps from subregister names to subregister indices. + StringMap Names2SubRegIndices; + + /// Maps from target index names to target indices. + StringMap Names2TargetIndices; + + /// Maps from direct target flag names to the direct target flag values. + StringMap Names2DirectTargetFlags; + + /// Maps from direct target flag names to the bitmask target flag values. + StringMap Names2BitmaskTargetFlags; + + /// Maps from MMO target flag names to MMO target flag values. + StringMap Names2MMOTargetFlags; + + /// Maps from register class names to register classes. + Name2RegClassMap Names2RegClasses; + + /// Maps from register bank names to register banks. + Name2RegBankMap Names2RegBanks; + + void initNames2InstrOpCodes(); + void initNames2Regs(); + void initNames2RegMasks(); + void initNames2SubRegIndices(); + void initNames2TargetIndices(); + void initNames2DirectTargetFlags(); + void initNames2BitmaskTargetFlags(); + void initNames2MMOTargetFlags(); + + void initNames2RegClasses(); + void initNames2RegBanks(); + +public: + /// Try to convert an instruction name to an opcode. Return true if the + /// instruction name is invalid. + bool parseInstrName(StringRef InstrName, unsigned &OpCode); + + /// Try to convert a register name to a register number. Return true if the + /// register name is invalid. + bool getRegisterByName(StringRef RegName, unsigned &Reg); + + /// Check if the given identifier is a name of a register mask. + /// + /// Return null if the identifier isn't a register mask. + const uint32_t *getRegMask(StringRef Identifier); + + /// Check if the given identifier is a name of a subregister index. + /// + /// Return 0 if the name isn't a subregister index class. + unsigned getSubRegIndex(StringRef Name); + + /// Try to convert a name of target index to the corresponding target index. + /// + /// Return true if the name isn't a name of a target index. + bool getTargetIndex(StringRef Name, int &Index); + + /// Try to convert a name of a direct target flag to the corresponding + /// target flag. + /// + /// Return true if the name isn't a name of a direct flag. + bool getDirectTargetFlag(StringRef Name, unsigned &Flag); + + /// Try to convert a name of a bitmask target flag to the corresponding + /// target flag. + /// + /// Return true if the name isn't a name of a bitmask target flag. + bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag); + + /// Try to convert a name of a MachineMemOperand target flag to the + /// corresponding target flag. + /// + /// Return true if the name isn't a name of a target MMO flag. + bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag); + + /// Check if the given identifier is a name of a register class. + /// + /// Return null if the name isn't a register class. + const TargetRegisterClass *getRegClass(StringRef Name); + + /// Check if the given identifier is a name of a register bank. + /// + /// Return null if the name isn't a register bank. + const RegisterBank *getRegBank(StringRef Name); + + PerTargetMIParsingState(const TargetSubtargetInfo &STI) + : Subtarget(STI) { + initNames2RegClasses(); + initNames2RegBanks(); + } + + ~PerTargetMIParsingState() = default; + + void setTarget(const TargetSubtargetInfo &NewSubtarget); +}; + struct PerFunctionMIParsingState { BumpPtrAllocator Allocator; MachineFunction &MF; SourceMgr *SM; const SlotMapping &IRSlots; - const Name2RegClassMap &Names2RegClasses; - const Name2RegBankMap &Names2RegBanks; + PerTargetMIParsingState &Target; DenseMap MBBSlots; DenseMap VRegInfos; @@ -63,8 +173,7 @@ PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM, const SlotMapping &IRSlots, - const Name2RegClassMap &Names2RegClasses, - const Name2RegBankMap &Names2RegBanks); + PerTargetMIParsingState &Target); VRegInfo &getVRegInfo(unsigned Num); VRegInfo &getVRegInfoNamed(StringRef RegName); Index: lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIParser.cpp +++ lib/CodeGen/MIRParser/MIParser.cpp @@ -26,6 +26,8 @@ #include "llvm/Analysis/MemoryLocation.h" #include "llvm/AsmParser/Parser.h" #include "llvm/AsmParser/SlotMapping.h" +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" +#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" #include "llvm/CodeGen/MIRPrinter.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -80,12 +82,242 @@ using namespace llvm; +void PerTargetMIParsingState::setTarget( + const TargetSubtargetInfo &NewSubtarget) { + + // If the subtarget changed, over conservatively assume everything is invalid. + if (&Subtarget == &NewSubtarget) + return; + + Names2InstrOpCodes.clear(); + Names2Regs.clear(); + Names2RegMasks.clear(); + Names2SubRegIndices.clear(); + Names2TargetIndices.clear(); + Names2DirectTargetFlags.clear(); + Names2BitmaskTargetFlags.clear(); + Names2MMOTargetFlags.clear(); + + initNames2RegClasses(); + initNames2RegBanks(); +} + +void PerTargetMIParsingState::initNames2Regs() { + if (!Names2Regs.empty()) + return; + + // The '%noreg' register is the register 0. + Names2Regs.insert(std::make_pair("noreg", 0)); + const auto *TRI = Subtarget.getRegisterInfo(); + assert(TRI && "Expected target register info"); + + for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) { + bool WasInserted = + Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I)) + .second; + (void)WasInserted; + assert(WasInserted && "Expected registers to be unique case-insensitively"); + } +} + +bool PerTargetMIParsingState::getRegisterByName(StringRef RegName, + unsigned &Reg) { + initNames2Regs(); + auto RegInfo = Names2Regs.find(RegName); + if (RegInfo == Names2Regs.end()) + return true; + Reg = RegInfo->getValue(); + return false; +} + +void PerTargetMIParsingState::initNames2InstrOpCodes() { + if (!Names2InstrOpCodes.empty()) + return; + const auto *TII = Subtarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) + Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); +} + +bool PerTargetMIParsingState::parseInstrName(StringRef InstrName, + unsigned &OpCode) { + initNames2InstrOpCodes(); + auto InstrInfo = Names2InstrOpCodes.find(InstrName); + if (InstrInfo == Names2InstrOpCodes.end()) + return true; + OpCode = InstrInfo->getValue(); + return false; +} + +void PerTargetMIParsingState::initNames2RegMasks() { + if (!Names2RegMasks.empty()) + return; + const auto *TRI = Subtarget.getRegisterInfo(); + assert(TRI && "Expected target register info"); + ArrayRef RegMasks = TRI->getRegMasks(); + ArrayRef RegMaskNames = TRI->getRegMaskNames(); + assert(RegMasks.size() == RegMaskNames.size()); + for (size_t I = 0, E = RegMasks.size(); I < E; ++I) + Names2RegMasks.insert( + std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I])); +} + +const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) { + initNames2RegMasks(); + auto RegMaskInfo = Names2RegMasks.find(Identifier); + if (RegMaskInfo == Names2RegMasks.end()) + return nullptr; + return RegMaskInfo->getValue(); +} + +void PerTargetMIParsingState::initNames2SubRegIndices() { + if (!Names2SubRegIndices.empty()) + return; + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) + Names2SubRegIndices.insert( + std::make_pair(StringRef(TRI->getSubRegIndexName(I)).lower(), I)); +} + +unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) { + initNames2SubRegIndices(); + auto SubRegInfo = Names2SubRegIndices.find(Name); + if (SubRegInfo == Names2SubRegIndices.end()) + return 0; + return SubRegInfo->getValue(); +} + +void PerTargetMIParsingState::initNames2TargetIndices() { + if (!Names2TargetIndices.empty()) + return; + const auto *TII = Subtarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + auto Indices = TII->getSerializableTargetIndices(); + for (const auto &I : Indices) + Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); +} + +bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) { + initNames2TargetIndices(); + auto IndexInfo = Names2TargetIndices.find(Name); + if (IndexInfo == Names2TargetIndices.end()) + return true; + Index = IndexInfo->second; + return false; +} + +void PerTargetMIParsingState::initNames2DirectTargetFlags() { + if (!Names2DirectTargetFlags.empty()) + return; + + const auto *TII = Subtarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); + for (const auto &I : Flags) + Names2DirectTargetFlags.insert( + std::make_pair(StringRef(I.second), I.first)); +} + +bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name, + unsigned &Flag) { + initNames2DirectTargetFlags(); + auto FlagInfo = Names2DirectTargetFlags.find(Name); + if (FlagInfo == Names2DirectTargetFlags.end()) + return true; + Flag = FlagInfo->second; + return false; +} + +void PerTargetMIParsingState::initNames2BitmaskTargetFlags() { + if (!Names2BitmaskTargetFlags.empty()) + return; + + const auto *TII = Subtarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags(); + for (const auto &I : Flags) + Names2BitmaskTargetFlags.insert( + std::make_pair(StringRef(I.second), I.first)); +} + +bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name, + unsigned &Flag) { + initNames2BitmaskTargetFlags(); + auto FlagInfo = Names2BitmaskTargetFlags.find(Name); + if (FlagInfo == Names2BitmaskTargetFlags.end()) + return true; + Flag = FlagInfo->second; + return false; +} + +void PerTargetMIParsingState::initNames2MMOTargetFlags() { + if (!Names2MMOTargetFlags.empty()) + return; + + const auto *TII = Subtarget.getInstrInfo(); + assert(TII && "Expected target instruction info"); + auto Flags = TII->getSerializableMachineMemOperandTargetFlags(); + for (const auto &I : Flags) + Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first)); +} + +bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name, + MachineMemOperand::Flags &Flag) { + initNames2MMOTargetFlags(); + auto FlagInfo = Names2MMOTargetFlags.find(Name); + if (FlagInfo == Names2MMOTargetFlags.end()) + return true; + Flag = FlagInfo->second; + return false; +} + +void PerTargetMIParsingState::initNames2RegClasses() { + if (!Names2RegClasses.empty()) + return; + + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { + const auto *RC = TRI->getRegClass(I); + Names2RegClasses.insert( + std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); + } +} + +void PerTargetMIParsingState::initNames2RegBanks() { + if (!Names2RegBanks.empty()) + return; + + const RegisterBankInfo *RBI = Subtarget.getRegBankInfo(); + // If the target does not support GlobalISel, we may not have a + // register bank info. + if (!RBI) + return; + + for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) { + const auto &RegBank = RBI->getRegBank(I); + Names2RegBanks.insert( + std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); + } +} + +const TargetRegisterClass * +PerTargetMIParsingState::getRegClass(StringRef Name) { + auto RegClassInfo = Names2RegClasses.find(Name); + if (RegClassInfo == Names2RegClasses.end()) + return nullptr; + return RegClassInfo->getValue(); +} + +const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) { + auto RegBankInfo = Names2RegBanks.find(Name); + if (RegBankInfo == Names2RegBanks.end()) + return nullptr; + return RegBankInfo->getValue(); +} + PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF, - SourceMgr &SM, const SlotMapping &IRSlots, - const Name2RegClassMap &Names2RegClasses, - const Name2RegBankMap &Names2RegBanks) - : MF(MF), SM(&SM), IRSlots(IRSlots), Names2RegClasses(Names2RegClasses), - Names2RegBanks(Names2RegBanks) { + SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T) + : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) { } VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) { @@ -136,26 +368,10 @@ StringRef Source, CurrentSource; MIToken Token; PerFunctionMIParsingState &PFS; - /// Maps from instruction names to op codes. - StringMap Names2InstrOpCodes; - /// Maps from register names to registers. - StringMap Names2Regs; - /// Maps from register mask names to register masks. - StringMap Names2RegMasks; - /// Maps from subregister names to subregister indices. - StringMap Names2SubRegIndices; /// Maps from slot numbers to function's unnamed basic blocks. DenseMap Slots2BasicBlocks; /// Maps from slot numbers to function's unnamed values. DenseMap Slots2Values; - /// Maps from target index names to target indices. - StringMap Names2TargetIndices; - /// Maps from direct target flag names to the direct target flag values. - StringMap Names2DirectTargetFlags; - /// Maps from direct target flag names to the bitmask target flag values. - StringMap Names2BitmaskTargetFlags; - /// Maps from MMO target flag names to MMO target flag values. - StringMap Names2MMOTargetFlags; public: MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, @@ -280,12 +496,6 @@ /// Otherwise return false. bool consumeIfPresent(MIToken::TokenKind TokenKind); - void initNames2InstrOpCodes(); - - /// Try to convert an instruction name to an opcode. Return true if the - /// instruction name is invalid. - bool parseInstrName(StringRef InstrName, unsigned &OpCode); - bool parseInstruction(unsigned &OpCode, unsigned &Flags); bool assignRegisterTies(MachineInstr &MI, @@ -294,62 +504,11 @@ bool verifyImplicitOperands(ArrayRef Operands, const MCInstrDesc &MCID); - void initNames2Regs(); - - /// Try to convert a register name to a register number. Return true if the - /// register name is invalid. - bool getRegisterByName(StringRef RegName, unsigned &Reg); - - void initNames2RegMasks(); - - /// Check if the given identifier is a name of a register mask. - /// - /// Return null if the identifier isn't a register mask. - const uint32_t *getRegMask(StringRef Identifier); - - void initNames2SubRegIndices(); - - /// Check if the given identifier is a name of a subregister index. - /// - /// Return 0 if the name isn't a subregister index class. - unsigned getSubRegIndex(StringRef Name); - const BasicBlock *getIRBlock(unsigned Slot); const BasicBlock *getIRBlock(unsigned Slot, const Function &F); const Value *getIRValue(unsigned Slot); - void initNames2TargetIndices(); - - /// Try to convert a name of target index to the corresponding target index. - /// - /// Return true if the name isn't a name of a target index. - bool getTargetIndex(StringRef Name, int &Index); - - void initNames2DirectTargetFlags(); - - /// Try to convert a name of a direct target flag to the corresponding - /// target flag. - /// - /// Return true if the name isn't a name of a direct flag. - bool getDirectTargetFlag(StringRef Name, unsigned &Flag); - - void initNames2BitmaskTargetFlags(); - - /// Try to convert a name of a bitmask target flag to the corresponding - /// target flag. - /// - /// Return true if the name isn't a name of a bitmask target flag. - bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag); - - void initNames2MMOTargetFlags(); - - /// Try to convert a name of a MachineMemOperand target flag to the - /// corresponding target flag. - /// - /// Return true if the name isn't a name of a target MMO flag. - bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag); - /// Get or create an MCSymbol for a given name. MCSymbol *getOrCreateMCSymbol(StringRef Name); @@ -1009,7 +1168,7 @@ if (Token.isNot(MIToken::Identifier)) return error("expected a machine instruction"); StringRef InstrName = Token.stringValue(); - if (parseInstrName(InstrName, OpCode)) + if (PFS.Target.parseInstrName(InstrName, OpCode)) return error(Twine("unknown machine instruction name '") + InstrName + "'"); lex(); return false; @@ -1018,7 +1177,7 @@ bool MIParser::parseNamedRegister(unsigned &Reg) { assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token"); StringRef Name = Token.stringValue(); - if (getRegisterByName(Name, Reg)) + if (PFS.Target.getRegisterByName(Name, Reg)) return error(Twine("unknown register name '") + Name + "'"); return false; } @@ -1069,21 +1228,20 @@ StringRef Name = Token.stringValue(); // Was it a register class? - auto RCNameI = PFS.Names2RegClasses.find(Name); - if (RCNameI != PFS.Names2RegClasses.end()) { + const TargetRegisterClass *RC = PFS.Target.getRegClass(Name); + if (RC) { lex(); - const TargetRegisterClass &RC = *RCNameI->getValue(); switch (RegInfo.Kind) { case VRegInfo::UNKNOWN: case VRegInfo::NORMAL: RegInfo.Kind = VRegInfo::NORMAL; - if (RegInfo.Explicit && RegInfo.D.RC != &RC) { + if (RegInfo.Explicit && RegInfo.D.RC != RC) { const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); return error(Loc, Twine("conflicting register classes, previously: ") + Twine(TRI.getRegClassName(RegInfo.D.RC))); } - RegInfo.D.RC = &RC; + RegInfo.D.RC = RC; RegInfo.Explicit = true; return false; @@ -1097,10 +1255,9 @@ // Should be a register bank or a generic register. const RegisterBank *RegBank = nullptr; if (Name != "_") { - auto RBNameI = PFS.Names2RegBanks.find(Name); - if (RBNameI == PFS.Names2RegBanks.end()) + RegBank = PFS.Target.getRegBank(Name); + if (!RegBank) return error(Loc, "expected '_', register class, or register bank name"); - RegBank = RBNameI->getValue(); } lex(); @@ -1172,7 +1329,7 @@ if (Token.isNot(MIToken::Identifier)) return error("expected a subregister index after '.'"); auto Name = Token.stringValue(); - SubReg = getSubRegIndex(Name); + SubReg = PFS.Target.getSubRegIndex(Name); if (!SubReg) return error(Twine("use of unknown subregister index '") + Name + "'"); lex(); @@ -1653,7 +1810,7 @@ bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { assert(Token.is(MIToken::SubRegisterIndex)); StringRef Name = Token.stringValue(); - unsigned SubRegIndex = getSubRegIndex(Token.stringValue()); + unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue()); if (SubRegIndex == 0) return error(Twine("unknown subregister index '") + Name + "'"); lex(); @@ -2128,7 +2285,7 @@ if (Token.isNot(MIToken::Identifier)) return error("expected the name of the target index"); int Index = 0; - if (getTargetIndex(Token.stringValue(), Index)) + if (PFS.Target.getTargetIndex(Token.stringValue(), Index)) return error("use of undefined target index '" + Token.stringValue() + "'"); lex(); if (expectAndConsume(MIToken::rparen)) @@ -2270,7 +2427,7 @@ case MIToken::Error: return true; case MIToken::Identifier: - if (const auto *RegMask = getRegMask(Token.stringValue())) { + if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) { Dest = MachineOperand::CreateRegMask(RegMask); lex(); break; @@ -2296,8 +2453,8 @@ return true; if (Token.isNot(MIToken::Identifier)) return error("expected the name of the target flag"); - if (getDirectTargetFlag(Token.stringValue(), TF)) { - if (getBitmaskTargetFlag(Token.stringValue(), TF)) + if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) { + if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF)) return error("use of undefined target flag '" + Token.stringValue() + "'"); } @@ -2307,7 +2464,7 @@ if (Token.isNot(MIToken::Identifier)) return error("expected the name of the target flag"); unsigned BitFlag = 0; - if (getBitmaskTargetFlag(Token.stringValue(), BitFlag)) + if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag)) return error("use of undefined target flag '" + Token.stringValue() + "'"); // TODO: Report an error when using a duplicate bit target flag. @@ -2468,7 +2625,7 @@ break; case MIToken::StringConstant: { MachineMemOperand::Flags TF; - if (getMMOTargetFlag(Token.stringValue(), TF)) + if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF)) return error("use of undefined target MMO flag '" + Token.stringValue() + "'"); Flags |= TF; @@ -2743,87 +2900,6 @@ return false; } -void MIParser::initNames2InstrOpCodes() { - if (!Names2InstrOpCodes.empty()) - return; - const auto *TII = MF.getSubtarget().getInstrInfo(); - assert(TII && "Expected target instruction info"); - for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) - Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); -} - -bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) { - initNames2InstrOpCodes(); - auto InstrInfo = Names2InstrOpCodes.find(InstrName); - if (InstrInfo == Names2InstrOpCodes.end()) - return true; - OpCode = InstrInfo->getValue(); - return false; -} - -void MIParser::initNames2Regs() { - if (!Names2Regs.empty()) - return; - // The '%noreg' register is the register 0. - Names2Regs.insert(std::make_pair("noreg", 0)); - const auto *TRI = MF.getSubtarget().getRegisterInfo(); - assert(TRI && "Expected target register info"); - for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) { - bool WasInserted = - Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I)) - .second; - (void)WasInserted; - assert(WasInserted && "Expected registers to be unique case-insensitively"); - } -} - -bool MIParser::getRegisterByName(StringRef RegName, unsigned &Reg) { - initNames2Regs(); - auto RegInfo = Names2Regs.find(RegName); - if (RegInfo == Names2Regs.end()) - return true; - Reg = RegInfo->getValue(); - return false; -} - -void MIParser::initNames2RegMasks() { - if (!Names2RegMasks.empty()) - return; - const auto *TRI = MF.getSubtarget().getRegisterInfo(); - assert(TRI && "Expected target register info"); - ArrayRef RegMasks = TRI->getRegMasks(); - ArrayRef RegMaskNames = TRI->getRegMaskNames(); - assert(RegMasks.size() == RegMaskNames.size()); - for (size_t I = 0, E = RegMasks.size(); I < E; ++I) - Names2RegMasks.insert( - std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I])); -} - -const uint32_t *MIParser::getRegMask(StringRef Identifier) { - initNames2RegMasks(); - auto RegMaskInfo = Names2RegMasks.find(Identifier); - if (RegMaskInfo == Names2RegMasks.end()) - return nullptr; - return RegMaskInfo->getValue(); -} - -void MIParser::initNames2SubRegIndices() { - if (!Names2SubRegIndices.empty()) - return; - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) - Names2SubRegIndices.insert( - std::make_pair(StringRef(TRI->getSubRegIndexName(I)).lower(), I)); -} - -unsigned MIParser::getSubRegIndex(StringRef Name) { - initNames2SubRegIndices(); - auto SubRegInfo = Names2SubRegIndices.find(Name); - if (SubRegInfo == Names2SubRegIndices.end()) - return 0; - return SubRegInfo->getValue(); -} - static void initSlots2BasicBlocks( const Function &F, DenseMap &Slots2BasicBlocks) { @@ -2893,86 +2969,6 @@ return ValueInfo->second; } -void MIParser::initNames2TargetIndices() { - if (!Names2TargetIndices.empty()) - return; - const auto *TII = MF.getSubtarget().getInstrInfo(); - assert(TII && "Expected target instruction info"); - auto Indices = TII->getSerializableTargetIndices(); - for (const auto &I : Indices) - Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); -} - -bool MIParser::getTargetIndex(StringRef Name, int &Index) { - initNames2TargetIndices(); - auto IndexInfo = Names2TargetIndices.find(Name); - if (IndexInfo == Names2TargetIndices.end()) - return true; - Index = IndexInfo->second; - return false; -} - -void MIParser::initNames2DirectTargetFlags() { - if (!Names2DirectTargetFlags.empty()) - return; - const auto *TII = MF.getSubtarget().getInstrInfo(); - assert(TII && "Expected target instruction info"); - auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); - for (const auto &I : Flags) - Names2DirectTargetFlags.insert( - std::make_pair(StringRef(I.second), I.first)); -} - -bool MIParser::getDirectTargetFlag(StringRef Name, unsigned &Flag) { - initNames2DirectTargetFlags(); - auto FlagInfo = Names2DirectTargetFlags.find(Name); - if (FlagInfo == Names2DirectTargetFlags.end()) - return true; - Flag = FlagInfo->second; - return false; -} - -void MIParser::initNames2BitmaskTargetFlags() { - if (!Names2BitmaskTargetFlags.empty()) - return; - const auto *TII = MF.getSubtarget().getInstrInfo(); - assert(TII && "Expected target instruction info"); - auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags(); - for (const auto &I : Flags) - Names2BitmaskTargetFlags.insert( - std::make_pair(StringRef(I.second), I.first)); -} - -bool MIParser::getBitmaskTargetFlag(StringRef Name, unsigned &Flag) { - initNames2BitmaskTargetFlags(); - auto FlagInfo = Names2BitmaskTargetFlags.find(Name); - if (FlagInfo == Names2BitmaskTargetFlags.end()) - return true; - Flag = FlagInfo->second; - return false; -} - -void MIParser::initNames2MMOTargetFlags() { - if (!Names2MMOTargetFlags.empty()) - return; - const auto *TII = MF.getSubtarget().getInstrInfo(); - assert(TII && "Expected target instruction info"); - auto Flags = TII->getSerializableMachineMemOperandTargetFlags(); - for (const auto &I : Flags) - Names2MMOTargetFlags.insert( - std::make_pair(StringRef(I.second), I.first)); -} - -bool MIParser::getMMOTargetFlag(StringRef Name, - MachineMemOperand::Flags &Flag) { - initNames2MMOTargetFlags(); - auto FlagInfo = Names2MMOTargetFlags.find(Name); - if (FlagInfo == Names2MMOTargetFlags.end()) - return true; - Flag = FlagInfo->second; - return false; -} - MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) { // FIXME: Currently we can't recognize temporary or local symbols and call all // of the appropriate forms to create them. However, this handles basic cases Index: lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIRParser.cpp +++ lib/CodeGen/MIRParser/MIRParser.cpp @@ -53,10 +53,8 @@ StringRef Filename; LLVMContext &Context; SlotMapping IRSlots; - /// Maps from register class names to register classes. - Name2RegClassMap Names2RegClasses; - /// Maps from register bank names to register banks. - Name2RegBankMap Names2RegBanks; + std::unique_ptr Target; + /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are /// created and inserted into the given module when this is true. bool NoLLVMIR = false; @@ -150,20 +148,6 @@ SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error, SMRange SourceRange); - void initNames2RegClasses(const MachineFunction &MF); - void initNames2RegBanks(const MachineFunction &MF); - - /// Check if the given identifier is a name of a register class. - /// - /// Return null if the name isn't a register class. - const TargetRegisterClass *getRegClass(const MachineFunction &MF, - StringRef Name); - - /// Check if the given identifier is a name of a register bank. - /// - /// Return null if the name isn't a register bank. - const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name); - void computeFunctionProperties(MachineFunction &MF); }; @@ -350,8 +334,13 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF, MachineFunction &MF) { // TODO: Recreate the machine function. - initNames2RegClasses(MF); - initNames2RegBanks(MF); + if (Target) { + // Avoid clearing state if we're using the same subtarget again. + Target->setTarget(MF.getSubtarget()); + } else { + Target.reset(new PerTargetMIParsingState(MF.getSubtarget())); + } + if (YamlMF.Alignment) MF.setAlignment(YamlMF.Alignment); MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); @@ -367,8 +356,7 @@ if (YamlMF.FailedISel) MF.getProperties().set(MachineFunctionProperties::Property::FailedISel); - PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses, - Names2RegBanks); + PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target); if (parseRegisterInfo(PFS, YamlMF)) return true; if (!YamlMF.Constants.empty()) { @@ -449,12 +437,12 @@ Info.Kind = VRegInfo::GENERIC; Info.D.RegBank = nullptr; } else { - const auto *RC = getRegClass(MF, VReg.Class.Value); + const auto *RC = Target->getRegClass(VReg.Class.Value); if (RC) { Info.Kind = VRegInfo::NORMAL; Info.D.RC = RC; } else { - const RegisterBank *RegBank = getRegBank(MF, VReg.Class.Value); + const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value); if (!RegBank) return error( VReg.Class.SourceRange.Start, @@ -844,48 +832,6 @@ Error.getFixIts()); } -void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) { - if (!Names2RegClasses.empty()) - return; - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { - const auto *RC = TRI->getRegClass(I); - Names2RegClasses.insert( - std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); - } -} - -void MIRParserImpl::initNames2RegBanks(const MachineFunction &MF) { - if (!Names2RegBanks.empty()) - return; - const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo(); - // If the target does not support GlobalISel, we may not have a - // register bank info. - if (!RBI) - return; - for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) { - const auto &RegBank = RBI->getRegBank(I); - Names2RegBanks.insert( - std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); - } -} - -const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF, - StringRef Name) { - auto RegClassInfo = Names2RegClasses.find(Name); - if (RegClassInfo == Names2RegClasses.end()) - return nullptr; - return RegClassInfo->getValue(); -} - -const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF, - StringRef Name) { - auto RegBankInfo = Names2RegBanks.find(Name); - if (RegBankInfo == Names2RegBanks.end()) - return nullptr; - return RegBankInfo->getValue(); -} - MIRParser::MIRParser(std::unique_ptr Impl) : Impl(std::move(Impl)) {}