change the singleton register handling code to be based on Record*'s

instead of strings, simplifying it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117889 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-11-01 01:47:07 +00:00
parent 02bcbc97fb
commit 1de8823578

View File

@ -78,6 +78,7 @@
#include "Record.h" #include "Record.h"
#include "StringMatcher.h" #include "StringMatcher.h"
#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
@ -413,9 +414,9 @@ struct InstructionInfo {
std::string ConversionFnKind; std::string ConversionFnKind;
/// getSingletonRegisterForToken - If the specified token is a singleton /// getSingletonRegisterForToken - If the specified token is a singleton
/// register, return the register name, otherwise return a null StringRef. /// register, return the Record for it, otherwise return null.
StringRef getSingletonRegisterForToken(unsigned i, Record *getSingletonRegisterForToken(unsigned i,
const AsmMatcherInfo &Info) const; const AsmMatcherInfo &Info) const;
/// operator< - Compare two instructions. /// operator< - Compare two instructions.
bool operator<(const InstructionInfo &RHS) const { bool operator<(const InstructionInfo &RHS) const {
@ -539,7 +540,7 @@ private:
/// BuildRegisterClasses - Build the ClassInfo* instances for register /// BuildRegisterClasses - Build the ClassInfo* instances for register
/// classes. /// classes.
void BuildRegisterClasses(std::set<std::string> &SingletonRegisterNames); void BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters);
/// BuildOperandClasses - Build the ClassInfo* instances for user defined /// BuildOperandClasses - Build the ClassInfo* instances for user defined
/// operand classes. /// operand classes.
@ -605,27 +606,24 @@ static Record *getRegisterRecord(CodeGenTarget &Target, StringRef Name) {
/// getSingletonRegisterForToken - If the specified token is a singleton /// getSingletonRegisterForToken - If the specified token is a singleton
/// register, return the register name, otherwise return a null StringRef. /// register, return the register name, otherwise return a null StringRef.
StringRef InstructionInfo:: Record *InstructionInfo::
getSingletonRegisterForToken(unsigned i, const AsmMatcherInfo &Info) const { getSingletonRegisterForToken(unsigned i, const AsmMatcherInfo &Info) const {
StringRef Tok = Tokens[i]; StringRef Tok = Tokens[i];
if (!Tok.startswith(Info.RegisterPrefix)) if (!Tok.startswith(Info.RegisterPrefix))
return StringRef(); return 0;
StringRef RegName = Tok.substr(Info.RegisterPrefix.size()); StringRef RegName = Tok.substr(Info.RegisterPrefix.size());
Record *Rec = getRegisterRecord(Info.Target, RegName); if (Record *Rec = getRegisterRecord(Info.Target, RegName))
return Rec;
if (!Rec) { // If there is no register prefix (i.e. "%" in "%eax"), then this may
// If there is no register prefix (i.e. "%" in "%eax"), then this may // be some random non-register token, just ignore it.
// be some random non-register token, just ignore it. if (Info.RegisterPrefix.empty())
if (Info.RegisterPrefix.empty()) return 0;
return StringRef();
std::string Err = "unable to find register for '" + RegName.str() + std::string Err = "unable to find register for '" + RegName.str() +
"' (which matches register prefix)"; "' (which matches register prefix)";
throw TGError(Instr->TheDef->getLoc(), Err); throw TGError(Instr->TheDef->getLoc(), Err);
}
return RegName;
} }
@ -691,8 +689,8 @@ AsmMatcherInfo::getOperandClass(StringRef Token,
return CI; return CI;
} }
void AsmMatcherInfo::BuildRegisterClasses(std::set<std::string> void AsmMatcherInfo::
&SingletonRegisterNames) { BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
std::vector<CodeGenRegisterClass> RegisterClasses; std::vector<CodeGenRegisterClass> RegisterClasses;
std::vector<CodeGenRegister> Registers; std::vector<CodeGenRegister> Registers;
@ -709,10 +707,11 @@ void AsmMatcherInfo::BuildRegisterClasses(std::set<std::string>
it->Elements.end())); it->Elements.end()));
// Add any required singleton sets. // Add any required singleton sets.
for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(), for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
ie = SingletonRegisterNames.end(); it != ie; ++it) ie = SingletonRegisters.end(); it != ie; ++it) {
if (Record *Rec = getRegisterRecord(Target, *it)) Record *Rec = *it;
RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1)); RegisterSets.insert(std::set<Record*>(&Rec, &Rec + 1));
}
// Introduce derived sets where necessary (when a register does not determine // Introduce derived sets where necessary (when a register does not determine
// a unique register set class), and build the mapping of registers to the set // a unique register set class), and build the mapping of registers to the set
@ -797,19 +796,18 @@ void AsmMatcherInfo::BuildRegisterClasses(std::set<std::string>
this->RegisterClasses[it->first] = RegisterSetClasses[it->second]; this->RegisterClasses[it->first] = RegisterSetClasses[it->second];
// Name the register classes which correspond to singleton registers. // Name the register classes which correspond to singleton registers.
for (std::set<std::string>::iterator it = SingletonRegisterNames.begin(), for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
ie = SingletonRegisterNames.end(); it != ie; ++it) { ie = SingletonRegisters.end(); it != ie; ++it) {
if (Record *Rec = getRegisterRecord(Target, *it)) { Record *Rec = *it;
ClassInfo *CI = this->RegisterClasses[Rec]; ClassInfo *CI = this->RegisterClasses[Rec];
assert(CI && "Missing singleton register class info!"); assert(CI && "Missing singleton register class info!");
if (CI->ValueName.empty()) { if (CI->ValueName.empty()) {
CI->ClassName = Rec->getName(); CI->ClassName = Rec->getName();
CI->Name = "MCK_" + Rec->getName(); CI->Name = "MCK_" + Rec->getName();
CI->ValueName = Rec->getName(); CI->ValueName = Rec->getName();
} else } else
CI->ValueName = CI->ValueName + "," + Rec->getName(); CI->ValueName = CI->ValueName + "," + Rec->getName();
}
} }
} }
@ -900,7 +898,7 @@ void AsmMatcherInfo::BuildInfo() {
// Parse the instructions; we need to do this first so that we can gather the // Parse the instructions; we need to do this first so that we can gather the
// singleton register classes. // singleton register classes.
std::set<std::string> SingletonRegisterNames; SmallPtrSet<Record*, 16> SingletonRegisters;
for (CodeGenTarget::inst_iterator I = Target.inst_begin(), for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
E = Target.inst_end(); I != E; ++I) { E = Target.inst_end(); I != E; ++I) {
const CodeGenInstruction &CGI = **I; const CodeGenInstruction &CGI = **I;
@ -934,10 +932,8 @@ void AsmMatcherInfo::BuildInfo() {
// Collect singleton registers, if used. // Collect singleton registers, if used.
for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) { for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
StringRef RegName = II->getSingletonRegisterForToken(i, *this); if (Record *Reg = II->getSingletonRegisterForToken(i, *this))
SingletonRegisters.insert(Reg);
if (RegName != StringRef())
SingletonRegisterNames.insert(RegName);
} }
// Compute the require features. // Compute the require features.
@ -951,7 +947,7 @@ void AsmMatcherInfo::BuildInfo() {
} }
// Build info for the register classes. // Build info for the register classes.
BuildRegisterClasses(SingletonRegisterNames); BuildRegisterClasses(SingletonRegisters);
// Build info for the user defined assembly operand classes. // Build info for the user defined assembly operand classes.
BuildOperandClasses(); BuildOperandClasses();
@ -965,8 +961,7 @@ void AsmMatcherInfo::BuildInfo() {
// simple string, not a $foo variable or a singleton register. // simple string, not a $foo variable or a singleton register.
assert(!II->Tokens.empty() && "Instruction has no tokens?"); assert(!II->Tokens.empty() && "Instruction has no tokens?");
StringRef Mnemonic = II->Tokens[0]; StringRef Mnemonic = II->Tokens[0];
if (Mnemonic[0] == '$' || if (Mnemonic[0] == '$' || II->getSingletonRegisterForToken(0, *this))
II->getSingletonRegisterForToken(0, *this) != StringRef())
throw TGError(II->Instr->TheDef->getLoc(), throw TGError(II->Instr->TheDef->getLoc(),
"Invalid instruction mnemonic '" + Mnemonic.str() + "'!"); "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
@ -975,9 +970,7 @@ void AsmMatcherInfo::BuildInfo() {
StringRef Token = II->Tokens[i]; StringRef Token = II->Tokens[i];
// Check for singleton registers. // Check for singleton registers.
StringRef RegName = II->getSingletonRegisterForToken(i, *this); if (Record *RegRecord = II->getSingletonRegisterForToken(i, *this)) {
if (RegName != StringRef()) {
Record *RegRecord = getRegisterRecord(Target, RegName);
InstructionInfo::Operand Op; InstructionInfo::Operand Op;
Op.Class = RegisterClasses[RegRecord]; Op.Class = RegisterClasses[RegRecord];
Op.OperandInfo = 0; Op.OperandInfo = 0;