mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-14 04:57:33 +00:00
llvm-mc/AsmMatcher: Tweak string matcher.
- Track whether we need to insert an explicit 'break'. - Invert conditional when matching a single prefix to reduce nesting/bracing/breaking. - wc -l of X86GenAsmMatcher.inc decreased by 10%. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78513 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
76eb6f5685
commit
72ffae90ce
@ -734,7 +734,9 @@ FindFirstNonCommonLetter(const std::vector<const StringPair*> &Matches) {
|
|||||||
/// EmitStringMatcherForChar - Given a set of strings that are known to be the
|
/// EmitStringMatcherForChar - Given a set of strings that are known to be the
|
||||||
/// same length and whose characters leading up to CharNo are the same, emit
|
/// same length and whose characters leading up to CharNo are the same, emit
|
||||||
/// code to verify that CharNo and later are the same.
|
/// code to verify that CharNo and later are the same.
|
||||||
static void EmitStringMatcherForChar(const std::string &StrVariableName,
|
///
|
||||||
|
/// \return - True if control can leave the emitted code fragment.
|
||||||
|
static bool EmitStringMatcherForChar(const std::string &StrVariableName,
|
||||||
const std::vector<const StringPair*> &Matches,
|
const std::vector<const StringPair*> &Matches,
|
||||||
unsigned CharNo, unsigned IndentCount,
|
unsigned CharNo, unsigned IndentCount,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
@ -749,7 +751,7 @@ static void EmitStringMatcherForChar(const std::string &StrVariableName,
|
|||||||
// FIXME: If Matches[0].first has embeded \n, this will be bad.
|
// FIXME: If Matches[0].first has embeded \n, this will be bad.
|
||||||
OS << Indent << Matches[0]->second << "\t // \"" << Matches[0]->first
|
OS << Indent << Matches[0]->second << "\t // \"" << Matches[0]->first
|
||||||
<< "\"\n";
|
<< "\"\n";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bucket the matches by the character we are comparing.
|
// Bucket the matches by the character we are comparing.
|
||||||
@ -766,24 +768,24 @@ static void EmitStringMatcherForChar(const std::string &StrVariableName,
|
|||||||
unsigned FirstNonCommonLetter = FindFirstNonCommonLetter(Matches);
|
unsigned FirstNonCommonLetter = FindFirstNonCommonLetter(Matches);
|
||||||
unsigned NumChars = FirstNonCommonLetter-CharNo;
|
unsigned NumChars = FirstNonCommonLetter-CharNo;
|
||||||
|
|
||||||
|
// Emit code to break out if the prefix doesn't match.
|
||||||
if (NumChars == 1) {
|
if (NumChars == 1) {
|
||||||
// Do the comparison with if (Str[1] == 'f')
|
// Do the comparison with if (Str[1] != 'f')
|
||||||
// FIXME: Need to escape general characters.
|
// FIXME: Need to escape general characters.
|
||||||
OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] == '"
|
OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] != '"
|
||||||
<< Matches[0]->first[CharNo] << "') {\n";
|
<< Matches[0]->first[CharNo] << "')\n";
|
||||||
|
OS << Indent << " break;\n";
|
||||||
} else {
|
} else {
|
||||||
// Do the comparison with if (Str.substr(1,3) == "foo").
|
// Do the comparison with if (Str.substr(1,3) != "foo").
|
||||||
OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << ","
|
|
||||||
<< NumChars << ") == \"";
|
|
||||||
|
|
||||||
// FIXME: Need to escape general strings.
|
// FIXME: Need to escape general strings.
|
||||||
OS << Matches[0]->first.substr(CharNo, NumChars) << "\") {\n";
|
OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << ","
|
||||||
|
<< NumChars << ") != \"";
|
||||||
|
OS << Matches[0]->first.substr(CharNo, NumChars) << "\")\n";
|
||||||
|
OS << Indent << " break;";
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitStringMatcherForChar(StrVariableName, Matches, FirstNonCommonLetter,
|
return EmitStringMatcherForChar(StrVariableName, Matches,
|
||||||
IndentCount+1, OS);
|
FirstNonCommonLetter, IndentCount, OS);
|
||||||
OS << Indent << "}\n";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we have multiple possible things, emit a switch on the
|
// Otherwise, we have multiple possible things, emit a switch on the
|
||||||
@ -796,21 +798,23 @@ static void EmitStringMatcherForChar(const std::string &StrVariableName,
|
|||||||
// TODO: escape hard stuff (like \n) if we ever care about it.
|
// TODO: escape hard stuff (like \n) if we ever care about it.
|
||||||
OS << Indent << "case '" << LI->first << "':\t // "
|
OS << Indent << "case '" << LI->first << "':\t // "
|
||||||
<< LI->second.size() << " strings to match.\n";
|
<< LI->second.size() << " strings to match.\n";
|
||||||
EmitStringMatcherForChar(StrVariableName, LI->second, CharNo+1,
|
if (EmitStringMatcherForChar(StrVariableName, LI->second, CharNo+1,
|
||||||
IndentCount+1, OS);
|
IndentCount+1, OS))
|
||||||
OS << Indent << " break;\n";
|
OS << Indent << " break;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << Indent << "}\n";
|
OS << Indent << "}\n";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// EmitStringMatcher - Given a list of strings and code to execute when they
|
/// EmitStringMatcher - Given a list of strings and code to execute when they
|
||||||
/// match, output a simple switch tree to classify the input string. If a
|
/// match, output a simple switch tree to classify the input string.
|
||||||
/// match is found, the code in Vals[i].second is executed. This code should do
|
///
|
||||||
/// a return to avoid falling through. If nothing matches, execution falls
|
/// If a match is found, the code in Vals[i].second is executed; control must
|
||||||
/// through. StrVariableName is the name of teh variable to test.
|
/// not exit this code fragment. If nothing matches, execution falls through.
|
||||||
|
///
|
||||||
|
/// \param StrVariableName - The name of the variable to test.
|
||||||
static void EmitStringMatcher(const std::string &StrVariableName,
|
static void EmitStringMatcher(const std::string &StrVariableName,
|
||||||
const std::vector<StringPair> &Matches,
|
const std::vector<StringPair> &Matches,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
@ -825,16 +829,14 @@ static void EmitStringMatcher(const std::string &StrVariableName,
|
|||||||
OS << " switch (" << StrVariableName << ".size()) {\n";
|
OS << " switch (" << StrVariableName << ".size()) {\n";
|
||||||
OS << " default: break;\n";
|
OS << " default: break;\n";
|
||||||
|
|
||||||
|
|
||||||
for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI =
|
for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI =
|
||||||
MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) {
|
MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) {
|
||||||
OS << " case " << LI->first << ":\t // " << LI->second.size()
|
OS << " case " << LI->first << ":\t // " << LI->second.size()
|
||||||
<< " strings to match.\n";
|
<< " strings to match.\n";
|
||||||
EmitStringMatcherForChar(StrVariableName, LI->second, 0, 0, OS);
|
if (EmitStringMatcherForChar(StrVariableName, LI->second, 0, 0, OS))
|
||||||
OS << " break;\n";
|
OS << " break;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OS << " }\n";
|
OS << " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user