#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"
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<const uint32_t *> RegMasks = TRI->getRegMasks();
+ ArrayRef<const char *> 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) {
StringRef Source, CurrentSource;
MIToken Token;
PerFunctionMIParsingState &PFS;
- /// Maps from instruction names to op codes.
- StringMap<unsigned> Names2InstrOpCodes;
- /// Maps from register names to registers.
- StringMap<unsigned> Names2Regs;
- /// Maps from register mask names to register masks.
- StringMap<const uint32_t *> Names2RegMasks;
- /// Maps from subregister names to subregister indices.
- StringMap<unsigned> Names2SubRegIndices;
/// Maps from slot numbers to function's unnamed basic blocks.
DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
/// Maps from slot numbers to function's unnamed values.
DenseMap<unsigned, const Value *> Slots2Values;
- /// Maps from target index names to target indices.
- StringMap<int> Names2TargetIndices;
- /// Maps from direct target flag names to the direct target flag values.
- StringMap<unsigned> Names2DirectTargetFlags;
- /// Maps from direct target flag names to the bitmask target flag values.
- StringMap<unsigned> Names2BitmaskTargetFlags;
- /// Maps from MMO target flag names to MMO target flag values.
- StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags;
public:
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
/// 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,
bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> 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);
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;
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;
}
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;
// 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();
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();
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();
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))
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;
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() +
"'");
}
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.
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;
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<const uint32_t *> RegMasks = TRI->getRegMasks();
- ArrayRef<const char *> 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<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
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
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class SourceMgr;
class StringRef;
class TargetRegisterClass;
+class TargetSubtargetInfo;
struct VRegInfo {
enum uint8_t {
using Name2RegClassMap = StringMap<const TargetRegisterClass *>;
using Name2RegBankMap = StringMap<const RegisterBank *>;
+struct PerTargetMIParsingState {
+private:
+ const TargetSubtargetInfo &Subtarget;
+
+ /// Maps from instruction names to op codes.
+ StringMap<unsigned> Names2InstrOpCodes;
+
+ /// Maps from register names to registers.
+ StringMap<unsigned> Names2Regs;
+
+ /// Maps from register mask names to register masks.
+ StringMap<const uint32_t *> Names2RegMasks;
+
+ /// Maps from subregister names to subregister indices.
+ StringMap<unsigned> Names2SubRegIndices;
+
+ /// Maps from target index names to target indices.
+ StringMap<int> Names2TargetIndices;
+
+ /// Maps from direct target flag names to the direct target flag values.
+ StringMap<unsigned> Names2DirectTargetFlags;
+
+ /// Maps from direct target flag names to the bitmask target flag values.
+ StringMap<unsigned> Names2BitmaskTargetFlags;
+
+ /// Maps from MMO target flag names to MMO target flag values.
+ StringMap<MachineMemOperand::Flags> 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<unsigned, MachineBasicBlock *> MBBSlots;
DenseMap<unsigned, VRegInfo*> VRegInfos;
PerFunctionMIParsingState(MachineFunction &MF, SourceMgr &SM,
const SlotMapping &IRSlots,
- const Name2RegClassMap &Names2RegClasses,
- const Name2RegBankMap &Names2RegBanks);
+ PerTargetMIParsingState &Target);
VRegInfo &getVRegInfo(unsigned Num);
VRegInfo &getVRegInfoNamed(StringRef RegName);