aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/DAGISelEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/DAGISelEmitter.cpp')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp64
1 files changed, 47 insertions, 17 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 7078942..d6c69ee 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1634,6 +1634,31 @@ static void RemoveAllTypes(TreePatternNode *N) {
RemoveAllTypes(N->getChild(i));
}
+/// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat' and
+/// add it to the tree. 'Pat' and 'Other' are isomorphic trees except that
+/// 'Pat' may be missing types. If we find an unresolved type to add a check
+/// for, this returns true otherwise false if Pat has all types.
+static bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
+ const std::string &Prefix, unsigned PatternNo,
+ std::ostream &OS) {
+ // Did we find one?
+ if (!Pat->hasTypeSet()) {
+ // Move a type over from 'other' to 'pat'.
+ Pat->setType(Other->getType());
+ OS << " if (" << Prefix << ".getValueType() != MVT::"
+ << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n";
+ return true;
+ } else if (Pat->isLeaf()) {
+ return false;
+ }
+
+ for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i)
+ if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i),
+ Prefix + utostr(i), PatternNo, OS))
+ return true;
+ return false;
+}
+
/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
/// stream to match the pattern, and generate the code for the match if it
/// succeeds.
@@ -1670,25 +1695,30 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
//
TreePatternNode *Pat = Pattern.first->clone();
RemoveAllTypes(Pat);
- bool MadeChange = true;
- try {
- while (MadeChange)
- MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/);
- } catch (...) {
- assert(0 && "Error: could not find consistent types for something we"
- " already decided was ok!");
- abort();
- }
-
- if (!Pat->ContainsUnresolvedType()) {
- unsigned TmpNo = 0;
- unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS);
- // Add the result to the map if it has multiple uses.
- OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n";
- OS << " return Tmp" << Res << ";\n";
- }
+ do {
+ // Resolve/propagate as many types as possible.
+ try {
+ bool MadeChange = true;
+ while (MadeChange)
+ MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/);
+ } catch (...) {
+ assert(0 && "Error: could not find consistent types for something we"
+ " already decided was ok!");
+ abort();
+ }
+
+ // Insert a check for an unresolved type and add it to the tree. If we find
+ // an unresolved type to add a check for, this returns true and we iterate,
+ // otherwise we are done.
+ } while (InsertOneTypeCheck(Pat, Pattern.first, "N", PatternNo, OS));
+
+ unsigned TmpNo = 0;
+ unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS);
+ // Add the result to the map if it has multiple uses.
+ OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n";
+ OS << " return Tmp" << Res << ";\n";
delete Pat;
OS << " }\n P" << PatternNo << "Fail:\n";