Implement the last major missing piece in the DAG isel generator: when emitting

a pattern match, make sure to emit the (minimal number of) type checks that
verify the pattern matches this specific instruction.  This allows FMA32
patterns to not match double expressions for example.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23748 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-10-15 21:34:21 +00:00
parent 8136cdae60
commit 7e82f1322c

View File

@ -1634,6 +1634,31 @@ static void RemoveAllTypes(TreePatternNode *N) {
RemoveAllTypes(N->getChild(i)); 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 /// 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 /// stream to match the pattern, and generate the code for the match if it
/// succeeds. /// succeeds.
@ -1670,25 +1695,30 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
// //
TreePatternNode *Pat = Pattern.first->clone(); TreePatternNode *Pat = Pattern.first->clone();
RemoveAllTypes(Pat); RemoveAllTypes(Pat);
bool MadeChange = true;
try { do {
while (MadeChange) // Resolve/propagate as many types as possible.
MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/); try {
} catch (...) { bool MadeChange = true;
assert(0 && "Error: could not find consistent types for something we" while (MadeChange)
" already decided was ok!"); MadeChange = Pat->ApplyTypeConstraints(TP,true/*Ignore reg constraints*/);
abort(); } catch (...) {
} assert(0 && "Error: could not find consistent types for something we"
" already decided was ok!");
abort();
}
if (!Pat->ContainsUnresolvedType()) { // Insert a check for an unresolved type and add it to the tree. If we find
unsigned TmpNo = 0; // an unresolved type to add a check for, this returns true and we iterate,
unsigned Res = CodeGenPatternResult(Pattern.second, TmpNo, VariableMap, OS); // otherwise we are done.
} while (InsertOneTypeCheck(Pat, Pattern.first, "N", PatternNo, OS));
// Add the result to the map if it has multiple uses.
OS << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp" << Res << ";\n"; unsigned TmpNo = 0;
OS << " return Tmp" << Res << ";\n"; 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; delete Pat;
OS << " }\n P" << PatternNo << "Fail:\n"; OS << " }\n P" << PatternNo << "Fail:\n";