[llvm-commits] [llvm] r117888 - /llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Chris Lattner
sabre at nondot.org
Sun Oct 31 18:37:30 PDT 2010
Author: lattner
Date: Sun Oct 31 20:37:30 2010
New Revision: 117888
URL: http://llvm.org/viewvc/llvm-project?rev=117888&view=rev
Log:
Give AsmMatcherInfo a CodeGenTarget, which simplifies a bunch of
argument passing. Consolidate all SingletonRegister detection
and handling into a new
InstructionInfo::getSingletonRegisterForToken method instead of
having it scattered about. No change in generated .inc files.
Modified:
llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=117888&r1=117887&r2=117888&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Sun Oct 31 20:37:30 2010
@@ -228,7 +228,7 @@
}
namespace {
-
+ class AsmMatcherInfo;
struct SubtargetFeatureInfo;
/// ClassInfo - Helper class for storing the information about a particular
@@ -411,6 +411,11 @@
/// ConvertToMCInst to convert parsed operands into an MCInst for this
/// function.
std::string ConversionFnKind;
+
+ /// getSingletonRegisterForToken - If the specified token is a singleton
+ /// register, return the register name, otherwise return a null StringRef.
+ StringRef getSingletonRegisterForToken(unsigned i,
+ const AsmMatcherInfo &Info) const;
/// operator< - Compare two instructions.
bool operator<(const InstructionInfo &RHS) const {
@@ -493,6 +498,9 @@
/// The tablegen AsmParser record.
Record *AsmParser;
+ /// Target - The target information.
+ CodeGenTarget &Target;
+
/// The AsmParser "CommentDelimiter" value.
std::string CommentDelimiter;
@@ -531,18 +539,17 @@
/// BuildRegisterClasses - Build the ClassInfo* instances for register
/// classes.
- void BuildRegisterClasses(CodeGenTarget &Target,
- std::set<std::string> &SingletonRegisterNames);
+ void BuildRegisterClasses(std::set<std::string> &SingletonRegisterNames);
/// BuildOperandClasses - Build the ClassInfo* instances for user defined
/// operand classes.
- void BuildOperandClasses(CodeGenTarget &Target);
+ void BuildOperandClasses();
public:
- AsmMatcherInfo(Record *_AsmParser);
+ AsmMatcherInfo(Record *AsmParser, CodeGenTarget &Target);
/// BuildInfo - Construct the various tables used during matching.
- void BuildInfo(CodeGenTarget &Target);
+ void BuildInfo();
/// getSubtargetFeature - Lookup or create the subtarget feature info for the
/// given operand.
@@ -585,6 +592,43 @@
}
}
+/// getRegisterRecord - Get the register record for \arg name, or 0.
+static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
+ for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
+ const CodeGenRegister &Reg = Target.getRegisters()[i];
+ if (Name == Reg.TheDef->getValueAsString("AsmName"))
+ return Reg.TheDef;
+ }
+
+ return 0;
+}
+
+/// getSingletonRegisterForToken - If the specified token is a singleton
+/// register, return the register name, otherwise return a null StringRef.
+StringRef InstructionInfo::
+getSingletonRegisterForToken(unsigned i, const AsmMatcherInfo &Info) const {
+ StringRef Tok = Tokens[i];
+ if (!Tok.startswith(Info.RegisterPrefix))
+ return StringRef();
+
+ StringRef RegName = Tok.substr(Info.RegisterPrefix.size());
+ Record *Rec = getRegisterRecord(Info.Target, RegName);
+
+ if (!Rec) {
+ // If there is no register prefix (i.e. "%" in "%eax"), then this may
+ // be some random non-register token, just ignore it.
+ if (Info.RegisterPrefix.empty())
+ return StringRef();
+
+ std::string Err = "unable to find register for '" + RegName.str() +
+ "' (which matches register prefix)";
+ throw TGError(Instr->TheDef->getLoc(), Err);
+ }
+
+ return RegName;
+}
+
+
static std::string getEnumNameForToken(StringRef Str) {
std::string Res;
@@ -604,17 +648,6 @@
return Res;
}
-/// getRegisterRecord - Get the register record for \arg name, or 0.
-static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
- for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
- const CodeGenRegister &Reg = Target.getRegisters()[i];
- if (Name == Reg.TheDef->getValueAsString("AsmName"))
- return Reg.TheDef;
- }
-
- return 0;
-}
-
ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
ClassInfo *&Entry = TokenClasses[Token];
@@ -658,8 +691,7 @@
return CI;
}
-void AsmMatcherInfo::BuildRegisterClasses(CodeGenTarget &Target,
- std::set<std::string>
+void AsmMatcherInfo::BuildRegisterClasses(std::set<std::string>
&SingletonRegisterNames) {
std::vector<CodeGenRegisterClass> RegisterClasses;
std::vector<CodeGenRegister> Registers;
@@ -781,7 +813,7 @@
}
}
-void AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) {
+void AsmMatcherInfo::BuildOperandClasses() {
std::vector<Record*> AsmOperands;
AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
@@ -839,14 +871,14 @@
}
}
-AsmMatcherInfo::AsmMatcherInfo(Record *asmParser)
- : AsmParser(asmParser),
+AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, CodeGenTarget &target)
+ : AsmParser(asmParser), Target(target),
CommentDelimiter(AsmParser->getValueAsString("CommentDelimiter")),
RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix"))
{
}
-void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
+void AsmMatcherInfo::BuildInfo() {
// Build information about all of the AssemblerPredicates.
std::vector<Record*> AllPredicates =
Records.getAllDerivedDefinitions("Predicate");
@@ -869,10 +901,9 @@
// Parse the instructions; we need to do this first so that we can gather the
// singleton register classes.
std::set<std::string> SingletonRegisterNames;
- const std::vector<const CodeGenInstruction*> &InstrList =
- Target.getInstructionsByEnumValue();
- for (unsigned i = 0, e = InstrList.size(); i != e; ++i) {
- const CodeGenInstruction &CGI = *InstrList[i];
+ for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
+ E = Target.inst_end(); I != E; ++I) {
+ const CodeGenInstruction &CGI = **I;
// If the tblgen -match-prefix option is specified (for tblgen hackers),
// filter the set of instructions we consider.
@@ -903,24 +934,10 @@
// Collect singleton registers, if used.
for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
- if (!II->Tokens[i].startswith(RegisterPrefix))
- continue;
-
- StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
- Record *Rec = getRegisterRecord(Target, RegName);
-
- if (!Rec) {
- // If there is no register prefix (i.e. "%" in "%eax"), then this may
- // be some random non-register token, just ignore it.
- if (RegisterPrefix.empty())
- continue;
-
- std::string Err = "unable to find register for '" + RegName.str() +
- "' (which matches register prefix)";
- throw TGError(CGI.TheDef->getLoc(), Err);
- }
-
- SingletonRegisterNames.insert(RegName);
+ StringRef RegName = II->getSingletonRegisterForToken(i, *this);
+
+ if (RegName != StringRef())
+ SingletonRegisterNames.insert(RegName);
}
// Compute the require features.
@@ -934,10 +951,10 @@
}
// Build info for the register classes.
- BuildRegisterClasses(Target, SingletonRegisterNames);
+ BuildRegisterClasses(SingletonRegisterNames);
// Build info for the user defined assembly operand classes.
- BuildOperandClasses(Target);
+ BuildOperandClasses();
// Build the instruction information.
for (std::vector<InstructionInfo*>::iterator it = Instructions.begin(),
@@ -945,34 +962,29 @@
InstructionInfo *II = *it;
// The first token of the instruction is the mnemonic, which must be a
- // simple string.
+ // simple string, not a $foo variable or a singleton register.
assert(!II->Tokens.empty() && "Instruction has no tokens?");
StringRef Mnemonic = II->Tokens[0];
- assert(Mnemonic[0] != '$' &&
- (RegisterPrefix.empty() || !Mnemonic.startswith(RegisterPrefix)));
+ if (Mnemonic[0] == '$' ||
+ II->getSingletonRegisterForToken(0, *this) != StringRef())
+ throw TGError(II->Instr->TheDef->getLoc(),
+ "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
// Parse the tokens after the mnemonic.
for (unsigned i = 1, e = II->Tokens.size(); i != e; ++i) {
StringRef Token = II->Tokens[i];
// Check for singleton registers.
- if (Token.startswith(RegisterPrefix)) {
- StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
- if (Record *RegRecord = getRegisterRecord(Target, RegName)) {
- InstructionInfo::Operand Op;
- Op.Class = RegisterClasses[RegRecord];
- Op.OperandInfo = 0;
- assert(Op.Class && Op.Class->Registers.size() == 1 &&
- "Unexpected class for singleton register");
- II->Operands.push_back(Op);
- continue;
- }
-
- if (!RegisterPrefix.empty()) {
- std::string Err = "unable to find register for '" + RegName.str() +
- "' (which matches register prefix)";
- throw TGError(II->Instr->TheDef->getLoc(), Err);
- }
+ StringRef RegName = II->getSingletonRegisterForToken(i, *this);
+ if (RegName != StringRef()) {
+ Record *RegRecord = getRegisterRecord(Target, RegName);
+ InstructionInfo::Operand Op;
+ Op.Class = RegisterClasses[RegRecord];
+ Op.OperandInfo = 0;
+ assert(Op.Class && Op.Class->Registers.size() == 1 &&
+ "Unexpected class for singleton register");
+ II->Operands.push_back(Op);
+ continue;
}
// Check for simple tokens.
@@ -1259,12 +1271,11 @@
}
/// EmitClassifyOperand - Emit the function to classify an operand.
-static void EmitClassifyOperand(CodeGenTarget &Target,
- AsmMatcherInfo &Info,
+static void EmitClassifyOperand(AsmMatcherInfo &Info,
raw_ostream &OS) {
OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n"
- << " " << Target.getName() << "Operand &Operand = *("
- << Target.getName() << "Operand*)GOp;\n";
+ << " " << Info.Target.getName() << "Operand &Operand = *("
+ << Info.Target.getName() << "Operand*)GOp;\n";
// Classify tokens.
OS << " if (Operand.isToken())\n";
@@ -1279,7 +1290,7 @@
for (std::map<Record*, ClassInfo*>::iterator
it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end();
it != ie; ++it)
- OS << " case " << Target.getName() << "::"
+ OS << " case " << Info.Target.getName() << "::"
<< it->first->getName() << ": return " << it->second->Name << ";\n";
OS << " }\n";
OS << " }\n\n";
@@ -1418,8 +1429,7 @@
/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
/// definitions.
-static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
- AsmMatcherInfo &Info,
+static void EmitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
raw_ostream &OS) {
OS << "// Flags for subtarget features that participate in "
<< "instruction matching.\n";
@@ -1436,14 +1446,13 @@
/// EmitComputeAvailableFeatures - Emit the function to compute the list of
/// available features given a subtarget.
-static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
- AsmMatcherInfo &Info,
+static void EmitComputeAvailableFeatures(AsmMatcherInfo &Info,
raw_ostream &OS) {
std::string ClassName =
Info.AsmParser->getValueAsString("AsmParserClassName");
- OS << "unsigned " << Target.getName() << ClassName << "::\n"
- << "ComputeAvailableFeatures(const " << Target.getName()
+ OS << "unsigned " << Info.Target.getName() << ClassName << "::\n"
+ << "ComputeAvailableFeatures(const " << Info.Target.getName()
<< "Subtarget *Subtarget) const {\n";
OS << " unsigned Features = 0;\n";
for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
@@ -1561,8 +1570,8 @@
std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
// Compute the information on the instructions to match.
- AsmMatcherInfo Info(AsmParser);
- Info.BuildInfo(Target);
+ AsmMatcherInfo Info(AsmParser, Target);
+ Info.BuildInfo();
// Sort the instruction table using the partial order on classes. We use
// stable_sort to ensure that ambiguous instructions are still
@@ -1627,7 +1636,7 @@
OS << "#undef GET_REGISTER_MATCHER\n\n";
// Emit the subtarget feature enumeration.
- EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
+ EmitSubtargetFeatureFlagEnumeration(Info, OS);
// Emit the function to match a register name to number.
EmitMatchRegisterName(Target, AsmParser, OS);
@@ -1651,13 +1660,13 @@
EmitMatchTokenString(Target, Info.Classes, OS);
// Emit the routine to classify an operand.
- EmitClassifyOperand(Target, Info, OS);
+ EmitClassifyOperand(Info, OS);
// Emit the subclass predicate routine.
EmitIsSubclass(Target, Info.Classes, OS);
// Emit the available features compute function.
- EmitComputeAvailableFeatures(Target, Info, OS);
+ EmitComputeAvailableFeatures(Info, OS);
size_t MaxNumOperands = 0;
More information about the llvm-commits
mailing list